How to Build a KYC verification Agent Using CrewAI in Python for wealth management
A KYC verification agent for wealth management collects client identity data, checks it against policy and regulatory rules, flags missing or inconsistent information, and produces an audit-ready decision trail. It matters because onboarding high-net-worth clients is slow, compliance-heavy, and expensive when analysts do this manually across passports, proof of address, source-of-funds documents, sanctions lists, and internal risk policies.
Architecture
- •
Intake layer
- •Receives structured client data from CRM or onboarding forms.
- •Normalizes fields like legal name, DOB, nationality, tax residency, and beneficial ownership.
- •
Document extraction layer
- •Pulls key facts from uploaded documents such as passports, utility bills, trust deeds, and corporate registries.
- •Can be backed by OCR or a document parsing service before the agent sees the data.
- •
KYC policy checker
- •Applies wealth-management-specific rules:
- •PEP screening
- •sanctions screening
- •source-of-funds/source-of-wealth checks
- •beneficial ownership thresholds
- •jurisdiction and residency restrictions
- •Applies wealth-management-specific rules:
- •
Decisioning agent
- •Classifies the case as
approve,review, orreject. - •Produces a reasoned explanation with evidence references for compliance review.
- •Classifies the case as
- •
Audit logger
- •Stores inputs, outputs, timestamps, model version, and rule hits.
- •Required for regulator review and internal model governance.
- •
Human escalation path
- •Sends edge cases to a compliance analyst when confidence is low or policy conflicts exist.
Implementation
1) Install CrewAI and define the KYC task context
Use a small set of agents instead of one giant prompt. For wealth management KYC, separate extraction from compliance reasoning so you can audit each step.
from crewai import Agent, Task, Crew, Process
from crewai_tools import SerperDevTool
# Optional: external lookup tool for sanctions/PEP/news context if your environment allows it
search_tool = SerperDevTool()
client_case = {
"full_name": "Amina Rahman",
"dob": "1982-04-11",
"nationality": "UAE",
"tax_residency": ["UAE", "UK"],
"address": "12 Berkeley Square, London",
"documents": [
{"type": "passport", "status": "valid"},
{"type": "proof_of_address", "status": "valid"},
{"type": "bank_statement", "status": "missing"}
],
"risk_flags": ["high_net_worth", "trust_structure"],
}
2) Create specialist agents with narrow responsibilities
This is the pattern that holds up in production: one agent extracts facts, another applies policy. Keep the policy agent deterministic in tone and make it cite missing evidence explicitly.
document_agent = Agent(
role="KYC Document Analyst",
goal="Extract and normalize KYC facts from client records and documents.",
backstory="You specialize in onboarding files for private banking and wealth management.",
verbose=True,
)
compliance_agent = Agent(
role="KYC Compliance Officer",
goal="Assess KYC completeness and risk according to wealth management policy.",
backstory="You evaluate AML/KYC cases for regulated financial institutions.",
tools=[search_tool],
verbose=True,
)
3) Define tasks that produce auditable outputs
Make the first task produce structured facts. Make the second task return a decision with reasons and missing items. That separation gives you cleaner logging and easier reviewer workflows.
extract_task = Task(
description=(
"Review the client case data and extract normalized KYC facts. "
"Return a concise JSON-like summary with identity completeness, "
"document status, and any obvious inconsistencies."
),
expected_output="A structured KYC summary with missing fields listed.",
agent=document_agent,
)
decision_task = Task(
description=(
"Using the extracted KYC summary, determine whether this client should be "
"'approve', 'review', or 'reject'. Consider sanctions risk, PEP risk, "
"source-of-funds gaps, beneficial ownership complexity, and jurisdiction concerns. "
"If information is incomplete, prefer 'review'."
),
expected_output="A final decision with rationale and remediation steps.",
agent=compliance_agent,
)
4) Run the crew and persist the result for audit
CrewAI’s Crew executes the workflow; Process.sequential is enough here because compliance review should follow extraction in order. In production you would write both task outputs to your case management system with immutable timestamps.
crew = Crew(
agents=[document_agent, compliance_agent],
tasks=[extract_task, decision_task],
process=Process.sequential,
verbose=True,
)
result = crew.kickoff(inputs={"client_case": client_case})
print(result)
If you want a more controlled output shape downstream, wrap the final result in your own parser before saving it to your case store. For regulated workflows, do not let free-form text become the only record of decisioning.
Production Considerations
- •
Deployment
- •Run the agent inside your bank’s approved network boundary.
- •Keep customer PII out of third-party endpoints unless legal review approves transfer.
- •Pin model versions and store prompt templates in version control.
- •
Monitoring
- •Track approval/review/reject rates by jurisdiction and client segment.
- •Alert on spikes in manual reviews or missing-document cases.
- •Log every tool call so compliance can reconstruct how a decision was reached.
- •
Guardrails
- •Enforce hard rules outside the LLM for sanctions hits and residency restrictions.
- •Use deterministic checks for required fields like passport expiry date and address proof recency.
- •Require human review whenever beneficial ownership is opaque or trust structures are involved.
- •
Data residency
- •Keep EU/UK client data in-region where required by policy.
- •Encrypt at rest and in transit.
- •Redact sensitive fields before sending context to non-core services.
Common Pitfalls
- •
Letting the LLM make final compliance decisions without deterministic checks
- •Avoid this by running hard rules first: sanctions match, expired ID document, missing source-of-funds evidence.
- •The agent should explain decisions; it should not override policy.
- •
Mixing extraction and judgment in one prompt
- •This creates messy outputs that are hard to audit.
- •Split into separate tasks so you can inspect what was known versus what was inferred.
- •
Ignoring jurisdiction-specific requirements
- •A UK private bank onboarding an offshore trust is not the same as retail account opening.
- •Encode residency rules, document freshness windows, PEP thresholds, and escalation triggers per booking center.
- •
Failing to preserve an audit trail
- •If you cannot reproduce why a case was reviewed or rejected, you do not have a compliant workflow.
- •Persist inputs, task outputs, tool results, timestamps, and model/prompt versions for every case.
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