How to Build a compliance checking Agent Using AutoGen in Python for lending

By Cyprian AaronsUpdated 2026-04-21
compliance-checkingautogenpythonlending

A compliance checking agent for lending reviews loan applications, policy documents, and supporting evidence against your internal credit policy and regulatory rules. It matters because lending decisions need to be explainable, auditable, and consistent; if the agent misses a restriction on debt-to-income, income verification, or jurisdiction-specific disclosures, you create credit risk and regulatory risk at the same time.

Architecture

  • Policy knowledge source
    • Stores lending rules: minimum income verification, max DTI, prohibited product types, residency constraints, adverse action requirements.
  • Document ingestion layer
    • Pulls structured fields from loan applications, bank statements, pay stubs, KYC records, and term sheets.
  • Compliance agent
    • Uses AutoGen to compare application facts against policy and produce a pass/fail plus rationale.
  • Human review agent
    • Handles ambiguous cases like missing documents or conflicting income evidence.
  • Audit logger
    • Persists inputs, outputs, timestamps, model version, and reviewer decisions for exam-ready traceability.
  • Decision service
    • Converts the agent output into workflow actions: approve to next stage, route to manual review, or reject with reason codes.

Implementation

1) Install AutoGen and define the compliance schema

For lending workflows, keep the output structured. You want a machine-readable decision object that downstream systems can store and auditors can inspect.

pip install pyautogen pydantic
from pydantic import BaseModel
from typing import List, Literal

class ComplianceFinding(BaseModel):
    rule_id: str
    status: Literal["pass", "fail", "review"]
    reason: str

class ComplianceResult(BaseModel):
    decision: Literal["approve", "manual_review", "reject"]
    findings: List[ComplianceFinding]
    summary: str

2) Create an AutoGen assistant configured for compliance review

Use AssistantAgent as the primary checker and UserProxyAgent to inject case data. In production you would connect this to a secure model endpoint and keep prompts tightly scoped to policy evaluation.

import autogen

llm_config = {
    "model": "gpt-4o-mini",
    "api_key": os.environ["OPENAI_API_KEY"],
    "temperature": 0,
}

compliance_agent = autogen.AssistantAgent(
    name="compliance_agent",
    llm_config=llm_config,
    system_message=(
        "You are a lending compliance reviewer. "
        "Check application facts against policy. "
        "Return concise findings with rule references. "
        "If data is missing or contradictory, mark review."
    ),
)

user_proxy = autogen.UserProxyAgent(
    name="case_loader",
    human_input_mode="NEVER",
    code_execution_config=False,
)

3) Run a case through the agent with explicit lending rules

The prompt should include only the facts needed for the decision. For lending, that usually means applicant income, requested amount, DTI, state/country of residence, employment verification status, and product type.

import os
import json

policy_text = """
POLICY:
1. Max DTI must be <= 43%.
2. Income must be verified with at least one primary document.
3. No lending in restricted jurisdictions.
4. Adverse action reasons must be recorded if rejected.
"""

case_text = """
APPLICATION:
- Applicant state: CA
- Product: unsecured personal loan
- Monthly income stated: $6,000
- Monthly debt obligations: $2,900
- Income verification: pay stub provided
- Requested amount: $25,000
"""

prompt = f"""
Review this lending case for compliance.

{policy_text}

{case_text}

Return:
- decision: approve | manual_review | reject
- findings: list of rule_id/status/reason
- summary: one paragraph suitable for audit notes
"""

result = user_proxy.initiate_chat(
    compliance_agent,
    message=prompt,
)

print(result.summary())

4) Add a second agent for escalation when rules are unclear

AutoGen works well when you separate deterministic compliance checks from judgment calls. A reviewer agent can inspect borderline cases like self-employed income with inconsistent deposits.

reviewer_agent = autogen.AssistantAgent(
    name="reviewer_agent",
    llm_config=llm_config,
    system_message=(
        "You are a senior lending operations reviewer. "
        "Resolve ambiguous compliance cases using only provided facts. "
        "Prefer manual review when evidence is incomplete."
    ),
)

escalation_prompt = """
Case has conflicting income evidence:
- Tax return annualized income suggests $72k
- Bank deposits average $4k/month over last 3 months
- Pay stub missing employer name

Should this be approved or routed to manual review? Explain briefly.
"""

review_result = user_proxy.initiate_chat(reviewer_agent, message=escalation_prompt)
print(review_result.summary())

Production Considerations

  • Log every decision artifact

    • Store prompt input, model response, policy version hash, timestamp, user ID, and final disposition.
    • Lending audits depend on reproducibility; if you cannot reconstruct why a loan was routed or rejected, you have a control problem.
  • Keep data residency explicit

    • If borrower data must stay in-region, route requests to approved endpoints only.
    • Do not send raw PII or bank statement images outside your permitted cloud boundary.
  • Use guardrails before the agent

    • Validate numeric fields like DTI and income with deterministic code before calling the model.
    • The agent should interpret policy; it should not calculate basic ratios from messy text if you can compute them in Python first.
  • Separate approval logic from explanation logic

    • Let your rules engine make hard stops on non-negotiable violations.
    • Use AutoGen for narrative analysis and exception handling so model drift does not change core credit policy.

Common Pitfalls

  1. Letting the model decide core underwriting math

    • Mistake: asking the LLM to compute DTI from raw documents every time.
    • Fix: calculate ratios in Python first; pass the result into AutoGen as structured input.
  2. Using free-form outputs in production

    • Mistake: reading plain text responses and parsing them with regex.
    • Fix: enforce a schema like ComplianceResult and reject responses that do not map cleanly to your contract.
  3. Ignoring adverse action traceability

    • Mistake: returning “reject” without specific rule reasons.
    • Fix: require each failure to reference a rule ID and maintain those reason codes in your LOS or decision engine.
  4. Sending sensitive borrower data without controls

    • Mistake: passing full documents into prompts by default.
    • Fix: redact unnecessary PII, minimize context windows, and restrict access by role and region before any AutoGen call.

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