CrewAI Tutorial (TypeScript): adding audit logs for advanced developers
This tutorial shows how to add structured audit logging to a CrewAI TypeScript app so every agent decision, tool call, and final output is traceable. You need this when you’re building systems in regulated environments like banking or insurance, where you must answer who did what, when, with which inputs, and what came out.
What You'll Need
- •Node.js 18+
- •A TypeScript project with
tsconfig.json - •CrewAI TypeScript package installed
- •OpenAI API key set as
OPENAI_API_KEY - •A place to write logs:
- •local JSONL file for dev
- •stdout for containerized runs
- •centralized log pipeline in prod
- •Basic familiarity with CrewAI concepts:
- •
Agent - •
Task - •
Crew - •
kickoff()
- •
Step-by-Step
- •Create a small audit logger that writes one JSON record per event.
Keep it boring: timestamps, correlation IDs, actor names, event type, payload, and success/failure. That format is easy to ship into Splunk, Datadog, or Elasticsearch later.
// audit.ts
import { appendFileSync } from "node:fs";
import { randomUUID } from "node:crypto";
export type AuditEvent = {
id: string;
ts: string;
runId: string;
actor: string;
event: string;
payload: Record<string, unknown>;
};
export function createRunId(): string {
return randomUUID();
}
export function audit(event: Omit<AuditEvent, "id" | "ts">) {
const record: AuditEvent = {
id: randomUUID(),
ts: new Date().toISOString(),
...event,
};
appendFileSync("audit.log", JSON.stringify(record) + "\n");
}
- •Define your agents and tasks with explicit names so your logs are readable.
In regulated workflows, anonymous agents are useless during incident review.
// crew.ts
import { Agent, Task, Crew } from "@crewai/crewai";
import { audit } from "./audit";
export function buildCrew(runId: string) {
const analyst = new Agent({
name: "claims_analyst",
role: "Claims Analyst",
goal: "Summarize claim risk clearly",
backstory: "You review insurance claims for fraud indicators.",
verbose: true,
});
const task = new Task({
description: "Review the claim notes and produce a risk summary.",
expectedOutput: "A concise risk summary with flagged concerns.",
agent: analyst,
});
const crew = new Crew({
agents: [analyst],
tasks: [task],
verbose: true,
});
audit({
runId,
actor: "system",
event: "crew_built",
payload: { agents: ["claims_analyst"], tasks: [task.description] },
});
return crew;
}
- •Wrap kickoff so you log the start, success, and failure of each run.
This is the core pattern. You do not want to scatter logging across business code; keep it at the execution boundary.
// index.ts
import { buildCrew } from "./crew";
import { audit, createRunId } from "./audit";
async function main() {
const runId = createRunId();
audit({
runId,
actor: "system",
event: "run_started",
payload: { workflow: "claims_review" },
});
try {
const crew = buildCrew(runId);
const result = await crew.kickoff();
audit({
runId,
actor: "system",
event: "run_succeeded",
payload: { result },
});
console.log(result);
} catch (error) {
audit({
runId,
actor: "system",
event: "run_failed",
payload: {
message: error instanceof Error ? error.message : String(error),
},
});
throw error;
}
}
main();
- •Add tool-level auditing when an agent calls external systems.
This matters more than model output logging because the real compliance risk is often the side effect — database reads, API calls, file access, or policy checks.
// tools.ts
import { Tool } from "@crewai/crewai";
import { audit } from "./audit";
export function makePolicyLookupTool(runId?: string) {
return new Tool({
name: "policy_lookup",
description: "Look up policy details by policy number",
func: async (policyNumber: string) => {
audit({
runId: runId ?? "unknown",
actor: "tool.policy_lookup",
event: "tool_called",
payload: { policyNumber },
});
const result = `Policy ${policyNumber}: active`;
audit({
runId: runId ?? "unknown",
actor: "tool.policy_lookup",
event": "tool_returned",
payload": { result },
});
return result;
},
});
}
- •Pass the tool into your agent and keep the run ID threaded through everything.
Correlation IDs are non-negotiable if you want a usable audit trail across multiple agents or downstream services.
// crew-with-tool.ts
import { Agent, Task, Crew } from "@crewai/crewai";
import { makePolicyLookupTool } from "./tools";
export function buildAuditedCrew(runId?: string) {
const lookupTool = makePolicyLookupTool(runId);
const investigator = new Agent({
name: "policy_investigator",
role": "Policy Investigator",
goal": "Verify policy status before making recommendations",
backstory": "You validate policy data before responding.",
tools": [lookupTool],
verbose": true,
});
const task = new Task({
description": "Check whether policy POL123 is active and summarize the result.",
expectedOutput": "A short status summary.",
agent": investigator,
});
return new Crew({
agents": [investigator],
tasks": [task],
verbose": true,
});
}
Testing It
Run the app once with a valid OPENAI_API_KEY, then inspect audit.log. You should see newline-delimited JSON records for run_started, crew_built, any tool events, and either run_succeeded or run_failed.
If you trigger an error — for example by removing the API key — confirm that failure is still logged before the process exits. That’s the important bit; failed runs are usually more valuable than successful ones during audits.
For production-style verification, grep by runId and make sure all events for one execution line up in order. If you’re shipping logs to a central platform later, this same schema should map cleanly into indexed fields.
Next Steps
- •Add redaction for PII fields before writing to disk or stdout.
- •Replace file-based logging with a structured logger like Pino and ship JSON directly.
- •Extend the schema with
tenantId,userId, andmodelso compliance teams can trace multi-tenant runs.
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