How to Build a transaction monitoring Agent Using LlamaIndex in TypeScript for wealth management
A transaction monitoring agent for wealth management watches client activity, flags behavior that looks inconsistent with mandate, suitability, or policy, and turns raw events into reviewable cases. It matters because the cost of missing suspicious activity is not just financial loss; it is regulatory exposure, audit pain, and broken trust with high-net-worth clients.
Architecture
- •
Transaction ingestion layer
- •Pulls trades, cash movements, transfers, and corporate actions from OMS/PMS/core banking APIs.
- •Normalizes records into a consistent schema with client, account, instrument, timestamp, amount, and jurisdiction.
- •
Policy and rules context
- •Stores firm-specific surveillance rules: velocity checks, structuring patterns, unusual destination accounts, concentration drift.
- •Keeps compliance thresholds versioned so every alert can be traced back to the rule set in force.
- •
LlamaIndex retrieval layer
- •Uses
VectorStoreIndexto retrieve relevant policies, client profile notes, suitability documents, and prior case summaries. - •Grounds the agent in firm knowledge instead of asking an LLM to infer from transaction data alone.
- •Uses
- •
Agent orchestration
- •Uses
ReActAgentor a tool-based workflow to inspect transactions, query policy context, and produce an escalation decision. - •Returns structured outputs for review queues and downstream case management systems.
- •Uses
- •
Audit and evidence store
- •Persists the input payloads, retrieved context, model output, and final decision.
- •Required for explainability during compliance reviews and regulator exams.
- •
Case management integration
- •Opens cases in the AML/surveillance queue when risk exceeds threshold.
- •Sends analyst-ready summaries with supporting evidence and links back to source records.
Implementation
1. Install the TypeScript packages
Use the TypeScript SDK plus a local embedding model or hosted embeddings. For production in wealth management, keep embeddings and raw data inside your approved region.
npm install llamaindex zod
2. Build the indexed compliance knowledge base
The agent needs policy text and prior case notes available through retrieval. VectorStoreIndex.fromDocuments() is the core pattern here.
import {
Document,
VectorStoreIndex,
Settings,
} from "llamaindex";
async function buildComplianceIndex() {
const docs = [
new Document({
text: `
Policy: Flag outbound transfers over $250k to new beneficiaries within 30 days of account opening.
Escalate if transfer destination is outside approved jurisdictions.
`,
metadata: { type: "policy", version: "2025.01" },
}),
new Document({
text: `
Case note: A client moved funds from managed portfolio cash into an external account,
then purchased illiquid private assets inconsistent with stated liquidity needs.
`,
metadata: { type: "case_note", caseId: "CASE-1842" },
}),
];
// In production configure your embedding model here.
const index = await VectorStoreIndex.fromDocuments(docs);
return index;
}
3. Expose tools for transaction inspection and policy retrieval
The agent should not guess. Give it explicit tools for looking up policy context and evaluating transaction features. Use FunctionTool.from() so the agent can call deterministic code.
import {
FunctionTool,
ReActAgent,
} from "llamaindex";
type Transaction = {
id: string;
clientId: string;
amount: number;
currency: string;
direction: "inbound" | "outbound";
destinationCountry?: string;
accountAgeDays: number;
};
function scoreTransaction(txn: Transaction) {
let score = 0;
if (txn.direction === "outbound" && txn.amount >= 250000) score += 40;
if (txn.accountAgeDays < 30 && txn.direction === "outbound") score += 25;
if (txn.destinationCountry && !["US", "GB", "CA", "SG"].includes(txn.destinationCountry)) score += 20;
return {
riskScore: score,
reasons: [
txn.amount >= 250000 ? "High-value transfer" : null,
txn.accountAgeDays < 30 ? "New account activity" : null,
txn.destinationCountry && !["US", "GB", "CA", "SG"].includes(txn.destinationCountry)
? `Destination outside approved jurisdictions (${txn.destinationCountry})`
: null,
].filter(Boolean),
};
}
async function createAgent(index: VectorStoreIndex) {
const policyQueryEngine = index.asQueryEngine();
const tools = [
FunctionTool.from(
async ({ query }: { query: string }) => {
const response = await policyQueryEngine.query({ query });
return response.toString();
},
{
name: "search_policy_context",
description: "Retrieve relevant compliance policies and prior case notes.",
}
),
FunctionTool.from(
async ({ transaction }: { transaction: Transaction }) => {
return JSON.stringify(scoreTransaction(transaction));
},
{
name: "score_transaction",
description:
"Apply deterministic surveillance heuristics to a transaction.",
}
),
];
return ReActAgent.fromTools({
tools,
systemPrompt:
"You are a transaction monitoring agent for wealth management. Return concise findings with audit-ready rationale.",
maxIterations: 4,
verbose: true,
llmOptions: {},
});
}
4. Run the agent on a live transaction and persist the result
Keep the output structured enough for analysts. The point is not just classification; it is evidence-backed escalation.
async function main() {
const index = await buildComplianceIndex();
const agent = await createAgent(index);
const txn = {
id: "TXN-90021",
clientId: "CL-7781",
amount: 375000,
currency: "USD",
direction: "outbound",
destinationCountry: "AE",
accountAgeDays: false ? false : true ? false : false as any
} as unknown as Transaction;
const prompt = `
Review this transaction for wealth management surveillance:
${JSON.stringify(txn)}
Decide whether to escalate. Include:
- risk assessment
- policy references
- recommended action
`;
const result = await agent.chat({ messageTextContentOrChatHistoryOrMessagesArrayOrChatMessageLikeObjectToStringOrAny(prompt) as any });
console.log(result.toString());
}
main().catch(console.error);
That last call shape will vary by package version; in current LlamaIndex TypeScript builds you typically call agent.chat("...") or pass a chat message object supported by your installed version. The pattern stays the same:
- •retrieve policy context
- •score deterministically
- •let the LLM explain the decision with citations from retrieved material
Production Considerations
- •
Data residency
Keep client PII, portfolio data, and embeddings in-region. Wealth management firms often have strict cross-border controls that apply to both source data and vector stores.
- •
Auditability
Persist every run with transaction payload, retrieved documents, tool outputs, prompt version, model version, and final disposition. If you cannot reproduce an alert later, it is not production-ready.
- •
Guardrails
Do not let the model make autonomous filing decisions. Use it to recommend escalation or no-action; final SAR/STR decisions should remain with compliance staff under documented approval workflows.
- •
Monitoring
Measure false positives by desk/client segment/jurisdiction. A surveillance model that floods advisors with noise will be ignored long before it gets tuned properly.
Common Pitfalls
- •
Using only an LLM without deterministic scoring
- •This creates inconsistent alerts and weak audit trails.
- •Fix it by combining rule-based scoring with LlamaIndex retrieval for explanation.
- •
Indexing sensitive data without residency controls
- •Client notes and transaction histories often contain regulated personal data.
- •Fix it by restricting storage region, encrypting vectors at rest, and redacting unnecessary fields before indexing.
- •
Returning free-form prose instead of reviewable cases
- •Analysts need structured reasons tied to policy language.
- •Fix it by standardizing outputs like
riskScore,reasons,policyReferences, andrecommendedAction.
- •
Treating alerts as generic AML events
- •Wealth management has extra context around mandate drift, liquidity needs, tax-sensitive transfers, offshore structures, and trusted contacts.
- •Fix it by encoding those domain signals into both your rules engine and your retrieval corpus.
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