How to Build a policy Q&A Agent Using LlamaIndex in TypeScript for healthcare
A policy Q&A agent for healthcare answers questions from staff, patients, or admins using approved policy documents instead of free-form model memory. That matters because healthcare teams need fast answers on eligibility, consent, retention, billing, and clinical operations without exposing protected data or inventing policy.
Architecture
- •
Document ingestion layer
- •Pulls policy PDFs, SOPs, handbooks, and compliance docs from a controlled source.
- •Splits content into chunks with metadata like
policyId,version,department, andjurisdiction.
- •
Vector index
- •Stores embeddings for semantic retrieval over policy text.
- •In TypeScript with LlamaIndex, this is typically an
InMemoryVectorStorefor dev or a persistent vector backend in production.
- •
Retriever
- •Finds the most relevant policy chunks for each question.
- •Should be tuned for healthcare terminology, abbreviations, and versioned policies.
- •
Response synthesizer / query engine
- •Generates grounded answers only from retrieved policy context.
- •Must refuse to answer when the policy corpus does not support the request.
- •
Guardrail layer
- •Blocks PHI leakage, unsafe medical advice, and unsupported compliance claims.
- •Adds redaction, citation checks, and escalation paths to human review.
- •
Audit and observability
- •Logs question, retrieved policy IDs, answer text, confidence signals, and user identity.
- •Required for compliance review and incident investigation.
Implementation
1) Install dependencies and load policies
Use the TypeScript LlamaIndex package and keep your documents tagged with healthcare metadata. In production, store source files in a controlled bucket or document system with access logging.
npm install llamaindex
import {
Document,
VectorStoreIndex,
Settings,
OpenAIEmbedding,
} from "llamaindex";
const policyDocs = [
new Document({
text: `
Employee Privacy Policy v3.2
Staff must not access patient charts unless they are assigned to the care team.
All access is logged and reviewed monthly.
`,
metadata: {
policyId: "HIPAA-PRIV-0032",
version: "3.2",
department: "Compliance",
jurisdiction: "US",
},
}),
new Document({
text: `
Medical Records Retention Policy
Adult patient records are retained for seven years after last encounter.
Minors' records are retained until age of majority plus seven years.
`,
metadata: {
policyId: "MRR-0011",
version: "1.1",
department: "Health Information Management",
jurisdiction: "US",
},
}),
];
Settings.embedModel = new OpenAIEmbedding({
model: "text-embedding-3-small",
});
2) Build the index and query engine
For a policy agent, retrieval quality matters more than generation style. Keep the answer constrained to retrieved context and return citations back to the source metadata.
const index = await VectorStoreIndex.fromDocuments(policyDocs);
const queryEngine = index.asQueryEngine({
similarityTopK: 3,
});
const response = await queryEngine.query({
query: "How long do we retain adult patient records?",
});
console.log(String(response));
That basic pattern works for a prototype. For healthcare use cases, you want the response to include source context so reviewers can verify which policy drove the answer.
3) Add structured citations and refusal behavior
The agent should answer only when it has enough evidence. If retrieval returns weak matches or conflicting versions, return an escalation message instead of guessing.
import { QueryEngineTool } from "llamaindex";
async function answerPolicyQuestion(question: string) {
const response = await queryEngine.query({ query: question });
const sourceNodes = response.sourceNodes ?? [];
if (sourceNodes.length === 0) {
return {
answer:
"I could not find an approved policy that answers this question. Please route it to Compliance or HIM.",
citations: [],
};
}
return {
answer: String(response),
citations: sourceNodes.map((node) => ({
policyId: node.node.metadata?.policyId,
version: node.node.metadata?.version,
department: node.node.metadata?.department,
})),
};
}
const result = await answerPolicyQuestion(
"Can a front desk agent view a patient's chart?"
);
console.log(JSON.stringify(result, null, 2));
If you want a tool-based agent later, wrap the query engine with QueryEngineTool. For many healthcare policy bots, a direct retrieval QA flow is safer than a fully autonomous agent because it reduces tool misuse.
4) Add pre-processing for PHI-safe inputs
Before querying policies, sanitize user input and block requests that ask for patient-specific advice. The agent should handle policy questions like “What is our retention period?” not “Can I disclose John Doe’s lab result?”
function redactPhi(input: string): string {
return input
.replace(/\b\d{3}-\d{2}-\d{4}\b/g, "[REDACTED_SSN]")
.replace(/\b[\w.-]+@[\w.-]+\.\w+\b/g, "[REDACTED_EMAIL]");
}
async function safeAsk(questionRaw: string) {
const question = redactPhi(questionRaw);
if (/\b(my patient|john doe|mrn|chart|lab result)\b/i.test(question)) {
return {
answer:
"This request appears to involve patient-specific information. Escalate to an authorized human reviewer.",
citations: [],
};
}
return answerPolicyQuestion(question);
}
Production Considerations
- •
Audit logging
- •Log every question, retrieved
policyId, model version, user identity, timestamp, and final answer. - •Keep logs immutable and retention-aligned with your internal compliance program.
- •Log every question, retrieved
- •
Data residency
- •Keep embeddings, indexes, and raw documents in-region if your healthcare organization has residency requirements.
- •If policies include regulated operational details, avoid sending them to unmanaged third-party storage.
- •
Access control
- •Enforce role-based access before retrieval.
- •A billing user should not retrieve HR-only policies; segment indexes by audience where needed.
- •
Monitoring and guardrails
- •Track refusal rate, low-confidence queries, retrieval hit rate, and citation coverage.
Common Pitfalls
- •
Mixing patient data into the policy corpus
- •Don’t index chart notes or ticket transcripts unless you have a separate PHI-safe pipeline.
- •Keep this agent scoped to policies only.
- •
Ignoring versioning
- •Healthcare policies change often.
- •Always store
version,effectiveDate, andsupersedesmetadata so you can prefer current documents during retrieval.
- •
Letting the model answer without evidence
- •If you don’t enforce citations or refusal behavior, the agent will fill gaps with plausible nonsense.
- •Require source nodes in every response path and escalate when retrieval confidence is weak.
- •
No separation between audiences
- •Staff-facing HR policies and clinician-facing operational policies should not share one flat index if access rules differ.
- •Split indexes by role or apply metadata filters before retrieval.
Keep learning
- •The complete AI Agents Roadmap — my full 8-step breakdown
- •Free: The AI Agent Starter Kit — PDF checklist + starter code
- •Work with me — I build AI for banks and insurance companies
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