By Sagar Shankaran, Founder of CallSphere
Build FinTech AI agents for KYC identity verification, document validation, transaction monitoring, and AML compliance workflows.
Key takeaways
Financial institutions face a regulatory paradox: they must onboard customers quickly to compete with nimble fintech challengers, yet they must also perform thorough identity verification and ongoing monitoring to satisfy anti-money laundering (AML) regulations. The penalties for getting this wrong are severe — billions of dollars in fines annually, plus reputational damage that can be existential.
Traditional KYC processes are manual, slow, and expensive. A standard customer onboarding involves identity document collection, manual verification, database checks against sanctions lists and PEP (Politically Exposed Persons) databases, proof of address verification, and risk scoring. This process typically takes 24 hours and costs $15-$50 per customer for retail banking, and hundreds of dollars for corporate KYC.
Agentic AI transforms this from a sequential manual process into an orchestrated, largely autonomous workflow. AI agents handle document validation, biometric verification, database screening, and risk assessment in parallel — reducing onboarding time from days to minutes while maintaining (and often improving) compliance accuracy.
Identity Verification Agent — Orchestrates the end-to-end identity verification process. Validates government-issued ID documents, performs facial matching against ID photos, verifies liveness to prevent spoofing, and cross-references personal details against authoritative databases.
flowchart LR
REQ(["Inbound request"])
PII["PII detection<br/>regex plus NER"]
POL{"Policy engine<br/>OPA or rules"}
REDACT["Redact or mask"]
LLM["LLM call"]
OUT["Response"]
AUDIT[("Append only<br/>audit log")]
BLOCK(["Block plus<br/>notify DPO"])
REQ --> PII --> POL
POL -->|Allow| REDACT --> LLM --> OUT --> AUDIT
POL -->|Deny| BLOCK
style POL fill:#4f46e5,stroke:#4338ca,color:#fff
style AUDIT fill:#ede9fe,stroke:#7c3aed,color:#1e1b4b
style BLOCK fill:#dc2626,stroke:#b91c1c,color:#fff
style OUT fill:#059669,stroke:#047857,color:#fff
Document Validation Agent — Specializes in analyzing identity documents (passports, driver's licenses, national IDs) for authenticity. Detects forgeries, validates security features, extracts data fields via OCR, and checks document expiration status.
Sanctions Screening Agent — Screens applicants against global sanctions lists, PEP databases, adverse media, and law enforcement watchlists. Handles name matching with fuzzy logic to catch variations, transliterations, and aliases.
Risk Scoring Agent — Calculates customer risk profiles based on multiple factors: geography (country risk), occupation, expected transaction patterns, source of funds, and screening results. Assigns risk tiers that determine ongoing monitoring intensity.
Transaction Monitoring Agent — Continuously monitors account activity against behavioral baselines, rule-based triggers, and anomaly detection models. Identifies suspicious patterns: structuring, rapid movement, unusual geographic patterns, and velocity anomalies.
Hear it before you finish reading
Talk to a live CallSphere AI voice agent for financial services in your browser — 60 seconds, no signup.
Suspicious Activity Agent — When the transaction monitoring agent flags activity, this agent conducts deeper investigation. Assembles evidence packages, generates narrative summaries, and determines whether a Suspicious Activity Report (SAR) filing is warranted.
Regulatory Reporting Agent — Prepares and files regulatory reports: SARs, Currency Transaction Reports (CTRs), and other jurisdiction-specific filings. Ensures reports meet format requirements and filing deadlines.
class KYCOrchestrator:
"""Orchestrate the end-to-end KYC verification process."""
async def verify_customer(self, application: CustomerApplication) -> KYCResult:
# Phase 1: Document validation and data extraction
doc_result = await self.document_agent.validate(
document_images=application.id_documents,
document_type=application.id_type,
)
if not doc_result.is_authentic:
return KYCResult(
status="rejected",
reason="Document authentication failed",
details=doc_result.failure_reasons,
)
# Phase 2: Parallel verification checks
identity_check, sanctions_check, adverse_media = await asyncio.gather(
self.identity_agent.verify(
extracted_data=doc_result.extracted_data,
selfie=application.selfie_image,
liveness_video=application.liveness_check,
),
self.sanctions_agent.screen(
name=doc_result.extracted_data.full_name,
dob=doc_result.extracted_data.date_of_birth,
nationality=doc_result.extracted_data.nationality,
),
self.adverse_media_agent.search(
name=doc_result.extracted_data.full_name,
jurisdiction=doc_result.extracted_data.country,
),
)
# Phase 3: Risk scoring
risk_score = await self.risk_agent.calculate(
identity_result=identity_check,
sanctions_result=sanctions_check,
adverse_media=adverse_media,
customer_profile=application.profile_data,
)
# Phase 4: Decision
if sanctions_check.has_matches:
return KYCResult(status="escalate_compliance", risk=risk_score)
if risk_score.tier == "high":
return KYCResult(status="enhanced_due_diligence", risk=risk_score)
if identity_check.verified and risk_score.tier in ("low", "medium"):
return KYCResult(status="approved", risk=risk_score)
return KYCResult(status="manual_review", risk=risk_score)
The document validation agent must detect increasingly sophisticated forgeries:
class DocumentValidationAgent:
"""Validate identity document authenticity and extract data."""
async def validate(
self, document_images: list, document_type: str
) -> DocumentResult:
results = {}
# 1. Image quality assessment
quality = await self.quality_checker.assess(document_images)
if quality.score < 0.5:
return DocumentResult(
is_authentic=False,
failure_reasons=["Image quality insufficient for verification"],
request_resubmission=True,
)
# 2. Document type classification and template matching
template = await self.classifier.identify_template(
document_images, expected_type=document_type
)
# 3. Security feature validation
security = await self.security_checker.validate(
images=document_images,
template=template,
checks=[
"hologram_presence",
"microprint_detection",
"uv_feature_analysis",
"font_consistency",
"photo_integration", # Detect photo substitution
"edge_analysis", # Detect cropping/splicing
],
)
# 4. OCR data extraction
extracted = await self.ocr_engine.extract(
images=document_images,
template=template,
fields=["full_name", "date_of_birth", "document_number",
"expiry_date", "nationality", "address", "mrz"],
)
# 5. MRZ validation (for passports and some national IDs)
if extracted.mrz:
mrz_valid = self.mrz_validator.validate(
mrz_data=extracted.mrz,
extracted_fields=extracted,
)
results["mrz_consistency"] = mrz_valid
# 6. Cross-reference extracted data
consistency = self.check_data_consistency(extracted)
is_authentic = (
security.passed
and extracted.confidence > 0.85
and consistency.is_consistent
)
return DocumentResult(
is_authentic=is_authentic,
extracted_data=extracted,
security_checks=security,
confidence=extracted.confidence,
failure_reasons=self.compile_failures(security, consistency),
)
Beyond document checks, verify that the person presenting the document is the document holder:
Sanctions screening is complicated by name variations across languages and cultures:
class SanctionsScreeningAgent:
"""Screen individuals against global sanctions and watchlists."""
DATABASES = [
"ofac_sdn", # US OFAC Specially Designated Nationals
"eu_sanctions", # EU Consolidated Sanctions
"un_sanctions", # UN Security Council Sanctions
"uk_sanctions", # UK HM Treasury Sanctions
"pep_databases", # Politically Exposed Persons
"interpol_notices", # Interpol Red Notices
]
async def screen(
self, name: str, dob: str = None, nationality: str = None
) -> ScreeningResult:
# Generate name variations for matching
variations = self.name_matcher.generate_variations(
name,
include_transliterations=True,
include_phonetic=True, # Soundex, Metaphone
include_partial=True, # First + last, initials
)
# Screen against all databases in parallel
all_matches = await asyncio.gather(*[
self.search_database(db, variations, dob, nationality)
for db in self.DATABASES
])
# Flatten and deduplicate matches
matches = self.deduplicate(
[m for db_matches in all_matches for m in db_matches]
)
# Score each match for relevance
scored = []
for match in matches:
score = self.match_scorer.score(
query_name=name,
query_dob=dob,
query_nationality=nationality,
match_record=match,
)
if score > 0.6: # Relevance threshold
scored.append((match, score))
scored.sort(key=lambda x: x[1], reverse=True)
return ScreeningResult(
has_matches=len(scored) > 0,
matches=[
ScreenMatch(
database=m.source,
matched_name=m.name,
match_score=s,
listing_reason=m.reason,
listing_date=m.date,
)
for m, s in scored
],
screening_date=utc_now(),
databases_checked=self.DATABASES,
)
KYC is not a one-time event. Regulations require ongoing monitoring — existing customers must be rescreened when sanctions lists are updated. Implement a delta-screening process:
Start with regulatory-required rules:
Rule-based detection catches known patterns but misses novel fraud schemes. Layer ML-based anomaly detection on top:
class TransactionMonitoringAgent:
"""Monitor transactions for suspicious activity."""
async def evaluate_transaction(
self, transaction: Transaction
) -> MonitoringResult:
# 1. Rule-based checks (regulatory requirements)
rule_alerts = await self.rule_engine.evaluate(transaction)
# 2. Behavioral anomaly detection
customer_baseline = await self.get_behavioral_baseline(
transaction.customer_id
)
anomaly_score = self.anomaly_model.score(
transaction=transaction,
baseline=customer_baseline,
features=[
"amount_vs_average",
"time_of_day_unusualness",
"counterparty_novelty",
"geographic_distance",
"frequency_deviation",
"channel_unusualness",
],
)
# 3. Network analysis — is this part of a suspicious pattern?
network_risk = await self.network_analyzer.assess(
transaction=transaction,
lookback_days=90,
)
# 4. Combine signals
combined_risk = self.combine_signals(
rule_alerts=rule_alerts,
anomaly_score=anomaly_score,
network_risk=network_risk,
)
if combined_risk > self.alert_threshold:
alert = await self.create_alert(
transaction=transaction,
risk_score=combined_risk,
contributing_factors=self.explain_risk(
rule_alerts, anomaly_score, network_risk
),
)
return MonitoringResult(flagged=True, alert=alert)
return MonitoringResult(flagged=False, risk_score=combined_risk)
Transaction monitoring systems are notorious for high false positive rates — often 95%+ of alerts are benign. This wastes analyst time and causes alert fatigue. Reduce false positives through:
Still reading? Stop comparing — try CallSphere live.
See the financial services AI agent handle a real call — complete, industry-specific, and live in your browser. No signup.
When a transaction monitoring alert warrants investigation, the suspicious activity agent compiles an evidence package:
SAR filings require a written narrative explaining the suspicious activity. The agent generates draft narratives that analysts can review and modify:
class SARNarrativeGenerator:
"""Generate SAR filing narratives from investigation data."""
async def generate_narrative(self, investigation: Investigation) -> str:
prompt = f"""Generate a SAR narrative based on this investigation data.
Subject: {investigation.subject_name}
Account: {investigation.account_number}
Period: {investigation.start_date} to {investigation.end_date}
Flagged transactions: {investigation.transaction_summary}
Alert triggers: {investigation.alert_reasons}
Customer risk tier: {investigation.risk_tier}
Prior SARs: {investigation.prior_sar_count}
Requirements:
- Use objective, factual language
- State observations, not conclusions about intent
- Include specific transaction amounts, dates, and counterparties
- Follow FinCEN narrative format guidelines
- Do not include information not supported by the evidence
- Length: 300-500 words"""
narrative = await self.llm.generate(prompt)
return narrative
Financial institutions operating globally must comply with different regulations per jurisdiction:
| Jurisdiction | KYC Regulation | AML Regulation | Reporting Requirements |
|---|---|---|---|
| United States | CIP (31 CFR 1020.220) | Bank Secrecy Act | SAR, CTR to FinCEN |
| European Union | AMLD 5/6 | AMLD 5/6 | STR to national FIU |
| United Kingdom | Money Laundering Regulations | POCA 2002 | SAR to NCA |
| Singapore | MAS Notice 626 | CDSA | STR to STRO |
| Australia | AML/CTF Act 2006 | AML/CTF Act 2006 | SMR to AUSTRAC |
Your agent system must be configurable per jurisdiction, applying the correct screening databases, risk rules, reporting formats, and filing thresholds for each operating region.
Every decision made by the KYC and monitoring agents must be logged with:
Retain audit trails for the period required by applicable regulation — typically 5-7 years from the date of the transaction or the end of the customer relationship.
Name changes are handled through historical name linking — when a customer updates their name, the system maintains the linkage to previous names for screening continuity. Dual nationality requires screening against sanctions lists for both nationalities and applying the higher risk rating. Document validation must accept valid documents from either nationality. These edge cases should be explicitly tested during system validation with a comprehensive test dataset.
Industry benchmarks suggest that well-tuned systems achieve 50-70% false positive rates, down from the 95%+ common with legacy rule-based systems. Regulators do not specify a target false positive rate — their concern is that you catch genuine suspicious activity (low false negatives). The practical goal is reducing false positives enough that compliance analysts can investigate every alert thoroughly rather than rushing through an unmanageable queue.
For low-risk customers with straightforward verification (clear documents, no sanctions matches, standard risk profile), fully automated KYC is increasingly accepted by regulators. However, high-risk customers, sanctions matches, and complex corporate structures still require human review. The practical approach is risk-based: automate the 70-80% of applications that are straightforward, and route the rest to human analysts with pre-assembled evidence packages that accelerate their review.
Risk scoring models can inadvertently discriminate based on geography, name origin, or nationality if training data reflects historical biases. Mitigate this through: (1) regular bias audits measuring risk score distribution across protected demographics, (2) excluding protected characteristics as direct features, (3) testing for proxy discrimination (e.g., ZIP code as a proxy for race), (4) maintaining human oversight for risk tier assignments that affect service access, and (5) documenting your fairness methodology for regulators.
Real-time transaction monitoring requires a streaming architecture (Apache Kafka or similar) for ingesting transaction events, a feature store for maintaining customer behavioral baselines, a low-latency scoring service for rule evaluation and ML inference, and a case management system for alert investigation. For a mid-size bank processing 1-5 million transactions daily, expect to provision dedicated compute for the scoring service (targeting sub-100ms evaluation per transaction) and a time-series database for historical pattern analysis.

Written by
Sagar Shankaran· Founder, CallSphere
LinkedInSagar Shankaran is the founder of CallSphere, where he builds production AI voice and chat agents deployed across healthcare, hospitality, real estate, and home services. He writes about agentic AI, LLM engineering, and shipping voice agents that handle real calls in production.
See how AI voice agents work for your industry. Live demo available -- no signup required.
Using GPT-Realtime-2 for healthcare voice agents. BAA scope, PHI handling, retention, logging, and why a managed platform usually wins this build.
AI Control Tower is the governance layer for ServiceNow's Project Arc — policy, monitoring, and audit logs for autonomous agents. Here is how it works.
The 2024 NPRM proposes mandatory penetration tests every 12 months and vulnerability scans every 6 months. Here is how an AI voice agent should be tested in 2026.
CAISI announced new agreements with Google DeepMind, Microsoft, and xAI in May 2026. What gets tested, what changes for enterprise AI buyers, what to watch.
Six-domain AI vendor diligence: financial, security, privacy, operational, legal, ethics. Plus 30+ specific questions, SOC 2 / ISO 27001 baselines, and review cadence.
Independent RIAs and advisors lose qualified prospects to slow callbacks. Here is how a 2026 voice agent runs a structured pre-screen, soft-AUM ask, and books a discovery call cleanly.
© 2026 CallSphere Inc. All rights reserved.
Made within San Francisco
Watch how CallSphere handles real customer calls, schedules appointments, and processes payments — live.
Try Live DemoBook a DemoCalculate Your ROI