Team: Yonsei University Data Science Lab (DSL) · NLP2 Modeling Team
Affiliation: Yonsei University Data Science Lab (DSL)
IRMA (Integrated Response for Multi-domain Administration) is a multi-agent LLM system that guides citizens through complaint procedures (민원) and subsidy / welfare programs (지원·복지) using a unified conversational interface.
By combining Supervisor → Knowledge → Action agent orchestration with Supabase semantic + text-index retrieval, phrase-first complaint ranking, and a FastAPI web UI, IRMA turns natural-language questions into structured service lookup and actionable answers grounded in a curated public-service database.
| Item | Description |
|---|---|
| Title | IRMA — Integrated Administrative & Welfare Guidance |
| Team | DSL NLP2 Modeling Team (Yonsei University) |
| Objective | Answer citizen questions about complaints and subsidies with accurate, grounded multi-turn guidance |
| Core Components | Supervisor Agent · Knowledge Agent · Action Agent · NLPMappingTool (Supabase) · FastAPI Web UI |
| Data Sources | Complaint services (민원) · Subsidy / welfare programs (지원·복지) |
| LLM | OpenAI GPT-4.1-mini (parsing & answer generation) |
| Embeddings | OpenAI text-embedding-3-small (pgvector semantic search) |
- Parses each user utterance into a structured
ParsedUserRequest(JSON). - Classifies data source (
COMPLAINTvsSUBSIDY), intent (lookup, eligibility, documents, fees, etc.), region, and user profile. - Detects missing fields and issues follow-up questions when the query is ambiguous.
- Handles multi-turn context: service selection from a prior candidate list, keyword carry-over, and persona-aware query refinement.
📁 Key files
agents/supervisor_agent.pyconfig/prompts.py
The Supervisor acts as the router and dialog manager, deciding whether to clarify, search, or finalize.
- Maps
ParsedUserRequestto Supabase records viaNLPMappingTool. - Subsidy (SUBSIDY): semantic search (
match_servicesRPC) + region-aware re-ranking. - Complaint (COMPLAINT): phrase-first text-index search with tuned integer ranking weights.
- Returns an
EvidencePack— ranked service candidates with match explanations and full detail fields (documents, application channels, etc.).
📁 Key files
agents/knowledge_agent.pytools/nlp_mapping_tool.pysupabase/match_services.sql
Knowledge retrieval is the evidence layer — every answer is anchored to concrete service records, not free-form hallucination.
- Consumes
ParsedUserRequest+EvidencePackand produces the finalActionResult. - Multiple candidates (≥2): presents a numbered list and asks the user to choose.
- Single candidate / detail mode: cites DB fields (required documents, channels, eligibility) in natural language.
- Optionally enriches answers with Brave Search snippets when external context is needed (
tools/external_search_tool.py).
📁 Key files
agents/action_agent.pyconfig/prompts.py
The Action Agent is the presentation layer — it converts structured evidence into citizen-friendly guidance.
- Session-based chat API (
POST /api/v1/chat) with cookie-backed session IDs. - Interactive multi-candidate selection buttons when the pipeline returns multiple services.
- Optional Redis backend for persistent sessions across processes.
- Local launch:
python -m web→ http://127.0.0.1:8080
📁 Key files
web/app.py,web/templates/index.html,web/static/
- Python 3.12+ recommended
- Supabase project with complaint & subsidy tables +
match_servicesRPC - OpenAI API key
cd IRMA_mk3/IRMA_mk2
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env # fill in API keys
python -m web # web UI at http://127.0.0.1:8080Terminal (CLI) mode:
python main.py| Variable | Required | Description |
|---|---|---|
OPENAI_API_KEY |
Yes | LLM & embedding calls |
SUPABASE_URL |
Yes | Supabase project URL |
SUPABASE_ANON_KEY or SUPABASE_SERVICE_ROLE_KEY |
Yes | PostgREST access |
BRAVE_API_KEY |
No | External search fallback |
REDIS_URL |
No | Persistent session store (default: in-memory) |
See .env.example for the full template. Never commit .env with real keys.
Final web UI demonstration: IRMA testing.mp4 (Google Drive)
IRMA was evaluated on curated gold sets covering complaint and subsidy queries with labeled service_id, data_source, intent, and follow-up expectations.
Grid search over re-ranking integer weights on a 300-query evaluation set:
| Metric | Best tuned result |
|---|---|
| Hit@1 | 50.7% |
| Hit@5 | 73.0% |
| Mean Top-1 F1 | 50.7% |
| Mean Top-k F1 | 25.8% |
Key tuning insights:
- Phrase-first gating for complaint text-index search stabilizes ranking.
- Region-aware weights (
region_metro_hit,region_district_hit) improve subsidy retrieval. - Special-condition bonuses (military, youth) reduce false negatives on targeted programs.
Full Supervisor → Knowledge → Action runs were scored on:
| Dimension | What was measured |
|---|---|
| Parsing accuracy | data_source, intent, follow-up need vs. gold labels |
| Retrieval accuracy | Gold service_id in top-k evidence |
| Dialog behavior | Correct follow-up questions vs. premature answers |
| Answer quality | Grounded citation of DB fields in final responses |
Batch evaluation was performed via main.py --script with --trace-json for per-turn traces; summaries are generated by evaluation/trace_summary.py.
IRMA_mk3/IRMA_mk2/
├── main.py # CLI & script-mode entry point
├── requirements.txt
├── .env.example # Environment template (no secrets)
│
├── agents/ # Multi-agent pipeline
│ ├── supervisor_agent.py # 1. Parse & clarify
│ ├── knowledge_agent.py # 2. Retrieve from DB
│ └── action_agent.py # 3. Generate answer
│
├── tools/ # Retrieval & schemas
│ ├── nlp_mapping_tool.py # Supabase search + re-ranking
│ ├── external_search_tool.py # Brave Search (optional)
│ └── schemas.py # Pydantic models
│
├── infra/ # Orchestration & state
│ ├── manager.py # run_turn() pipeline
│ ├── state_store.py # In-memory session/case store
│ ├── redis_state_store.py # Redis session store (optional)
│ ├── pii_masker.py # Phone-number masking
│ └── logging_tool.py # Structured JSON logs
│
├── config/
│ ├── prompts.py # Agent system prompts
│ └── settings.yaml # Model name, top_k, etc.
│
├── web/ # FastAPI web UI
│ ├── app.py
│ ├── templates/index.html
│ └── static/ # Logos, avatars, OG image
│
├── supabase/
│ ├── match_services.sql # pgvector RPC definition
│ └── README.md # DB setup guide
│
└── evaluation/ # Trace summary utilities (script mode)
├── trace_summary.py
└── results_layout.py
- No API keys or credentials are included in this repository.
.envis listed in.gitignore; only.env.examplewith placeholders is shipped.- User phone numbers are masked via
infra/pii_masker.pybefore logging. - Supabase credentials must be supplied by the evaluator at runtime.
This project was conducted for academic and non-commercial purposes under the Yonsei University Data Science Lab (DSL). Public-service data is used strictly for research and demonstration. Generated guidance is informational only and does not constitute official government advice.
- LangChain — langchain-ai/langchain
- FastAPI — tiangolo/fastapi
- OpenAI Python SDK — openai/openai-python
- Supabase PostgREST — supabase/postgrest-py
- GPT-4.1-mini — OpenAI chat model for agent parsing & generation
- text-embedding-3-small — OpenAI embedding model for semantic service search
- pgvector — Vector similarity search in PostgreSQL
- Brave Search API — Optional external web search enrichment
- Redis — Optional session persistence for web deployment
supabase/README.md— Database schema and RPC setupweb/app.pymodule docstring — Web server configuration options
Korean version: README_ko.md