How to Build a compliance checking Agent Using AutoGen in TypeScript for retail banking

By Cyprian AaronsUpdated 2026-04-21
compliance-checkingautogentypescriptretail-banking

A compliance checking agent for retail banking reviews customer-facing text, policy drafts, and operational decisions against internal controls and regulatory rules before they go live. It matters because small wording mistakes in lending, deposits, fees, or collections can create audit findings, customer harm, and regulatory exposure.

Architecture

  • Policy ingestion layer

    • Pulls bank policies, product rules, and regulatory guidance into a structured knowledge base.
    • Keep this separate from the agent so policy updates do not require code changes.
  • Compliance checker agent

    • Uses AssistantAgent to analyze text and flag violations.
    • Produces structured findings: issue type, severity, rationale, and recommended fix.
  • Reviewer or approver agent

    • Uses a second AssistantAgent to challenge the first agent’s output.
    • Useful for reducing false positives on benign marketing language or edge-case disclosures.
  • Human escalation path

    • Routes high-risk items to a compliance officer.
    • Required for anything that touches lending eligibility, adverse action language, fees, or KYC/AML-related statements.
  • Audit logging layer

    • Stores input, output, model version, timestamps, and reviewer decisions.
    • This is non-negotiable in retail banking.
  • Data control boundary

    • Redacts PII before sending content to the model.
    • Enforces data residency and retention rules based on jurisdiction.

Implementation

1) Install AutoGen for TypeScript and define the compliance output shape

Use the TypeScript AutoGen package and keep your output structured. For banking workflows, free-form prose is hard to audit and harder to route.

npm install @autogen-ai/autogen openai zod
import { AssistantAgent } from "@autogen-ai/autogen";
import { z } from "zod";

const ComplianceFindingSchema = z.object({
  status: z.enum(["pass", "review", "fail"]),
  severity: z.enum(["low", "medium", "high"]),
  ruleId: z.string(),
  issue: z.string(),
  rationale: z.string(),
  remediation: z.string(),
});

export type ComplianceFinding = z.infer<typeof ComplianceFindingSchema>;

2) Build the compliance checker agent

The pattern here is simple: one agent gets the policy context and the artifact to review, then returns a strict JSON result. In retail banking, keep the system prompt narrow so the model does not invent policy.

import OpenAI from "openai";
import { AssistantAgent } from "@autogen-ai/autogen";

const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

const complianceAgent = new AssistantAgent({
  name: "compliance_checker",
  modelClient: client,
  systemMessage: [
    "You are a retail banking compliance reviewer.",
    "Check customer-facing content against provided bank policy.",
    "Focus on disclosure accuracy, fair lending language, fee transparency,",
    "collections language, marketing claims, and prohibited promises.",
    "Return only valid JSON matching this schema:",
    '{"status":"pass|review|fail","severity":"low|medium|high","ruleId":"string","issue":"string","rationale":"string","remediation":"string"}',
    "If policy context is insufficient, set status to review.",
    "Never invent regulations not present in the input."
  ].join(" "),
});

3) Run a review with policy context and validate the result

This example reviews a draft message for a deposit product. The important bit is that you pass both the artifact and the relevant policy excerpt; don’t ask the model to infer your bank’s rules from general knowledge.

const policyContext = `
Rule D-14: All deposit marketing must clearly state APY conditions.
Rule F-02: Do not imply guaranteed approval for credit products.
Rule C-09: Fee disclosures must be visible near any fee claim.
`;

const draftCopy = `
Open an account today and earn up to 5% APY with no conditions.
Guaranteed approval for eligible customers.
`;

async function runComplianceCheck() {
  const resultText = await complianceAgent.send({
    messages: [
      {
        role: "user",
        content:
          `Policy:\n${policyContext}\n\nArtifact:\n${draftCopy}\n\nReview this content.`,
      },
    ],
  });

  const parsed = ComplianceFindingSchema.parse(JSON.parse(resultText.content as string));
  return parsed;
}

runComplianceCheck().then((finding) => {
  console.log("Compliance result:", finding);
});

4) Add a second-pass reviewer for high-risk cases

For retail banking, I prefer a two-agent pattern on anything customer-facing. The first agent flags issues; the second agent checks whether those flags are justified or whether the first pass overreached.

const reviewerAgent = new AssistantAgent({
  name: "compliance_reviewer",
  modelClient: client,
  systemMessage:
    "You are a senior banking compliance reviewer. Critique another agent's finding. Return JSON with keys status, severity, ruleId, issue, rationale, remediation.",
});

async function secondPassReview(finding: ComplianceFinding) {
  const response = await reviewerAgent.send({
    messages: [
      {
        role: "user",
        content: `Review this finding for accuracy:\n${JSON.stringify(finding)}`,
      },
    ],
  });

  return ComplianceFindingSchema.parse(JSON.parse(response.content as string));
}

Production Considerations

  • Deploy inside your controlled environment

    • Keep prompts, policies, logs, and redaction services in your bank’s network boundary where possible.
    • If you use external model APIs, confirm data processing terms and regional hosting options meet residency requirements.
  • Log everything needed for audit

    • Store request payload hashes, redacted inputs, final findings, model name/version, timestamp, and human override decisions.
    • Auditors will ask why a message passed or failed six months later.
  • Add hard guardrails before model calls

    • Redact account numbers, SSNs/NINs/PANs, addresses, phone numbers, and transaction details.
    • Block unsupported use cases like individualized credit decisions unless legal has signed off.
  • Use risk-based routing

    • Low-severity copy issues can auto-return with remediation suggestions.
    • High-severity items like APR claims or adverse action language should always go to human compliance review.

Common Pitfalls

  1. Treating the model as the source of truth

    • Don’t ask it to “know” bank policy.
    • Always inject current policy text or retrieve it from an approved source of record.
  2. Sending raw PII into prompts

    • Redact before inference.
    • Replace identifiers with stable tokens so you can still trace cases during investigation without exposing customer data.
  3. Using one-pass approvals for regulated content

    • A single agent can miss nuance in disclosure wording or overflag harmless text.
    • Use a second reviewer or deterministic rules for high-risk categories.
  4. Skipping structured outputs

    • Free-text answers break downstream automation and make audits painful.
    • Force JSON output with validation using zod, then reject anything that does not parse cleanly.

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