How to Build a loan approval Agent Using CrewAI in Python for investment banking

By Cyprian AaronsUpdated 2026-04-21
loan-approvalcrewaipythoninvestment-banking

A loan approval agent in investment banking takes a credit application, pulls the relevant borrower and deal data, analyzes risk, checks policy constraints, and returns a decision package with rationale. It matters because bankers need faster turnaround without losing control over compliance, auditability, and credit discipline.

Architecture

  • Intake layer
    • Normalizes borrower data, financial statements, KYC fields, and deal terms into a structured payload.
  • Credit analysis agent
    • Reviews leverage, DSCR, cash flow stability, collateral coverage, and covenant headroom.
  • Policy/compliance agent
    • Checks internal lending policy, AML/KYC flags, sanctions screening status, and jurisdiction-specific constraints.
  • Risk committee summarizer
    • Produces an approval memo with decision, rationale, exceptions, and required conditions precedent.
  • Audit logger
    • Persists prompts, tool calls, outputs, timestamps, and model version for review by compliance and model risk teams.
  • Human approval gate
    • Routes borderline cases to a credit officer or committee instead of auto-deciding.

Implementation

  1. Install CrewAI and define your task boundaries

    Keep the agent narrow. In investment banking, you do not want one general-purpose agent making final credit decisions without explicit controls.

    pip install crewai crewai-tools
    
  2. Create agents for credit analysis and compliance

    Use separate Agent objects so each role has a different objective. The compliance agent should never “approve” a loan; it should only validate constraints and flag exceptions.

    from crewai import Agent
    
    credit_analyst = Agent(
        role="Senior Credit Analyst",
        goal="Assess borrower creditworthiness using financial ratios and deal terms",
        backstory=(
            "You are a senior investment banking credit analyst. "
            "You evaluate leverage, liquidity, cash flow coverage, collateral quality, "
            "and covenant headroom. You write concise approval memos."
        ),
        verbose=True,
        allow_delegation=False,
    )
    
    compliance_officer = Agent(
        role="Lending Compliance Officer",
        goal="Check the application against lending policy and regulatory constraints",
        backstory=(
            "You review KYC/AML status, sanctions exposure, jurisdictional restrictions, "
            "and internal policy exceptions. You never override policy."
        ),
        verbose=True,
        allow_delegation=False,
    )
    
    memo_writer = Agent(
        role="Credit Committee Memo Writer",
        goal="Summarize findings into an approval recommendation with audit-ready reasoning",
        backstory=(
            "You produce decision memos for investment banking credit committees. "
            "You include risks, mitigants, open items, and conditions precedent."
        ),
        verbose=True,
        allow_delegation=False,
    )
    
  3. Define tasks with explicit outputs

    Each task should produce structured text that downstream systems can parse. For production systems, I usually force JSON-like output in the task description so the memo can be stored in a case management system.

    from crewai import Task
    
    credit_task = Task(
        description=(
            "Review the borrower profile and loan terms. Assess leverage ratio, "
            "interest coverage ratio, debt service coverage ratio, liquidity runway, "
            "and collateral strength. Return: risk rating, key positives, key negatives."
        ),
        expected_output="A concise credit assessment with risk rating and supporting rationale.",
        agent=credit_analyst,
    )
    
    compliance_task = Task(
        description=(
            "Validate the application against lending policy. Check KYC completeness, "
            "AML/sanctions flags, restricted industries exposure, jurisdictional issues, "
            "and any policy exceptions required."
        ),
        expected_output="A compliance review listing pass/fail items and any exceptions.",
        agent=compliance_officer,
    )
    
    memo_task = Task(
        description=(
            "Combine the credit assessment and compliance review into a committee memo. "
            "Recommend approve / approve with conditions / decline. Include reasons."
        ),
        expected_output="An audit-ready approval memo with recommendation and conditions.",
        agent=memo_writer,
    )
    
  4. Wire everything into a Crew and execute it

    This is the actual pattern you want: separate specialists plus one summarizer. If you have internal tools for pulling borrower data from your underwriting stack or document store, attach them to the relevant agents through tools=[...].

    from crewai import Crew
    from crewai import Process
    
    loan_approval_crew = Crew(
        agents=[credit_analyst, compliance_officer, memo_writer],
        tasks=[credit_task, compliance_task, memo_task],
        process=Process.sequential,
        verbose=True,
    )
    
    application = {
        "borrower_name": "Northwind Capital Holdings",
        "facility": "Senior secured term loan",
        "amount_usd": 25000000,
        "tenor_months": 60,
        "ebitda_usd": 12000000,
        "total_debt_usd": 28000000,
        "interest_expense_usd": 1800000,
        "dscr": 1.45,
        "collateral_coverage": 1.3,
        "kyc_status": "complete",
        "aml_screening": "clear",
        "jurisdiction": "UK",
    }
    
    result = loan_approval_crew.kickoff(inputs={"application": application})
    print(result)
    

Production Considerations

  • Keep data residency explicit

    • If borrower data must stay in-region for UK/EU or local regulatory reasons:
      • run the model endpoint in-region
      • avoid sending raw PII to external services
      • redact identifiers before tool calls when possible
  • Log every decision path

    • Store:
      • input snapshot hash
      • prompt versions
      • tool outputs
      • final recommendation
      • model name/version
      • human override if one occurs
        This is non-negotiable for audit and model risk management.
  • Use hard guardrails for policy

    • Do not let the LLM infer policy from memory.
    • Pull approved thresholds from a versioned rules service:
      • max leverage
      • minimum DSCR
      • restricted sectors
      • country restrictions
      • approval authority limits
  • Route edge cases to humans

    • Borderline leverage or incomplete KYC should trigger:
      • “approve with conditions”
      • “needs committee review”
      • “decline pending remediation”
        Never let the agent finalize exceptions outside delegated authority.

Common Pitfalls

  • Using one agent for everything

    • A single agent will mix credit judgment with compliance logic.
    • Split responsibilities so each task is testable and auditable.
  • Letting the model invent missing facts

    • If DSCR or KYC fields are missing, force the workflow to return “insufficient data.”
    • Do not allow assumptions about borrower financials or sanctions status.
  • Skipping structured outputs

    • Free-form prose is hard to store in underwriting systems.
    • Standardize on fields like:
      • recommendation
      • risk_rating
      • exceptions
      • conditions_precedent
      • reviewer_notes
        That makes downstream integration with case management and audit systems much cleaner.

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