How to Build a customer support Agent Using CrewAI in TypeScript for wealth management

By Cyprian AaronsUpdated 2026-04-21
customer-supportcrewaitypescriptwealth-management

A customer support agent for wealth management handles client questions, routes requests, drafts compliant responses, and escalates anything that touches suitability, trading, or account changes. That matters because support in this domain is not just about speed; every answer has compliance, audit, and client trust implications.

Architecture

  • Client intake layer

    • Accepts chat, email, or CRM tickets.
    • Normalizes the request into a structured case object with client ID, topic, urgency, and jurisdiction.
  • Policy retrieval layer

    • Pulls approved knowledge from internal FAQs, product docs, fee schedules, and compliance playbooks.
    • Restricts retrieval to region-specific content for data residency and regulatory alignment.
  • Support agent

    • Uses Agent to classify intent, summarize context, and draft a response.
    • Keeps the tone professional and avoids advice that could be interpreted as personalized investment guidance.
  • Compliance reviewer

    • A second Agent checks the draft for prohibited language, missing disclosures, escalation triggers, and suitability risk.
    • Flags anything involving trades, portfolio recommendations, tax advice, or beneficiary changes.
  • Escalation workflow

    • Routes complex cases to a human advisor or operations queue.
    • Stores the decision trail for auditability.
  • Audit and observability

    • Logs prompts, tool calls, retrieved sources, model output, and final disposition.
    • Supports internal review and regulatory exams.

Implementation

  1. Install CrewAI for TypeScript and define your case shape

    Start with a small domain model. In wealth management support, your agent should never work on raw free-text alone; it needs structured metadata for routing and controls.

    // package.json dependencies:
    // "crewai": "^0.x.x"
    // "zod": "^3.x.x"
    
    import { z } from "zod";
    
    export const SupportCaseSchema = z.object({
      caseId: z.string(),
      clientId: z.string(),
      jurisdiction: z.enum(["US", "UK", "EU", "APAC"]),
      channel: z.enum(["chat", "email", "crm"]),
      topic: z.string(),
      message: z.string(),
      urgency: z.enum(["low", "medium", "high"]),
    });
    
    export type SupportCase = z.infer<typeof SupportCaseSchema>;
    
  2. Create two agents: one for support drafting and one for compliance review

    Use Agent for both roles. The support agent should stay narrow: answer policy questions, explain process steps, and escalate anything regulated. The compliance agent should act like a hard gate before anything reaches the client.

    import { Agent } from "crewai";
    
    export const supportAgent = new Agent({
      name: "WealthSupportAgent",
      role: "Client Support Specialist",
      goal:
        "Draft accurate client support responses using approved policy content only.",
      backstory:
        "You handle wealth management service requests. You never provide personalized investment advice or promise outcomes.",
      verbose: true,
    });
    
    export const complianceAgent = new Agent({
      name: "ComplianceReviewer",
      role: "Compliance Reviewer",
      goal:
        "Detect unsuitable language, missing disclosures, and escalation triggers in client-facing drafts.",
      backstory:
        "You review all outbound wealth management communications for regulatory risk.",
      verbose: true,
    });
    
  3. Define tasks and run them as a crew

    The pattern here is sequential review: draft first, then compliance checks second. That gives you a clean audit trail and prevents unreviewed responses from leaving the system.

    import { Crew } from "crewai";
    import { Task } from "crewai";
    import { supportAgent, complianceAgent } from "./agents";
    import { SupportCase } from "./schema";
    
    export async function handleSupportCase(input: SupportCase) {
      const draftTask = new Task({
        description: `
          Given this wealth management support case:
          ${JSON.stringify(input)}
    
          Draft a concise client response using only approved service language.
          If the request involves trades, portfolio changes, tax advice,
          performance guarantees, or account ownership changes,
          mark it for escalation instead of answering directly.
        `,
        expectedOutput:
          "A client-safe draft response or an explicit escalation note.",
        agent: supportAgent,
      });
    
      const reviewTask = new Task({
        description: `
          Review the drafted response for compliance risk.
          Check for suitability issues, missing disclaimers,
          prohibited advice language, and any need for human escalation.
        `,
        expectedOutput:
          "Approved response or rejection with specific reasons.",
        agent: complianceAgent,
        context: [draftTask],
      });
    
      const crew = new Crew({
        agents: [supportAgent, complianceAgent],
        tasks: [draftTask, reviewTask],
        verbose: true,
      });
    
      const result = await crew.kickoff();
      return result;
    }
    
  4. Add routing logic before kickoff

    Don’t send every ticket to the LLM. Use deterministic rules first so you can keep high-risk cases out of automated response paths.

     import { SupportCaseSchema } from "./schema";
     import { handleSupportCase } from "./workflow";
    
     function requiresHumanReview(topic: string) {
       const highRisk = [
         "trade",
         "sell",
         "buy",
         "portfolio",
         "tax",
         "beneficiary",
         "wire",
         "transfer",
         "complaint",
       ];
       return highRisk.some((word) => topic.toLowerCase().includes(word));
     }
    
     export async function processIncomingTicket(raw: unknown) {
       const input = SupportCaseSchema.parse(raw);
    
       if (requiresHumanReview(input.topic) || input.urgency === "high") {
         return {
           disposition: "escalate",
           reason: "High-risk wealth management topic requires human handling.",
         };
       }
    
       return await handleSupportCase(input);
     }
    

Production Considerations

  • Deploy regionally

    • Keep processing in the same legal region as the client data where possible.
    • For EU clients under GDPR or local bank secrecy rules, avoid sending data to non-approved regions.
  • Log everything needed for audit

    • Store input payloads, retrieved policy sources, task outputs, final disposition, model version, and timestamps.
    • Make logs immutable or append-only so compliance can reconstruct decisions later.
  • Add guardrails before generation

    • Block PII beyond what is needed for resolution.
    • Redact account numbers unless absolutely required.
    • Reject prompts asking for recommendations on asset allocation or security selection.
  • Monitor escalation rates

    • A sudden drop in escalations can mean the model is overconfident.
    • A sudden spike can mean your policy corpus is stale or your prompts are too conservative.

Common Pitfalls

  • Letting the agent answer regulated questions directly

    • Mistake: allowing the model to respond to trade instructions or suitability questions.
    • Fix: route those cases to human review with deterministic pre-checks before Crew.kickoff().
  • Skipping source grounding

    • Mistake: relying on model memory instead of approved policy documents.
    • Fix: connect retrieval to internal knowledge only and constrain responses to cited internal sources.
  • Ignoring jurisdiction-specific rules

    • Mistake: using one global prompt for US clients and EU clients.
    • Fix: pass jurisdiction into routing logic and maintain separate policy sets by region.
  • No audit trail on outbound messages

    • Mistake: storing only final answers without intermediate reasoning artifacts.
    • Fix: persist task inputs/outputs plus reviewer decisions so compliance can inspect every step later.

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