How to Build a policy Q&A Agent Using LangGraph in Python for healthcare

By Cyprian AaronsUpdated 2026-04-21
policy-q-alanggraphpythonhealthcarepolicy-qanda

A policy Q&A agent for healthcare answers questions like “Does this plan cover telehealth?” or “What is the prior auth rule for MRI?” by retrieving the right policy, checking the answer against approved sources, and returning a grounded response with citations. That matters because healthcare teams cannot afford hallucinated policy answers: bad guidance creates compliance risk, denied claims, and patient friction.

Architecture

  • User input layer

    • Accepts free-text policy questions from staff, members, or support agents.
    • Normalizes intent and strips obvious PHI before any downstream processing.
  • Policy retrieval layer

    • Pulls from approved sources only: plan documents, SOPs, coverage policies, CMS guidance, internal knowledge bases.
    • Uses vector search or keyword retrieval depending on how structured the corpus is.
  • Reasoning and answer generation layer

    • Produces a grounded answer from retrieved policy snippets.
    • Must cite source passages and avoid answering when evidence is weak.
  • Guardrail and compliance layer

    • Detects PHI/PII exposure, blocks unsupported claims, and enforces “answer only from sources.”
    • Adds audit metadata: source IDs, timestamps, model version, and decision path.
  • Human escalation layer

    • Routes ambiguous or high-risk questions to a reviewer.
    • Useful for benefit exceptions, appeals, prior auth edge cases, and state-specific rules.

Implementation

1. Model the workflow as a LangGraph state machine

For healthcare policy Q&A, the graph should do three things in order: retrieve evidence, generate an answer, then grade whether the answer is safe enough to return. LangGraph’s StateGraph is a good fit because you can make each step explicit and auditable.

from typing import TypedDict, List
from langgraph.graph import StateGraph, START, END
from langchain_core.documents import Document
from langchain_core.messages import HumanMessage
from langchain_openai import ChatOpenAI

class PolicyState(TypedDict):
    question: str
    docs: List[Document]
    answer: str
    needs_human_review: bool

llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)

def retrieve_policy(state: PolicyState) -> PolicyState:
    # Replace with your vector store / search backend
    docs = [
        Document(
            page_content="Telehealth visits are covered for behavioral health services.",
            metadata={"source": "policy_telehealth_v3.pdf", "section": "2.1"}
        )
    ]
    return {**state, "docs": docs}

def generate_answer(state: PolicyState) -> PolicyState:
    context = "\n\n".join(
        f"[{d.metadata['source']}#{d.metadata['section']}] {d.page_content}"
        for d in state["docs"]
    )
    prompt = (
        "Answer the healthcare policy question using only the provided context.\n"
        f"Question: {state['question']}\n\nContext:\n{context}\n\n"
        "Return a concise answer with citations."
    )
    response = llm.invoke([HumanMessage(content=prompt)])
    return {**state, "answer": response.content}

def grade_answer(state: PolicyState) -> PolicyState:
    needs_review = len(state["docs"]) == 0 or "cannot determine" in state["answer"].lower()
    return {**state, "needs_human_review": needs_review}

graph = StateGraph(PolicyState)
graph.add_node("retrieve_policy", retrieve_policy)
graph.add_node("generate_answer", generate_answer)
graph.add_node("grade_answer", grade_answer)

graph.add_edge(START, "retrieve_policy")
graph.add_edge("retrieve_policy", "generate_answer")
graph.add_edge("generate_answer", "grade_answer")
graph.add_conditional_edges(
    "grade_answer",
    lambda state: "human_review" if state["needs_human_review"] else END,
    {"human_review": END}
)

app = graph.compile()

2. Add a real retrieval step backed by approved healthcare content

In production you should replace the stubbed retrieve_policy() function with a retriever from your indexed corpus. Keep the corpus narrow and curated; for healthcare policy work, “more documents” usually means more ambiguity.

A practical pattern is:

  • chunk by section boundaries instead of arbitrary token windows
  • store source metadata like document ID, effective date, jurisdiction, and version
  • filter by line of business and state before semantic search
  • reject expired policies unless explicitly requested

If you are using a vector store through LangChain-compatible retrievers, your node can call retriever.invoke(question) and pass those Document objects into the graph state.

3. Add escalation logic for low-confidence or regulated questions

Healthcare policy has many edge cases that should not be auto-answered. Prior auth exceptions, Medicare Advantage rules, state-specific coverage differences, and anything involving patient-specific facts should go to review when confidence is low.

def route_after_grade(state: PolicyState):
    if state["needs_human_review"]:
        return "human_review"
    return END

# Example of adding an explicit human review node later:
def human_review(state: PolicyState) -> PolicyState:
    reviewed_answer = (
        "Escalated to policy analyst due to insufficient evidence. "
        f"Question was: {state['question']}"
    )
    return {**state, "answer": reviewed_answer}

If you want stronger control over routing decisions in LangGraph v1-style APIs later on, keep routing logic isolated in small functions like route_after_grade(). That makes audits easier because you can explain exactly why a question was escalated.

4. Expose the graph behind an API with audit logging

Your API handler should log the question hash, retrieved source IDs, final route taken through the graph, and model version. Do not log raw PHI unless your compliance posture explicitly allows it and your storage location is approved.

A minimal production shape looks like this:

  • request comes in through FastAPI
  • sanitize input for obvious identifiers
  • invoke app.invoke({"question": user_question})
  • persist trace metadata to your audit store
  • return answer plus citations or escalation status

Production Considerations

  • Compliance controls

    • Enforce “answer only from approved sources.”
    • Store prompt/response traces in an audit log with retention aligned to your policy.
    • Make sure access controls reflect HIPAA minimum necessary principles.
  • Data residency

    • Keep embeddings, logs, and model traffic in approved regions.
    • If your organization has residency requirements by country or state network boundary, pin both vector storage and inference endpoints accordingly.
  • Monitoring

    • Track retrieval hit rate, escalation rate, citation coverage, and unanswered-question volume.
    • Alert on answers generated without supporting documents or with stale source versions.
  • Guardrails

    • Detect PHI before sending text to external services.
    • Block medical advice responses; this agent should answer policy questions only.
    • Require citations for every factual claim returned to users.

Common Pitfalls

  1. Using generic RAG over uncurated documents

    • This causes conflicting answers across versions of policies.
    • Fix it by indexing only approved sources and filtering by effective date and jurisdiction before retrieval.
  2. Letting the model answer without evidence

    • In healthcare this becomes a compliance problem fast.
    • Fix it by making “no docs found” a first-class branch that routes to human review instead of forcing an answer.
  3. Logging sensitive text everywhere

    • Raw prompts often contain member IDs, diagnoses, or claim details.
    • Fix it by redacting inputs early and storing only hashed identifiers plus minimal audit metadata unless full-text retention is explicitly approved.

A healthcare policy Q&A agent works when it behaves like a controlled workflow instead of a chat demo. LangGraph gives you that control: explicit nodes for retrieval, generation, grading, and escalation; clear auditability; and enough structure to keep compliance teams comfortable without slowing developers down.


Keep learning

By Cyprian Aarons, AI Consultant at Topiax.

Want the complete 8-step roadmap?

Grab the free AI Agent Starter Kit — architecture templates, compliance checklists, and a 7-email deep-dive course.

Get the Starter Kit

Related Guides