CrewAI Tutorial (TypeScript): optimizing token usage for advanced developers
By Cyprian AaronsUpdated 2026-04-21
crewaioptimizing-token-usage-for-advanced-developerstypescript
This tutorial shows you how to reduce token spend in a CrewAI TypeScript workflow without breaking task quality. You’ll wire in tighter prompts, smaller context windows, controlled delegation, and explicit output contracts so agents stop burning tokens on unnecessary chatter.
What You'll Need
- •Node.js 18+
- •A TypeScript project with
ts-nodeortsx - •CrewAI JS/TS package installed
- •An OpenAI API key exported as
OPENAI_API_KEY - •A basic understanding of
Agent,Task, andCrew - •Optional:
zodfor validating structured outputs
npm install @crewai/core openai zod
npm install -D typescript tsx @types/node
Step-by-Step
- •Start with a minimal crew and make the model do less work per call. The biggest token waste usually comes from verbose role instructions and vague tasks that force the agent to think out loud.
import { Agent, Task, Crew } from "@crewai/core";
const analyst = new Agent({
role: "Claims triage analyst",
goal: "Classify claim severity from a short incident note",
backstory: "You only return concise classifications.",
verbose: false,
});
const task = new Task({
description:
"Classify the incident note into one of: low, medium, high. Return only the label.",
expectedOutput: "One word: low, medium, or high.",
agent: analyst,
});
const crew = new Crew({
agents: [analyst],
tasks: [task],
});
- •Force structured output early. If you let an agent freestyle, it tends to add explanations, caveats, and repeated reasoning that all cost tokens.
import { z } from "zod";
import { Agent, Task } from "@crewai/core";
const claimSchema = z.object({
severity: z.enum(["low", "medium", "high"]),
reason: z.string().max(120),
});
const classifier = new Agent({
role: "Claims classifier",
goal: "Return compact JSON only",
backstory: "You never add extra text outside valid JSON.",
verbose: false,
});
const classifyTask = new Task({
description:
'Read the note and return JSON matching {"severity":"low|medium|high","reason":"short string"}.',
expectedOutput: claimSchema.toString(),
agent: classifier,
});
- •Reduce context size before the agent sees it. Do not pass raw documents when a preprocessor can trim them to the relevant fields; this is where most enterprise token waste happens.
type ClaimNote = {
policyId: string;
note: string;
amount?: number;
};
function compactNote(input: ClaimNote): string {
const trimmed = input.note.slice(0, 500);
return [
`policyId=${input.policyId}`,
input.amount ? `amount=${input.amount}` : null,
`note=${trimmed}`,
]
.filter(Boolean)
.join("\n");
}
const input = compactNote({
policyId: "POL-48291",
amount: 4200,
note:
"Customer reported water damage after pipe burst in kitchen. No injuries. Photos attached in CRM...",
});
- •Split work into a cheap pass and an expensive pass. Use one small task to extract facts, then feed only those facts into the second task that makes the actual decision.
import { Agent, Task, Crew } from "@crewai/core";
const extractor = new Agent({
role: "Fact extractor",
goal: "Extract only relevant facts",
backstory: "You produce short bullet facts.",
});
const decisionMaker = new Agent({
role: "Decision maker",
goal: "Make the final classification from extracted facts",
backstory: "You rely only on provided facts.",
});
const extractTask = new Task({
description:
"Extract the key facts from the incident note as three bullets max.",
expectedOutput: "Three bullets max.",
agent: extractor,
});
const decideTask = new Task({
description:
"Use only the extracted facts to classify severity as low, medium, or high.",
expectedOutput: "One label plus one short reason.",
agent: decisionMaker,
});
- •Turn off unnecessary delegation and verbose behavior. Delegation creates extra calls; if your workflow is deterministic, keep it single-path.
import { Agent } from "@crewai/core";
const lockedDownAgent = new Agent({
role: "Underwriter assistant",
goal: "Answer directly with minimal tokens",
backstory:
"You do not delegate unless explicitly instructed. You do not explain your chain of thought.",
verbose: false,
});
lockedDownAgent.allowDelegation = false;
lockedDownAgent.maxIter = undefined;
- •Run the crew with compact inputs and inspect the output size. In production you want predictable payloads, so keep both prompts and responses narrow enough to audit easily.
import { Agent, Task, Crew } from "@crewai/core";
async function main() {
const analyst = new Agent({
role: "Claims triage analyst",
goal: "Classify claim severity from a short incident note",
backstory: "Return concise classifications only.",
verbose: false,
allowDelegation: false,
});
---
## Keep learning
- [The complete AI Agents Roadmap](/blog/ai-agents-roadmap-2026) — my full 8-step breakdown
- [Free: The AI Agent Starter Kit](/starter-kit) — PDF checklist + starter code
- [Work with me](/contact) — I build AI for banks and insurance companies
*By Cyprian Aarons, AI Consultant at [Topiax](https://topiax.xyz).*
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