A LangChain RAG + agent application for Medicare risk-adjustment coding. Coders describe conditions in clinical language; the assistant retrieves candidate ICD-10-CM codes, validates them, maps them to CMS-HCC V28 categories, and estimates RAF impact — with every number coming from tools over official CMS reference data, never from LLM memory.
Inspired by a production HCC extraction pipeline I built for a value-based care organization; this repo is a standalone, shareable implementation over public CMS data (ICD-10-CM 2026, CMS-HCC V28 mappings and coefficients).
py -m venv .venv
.venv\Scripts\pip install -r requirements.txt
# .env in the project root must contain OPENAI_API_KEY (and optionally OPENAI_MODEL)
.venv\Scripts\python kb_build.py # one-time: embeds ~8K HCC-mapped codes
.venv\Scripts\python chat.py| Piece | File | LangChain concept |
|---|---|---|
| Code catalog → embedded documents | kb_build.py |
Document, OpenAIEmbeddings, InMemoryVectorStore |
| Clinical language → candidate codes | agent.py |
retriever, create_retriever_tool |
| Validation / HCC mapping / RAF math | hcc_tools.py |
@tool (docstring = tool description the LLM reads) |
| Decides retrieve vs. calculate vs. answer | agent.py |
create_agent (LangChain 1.x, LangGraph-based) |
| Multi-turn context ("now add CHF to that") | agent.py |
LangGraph InMemorySaver checkpointer + thread_id |
| System behavior + guardrails | agent.py |
system_prompt on the agent |
- RAG over the code catalog, not the LLM's memory. ICD/HCC mappings change yearly; the model's parametric knowledge is stale and unverifiable. Retrieval pins answers to the 2026 files this repo ships.
- Deterministic math lives in tools. RAF coefficients are looked up and summed in Python. The agent is prompted to never compute coefficients from memory.
- Validation before presentation. The system prompt forces
lookup_icd10before any code is shown. - Simplified RAF model, stated as such. The tool ignores V28 hierarchies, interactions, and demographic factors, and says so in every answer. Honest scoping beats silent wrongness.
InMemoryVectorStoreon purpose. ~8K short documents don't need a vector database; zero native dependencies keeps the demo reproducible on any machine. Swapping to Chroma/pgvector is a two-line change if the corpus grows.
elderly patient with type 2 diabetes, stage 4 CKD, and chronic systolic heart failure
what HCC does E11.22 map to?
calculate RAF for E11.22, I50.22, N18.4
is Z79.4 risk-adjusting?
tell me about HCC 226
Public CMS reference files (2026 payment year): ICD-10-CM code descriptions, CMS-HCC V28 ICD-to-HCC mapping, V28 RAF coefficients (Community NonDual Aged), and HCC category descriptions.