How to Build a fraud detection Agent Using LlamaIndex in TypeScript for banking

By Cyprian AaronsUpdated 2026-04-21
fraud-detectionllamaindextypescriptbanking

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 VectorStoreIndex to retrieve relevant prior cases, policies, and customer risk signals.
    • Keeps the agent grounded in bank-approved data instead of free-form reasoning.
  • LLM reasoning layer

    • Uses OpenAI or another supported model through LlamaIndex to summarize risk and explain why a case is suspicious.
    • Produces structured output for downstream case management.
  • 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.

Common Pitfalls

  1. 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.
  2. 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.
  3. 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.
  4. 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

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