How to Build a KYC verification Agent Using CrewAI in Python for fintech
A KYC verification agent automates the boring but high-stakes part of onboarding: collecting customer identity data, checking it against policy and external sources, and producing a decision with an audit trail. For fintech, this matters because manual review does not scale, inconsistent checks create compliance risk, and weak evidence handling turns every onboarding exception into a future audit problem.
Architecture
- •
Input normalization layer
- •Takes raw onboarding payloads from your app or CRM.
- •Converts names, addresses, dates of birth, and document metadata into a clean internal schema.
- •
Verification tools
- •Deterministic functions for passport validation, sanctions screening, address lookup, and age checks.
- •These should call internal services or approved vendors, not free-form model output.
- •
KYC policy agent
- •Uses CrewAI
Agentto interpret the case against your policy rules. - •Produces a structured recommendation: approve, reject, or escalate.
- •Uses CrewAI
- •
Evidence collector
- •Stores all tool outputs, timestamps, and source references.
- •This is what you hand to compliance and auditors.
- •
Decision orchestrator
- •A
Crewthat coordinates the sequence of checks. - •Keeps the flow deterministic and easy to trace.
- •A
- •
Review handoff
- •Routes edge cases to a human analyst.
- •Prevents the model from making unsupported decisions on thin evidence.
Implementation
1) Install CrewAI and define your tools
Use tools for deterministic checks. In fintech, the model should reason over evidence; it should not invent evidence.
from crewai import Agent, Task, Crew, Process
from crewai.tools import BaseTool
from pydantic import BaseModel, Field
class KYCInput(BaseModel):
full_name: str = Field(..., description="Customer legal name")
date_of_birth: str = Field(..., description="YYYY-MM-DD")
country: str = Field(..., description="ISO country code")
id_number: str = Field(..., description="Government ID number")
class SanctionsScreenTool(BaseTool):
name: str = "sanctions_screen"
description: str = "Checks whether the customer appears on sanctions/watchlists."
def _run(self, full_name: str) -> str:
# Replace with your sanctioned-vendor API call
if "test" in full_name.lower():
return "match_found=false; source=internal_mock"
return "match_found=false; source=vendor_api"
class AgeCheckTool(BaseTool):
name: str = "age_check"
description: str = "Validates minimum age based on date of birth."
def _run(self, date_of_birth: str) -> str:
# Replace with real date parsing logic
return f"dob={date_of_birth}; age_verified=true"
class IdentityDocTool(BaseTool):
name: str = "identity_document_check"
description: str = "Validates ID format and basic consistency."
def _run(self, id_number: str, country: str) -> str:
return f"id_number={id_number}; country={country}; doc_valid=true"
2) Create a KYC analyst agent
The agent should summarize findings and apply policy. Keep the instructions narrow so it does not drift into generic compliance advice.
kyc_agent = Agent(
role="KYC Analyst",
goal="Review customer identity evidence and produce a compliant KYC recommendation.",
backstory=(
"You work for a regulated fintech. "
"You must rely only on tool outputs and provided customer data. "
"If evidence is incomplete or conflicting, escalate for human review."
),
tools=[SanctionsScreenTool(), AgeCheckTool(), IdentityDocTool()],
verbose=True,
)
3) Define the task and run the crew
Use one task for one customer record. The output should be structured enough for downstream systems to parse.
kyc_task = Task(
description=(
"Perform KYC verification for this customer:\n"
"{customer}\n\n"
"Use all available tools. Return:\n"
"- recommendation: approve | reject | escalate\n"
"- reasons: bullet list\n"
"- evidence_summary: short paragraph\n"
"- compliance_notes: mention any unresolved risk"
),
expected_output="A concise KYC decision with supporting evidence.",
agent=kyc_agent,
)
crew = Crew(
agents=[kyc_agent],
tasks=[kyc_task],
process=Process.sequential,
verbose=True,
)
customer = KYCInput(
full_name="Jane Doe",
date_of_birth="1992-04-11",
country="GB",
id_number="GB1234567",
)
result = crew.kickoff(inputs={"customer": customer.model_dump()})
print(result)
4) Add a human-review threshold
For production KYC flows, do not let every case auto-close. Route uncertain cases to an operations queue.
def route_decision(crew_output: str) -> str:
output = crew_output.lower()
if "recommendation: approve" in output:
return "auto_approve"
if "recommendation: reject" in output:
return "auto_reject"
return "human_review"
decision_route = route_decision(str(result))
print(decision_route)
Production Considerations
- •
Auditability
- •Persist raw tool responses, agent prompts, final outputs, timestamps, and versioned policy rules.
- •Regulators care about why a decision was made, not just the final label.
- •
Data residency
- •Keep PII inside approved regions and approved vendors only.
- •If your CrewAI deployment calls external LLM APIs, verify where prompts and logs are processed and stored.
- •
Guardrails
- •Force structured outputs where possible.
- •Reject free-text approvals that do not cite evidence from tools.
- •Never allow the agent to override sanctions or AML hits without human escalation.
- •
Monitoring
- •Track approval rate, escalation rate, false positive rates on sanctions screening, tool latency, and failed vendor calls.
- •A sudden shift in any of these can indicate policy drift or upstream data issues.
Common Pitfalls
- •
Letting the model make up facts
- •Mistake: asking the agent to “verify identity” without deterministic tools.
- •Fix: use tools for all external checks and make the agent reason over tool outputs only.
- •
Skipping structured audit logs
- •Mistake: storing only the final recommendation.
- •Fix: store prompt versions, tool inputs/outputs, timestamps, reviewer actions, and policy version IDs.
- •
Auto-approving borderline cases
- •Mistake: treating low-confidence matches as clean passes.
- •Fix: define explicit escalation rules for mismatched names, incomplete documents, sanctions ambiguity, or missing residency signals.
- •
Ignoring regional compliance constraints
- •Mistake: sending PII to a model endpoint outside your approved jurisdiction.
- •Fix: pin workloads to compliant infrastructure and document data flow end-to-end before launch.
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