How to Build a compliance checking Agent Using CrewAI in Python for fintech

By Cyprian AaronsUpdated 2026-04-21
compliance-checkingcrewaipythonfintech

A compliance checking agent reviews customer-facing text, transactions, or policy changes against fintech rules before they ship. In practice, that means catching risky language, missing disclosures, sanctions issues, or jurisdiction-specific violations early enough to avoid regulatory exposure and rework.

Architecture

A production compliance agent for fintech needs a small set of focused components:

  • Input normalizer

    • Takes raw text, product metadata, jurisdiction, and customer segment.
    • Converts them into a structured payload the agent can reason over.
  • Policy retrieval layer

    • Pulls internal compliance rules, approved wording, and regulatory snippets from a controlled source.
    • Keeps the agent grounded in your actual policy set instead of generic advice.
  • Compliance analysis task

    • Checks the input against disclosure rules, prohibited claims, KYC/AML constraints, and region-specific requirements.
    • Produces a structured verdict with reasons and references.
  • Audit logger

    • Persists every request, output, timestamp, model version, and rule set used.
    • This is non-negotiable in fintech.
  • Escalation path

    • Routes ambiguous cases to a human compliance reviewer.
    • Prevents the agent from making final decisions on edge cases.

Implementation

1) Install CrewAI and define the compliance scope

Use CrewAI for orchestration and keep the scope narrow. For fintech, do not ask the agent to “decide compliance” in the abstract; give it one job: classify content against explicit policy.

pip install crewai crewai-tools
from crewai import Agent, Task, Crew, Process
from pydantic import BaseModel
from typing import Literal

class ComplianceResult(BaseModel):
    status: Literal["approved", "needs_review", "rejected"]
    reason: str
    policy_refs: list[str]

2) Create an agent with a strict role and guardrails

The key pattern is to constrain the agent’s behavior through role definition and task instructions. In regulated environments, you want deterministic outputs that can be logged and reviewed later.

from crewai import Agent

compliance_agent = Agent(
    role="Fintech Compliance Checker",
    goal="Review fintech content for regulatory risk using provided policies only",
    backstory=(
        "You are a senior compliance analyst for a regulated fintech company. "
        "You must identify missing disclosures, misleading claims, sanctions risk, "
        "and jurisdiction-specific violations."
    ),
    verbose=True,
    allow_delegation=False,
)

3) Define the analysis task with structured output expectations

CrewAI Task objects are where you make the workflow concrete. Put the exact policy context in the description and require a structured response that downstream systems can parse.

from crewai import Task

review_task = Task(
    description=(
        "Review the following fintech marketing copy for compliance issues.\n\n"
        "Jurisdiction: UK\n"
        "Product: Consumer credit card\n"
        "Customer segment: Retail customers\n\n"
        "Copy:\n"
        "\"Instant approval guaranteed. No credit checks. Best rates in the market.\"\n\n"
        "Check for misleading claims, required disclosures, and risky wording."
    ),
    expected_output=(
        "A JSON-style assessment with status (approved|needs_review|rejected), "
        "reason, and policy_refs."
    ),
    agent=compliance_agent,
)

4) Run the crew and map results into your audit trail

For a single-agent workflow like this, Crew with Process.sequential is enough. If you later add retrieval or escalation agents, keep the same audit contract so every decision is traceable.

from crewai import Crew, Process

crew = Crew(
    agents=[compliance_agent],
    tasks=[review_task],
    process=Process.sequential,
    verbose=True,
)

result = crew.kickoff()

print(result)

If you want to make this usable in production, wrap it in a service function that logs inputs and outputs before returning them:

import json
from datetime import datetime

def check_compliance(copy_text: str) -> dict:
    task = Task(
        description=(
            f"Review this fintech copy for compliance.\n\n"
            f"Jurisdiction: UK\n"
            f"Product: Consumer credit card\n"
            f"Copy:\n{copy_text}"
        ),
        expected_output="JSON with status, reason, policy_refs",
        agent=compliance_agent,
    )

    crew = Crew(agents=[compliance_agent], tasks=[task], process=Process.sequential)
    result = crew.kickoff()

    audit_record = {
        "timestamp": datetime.utcnow().isoformat(),
        "jurisdiction": "UK",
        "product": "Consumer credit card",
        "input": copy_text,
        "output": str(result),
    }

    print(json.dumps(audit_record))
    return audit_record

Production Considerations

  • Deploy inside your controlled environment

    • Keep prompts, policies, and logs in-region if your data residency requirements demand it.
    • For EU/UK financial data, avoid sending sensitive content to unmanaged third-party endpoints without legal review.
  • Log every decision

    • Store request payloads, model/version identifiers, task descriptions, and final verdicts.
    • Auditors will ask why a piece of copy was approved or rejected six months later.
  • Add human-in-the-loop escalation

    • Anything ambiguous should return needs_review, not approved.
    • This matters for borderline financial promotions language or AML-adjacent cases.
  • Use deterministic guardrails

    • Restrict outputs to a fixed schema.
    • Reject free-form answers when downstream systems need machine-readable decisions.

Common Pitfalls

  1. Using a generic prompt without policy context

    • Problem: The agent gives plausible but useless answers.
    • Fix: Inject jurisdiction-specific rules and approved wording into every task.
  2. Letting the agent make final decisions on high-risk cases

    • Problem: False approvals create regulatory exposure.
    • Fix: Use needs_review as the default for anything ambiguous or incomplete.
  3. Skipping audit logging

    • Problem: You cannot explain why a decision was made.
    • Fix: Persist input text, output text, timestamps, policy version, and model metadata for every run.
  4. Ignoring residency constraints

    • Problem: Sensitive customer or transaction data crosses borders unintentionally.
    • Fix: Keep processing aligned with your banking/insurance data residency rules and approved infrastructure boundaries.

Keep learning

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

Related Guides