Introduction
In this eighth article of the AI Agents series, we focus on the Fraud Detection & Prevention Agent, a vital agent for any business that handles sensitive data, payments, or user transactions. This agent’s main job is to automatically flag fraudulent activities, detect suspicious patterns, and prevent financial losses. It leverages advanced machine learning techniques, as well as established policies, to monitor transactions in real-time, alerting teams or blocking potentially fraudulent transactions. Just like the previous agents, this system never claims success unless all actions are fully executed and receipts are generated.
The Use Case
In financial sectors, e-commerce, and other data-sensitive industries, fraud detection is a critical aspect of the business. The agent examines transactions based on certain patterns, such as unusual spending behavior, location inconsistencies, or account activity that deviates from the norm. It integrates with payment gateways, banks, and other third-party services to detect irregularities in real-time and alert the relevant teams or automatically block fraudulent transactions. By using machine learning and predefined rules, the agent can prevent significant losses before they occur.
Prompt Contract (agent interface)
# file: contracts/fraud_detection_v1.yaml
role: "FraudDetectionAgent"
scope: >
Detect fraudulent activities by analyzing transaction data, customer behavior, and account anomalies.
Ask once for missing fields (transaction_id, customer_id, amount, location, transaction_type).
Propose tool calls; never assert success without a receipt.
output:
type: object
required: [summary, decision, fraud_alert, citations, next_steps, tool_proposals]
properties:
summary: {type: string, maxWords: 100}
decision: {type: string, enum: ["approve","block","need_approval","need_more_info"]}
fraud_alert:
type: object
required: [transaction_id, customer_id, amount, risk_level, flagged_reason]
properties:
transaction_id: {type: string}
customer_id: {type: string}
amount: {type: integer}
risk_level: {type: string, enum: ["low", "medium", "high"]}
flagged_reason: {type: string}
citations: {type: array, items: {type: string}}
next_steps: {type: array, items: {type: string}, maxItems: 6}
tool_proposals:
type: array
items:
type: object
required: [name, args, preconditions, idempotency_key]
properties:
name: {type: string, enum: [AnalyzeTransaction, CheckAnomalyPatterns, BlockTransaction, RequestApproval]}
args: {type: object}
preconditions: {type: string}
idempotency_key: {type: string}
policy_id: "fraud_detection_policy.v4"
citation_rule: "1–2 minimal-span claim_ids per factual sentence"
decoding:
narrative: {top_p: 0.92, temperature: 0.72, stop: ["\n\n## "]}
bullets: {top_p: 0.82, temperature: 0.45}
Example claims (context provided to the model)
[
{"claim_id":"policy:fraud:location_mismatch","text":"Transactions from new locations or IP addresses need further scrutiny.",
"effective_date":"2025-01-01","source_id":"doc:fraud_detection_policy_v4","span":"new locations or IP addresses"},
{"claim_id":"policy:fraud:high_amount","text":"Transactions exceeding $500 should be flagged for review if the user hasn't made similar payments in the past.",
"effective_date":"2025-01-01","source_id":"doc:fraud_detection_policy_v4","span":"exceeding $500 should be flagged"},
{"claim_id":"policy:fraud:unusual_behavior","text":"Transactions with frequent logins from different devices or IP addresses must be flagged.",
"effective_date":"2025-01-01","source_id":"doc:fraud_detection_policy_v4","span":"frequent logins from different devices"}
]
Tool Interfaces (typed, with receipts)
# tools.py
from pydantic import BaseModel
from typing import Optional, List, Dict
from datetime import datetime
class AnalyzeTransactionArgs(BaseModel):
transaction_id: str
customer_id: str
amount: int
location: str
transaction_type: str
class CheckAnomalyPatternsArgs(BaseModel):
customer_id: str
transaction_history: List[Dict[str, str]] # e.g., [{amount: int, location: str, transaction_type: str}]
class BlockTransactionArgs(BaseModel):
transaction_id: str
customer_id: str
amount: int
flagged_reason: str
class RequestApprovalArgs(BaseModel):
transaction_id: str
approver_id: str
class ToolReceipt(BaseModel):
tool: str
ok: bool
ref: str
message: str = ""
data: Optional[Dict] = None
# adapters.py (demo logic)
from tools import *
from datetime import datetime
TRANSACTIONS = {
"trans-001": {"customer_id": "C001", "amount": 1500, "location": "New York", "transaction_type": "purchase", "approved": False},
"trans-002": {"customer_id": "C002", "amount": 100, "location": "California", "transaction_type": "transfer", "approved": False}
}
def analyze_transaction(a: AnalyzeTransactionArgs) -> ToolReceipt:
if a.amount > 1000:
risk_level = "high"
flagged_reason = "High transaction amount"
else:
risk_level = "low"
flagged_reason = "Normal transaction"
return ToolReceipt(tool="AnalyzeTransaction", ok=True, ref=f"trans-{a.transaction_id}",
message="Transaction analyzed", data={"risk_level": risk_level, "flagged_reason": flagged_reason})
def check_anomaly_patterns(a: CheckAnomalyPatternsArgs) -> ToolReceipt:
if len(a.transaction_history) > 5: # Simple anomaly detection logic
return ToolReceipt(tool="CheckAnomalyPatterns", ok=False, ref="pattern-mismatch",
message="Customer has frequent logins from different locations", data={"flagged": True})
return ToolReceipt(tool="CheckAnomalyPatterns", ok=True, ref="pattern-ok", message="No anomalies detected")
def block_transaction(a: BlockTransactionArgs) -> ToolReceipt:
TRANSACTIONS[a.transaction_id]["approved"] = False
return ToolReceipt(tool="BlockTransaction", ok=True, ref=f"block-{a.transaction_id}",
message=f"Transaction {a.transaction_id} blocked", data={"reason": a.flagged_reason})
def request_approval(a: RequestApprovalArgs) -> ToolReceipt:
return ToolReceipt(tool="RequestApproval", ok=True, ref=f"approval-{a.transaction_id}",
message=f"Approval requested for transaction {a.transaction_id}", data={"approver_id": a.approver_id})

Join the conversation! Your thoughts help the community grow.