How to Build a claims processing Agent Using AutoGen in TypeScript for insurance
A claims processing agent takes a first notice of loss, extracts the key facts, checks policy context, asks for missing documents, and drafts a claim summary for an adjuster or downstream workflow. In insurance, that matters because claims handling is where speed, consistency, and auditability either hold up or collapse under volume.
Architecture
A production claims agent needs a small set of components that are easy to reason about and easy to audit:
- •
Ingress layer
- •Receives FNOL payloads from web forms, email parsers, call center transcripts, or document OCR.
- •Normalizes the input into a structured claim object.
- •
AutoGen agent runtime
- •Uses
AssistantAgentfor reasoning and extraction. - •Uses
UserProxyAgentor a custom orchestrator to control tool execution and approvals.
- •Uses
- •
Claims tools
- •Policy lookup
- •Coverage validation
- •Document checklist generation
- •Claim severity classification
- •Audit log writer
- •
Persistence layer
- •Stores conversation state, extracted entities, tool outputs, and final recommendations.
- •Needs immutable audit records for regulatory review.
- •
Guardrail layer
- •Blocks unsupported decisions like coverage denial without human review.
- •Redacts PII before logging outside the secure boundary.
- •
Human handoff path
- •Routes exceptions to an adjuster when confidence is low or policy language is ambiguous.
Implementation
1) Install AutoGen and define the claim shape
For TypeScript, use the AutoGen package that exposes AssistantAgent, UserProxyAgent, and OpenAIChatCompletionClient. Keep your claim payload strict from the start. Insurance workflows fail when the agent is allowed to freestyle around missing fields.
npm install @autogenai/autogen openai zod
import { z } from "zod";
export const ClaimInputSchema = z.object({
claimId: z.string(),
policyNumber: z.string(),
claimantName: z.string(),
lossType: z.enum(["auto", "property", "health", "liability"]),
lossDate: z.string(),
description: z.string(),
jurisdiction: z.string(),
});
export type ClaimInput = z.infer<typeof ClaimInputSchema>;
2) Create tools for policy lookup and audit logging
Do not let the model invent policy facts. Put policy retrieval behind tools and return only the minimum necessary data. In regulated environments, every tool call should be logged with timestamps and correlation IDs.
import { randomUUID } from "crypto";
type PolicySummary = {
policyNumber: string;
active: boolean;
coverageLimit: number;
deductible: number;
};
export async function getPolicySummary(policyNumber: string): Promise<PolicySummary> {
// Replace with your policy admin system call.
return {
policyNumber,
active: true,
coverageLimit: 50000,
deductible: 1000,
};
}
export async function writeAuditEvent(event: Record<string, unknown>) {
const record = {
eventId: randomUUID(),
timestamp: new Date().toISOString(),
...event,
};
console.log(JSON.stringify(record));
}
3) Build the AutoGen agents and wire a controlled workflow
This pattern keeps the assistant focused on extraction and recommendation while the user proxy executes tools. The key point is that the model proposes; your code decides what actually runs.
import {
AssistantAgent,
UserProxyAgent,
} from "@autogenai/autogen";
import { OpenAIChatCompletionClient } from "@autogenai/autogen/openai";
import { ClaimInputSchema } from "./claim-schema";
import { getPolicySummary, writeAuditEvent } from "./tools";
const client = new OpenAIChatCompletionClient({
model: "gpt-4o-mini",
});
const claimsAgent = new AssistantAgent({
name: "claims_agent",
llmConfig: { modelClient: client },
systemMessage: `
You are a claims processing assistant for an insurance carrier.
Extract facts from the input, validate against policy context, identify missing documents,
and produce a concise claim summary for an adjuster.
Never approve or deny coverage. Always escalate ambiguous coverage questions to a human.
Return structured JSON with keys:
summary, missingInformation, riskFlags, nextAction.
`,
});
const orchestrator = new UserProxyAgent({
name: "claims_orchestrator",
});
export async function processClaim(rawInput: unknown) {
const claim = ClaimInputSchema.parse(rawInput);
await writeAuditEvent({
action: "claim_received",
claimId: claim.claimId,
policyNumber: claim.policyNumber,
lossType: claim.lossType,
jurisdiction: claim.jurisdiction,
});
const policy = await getPolicySummary(claim.policyNumber);
const prompt = `
Claim:
${JSON.stringify(claim)}
Policy summary:
${JSON.stringify(policy)}
Task:
1. Summarize the claim.
2. List missing information needed to continue handling.
3. Flag any compliance or coverage risks.
4. Recommend next action for an adjuster.
`;
const result = await orchestrator.initiateChat(claimsAgent, prompt);
await writeAuditEvent({
action: "claim_processed",
claimId: claim.claimId,
resultPreview: String(result).slice(0, 1000),
});
return result;
}
4) Add a human-review gate for risky outcomes
Claims systems need deterministic rules around escalation. If the model sees exclusions, late notice issues, high severity losses, or jurisdiction-specific constraints, route to an adjuster instead of letting the agent continue autonomously.
function requiresHumanReview(outputText: string): boolean {
const riskySignals = [
"deny",
"exclude",
"fraud",
"coverage unclear",
"late notice",
"reservation of rights",
];
return riskySignals.some((signal) => outputText.toLowerCase().includes(signal));
}
Then use it after each run:
const response = await processClaim(input);
if (requiresHumanReview(String(response))) {
await writeAuditEvent({
action: "escalate_to_human",
claimId: input.claimId,
reason: "risk_signal_detected",
});
}
Production Considerations
- •
Data residency
- •Keep FNOL payloads and model prompts in-region if your carrier operates under local residency rules.
- •Do not send raw PII to non-approved telemetry sinks.
- •
Auditability
- •Persist every tool call, prompt version, model version, and final output.
- •Claims teams need traceability when regulators ask why a file was routed a certain way.
- •
Guardrails
- •Hard-block autonomous denial or settlement recommendations unless explicitly approved by business rules.
- •Redact SSNs, bank details, medical details, and payment info before logs leave the secure boundary.
- •
Monitoring
- •Track escalation rate, extraction accuracy, average time-to-triage, and tool failure rate.
- •Alert on unusual spikes in “coverage unclear” outputs; that usually means upstream data quality broke.
Common Pitfalls
- •
Letting the model decide coverage
- •Mistake: asking the agent to “determine if this is covered.”
- •Fix: constrain it to summarize facts and flag risks; keep coverage decisions in rules plus human review.
- •
Skipping schema validation
- •Mistake: passing raw email text straight into the agent.
- •Fix: validate with Zod first so your workflow always starts from structured fields like
policyNumber,lossDate, andjurisdiction.
- •
Weak audit trails
- •Mistake: logging only final answers.
- •Fix: store prompt versioning, tool inputs/outputs, escalation triggers, and timestamps. In insurance ops, incomplete traces become compliance problems fast.
- •
Ignoring jurisdiction differences
- •Mistake: using one generic claims flow across all regions.
- •Fix: branch logic by jurisdiction for notice periods, disclosure rules, medical privacy handling, and retention requirements.
A claims agent built this way does one job well: triage files fast without crossing into unauthorized decision-making. That’s the right shape for insurance automation—structured intake, controlled reasoning, immutable audit logs, and human oversight where regulation demands it.
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