How to Build a underwriting Agent Using AutoGen in Python for pension funds

By Cyprian AaronsUpdated 2026-04-21
underwritingautogenpythonpension-funds

A underwriting agent for pension funds takes member, employer, contribution, and policy data, then produces a risk-aware recommendation: approve, reject, escalate, or request more information. It matters because pension underwriting is not just scoring risk; it has to respect compliance rules, auditability, data residency, and conservative decisioning that protects long-term liabilities.

Architecture

  • Data ingestion layer

    • Pulls structured inputs from CRM, policy admin systems, document stores, and actuarial tables.
    • Normalizes member age, contribution history, employer sector, benefit type, and jurisdiction.
  • Policy and rules engine

    • Encodes pension-specific eligibility rules.
    • Handles hard stops like missing KYC/AML fields, jurisdiction restrictions, or contribution anomalies.
  • AutoGen agent group

    • One agent drafts the assessment.
    • One agent checks compliance and policy alignment.
    • A coordinator agent resolves disagreements and produces the final recommendation.
  • Evidence retriever

    • Retrieves supporting documents and prior cases.
    • Keeps the agent grounded in approved policy text instead of free-form reasoning.
  • Audit logger

    • Stores prompts, tool calls, outputs, timestamps, model version, and decision rationale.
    • Required for review by compliance teams and internal audit.
  • Human escalation path

    • Routes borderline cases to a pension operations analyst.
    • Prevents silent automation on high-risk or incomplete applications.

Implementation

1) Install AutoGen and define your case schema

Use the current AutoGen package and keep the underwriting payload explicit. For pension funds, your schema should carry jurisdiction and residency fields because those affect both compliance and where data can be processed.

from dataclasses import dataclass
from typing import Optional

@dataclass
class UnderwritingCase:
    case_id: str
    member_age: int
    employer_name: str
    contribution_history_years: int
    annual_contribution: float
    jurisdiction: str
    residency_region: str
    kyc_complete: bool
    aml_clear: bool
    notes: Optional[str] = None

2) Create specialized agents with AutoGen

AutoGen’s AssistantAgent is enough for this pattern. Use separate agents for underwriting analysis and compliance review so you do not collapse business logic into one prompt.

import autogen

llm_config = {
    "model": "gpt-4o-mini",
    "temperature": 0,
}

underwriter = autogen.AssistantAgent(
    name="underwriter",
    llm_config=llm_config,
    system_message=(
        "You are a pension fund underwriting analyst. "
        "Assess risk conservatively. "
        "Return only one of: APPROVE, REJECT, ESCALATE. "
        "Always cite which case fields influenced the decision."
    ),
)

compliance = autogen.AssistantAgent(
    name="compliance",
    llm_config=llm_config,
    system_message=(
        "You are a pension fund compliance reviewer. "
        "Check KYC/AML completeness, residency constraints, "
        "and whether the recommendation is defensible. "
        "Return APPROVE or ESCALATE only."
    ),
)

3) Orchestrate the review with a group chat

GroupChat plus GroupChatManager gives you a simple multi-agent workflow. The underwriter drafts the recommendation first; compliance validates it; then you parse the result into an application decision.

import json
from autogen import GroupChat, GroupChatManager

case = UnderwritingCase(
    case_id="PF-2026-001",
    member_age=54,
    employer_name="Northwind Manufacturing",
    contribution_history_years=9,
    annual_contribution=18500.0,
    jurisdiction="ZA",
    residency_region="af-south-1",
    kyc_complete=True,
    aml_clear=True,
)

groupchat = GroupChat(
    agents=[underwriter, compliance],
    messages=[],
    max_round=4,
)

manager = GroupChatManager(groupchat=groupchat, llm_config=llm_config)

prompt = f"""
Underwrite this pension fund case as JSON:
{json.dumps(case.__dict__, indent=2)}

Rules:
- Reject if KYC or AML is false.
- Escalate if jurisdiction is missing or residency_region is outside approved regions.
- Approve only if contributions are consistent and no compliance issues exist.
"""

result = underwriter.initiate_chat(manager, message=prompt)
print(result.summary)

4) Add deterministic guardrails before the model speaks

Do not let the model decide on obvious policy failures. Run rule checks first; then send only eligible cases to AutoGen. This keeps your underwriting pipeline explainable and reduces noisy escalations.

APPROVED_REGIONS = {"af-south-1", "eu-west-1"}

def precheck(case: UnderwritingCase):
    if not case.kyc_complete or not case.aml_clear:
        return "REJECT", "KYC/AML failed"
    if not case.jurisdiction:
        return "ESCALATE", "Missing jurisdiction"
    if case.residency_region not in APPROVED_REGIONS:
        return "ESCALATE", "Data residency constraint"
    return None, None

decision, reason = precheck(case)
if decision:
    print({"case_id": case.case_id, "decision": decision, "reason": reason})
else:
    response = underwriter.initiate_chat(manager, message=prompt)

Production Considerations

  • Deploy inside your approved data boundary

    • Pension data often cannot leave a specific region.
    • Pin model endpoints and vector stores to the same residency zone as member records.
  • Log every decision path

    • Store input payloads, precheck results, agent messages, final output, and reviewer overrides.
    • Audit teams will want a full trail for each underwriting outcome.
  • Use strict escalation thresholds

    • Anything involving missing identity fields, unusual contribution spikes, sanctioned jurisdictions, or ambiguous employment history should go to human review.
    • Conservative escalation is better than an incorrect approval.
  • Monitor drift by segment

    • Track approval rates by employer sector, age band, jurisdiction, and contribution profile.
    • Pension portfolios can drift slowly; segment-level monitoring catches bad policy assumptions early.

Common Pitfalls

  • Letting one agent make final decisions without policy checks

    • Fix it by running deterministic rules before any LLM call.
    • The model should interpret edge cases; it should not override hard controls.
  • Ignoring auditability

    • Fix it by persisting prompts, outputs, timestamps, model versions, and reviewer actions.
    • If you cannot reconstruct why a case was approved six months later, the workflow is not production-ready.
  • Mixing jurisdictions in one runtime

    • Fix it by routing cases to region-specific workers and storage buckets.
    • Pension funds often have strict residency requirements that apply to both raw data and derived artifacts.

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