How to Build a transaction monitoring Agent Using LlamaIndex in TypeScript for insurance

By Cyprian AaronsUpdated 2026-04-21
transaction-monitoringllamaindextypescriptinsurance

A transaction monitoring agent for insurance watches policy, premium, claims, and payout activity for suspicious patterns, then turns those signals into a reviewable case. It matters because insurers need to catch fraud, sanctions exposure, duplicate claims, rapid policy changes, and unusual payout behavior without burying analysts in noise.

Architecture

  • Event ingestion layer

    • Pulls transactions from claims systems, billing platforms, and policy admin events.
    • Normalizes records into a consistent schema: policyId, customerId, amount, currency, eventType, timestamp.
  • Risk rules and enrichment layer

    • Applies deterministic checks first: threshold breaches, velocity rules, duplicate payment checks.
    • Enriches with customer tenure, claim history, geography, and prior alerts.
  • LlamaIndex agent layer

    • Uses FunctionAgent or ReActAgent to decide which tools to call.
    • Queries internal knowledge like underwriting rules, fraud playbooks, and compliance policies through a vector index.
  • Case management layer

    • Creates an investigation payload with evidence, risk score, explanation, and recommended next action.
    • Writes to a case system or queue for human review.
  • Audit and observability layer

    • Stores every tool call, prompt input, retrieved context, and model output.
    • Keeps a full trace for regulators and internal audit.

Implementation

1. Install dependencies and define the insurance event shape

Use LlamaIndex’s TypeScript package plus a real embedding/model provider. For production insurance workflows, keep the schema strict so your agent only reasons over normalized fields.

npm install llamaindex zod
import { z } from "zod";

export const InsuranceTransactionSchema = z.object({
  transactionId: z.string(),
  policyId: z.string(),
  customerId: z.string(),
  eventType: z.enum(["premium_payment", "claim_submission", "claim_payout", "policy_change"]),
  amount: z.number(),
  currency: z.string(),
  country: z.string(),
  timestamp: z.string(),
});

export type InsuranceTransaction = z.infer<typeof InsuranceTransactionSchema>;

2. Build a knowledge index over fraud and compliance documents

This is where LlamaIndex helps most. Put underwriting rules, fraud typologies, claims handling SOPs, sanctions guidance, and retention policies into a vector index so the agent can retrieve the right context before deciding.

import {
  Document,
  VectorStoreIndex,
} from "llamaindex";

const docs = [
  new Document({
    text: `
      Fraud rule: escalate if multiple claim payouts occur within 7 days for the same policyholder.
      Compliance rule: retain alert evidence for audit according to local retention policy.
    `,
    metadata: { source: "fraud_playbook" },
  }),
  new Document({
    text: `
      Insurance AML control: flag high-value premium payments from high-risk jurisdictions.
      Review all cross-border payouts above internal threshold.
    `,
    metadata: { source: "compliance_manual" },
  }),
];

const index = await VectorStoreIndex.fromDocuments(docs);
const retriever = index.asRetriever({ similarityTopK: 3 });

3. Expose tools for scoring and evidence lookup

The agent should not hallucinate risk logic. Give it explicit tools for deterministic scoring and retrieval. In LlamaIndex TypeScript, FunctionTool.from is the clean way to wrap business logic.

import {
  FunctionTool,
  FunctionAgent,
} from "llamaindex";

const scoreTransactionTool = FunctionTool.from(
  async ({ amount, country, eventType }: { amount: number; country: string; eventType: string }) => {
    let score = 0;

    if (amount >= 10000) score += 40;
    if (country !== "US") score += 15;
    if (eventType === "claim_payout") score += 20;
    if (amount >= 50000) score += 25;

    return {
      riskScore: Math.min(score, 100),
      reasons: [
        amount >= 10000 ? "High-value transaction" : null,
        country !== "US" ? "Cross-border activity" : null,
        eventType === "claim_payout" ? "Payout event" : null,
      ].filter(Boolean),
    };
  },
);

const retrievePolicyTool = FunctionTool.from(
  async ({ query }: { query: string }) => {
    const results = await retriever.retrieve(query);
    return results.map((r) => ({
      text: r.node.getContent(),
      source: r.node.metadata?.source,
      score: r.score,
    }));
  },
);

4. Create the agent and run a monitoring decision

The agent combines deterministic scoring with retrieved policy context. In practice this gives you an explainable alert package that an investigator can trust.

import { OpenAI } from "@llamaindex/openai";
import { Settings } from "llamaindex";

Settings.llm = new OpenAI({ model: "gpt-4o-mini" });

const agent = new FunctionAgent({
  llm: Settings.llm,
  tools: [scoreTransactionTool, retrievePolicyTool],
});

const transaction = InsuranceTransactionSchema.parse({
  transactionId: "txn_123",
  policyId: "pol_789",
  customerId: "cus_456",
  eventType: "claim_payout",
  amount: 25000,
  currency: "USD",
   country: "NG",
   timestamp: new Date().toISOString(),
});

const result = await agent.chat({
   message:
     `Review this insurance transaction for monitoring:
${JSON.stringify(transaction)}

Return:
1) risk assessment
2) relevant policy citations
3) recommended action`,
});

console.log(result.message.content);

Production Considerations

  • Keep data residency explicit

    If your insurer operates across regions, pin embeddings, vector stores, and LLM endpoints to approved jurisdictions. Do not send PII or claim details outside the region without legal approval.

  • Log every decision path

    Store retrieved chunks, tool inputs/outputs, final prompt text, model response, and analyst override. Regulators care about why an alert was raised more than the raw score.

  • Put guardrails around PII

    Redact national IDs, bank details, medical claim notes, and beneficiary data before sending content to the model unless you have a formal processing basis. Use structured fields plus masked text wherever possible.

  • Separate scoring from explanation

    Let deterministic rules produce the alert trigger. Use the LLM only to summarize evidence and map it back to policy language.

Common Pitfalls

  • Using the model as the scorer

    Don’t ask the LLM to invent risk scores from scratch. Use hard rules or statistical models first; let LlamaIndex handle retrieval and orchestration.

  • Indexing raw sensitive documents without filtering

    Claims files often contain medical or financial data that should never be broadly retrievable. Split documents into safe chunks and apply field-level redaction before indexing.

  • Skipping auditability

    If you can’t reproduce why an alert fired six months later, you’ll fail internal audit fast. Persist prompt versions, tool versions, document hashes, and model identifiers alongside each case.


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