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

By Cyprian AaronsUpdated 2026-04-21
fraud-detectionllamaindexpythonlending

A fraud detection agent for lending screens applications, documents, and supporting evidence for signs of identity fraud, synthetic identities, income misrepresentation, and document tampering. It matters because lending decisions need to be fast, explainable, and defensible: if you miss fraud, you eat losses; if you over-block legitimate borrowers, you create avoidable friction and compliance risk.

Architecture

  • Document ingestion layer

    • Pulls in loan applications, bank statements, payslips, IDs, bureau notes, and internal case notes.
    • Normalizes PDFs, text, and structured fields into a common indexable format.
  • LlamaIndex knowledge layer

    • Uses VectorStoreIndex for semantic retrieval over policy docs, fraud playbooks, historical cases, and KYC rules.
    • Uses SummaryIndex or metadata filters when you need high-level case context or scoped retrieval.
  • Fraud signal extractor

    • Converts raw application data into structured signals like income mismatch, address mismatch, duplicate employer names, velocity anomalies, and document inconsistencies.
    • Feeds those signals into the agent as tool outputs or prompt context.
  • Decisioning agent

    • Uses LlamaIndex’s ReActAgent or FunctionAgent to reason over retrieved policy content and extracted signals.
    • Produces a risk assessment plus a human-readable rationale.
  • Audit and case logging

    • Stores every retrieved chunk, tool call, and final decision.
    • Required for model governance, adverse action review support, and internal audit.
  • Policy guardrails

    • Enforces what the agent can recommend versus what a human underwriter must approve.
    • Keeps the system aligned with lending policy and regulatory expectations.

Implementation

1) Install dependencies and load your lending corpus

Start with your policy docs and prior fraud playbooks. In production you usually split sources by residency zone and access control before indexing them.

pip install llama-index llama-index-llms-openai llama-index-embeddings-openai pypdf
import os
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.core import Settings
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding

os.environ["OPENAI_API_KEY"] = "your-key"

Settings.llm = OpenAI(model="gpt-4o-mini", temperature=0)
Settings.embed_model = OpenAIEmbedding(model="text-embedding-3-small")

docs = SimpleDirectoryReader(
    input_dir="./lending_policy_docs",
    recursive=True
).load_data()

index = VectorStoreIndex.from_documents(docs)
query_engine = index.as_query_engine(similarity_top_k=5)

2) Define the fraud analysis function the agent can call

This is where you codify lending-specific checks. Keep this deterministic; don’t ask the model to invent the signal math.

from typing import Dict

def analyze_application(application: Dict) -> str:
    income = float(application["declared_monthly_income"])
    bank_avg = float(application["bank_statement_avg_income"])
    employer_match = application["employer_name_match"]
    id_match = application["identity_match"]
    address_match = application["address_match"]

    flags = []
    if bank_avg < income * 0.7:
        flags.append("income_mismatch")
    if not employer_match:
        flags.append("employer_inconsistency")
    if not id_match:
        flags.append("identity_mismatch")
    if not address_match:
        flags.append("address_mismatch")

    risk = "high" if len(flags) >= 2 else "medium" if len(flags) == 1 else "low"
    return f"risk={risk}; flags={','.join(flags) if flags else 'none'}"

3) Wrap retrieval plus tools in a LlamaIndex agent

Use the retriever to ground decisions in policy text. Then let the agent combine that with your structured fraud signals.

from llama_index.core.tools import FunctionTool
from llama_index.core.agent import ReActAgent

fraud_tool = FunctionTool.from_defaults(
    fn=analyze_application,
    name="analyze_application",
    description="Analyze lending application fields for fraud indicators"
)

policy_tool = query_engine.as_tool(
    name="lending_policy_search",
    description="Search lending policies and fraud playbooks"
)

agent = ReActAgent.from_tools(
    tools=[fraud_tool, policy_tool],
    llm=Settings.llm,
    verbose=True,
)

application = {
    "declared_monthly_income": "8500",
    "bank_statement_avg_income": "5400",
    "employer_name_match": False,
    "identity_match": True,
    "address_match": False,
}

prompt = f"""
Assess this lending application for fraud risk.
Application data: {application}
Use policy search to ground your answer in lending rules.
Return:
1) risk level
2) key reasons
3) whether to escalate to manual review
4) short audit-friendly explanation
"""

response = agent.chat(prompt)
print(response)

4) Add an auditable output schema

For lending ops teams, free-form text is not enough. Persist a structured record that your case management system can ingest.

import json
from datetime import datetime

result_record = {
    "case_id": "LN-2026-000184",
    "timestamp_utc": datetime.utcnow().isoformat(),
    "application_id": "APP-99821",
    "agent_output": str(response),
    "source_policy_docs": ["fraud_playbook_v3.pdf", "kyc_policy_2026.pdf"],
}

with open("fraud_case_audit.jsonl", "a") as f:
    f.write(json.dumps(result_record) + "\n")

Production Considerations

  • Deploy in-region

    • Lending data often has residency constraints. Keep embeddings, indexes, logs, and LLM calls inside approved regions where required by policy or regulation.
  • Log retrieval traces

    • Store which chunks were retrieved from VectorStoreIndex, which tools were called, and the final recommendation.
    • This is how you defend a decision during audit or dispute resolution.
  • Put humans on escalation paths

    • The agent should recommend “manual review” for ambiguous cases rather than auto-decline.
    • High-risk outcomes need underwriter review when identity evidence conflicts or documents are incomplete.
  • Monitor drift on fraud patterns

    • Track false positives by segment: product type, geography, channel partner, employer category.
    • Fraud patterns change fast; retrain your retrieval corpus and update rules when new schemes appear.

Common Pitfalls

  1. Using the LLM as the fraud detector

    • Don’t ask it to infer numeric inconsistencies from raw documents alone.
    • Extract deterministic signals first; use LlamaIndex to retrieve policy context and generate an explanation on top.
  2. Skipping auditability

    • If you cannot show what evidence drove the recommendation, the system is weak for lending operations.
    • Persist source chunks, tool inputs/outputs, timestamps, and final rationale.
  3. Mixing policy guidance with final credit decisions

    • The agent should support underwriting workflow, not silently approve or decline loans.
    • Keep hard decision thresholds in governed code or decision engines; let the agent explain and escalate.
  4. Ignoring data residency and access control

    • Fraud cases include PII, bank data, tax docs, and ID images.
    • Segment indexes by tenant or region and enforce least privilege before any retrieval happens.

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