How to Build a policy Q&A Agent Using LlamaIndex in TypeScript for insurance

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

A policy Q&A agent answers customer or internal staff questions against insurance policy documents, endorsements, exclusions, and underwriting guides. It matters because most policy confusion comes from language buried across multiple PDFs, and the agent can turn that into a fast, auditable answer with citations instead of a call center escalation.

Architecture

  • Document ingestion layer

    • Pulls policy PDFs, rider documents, product brochures, and claims guidelines from approved storage.
    • Normalizes text before indexing so clause boundaries and section headers survive parsing.
  • Indexing layer

    • Uses VectorStoreIndex to embed chunks for semantic retrieval.
    • Keeps metadata like policy_id, jurisdiction, effective_date, and document_type for filtering.
  • Retrieval + synthesis layer

    • Uses a query engine built from the index to fetch relevant chunks.
    • Produces grounded answers with source citations so adjusters and service agents can verify them.
  • Policy guardrail layer

    • Restricts answers to the active policy set and jurisdiction.
    • Blocks unsupported advice such as legal interpretation beyond the document text.
  • Audit and observability layer

    • Logs the question, retrieved chunk IDs, response, and model version.
    • Supports post-hoc review for compliance and dispute handling.

Implementation

1) Install the LlamaIndex TypeScript packages

You need the core package plus an OpenAI integration if you are using OpenAI embeddings and chat models. In production, swap the model provider if your residency or vendor constraints require it.

npm install llamaindex dotenv

2) Load insurance policy documents with metadata

The important part here is metadata. Insurance Q&A is not just “search all docs”; you need to know which policy form, state filing, and effective date each chunk belongs to.

import "dotenv/config";
import { Document } from "llamaindex";

const docs = [
  new Document({
    text: `
Section 4: Water Damage Exclusion
We do not cover loss caused by continuous or repeated seepage or leakage of water...
    `,
    metadata: {
      policy_id: "HO-2024-001",
      jurisdiction: "US-CA",
      document_type: "policy_form",
      effective_date: "2024-01-01",
    },
  }),
  new Document({
    text: `
Section 9: Additional Living Expense
If a covered loss makes the residence uninhabitable, we will pay necessary increase in living expenses...
    `,
    metadata: {
      policy_id: "HO-2024-001",
      jurisdiction: "US-CA",
      document_type: "policy_form",
      effective_date: "2024-01-01",
    },
  }),
];

3) Build the index and query engine

This is the core pattern. VectorStoreIndex.fromDocuments() indexes your content, then asQueryEngine() gives you a retrieval-backed Q&A interface. For insurance, keep similarityTopK tight enough to avoid noisy clauses.

import { VectorStoreIndex } from "llamaindex";

async function main() {
  const index = await VectorStoreIndex.fromDocuments(docs);

  const queryEngine = index.asQueryEngine({
    similarityTopK: 3,
    responseMode: "compact",
  });

  const question =
    "Does this homeowners policy cover damage from slow water seepage behind a wall?";

  const response = await queryEngine.query({
    query: question,
  });

  console.log("ANSWER:\n", response.toString());
}

main().catch(console.error);

4) Add structured filtering for insurance scope

If you serve multiple products or states, filter by metadata before answering. That prevents cross-policy contamination, which is a common failure mode in insurance support systems.

import { MetadataFilter, MetadataFilters } from "llamaindex";

const filters = new MetadataFilters({
  filters: [
    new MetadataFilter({
      key: "policy_id",
      value: "HO-2024-001",
    }),
    new MetadataFilter({
      key: "jurisdiction",
      value: "US-CA",
    }),
  ],
});

async function askPolicyQuestion(index: VectorStoreIndex) {
  const engine = index.asQueryEngine({
    similarityTopK: 3,
    filters,
    responseMode: "compact",
  });

  const result = await engine.query({
    query:
      "Is gradual seepage covered under this policy?",
  });

  return result.toString();
}

Production Considerations

  • Compliance logging

    • Persist the exact user question, retrieved node IDs, answer text, timestamp, model name, and policy version.
    • This gives compliance teams an audit trail when a claim decision is challenged.
  • Data residency

    • Keep embeddings, vector stores, and model inference in-region if your policies or regulators require it.
    • For EU or state-regulated workloads, verify where document text is processed and stored.
  • Guardrails

    • Refuse questions that ask for legal advice or coverage determinations outside the cited policy text.
    • Return “I can only answer based on the active policy wording” when retrieval confidence is low.
  • Monitoring

    • Track retrieval hit rate, unanswered questions, citation coverage, and top fallback prompts.
    • Alert when users frequently ask about exclusions or endorsements that are missing from the indexed corpus; that usually means ingestion drift.

Common Pitfalls

  1. Indexing mixed policies without filters

    • If you dump all products into one index without metadata constraints, the agent will blend forms across states or plan types.
    • Fix it by filtering on policy_id, jurisdiction, product_line, and effective_date.
  2. Using broad retrieval settings

    • Large similarityTopK values pull in irrelevant clauses like general definitions instead of the actual exclusion.
    • Keep retrieval narrow and test against real insurer phrasing such as “seepage,” “wear and tear,” “sudden accidental loss,” and “ensuing loss.”
  3. Treating generated answers as final authority

    • A Q&A agent should summarize policy language with citations, not decide coverage on its own.
    • Make the UI show source snippets and route edge cases to a licensed adjuster or legal reviewer.

If you want this to hold up in production insurance workflows, keep the system boring: constrained corpus, strict metadata filters, grounded answers, full audit logs. That’s what keeps support teams fast without creating compliance problems later.


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