How to Build a transaction monitoring Agent Using CrewAI in TypeScript for investment banking

By Cyprian AaronsUpdated 2026-04-21
transaction-monitoringcrewaitypescriptinvestment-banking

A transaction monitoring agent watches trades, payments, and internal transfers for patterns that could indicate market abuse, sanctions exposure, fraud, or AML risk. In investment banking, that matters because the difference between catching a suspicious sequence early and missing it is measured in regulatory exposure, client impact, and audit findings.

Architecture

  • Transaction ingestion layer

    • Pulls trade events, wire transfers, booking entries, and reference data from Kafka, S3, a database, or an API.
    • Normalizes everything into one schema before analysis.
  • Risk scoring toolset

    • Computes deterministic signals like threshold breaches, velocity checks, counterparty concentration, and jurisdiction risk.
    • Keeps the model grounded in explainable features.
  • CrewAI agent

    • Uses Agent to reason over the transaction context.
    • Produces a structured alert decision: clear, review, or escalate.
  • Task orchestration

    • Uses Task objects to separate triage, enrichment, and escalation.
    • Makes the workflow auditable and easier to test.
  • Compliance evidence store

    • Persists inputs, outputs, prompts, tool calls, and timestamps.
    • Required for model risk management and regulator review.
  • Case management integration

    • Pushes suspicious activity into an internal queue like ServiceNow, Actimize-style case systems, or a custom AML platform.

Implementation

1) Install the runtime and define your event shape

For TypeScript projects, keep the agent boundary small. The agent should not talk directly to raw feeds; it should receive normalized transactions with enough context to make a decision.

npm install @crew-ai/crewai zod
// src/types.ts
import { z } from "zod";

export const TransactionSchema = z.object({
  transactionId: z.string(),
  accountId: z.string(),
  counterpartyId: z.string(),
  amount: z.number().positive(),
  currency: z.string().length(3),
  country: z.string().length(2),
  channel: z.enum(["wire", "trade", "internal_transfer", "cash"]),
  timestamp: z.string().datetime(),
  notes: z.string().optional(),
});

export type Transaction = z.infer<typeof TransactionSchema>;

2) Create deterministic tools for compliance-friendly signals

Do not ask the model to invent risk signals. Give it tools that calculate facts you can defend in front of compliance and audit.

// src/tools.ts
import { Transaction } from "./types";

export function calculateRiskScore(tx: Transaction): {
  score: number;
  reasons: string[];
} {
  const reasons: string[] = [];
  let score = 0;

  if (tx.amount >= 1000000) {
    score += 30;
    reasons.push("High-value transaction");
  }

  if (["IR", "KP", "RU", "SY"].includes(tx.country)) {
    score += 40;
    reasons.push("Higher-risk jurisdiction");
  }

  if (tx.channel === "cash") {
    score += 20;
    reasons.push("Cash movement");
  }

  if (tx.notes?.toLowerCase().includes("urgent")) {
    score += 10;
    reasons.push("Urgency language detected");
  }

  return { score: Math.min(score, 100), reasons };
}

3) Wire up the CrewAI agent with explicit instructions

Use one agent for triage. Keep the output narrow so downstream systems can consume it without parsing free text.

// src/monitoringAgent.ts
import { Agent } from "@crew-ai/crewai";
import { calculateRiskScore } from "./tools";
import { Transaction } from "./types";

export function buildMonitoringAgent() {
  return new Agent({
    role: "Transaction Monitoring Analyst",
    goal:
      "Assess banking transactions for AML, sanctions, fraud, and market abuse indicators using deterministic evidence.",
    backstory:
      "You work in an investment bank's financial crime team. You must be conservative, explain every escalation clearly, and never speculate beyond provided facts.",
    verbose: true,
    allowDelegation: false,
    tools: [
      {
        name: "calculateRiskScore",
        description:
          "Return a deterministic risk score and reasons for a transaction.",
        func: calculateRiskScore,
      },
    ],
    maxIter: 3,
    memory: false,
    llm:
      process.env.CREWAI_MODEL ?? undefined,
    systemPrompt:
      "Only use provided transaction data and tool outputs. Return JSON with decision, riskScore, reasons, and recommendedAction.",
  });
}

4) Run a task and persist an audit trail

The important pattern is to store the exact input and output alongside metadata. That is what makes this usable in investment banking instead of just being a demo.

// src/index.ts
import { CrewAI } from "@crew-ai/crewai";
import { Task } from "@crew-ai/crewai";
import { buildMonitoringAgent } from "./monitoringAgent";
import { TransactionSchema } from "./types";
import fs from "node:fs/promises";

async function main() {
  const raw = {
    transactionId: "TX-88421",
    accountId: "ACC-10091",
    counterpartyId: "CP-4412",
    amount: 2500000,
    currency: "USD",
    country: "AE",
    channel: "wire",
    timestamp: new Date().toISOString(),
    notes: "urgent settlement requested by client desk",
  };

   const tx = TransactionSchema.parse(raw);
   const agent = buildMonitoringAgent();

   const task = new Task({
     description:
       `Review this transaction for suspicious activity:\n${JSON.stringify(tx)}`,
     expectedOutput:
       'Valid JSON with keys decision, riskScore, reasons, recommendedAction',
     agent,
   });

   const crew = new CrewAI({
     agents: [agent],
     tasks: [task],
     verbose: true,
   });

   const result = await crew.kickoff();

   await fs.writeFile(
     `./audit/${tx.transactionId}.json`,
     JSON.stringify(
       {
         input: tx,
         output: result,
         reviewedAt: new Date().toISOString(),
         modelVersion:
           process.env.CREWAI_MODEL ?? "default",
       },
       null,
       2
     )
   );

   console.log(result);
}

main().catch((err) => {
   console.error(err);
   process.exit(1);
});

Production Considerations

  • Deploy close to your data boundary

    Keep the agent inside your approved cloud region or on-prem network segment. Investment banking teams often have strict data residency requirements for client data and trade records.

  • Log everything needed for audit

    Store prompt inputs, tool outputs, model version, timestamps, user identity that triggered the run, and final disposition. If compliance asks why a case was escalated six months later, you need evidence without reconstructing history from logs alone.

  • Put hard guardrails around outputs

    Require structured JSON only. Reject any response that does not match your schema before it reaches case management or alerting systems.

  • Monitor drift by desk and corridor

    Risk patterns differ across equities trading desks, prime brokerage flows, FX payments, and cross-border treasury movements. Track false positives by business line so you do not tune one desk at the expense of another.

Common Pitfalls

  • Letting the model make unsupported claims

    If you do not provide deterministic tools and strict instructions, the agent will infer intent from weak signals. Avoid this by forcing every escalation reason to map back to a known field or tool output.

  • Skipping schema validation

    Free-form text breaks downstream automation fast. Use zod or equivalent validation before writing alerts into your case system.

  • Ignoring human review thresholds

    Not every anomaly should become a SAR or escalation. Define clear thresholds for low-risk logging versus high-risk referral so analysts are not flooded with noise.

  • Treating audit as an afterthought

    In investment banking you need reproducibility first. Persist inputs, outputs, versioning metadata, and rule snapshots at the time of execution; otherwise your monitoring stack will fail governance review even if it works technically.


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