How to Build a underwriting Agent Using LlamaIndex in TypeScript for wealth management
An underwriting agent for wealth management takes a client profile, investment objectives, risk tolerance, liquidity needs, and policy constraints, then turns that into a structured suitability decision. It matters because the firm needs fast, consistent recommendations that still respect compliance, auditability, and jurisdiction-specific rules.
Architecture
- •
Client intake layer
- •Normalizes inputs from CRM, onboarding forms, KYC/AML systems, and portfolio data.
- •Produces a single underwriting request object with client identity, residency, asset mix, and constraints.
- •
Policy and suitability knowledge base
- •Stores product rules, house policy, jurisdictional restrictions, and internal underwriting standards.
- •Backed by LlamaIndex retrieval over approved documents only.
- •
Underwriting reasoning engine
- •Uses an LLM to classify risk fit, flag missing information, and generate a recommendation draft.
- •Must return structured output so downstream systems can route decisions reliably.
- •
Audit and evidence store
- •Captures retrieved passages, model output, timestamps, prompt version, and final decision.
- •Required for compliance reviews and post-trade or suitability audits.
- •
Guardrail layer
- •Blocks disallowed recommendations, enforces required disclosures, and checks for residency or product eligibility issues.
- •Prevents the agent from inventing policy or bypassing approval thresholds.
Implementation
1) Build a retrieval index over approved underwriting policy
Use SimpleDirectoryReader to load policy docs and VectorStoreIndex to make them searchable. In wealth management, keep this corpus tightly scoped to approved materials only.
import { SimpleDirectoryReader } from "llamaindex";
import { VectorStoreIndex } from "llamaindex";
async function buildPolicyIndex() {
const docs = await new SimpleDirectoryReader({
inputDir: "./policy-docs",
}).loadData();
const index = await VectorStoreIndex.fromDocuments(docs);
return index;
}
This gives you a retrieval layer you can use to ground every recommendation in approved content. If the product team updates suitability rules, re-index the new policy set and version it.
2) Define a structured underwriting response
For production underwriting, do not return free-form prose only. Use ContextChatEngine or direct chat calls with a strict response shape in your application code.
type UnderwritingRequest = {
clientId: string;
residency: string;
age: number;
netWorthUsd: number;
liquidAssetsUsd: number;
riskTolerance: "low" | "medium" | "high";
objective: "income" | "growth" | "preservation";
};
type UnderwritingDecision = {
decision: "approve" | "review" | "reject";
rationale: string;
missingInfo: string[];
citedPolicyRefs: string[];
};
Keep this schema stable. Wealth management teams need deterministic fields for case management systems, not just narrative summaries.
3) Wire LlamaIndex into an underwriting service
Use OpenAI as the LLM and ContextChatEngine.fromDefaults with a retriever from your index. The engine gets policy context; your application formats the final decision object.
import {
OpenAI,
ContextChatEngine,
} from "llamaindex";
async function underwrite(request: UnderwritingRequest): Promise<UnderwritingDecision> {
const index = await buildPolicyIndex();
const retriever = index.asRetriever({ similarityTopK: 4 });
const llm = new OpenAI({
model: "gpt-4o-mini",
temperature: 0,
apiKey: process.env.OPENAI_API_KEY,
});
const chatEngine = ContextChatEngine.fromDefaults({
retriever,
llm,
systemPrompt:
"You are an underwriting assistant for wealth management. Use only retrieved policy context. If information is missing or eligibility is unclear, return review.",
});
const prompt = `
Client profile:
${JSON.stringify(request, null, 2)}
Return:
- decision
- rationale
- missingInfo
- citedPolicyRefs
`;
const response = await chatEngine.chat({ message: prompt });
return {
decision:
response.response.includes("approve")
? "approve"
: response.response.includes("reject")
? "reject"
: "review",
rationale: response.response,
missingInfo: [],
citedPolicyRefs: [],
};
}
This pattern is simple but production-friendly if you add strict parsing on top of the model output. In practice, I’d pair this with JSON schema validation before anything reaches an advisor workflow.
Step-by-step flow
- •
Load approved documents
- •Store product guides, suitability policies, jurisdiction notes, and exception procedures in one controlled directory.
- •Exclude drafts and email threads.
- •
Create the retrieval index
- •Build a
VectorStoreIndexfrom those documents. - •Rebuild on every policy release; keep index versions aligned to legal approval dates.
- •Build a
- •
Run underwriting requests through a guarded chat engine
- •Use
ContextChatEngineso the model answers against retrieved evidence. - •Set temperature to zero for stable outputs.
- •Use
- •
Persist the full audit trail
- •Save request payloads, retrieved chunks, model output, decision version, and operator overrides.
- •This is non-negotiable for regulated advice workflows.
Production Considerations
- •
Deployment
- •Keep the agent behind an internal API gateway with mTLS and SSO.
- •Pin the model version and prompt version so decisions are reproducible during audits.
- •
Monitoring
- •Track approval/review/reject rates by advisor desk, jurisdiction, and product line.
- •Alert on spikes in “review” outcomes; that usually means policy drift or broken retrieval.
- •
Guardrails
- •Enforce hard rules outside the LLM for residency restrictions, minimum investable assets, leverage limits, and prohibited products.
- •Never let the model override deterministic compliance checks.
- •
Data residency
- •Route EU/UK client data to compliant storage and inference paths only.
- •Redact PII before logging prompts unless your retention controls are explicitly approved by legal and security teams.
Common Pitfalls
- •
Letting free-form model output drive decisions
- •This breaks downstream automation fast.
- •Fix it by validating responses against a strict schema and mapping only known values into your workflow engine.
- •
Mixing policy docs with operational noise
- •If you ingest unapproved content or outdated PDFs, retrieval quality collapses.
- •Fix it by curating a versioned corpus with legal sign-off and document metadata like jurisdiction and effective date.
- •
Skipping compliance evidence capture
- •Wealth management reviews will ask why a recommendation was made.
- •Fix it by storing retrieved passages, prompt text, model version, timestamp, user identity, and final human override in an immutable audit log.
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