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

By Cyprian AaronsUpdated 2026-04-21
fraud-detectionllamaindextypescriptlending

A fraud detection agent for lending reviews borrower applications, supporting documents, and transaction signals to flag suspicious patterns before credit is issued. In lending, that matters because bad decisions are expensive: you want to catch synthetic identities, document tampering, income inflation, and velocity abuse early, while keeping an audit trail for compliance teams and underwriters.

Architecture

  • Application intake layer
    • Receives borrower data from the loan origination system: KYC fields, bank statements, payslips, device metadata, and application history.
  • Document parsing and indexing
    • Converts PDFs and text into LlamaIndex Document objects and stores them in a vector index for retrieval.
  • Fraud policy engine
    • Encodes lending rules like mismatched employer names, repeated phone numbers across applicants, or suspicious income patterns.
  • Agent orchestration layer
    • Uses a ReActAgent or OpenAIAgent to reason over retrieved evidence and produce a structured fraud assessment.
  • Decision output layer
    • Returns a risk score, reasons, and recommended action: approve, manual review, or reject.
  • Audit and logging layer
    • Persists prompts, retrieved chunks, model output, and decision metadata for model risk management and regulatory review.

Implementation

1) Install dependencies and set up the project

You need the core LlamaIndex packages plus an LLM provider. For this example, use OpenAI through LlamaIndex’s TypeScript SDK.

npm install llamaindex dotenv zod

Create a .env file:

OPENAI_API_KEY=your_key_here

2) Load lending documents into a vector index

The agent needs evidence. In lending, that usually means application forms, bank statements, payslips, bureau summaries, and internal fraud notes. Use Document, VectorStoreIndex, and Settings from LlamaIndex.

import "dotenv/config";
import {
  Document,
  VectorStoreIndex,
  Settings,
  OpenAI,
} from "llamaindex";

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

async function buildIndex() {
  const docs = [
    new Document({
      text: `
        Applicant: John Doe
        Employer: Acme Logistics Ltd
        Monthly Income: $8,500
        Bank Statement Notes: salary deposits vary by date; one deposit memo says "cash transfer"
        Device Fingerprint: shared with prior rejected application
      `,
      metadata: { source: "application_001" },
    }),
    new Document({
      text: `
        Fraud Policy:
        - Flag shared device fingerprints across applicants
        - Flag salary claims unsupported by bank deposits
        - Flag inconsistent employer names across documents
      `,
      metadata: { source: "policy_v1" },
    }),
  ];

  return await VectorStoreIndex.fromDocuments(docs);
}

3) Create retrievers and run the agent over evidence

This is the core pattern. Retrieve relevant chunks first, then ask the agent to classify risk with explicit lending rules. Keep the output structured so downstream systems can route the case.

import {
  QueryEngineTool,
  ToolMetadata,
  ReActAgent,
} from "llamaindex";

async function main() {
  const index = await buildIndex();
  const queryEngine = index.asQueryEngine({ similarityTopK: 3 });

  const fraudTool = QueryEngineTool.fromDefaults({
    queryEngine,
    name: "fraud_evidence_search",
    description:
      "Search borrower application data and fraud policy notes for suspicious lending patterns.",
  });

  const agent = new ReActAgent({
    tools: [fraudTool],
    systemPrompt: `
You are a lending fraud analyst.
Use only retrieved evidence.
Return:
1. risk_level: low | medium | high
2. reasons: bullet list
3. recommended_action: approve | manual_review | reject
4. audit_notes: short explanation referencing evidence sources
`,
  });

  const response = await agent.chat({
    message:
      "Assess this loan application for fraud risk. Look for synthetic identity signals, income mismatch, and device reuse.",
  });

  console.log(response.response);
}

main().catch(console.error);

4) Add structured decisioning for underwriting workflows

For production lending systems, don’t pass free-form text directly into orchestration. Parse the response into a schema so your LOS can route cases deterministically.

import { z } from "zod";

const FraudDecisionSchema = z.object({
  risk_level: z.enum(["low", "medium", "high"]),
  reasons: z.array(z.string()).min(1),
  recommended_action: z.enum(["approve", "manual_review", "reject"]),
  audit_notes: z.string(),
});

type FraudDecision = z.infer<typeof FraudDecisionSchema>;

function parseDecision(rawText: string): FraudDecision {
  const parsed = JSON.parse(rawText);
  return FraudDecisionSchema.parse(parsed);
}

In practice, you would instruct the agent to emit JSON only. Then validate it before writing the result into your case management system.

Production Considerations

  • Data residency
    • Keep borrower PII in-region. If your lender operates in multiple jurisdictions, pin storage and model endpoints to approved regions and avoid cross-border retrieval unless legal has signed off.
  • Auditability
    • Log every retrieved chunk ID, prompt version, model version, and final decision. For lending disputes, you need to explain why a case was flagged months later.
  • Guardrails
    • Separate policy checks from model reasoning. Hard rules like “shared SSN across active applications” should not depend on an LLM judgment.
  • Monitoring
    • Track false positives by segment: product type, geography, employment type, channel source. Fraud models drift fast when attackers adapt.

Common Pitfalls

  • Using the agent as the sole decision-maker
    • Don’t let the model approve or decline loans without deterministic controls. Use it as an investigation layer feeding a rules engine or human review queue.
  • Mixing unredacted PII into prompts
    • Mask sensitive fields where possible. Pass only what the task needs; keep full records in secure systems with strict access controls.
  • No grounding on source evidence
    • If the agent can answer without retrieval context, it will hallucinate. Force it to cite retrieved application artifacts and policy notes in every decision.
  • Ignoring compliance requirements
    • Lending decisions are regulated. Preserve prompt/output logs, version your policies, and make sure adverse action explanations can be generated from stored evidence.

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