How to Build a fraud detection Agent Using CrewAI in TypeScript for banking
A fraud detection agent in banking watches transactions, customer behavior, and account context, then flags suspicious activity for review or action. The point is not to replace your fraud engine; it is to add an orchestration layer that can investigate signals, explain why something looks risky, and route cases with enough evidence for compliance and ops teams.
Architecture
- •
Transaction intake layer
- •Pulls card swipes, ACH transfers, wire activity, login events, and device fingerprints from your internal systems.
- •Normalizes them into a single case schema before the agent sees anything.
- •
Risk scoring tool
- •Exposes deterministic fraud signals like velocity checks, geo mismatch, amount anomalies, beneficiary novelty, and account age.
- •Keeps the model from inventing risk logic.
- •
Investigation agent
- •Uses CrewAI
Agentto inspect the case, call tools, and produce a structured fraud assessment. - •Should be constrained to evidence-based reasoning only.
- •Uses CrewAI
- •
Review workflow
- •Uses
Taskobjects to separate triage, enrichment, and final recommendation. - •Routes high-risk cases to human analysts or automated holds.
- •Uses
- •
Audit and logging layer
- •Stores prompts, tool outputs, scores, and final decisions.
- •Needed for model governance, SAR support, and post-incident review.
- •
Policy guardrails
- •Enforces data residency, redaction of PII where possible, and bank-approved decision thresholds.
- •Prevents the agent from taking irreversible actions without approval.
Implementation
1) Install CrewAI for TypeScript and define your case model
Use the TypeScript SDK in a Node service. Keep the input shape strict so your tools do not receive arbitrary JSON from upstream systems.
// src/types.ts
export type FraudCase = {
transactionId: string;
customerId: string;
amount: number;
currency: string;
country: string;
merchantCategory: string;
deviceId: string;
ipAddress: string;
accountAgeDays: number;
priorTransactions24h: number;
priorDeclines24h: number;
};
export type FraudFinding = {
riskLevel: "low" | "medium" | "high";
reasons: string[];
recommendedAction: "approve" | "review" | "hold";
};
2) Build deterministic tools for risk checks
CrewAI works best when the LLM reasons over facts produced by tools. In banking, this matters because you want explainability and repeatability more than free-form analysis.
// src/tools/fraudTools.ts
import { Tool } from "@crewai/crewai";
export const velocityCheckTool = new Tool({
name: "velocity_check",
description: "Checks recent transaction velocity and decline frequency.",
func: async (input: string) => {
const data = JSON.parse(input) as { priorTransactions24h: number; priorDeclines24h: number };
const velocityRisk =
data.priorTransactions24h > 15 || data.priorDeclines24h > 3 ? "elevated" : "normal";
return JSON.stringify({
velocityRisk,
rule: "priorTransactions24h > 15 OR priorDeclines24h > 3"
});
}
});
export const geoMismatchTool = new Tool({
name: "geo_mismatch_check",
description: "Flags country mismatch against expected customer profile.",
func: async (input: string) => {
const data = JSON.parse(input) as { country: string; expectedCountry?: string };
return JSON.stringify({
geoMismatch: data.expectedCountry ? data.country !== data.expectedCountry : false
});
}
});
3) Create the fraud investigation crew
The pattern here is one investigator agent plus one triage task. If you need separation of duties later, add a second analyst agent for verification.
// src/crew.ts
import { Agent, Crew } from "@crewai/crewai";
import { velocityCheckTool, geoMismatchTool } from "./tools/fraudTools";
import type { FraudCase } from "./types";
export function buildFraudCrew(fraudCase: FraudCase) {
const investigator = new Agent({
role: "Fraud Investigator",
goal:
"Assess whether the transaction is suspicious using only provided evidence and approved tools.",
backstory:
"You work in a bank fraud operations team. You must produce concise findings with audit-friendly reasoning.",
tools: [velocityCheckTool, geoMismatchTool],
verbose: true
});
return new Crew({
agents: [investigator],
tasks: [
{
description: `Analyze this banking transaction for fraud risk:
${JSON.stringify(fraudCase)}`,
expectedOutput:
'A JSON object with keys riskLevel, reasons[], recommendedAction'
}
]
});
}
4) Run the crew and map output into a bank-safe decision
Do not let the model directly freeze accounts or block payments. Convert its output into a recommendation that a policy engine or human reviewer can approve.
// src/index.ts
import { buildFraudCrew } from "./crew";
import type { FraudCase, FraudFinding } from "./types";
async function main() {
const fraudCase: FraudCase = {
transactionId: "txn_10001",
customerId: "cust_42",
amount: 9800,
currency: "USD",
country: "NG",
merchantCategory: "electronics",
deviceId: "device_abc",
ipAddress: "203.0.113.10",
accountAgeDays: 12,
priorTransactions24h: 19,
priorDeclines24h":4
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