How to Build a transaction monitoring Agent Using AutoGen in Python for wealth management

By Cyprian AaronsUpdated 2026-04-21
transaction-monitoringautogenpythonwealth-management

A transaction monitoring agent in wealth management watches client activity for patterns that look unusual, policy-breaking, or potentially suspicious. It matters because you need to catch issues early without flooding compliance teams with noise, while preserving an audit trail that stands up to regulatory review.

Architecture

  • Transaction intake layer

    • Pulls trades, transfers, deposits, withdrawals, and account metadata from your internal systems.
    • Normalizes records into a consistent schema before the agent sees them.
  • Policy and rules engine

    • Encodes wealth-management-specific checks like large cash movements, rapid in/out transfers, concentration changes, and jurisdiction mismatches.
    • Produces deterministic flags before any LLM reasoning happens.
  • AutoGen analyst agent

    • Uses AssistantAgent to review flagged transactions and explain why a case deserves escalation or closure.
    • Generates structured outputs for compliance review.
  • Compliance reviewer agent

    • Uses a second AssistantAgent to challenge the first agent’s reasoning.
    • Reduces false positives by forcing a second pass on edge cases.
  • Audit logger

    • Persists prompts, model outputs, rule hits, and final decisions.
    • Required for traceability in regulated environments.
  • Human escalation path

    • Routes high-risk cases to a compliance analyst when confidence is low or policy requires manual review.
    • Keeps the agent advisory, not autonomous.

Implementation

1. Install AutoGen and define the transaction schema

For this pattern, use AutoGen’s AssistantAgent, UserProxyAgent, and GroupChatManager. Keep the schema explicit so every downstream decision is auditable.

from dataclasses import dataclass
from typing import List, Dict, Any
import json

from autogen import AssistantAgent, UserProxyAgent, GroupChat, GroupChatManager


@dataclass
class Transaction:
    tx_id: str
    client_id: str
    amount: float
    currency: str
    country: str
    channel: str
    tx_type: str
    timestamp: str
    risk_tags: List[str]


def to_prompt(tx: Transaction) -> str:
    return json.dumps({
        "tx_id": tx.tx_id,
        "client_id": tx.client_id,
        "amount": tx.amount,
        "currency": tx.currency,
        "country": tx.country,
        "channel": tx.channel,
        "tx_type": tx.tx_type,
        "timestamp": tx.timestamp,
        "risk_tags": tx.risk_tags,
    }, indent=2)

2. Create the analyst and reviewer agents

Use two assistants with different system prompts. One produces a first-pass assessment; the other critiques it using compliance logic. For wealth management, make sure the prompts explicitly mention AML/KYC context, suitability concerns where relevant, and escalation thresholds.

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

analyst = AssistantAgent(
    name="transaction_analyst",
    llm_config=llm_config,
    system_message=(
        "You are a transaction monitoring analyst for wealth management. "
        "Review transactions for AML red flags, unusual behavior relative to client profile, "
        "jurisdictional risk, structuring patterns, rapid movement of funds, and inconsistent channels. "
        "Return concise JSON with fields: decision, rationale, risk_level, escalate_to_human."
    ),
)

reviewer = AssistantAgent(
    name="compliance_reviewer",
    llm_config=llm_config,
    system_message=(
        "You are a senior compliance reviewer for wealth management. "
        "Challenge weak reasoning, check for false positives, and ensure decisions are defensible. "
        "Return concise JSON with fields: agree_with_decision, corrections_needed, final_risk_level."
    ),
)

user_proxy = UserProxyAgent(
    name="case_router",
    human_input_mode="NEVER",
)

3. Run a two-agent case review with AutoGen

This is the core pattern. The user proxy injects the transaction into a group chat; the analyst evaluates it; the reviewer validates it; then your application consumes the result.

import os

def monitor_transaction(tx: Transaction) -> str:
    message = (
        "Assess this wealth management transaction for monitoring purposes.\n"
        f"{to_prompt(tx)}"
    )

    groupchat = GroupChat(
        agents=[user_proxy, analyst, reviewer],
        messages=[],
        max_round=4,
    )

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

    user_proxy.initiate_chat(manager, message=message)
    return json.dumps(groupchat.messages[-1], indent=2)


if __name__ == "__main__":
    tx = Transaction(
        tx_id="TX-10091",
        client_id="C-44821",
        amount=250000.00,
        currency="USD",
        country="US",
        channel="wire",
        tx_type="outgoing_transfer",
        timestamp="2026-04-21T10:15:00Z",
        risk_tags=["new_beneficiary", "high_value", "cross_border_history"],
    )

    result = monitor_transaction(tx)
    print(result)

4. Add deterministic pre-filters before calling the model

Do not send every transaction to the LLM. Use rules first so you control cost and reduce exposure of sensitive data. In wealth management workflows, this also helps separate obvious policy hits from nuanced reviews.

def rule_flags(tx: Transaction) -> List[str]:
    flags = []

    if tx.amount >= 100000:
      flags.append("high_value")
    if "new_beneficiary" in tx.risk_tags:
      flags.append("new_beneficiary")
    if tx.country not in {"US", "CA", "GB", "DE", "FR"}:
      flags.append("higher_jurisdiction_risk")

    return flags


def should_escalate(tx: Transaction) -> bool:
   return len(rule_flags(tx)) > 0


if should_escalate(tx):
   print(monitor_transaction(tx))
else:
   print({"decision": "clear", "reason": "No rule-based risk triggers"})

Production Considerations

  • Deploy in-region

    • Wealth management data often has residency constraints tied to jurisdiction and client agreements.
    • Keep prompts and transcripts inside approved regions and avoid sending raw PII outside controlled boundaries.
  • Log everything needed for audit

    • Store input transaction payloads, rule hits, agent outputs, timestamps, model version, and final disposition.
    • Compliance teams will want reproducibility months later.
  • Use guardrails around output format

    • Force JSON output and validate it before persisting or routing.
    • Reject free-form responses that omit decision, risk_level, or escalate_to_human.
  • Keep humans in the loop for high-risk cases

    • Any politically exposed person activity, sanctions adjacency, large cross-border movement, or repeated structuring pattern should be escalated.
    • The agent should recommend; compliance should decide.

Common Pitfalls

  • Sending raw client data directly to the model

    • Avoid dumping full account statements or KYC files into prompts.
    • Minimize fields to what is needed for monitoring and redact identifiers where possible.
  • Using one agent for both analysis and approval

    • A single agent tends to rubber-stamp its own reasoning.
    • Split analysis and review into separate agents with different system messages.
  • Treating LLM output as final truth

    • LLMs are good at triage summaries, not regulatory decisions.
    • Always combine model output with deterministic rules and human review thresholds.

This pattern gives you a practical starting point: rules first, AutoGen second-pass reasoning next, human escalation last. That is the right shape for wealth management where explainability, auditability, and jurisdictional controls matter more than raw automation.


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