How to Build a fraud detection Agent Using LlamaIndex in TypeScript for banking
A fraud detection agent in banking is a decision-support layer that reads transaction context, customer history, policy rules, and recent alerts, then returns a risk assessment with evidence. It matters because fraud teams need faster triage without turning every suspicious transaction into a manual review queue.
Architecture
- •
Transaction intake service
- •Receives payment events, card swipes, ACH transfers, login anomalies, or account changes.
- •Normalizes payloads into a consistent schema before the agent sees them.
- •
Policy and controls store
- •Holds bank-specific fraud rules, escalation thresholds, and compliance text.
- •This is where you keep chargeback policy, AML triggers, and internal investigation playbooks.
- •
LlamaIndex retrieval layer
- •Uses
VectorStoreIndexto retrieve relevant prior cases, policies, and customer risk signals. - •Keeps the agent grounded in bank-approved data instead of free-form reasoning.
- •Uses
- •
LLM reasoning layer
- •Uses
OpenAIor another supported model through LlamaIndex to summarize risk and explain why a case is suspicious. - •Produces structured output for downstream case management.
- •Uses
- •
Audit and case logging
- •Stores every prompt, retrieved document ID, score, and final decision.
- •Required for model governance, dispute handling, and regulator review.
- •
Human review handoff
- •Routes high-risk or ambiguous cases to an analyst queue.
- •The agent should recommend action, not auto-block high-value payments without controls.
Implementation
1) Install the core packages
Use the TypeScript LlamaIndex package plus a vector store provider. For local development you can start with in-memory storage; for production use something durable like PostgreSQL + pgvector or Pinecone.
npm install llamaindex zod dotenv
Set your model key in .env:
OPENAI_API_KEY=your_key_here
2) Define the documents the agent can trust
In banking, don’t feed raw transaction streams directly into the model. Wrap approved sources: fraud playbooks, prior investigation summaries, device fingerprint notes, and customer risk profiles that are allowed under your data policy.
import "dotenv/config";
import {
Document,
VectorStoreIndex,
Settings,
OpenAI,
} from "llamaindex";
Settings.llm = new OpenAI({
model: "gpt-4o-mini",
});
const docs = [
new Document({
text: `
Fraud rule FP-17:
Flag transactions above $5,000 when beneficiary account was created within 24 hours
and the customer has no prior international transfer history.
Escalate to manual review if device reputation is unknown.
`,
metadata: { source: "fraud_playbook", version: "2025-01" },
}),
new Document({
text: `
Case note CN-4412:
Customer initiated three failed login attempts from a new country,
then requested a beneficiary change and sent an urgent wire transfer.
Analyst outcome: confirmed account takeover.
`,
metadata: { source: "historical_case", caseId: "CN-4412" },
}),
];
3) Build the index and query engine
This is the retrieval backbone. The agent will pull only relevant policy/case evidence before it reasons about a transaction.
const index = await VectorStoreIndex.fromDocuments(docs);
const queryEngine = index.asQueryEngine({
similarityTopK: 2,
});
4) Create a fraud assessment function
Keep the output structured. Banks need deterministic downstream handling, not prose-only answers. The pattern below asks for a JSON-like response with risk level, rationale, and recommended action.
type FraudAssessment = {
riskLevel: "low" | "medium" | "high";
reason: string;
recommendedAction: "allow" | "step_up_auth" | "manual_review" | "block";
};
async function assessTransaction(input: {
amount: number;
currency: string;
beneficiaryAgeHours: number;
deviceReputation: "known" | "unknown" | "bad";
loginCountryMismatch: boolean;
}) : Promise<FraudAssessment> {
const prompt = `
You are a banking fraud triage assistant.
Use only the provided policy/case context to assess this transaction.
Transaction:
- amount: ${input.amount}
- currency: ${input.currency}
- beneficiaryAgeHours: ${input.beneficiaryAgeHours}
- deviceReputation: ${input.deviceReputation}
- loginCountryMismatch: ${input.loginCountryMismatch}
Return JSON with keys:
riskLevel (low|medium|high),
reason,
recommendedAction (allow|step_up_auth|manual_review|block)
`;
const response = await queryEngine.query({ query: prompt });
const text = response.toString();
return JSON.parse(text) as FraudAssessment;
}
What this looks like in practice
async function main() {
const result = await assessTransaction({
amount: 8200,
currency: "USD",
beneficiaryAgeHours: 6,
deviceReputation: "unknown",
loginCountryMismatch: true,
});
console.log(result);
}
main().catch(console.error);
The important part is not just calling an LLM. It is constraining the model with bank-approved documents through VectorStoreIndex, then forcing an operationally useful response shape.
Production Considerations
- •
Deploy in-region
- •Keep embeddings, vector stores, logs, and model endpoints inside approved data residency boundaries.
- •If your bank operates in multiple jurisdictions, split indexes by region to avoid cross-border leakage.
- •
Log every decision path
- •Store transaction inputs, retrieved document IDs, prompt version, model version, and final recommendation.
- •This gives you auditability for internal risk teams and external examiners.
- •
Add hard guardrails
- •Never let the agent auto-block based on one signal alone unless policy explicitly allows it.
- •Use rule-based thresholds outside the model for high-value wires, sanctions hits, or confirmed mule-account patterns.
- •
Monitor drift and false positives
- •Track precision/recall by product line: cards, wires, ACH, RTP.
- •Watch for seasonal behavior shifts such as payroll days or holiday shopping spikes.
- •Retrain or refresh retrieval content when fraud patterns change.
- •Track precision/recall by product line: cards, wires, ACH, RTP.
Common Pitfalls
- •
Letting the model see raw sensitive data
- •Don’t pass full PANs, SSNs, or unrestricted PII into prompts.
- •Tokenize or redact first; only expose fields needed for triage.
- •
Using ungoverned documents as truth
- •If you index analyst notes without curation, you’ll encode mistakes into retrieval.
- •Only ingest approved playbooks and reviewed case summaries with clear metadata.
- •
Treating the agent as an auto-decision engine
- •Fraud agents should recommend actions and explain evidence.
- •Final block/allow decisions need policy checks outside the model plus human review for edge cases.
- •
Ignoring prompt/version control
- •A small prompt change can shift false positive rates materially.
- •Version prompts like code and tie them to release artifacts so investigations are reproducible.
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