How to Build a underwriting Agent Using AutoGen in Python for wealth management
An underwriting agent for wealth management takes client inputs, portfolio data, risk constraints, and policy rules, then produces a consistent suitability or credit-style decision with an audit trail. It matters because wealth firms need faster onboarding and proposal review without losing control over compliance, explainability, and data residency.
Architecture
- •
User-facing orchestrator
- •Accepts the advisor or operations request.
- •Normalizes the input into a structured underwriting case.
- •
Policy retrieval layer
- •Pulls firm rules, suitability thresholds, restricted asset lists, and jurisdiction-specific constraints.
- •Keeps the agent grounded in current policy instead of model memory.
- •
Underwriting analyst agent
- •Reviews the case against policy.
- •Produces a recommendation: approve, reject, or escalate.
- •
Compliance reviewer agent
- •Checks the analyst output for regulatory language, missing disclosures, and audit completeness.
- •Flags cases needing human review.
- •
Audit logger
- •Persists prompts, responses, decision rationale, timestamps, and document references.
- •Required for FINRA/SEC-style traceability and internal controls.
- •
Human escalation path
- •Routes exceptions to a licensed advisor or compliance officer.
- •Prevents autonomous approval on edge cases.
Implementation
1) Install AutoGen and define your case schema
Use the current AutoGen package and keep your underwriting input structured. In wealth management, free-form text is how you get inconsistent decisions and weak auditability.
from pydantic import BaseModel
from typing import List, Optional
class UnderwritingCase(BaseModel):
client_id: str
jurisdiction: str
age: int
liquid_net_worth: float
annual_income: float
investment_objective: str
risk_tolerance: str
requested_product: str
restricted_assets: List[str] = []
notes: Optional[str] = None
case = UnderwritingCase(
client_id="C-10492",
jurisdiction="US",
age=54,
liquid_net_worth=1250000,
annual_income=340000,
investment_objective="capital preservation",
risk_tolerance="moderate",
requested_product="structured note",
)
print(case.model_dump())
2) Create specialist agents with explicit roles
AutoGen’s AssistantAgent works well when each agent has one job. For underwriting, keep the analyst separate from compliance so the model doesn’t blur business judgment with control checks.
import os
from autogen_agentchat.agents import AssistantAgent
llm_config = {
"model": "gpt-4o-mini",
"api_key": os.environ["OPENAI_API_KEY"],
}
underwriter = AssistantAgent(
name="underwriter",
model_client=None,
)
compliance_reviewer = AssistantAgent(
name="compliance_reviewer",
model_client=None,
)
If you are using the newer AutoGen stack with a model client wrapper in your environment, wire it there. The point is the same: one agent generates a decision memo; another validates it against policy.
3) Run a two-agent review loop
Use RoundRobinGroupChat when you want deterministic turn-taking between analyst and compliance. This pattern gives you a clean transcript for audit logging.
import asyncio
from autogen_agentchat.messages import TextMessage
from autogen_agentchat.teams import RoundRobinGroupChat
async def run_underwriting(case_payload: dict):
team = RoundRobinGroupChat(
participants=[underwriter, compliance_reviewer],
max_turns=2,
)
prompt = f"""
You are underwriting a wealth management request.
Case:
{case_payload}
Rules:
- Evaluate suitability based on income, net worth, objective, and risk tolerance.
- Flag any restricted assets or missing information.
- Do not make final approval if jurisdiction is unclear.
- Output a concise recommendation with rationale and escalation status.
"""
result = await team.run(task=prompt)
return result
if __name__ == "__main__":
case_payload = case.model_dump()
output = asyncio.run(run_underwriting(case_payload))
print(output)
This is the core pattern:
- •The underwriter agent drafts the recommendation.
- •The compliance reviewer checks for policy gaps or regulatory issues.
- •The team transcript becomes your audit artifact.
4) Add deterministic guardrails before any downstream action
Do not let the model directly trigger account opening or trade execution. In wealth management, the agent should recommend; your workflow engine should decide whether to proceed after validation.
def hard_gate(case: UnderwritingCase) -> list[str]:
issues = []
if case.jurisdiction not in {"US", "UK", "EU"}:
issues.append("Unsupported jurisdiction")
if case.risk_tolerance == "high" and case.investment_objective == "capital preservation":
issues.append("Risk/objective mismatch")
if "private credit" in case.restricted_assets:
issues.append("Restricted asset present")
return issues
issues = hard_gate(case)
if issues:
print({"status": "escalate", "issues": issues})
else:
print({"status": "send_to_autogen"})
That pre-check keeps obviously invalid cases out of the LLM path and reduces both cost and compliance exposure.
Production Considerations
- •
Data residency
- •Keep client PII and portfolio data inside approved regions.
- •If you operate in multiple jurisdictions, route EU client cases to EU-hosted inference endpoints only.
- •
Audit logging
- •Store prompts, responses, tool calls, policy version hashes, and final disposition.
- •Tie each decision to a case ID and immutable timestamp so compliance can reconstruct it later.
- •
Human-in-the-loop controls
- •Escalate low-confidence cases automatically.
- •Require manual approval for high-risk products like structured notes, alternatives, margin-related requests, or anything involving suitability exceptions.
- •
Monitoring
- •Track approval rates by product type, jurisdiction, advisor desk, and model version.
- •Watch for drift in rejection reasons; that usually means either policy changed or prompt quality degraded.
Common Pitfalls
- •
Letting the model decide without policy grounding
- •Mistake: asking the LLM to “be smart” about suitability with no retrieved rules.
- •Fix: inject current underwriting policy into every run or retrieve it from a controlled source before calling
AssistantAgent.
- •
Skipping structured inputs
- •Mistake: passing raw advisor notes as plain text.
- •Fix: use typed objects like
UnderwritingCaseso validation happens before inference and audit records stay consistent.
- •
Treating compliance as a postscript
- •Mistake: generating a decision first and checking compliance later by hand.
- •Fix: make compliance an explicit second agent or rule gate in the workflow. In wealth management, that separation is what keeps automation defensible under review.
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