AutoGen Tutorial (TypeScript): running agents in parallel for advanced developers
This tutorial shows you how to run multiple AutoGen agents in parallel with TypeScript, then collect and merge their outputs into one result. You need this when a single agent becomes the bottleneck: parallelizing research, validation, or independent subtasks cuts latency and gives you cleaner separation of concerns.
What You'll Need
- •Node.js 18+ and npm
- •A TypeScript project initialized with
tsconfig.json - •AutoGen for TypeScript installed:
- •
npm install @autogen/agentchat @autogen/core openai
- •
- •An OpenAI API key set in your environment:
- •
export OPENAI_API_KEY="your-key"
- •
- •A model that supports chat completions, such as:
- •
gpt-4o-mini
- •
- •Basic familiarity with AutoGen agents and async/await
Step-by-Step
- •Start by creating a small project structure that keeps your agent setup isolated from your orchestration code. For parallel execution, the important part is that each agent gets its own runtime context and can be awaited independently.
import { OpenAIChatCompletionClient } from "@autogen/openai";
import { AssistantAgent } from "@autogen/agentchat";
const modelClient = new OpenAIChatCompletionClient({
model: "gpt-4o-mini",
apiKey: process.env.OPENAI_API_KEY,
});
const financeAgent = new AssistantAgent({
name: "finance_agent",
modelClient,
systemMessage: "You are a financial analyst. Return concise bullet points.",
});
const riskAgent = new AssistantAgent({
name: "risk_agent",
modelClient,
systemMessage: "You are a risk analyst. Focus on operational and compliance risks.",
});
- •Define a helper that runs one agent task and returns plain text. This keeps the parallel orchestration clean and makes it easy to add retries, logging, or timeouts later.
async function runAgent(agent: AssistantAgent, task: string): Promise<string> {
const result = await agent.run(task);
return result.messages
.map((m) => (typeof m.content === "string" ? m.content : JSON.stringify(m.content)))
.join("\n");
}
- •Run the agents with
Promise.allso both requests go out at the same time. This is the core pattern: independent work should be launched together, then joined only when all results are ready.
async function main() {
const task = "Analyze the impact of delayed claims processing on customer retention.";
const [financeResult, riskResult] = await Promise.all([
runAgent(financeAgent, task),
runAgent(riskAgent, task),
]);
console.log("=== Finance Agent ===");
console.log(financeResult);
console.log("\n=== Risk Agent ===");
console.log(riskResult);
}
main().catch((error) => {
console.error(error);
process.exit(1);
});
- •If you need more control, wrap each agent call in its own timeout. In production systems, parallelism without time limits becomes a liability because one slow model call can hold the entire workflow hostage.
function withTimeout<T>(promise: Promise<T>, ms: number): Promise<T> {
return new Promise((resolve, reject) => {
const timer = setTimeout(() => reject(new Error(`Timed out after ${ms}ms`)), ms);
promise.then(
(value) => {
clearTimeout(timer);
resolve(value);
},
(error) => {
clearTimeout(timer);
reject(error);
}
);
});
}
async function mainWithTimeout() {
const task = "Summarize the top three reasons claims automation fails in insurance.";
const [a, b] = await Promise.all([
withTimeout(runAgent(financeAgent, task), 15000),
withTimeout(runAgent(riskAgent, task), 15000),
]);
console.log({ finance: a.length, risk: b.length });
}
- •For advanced workflows, use parallel agents for different roles and then add a synthesis step. The synthesis agent should not redo the research; it should merge and normalize the outputs from the specialist agents.
const synthesisAgent = new AssistantAgent({
name: "synthesis_agent",
modelClient,
systemMessage: "Combine inputs into one executive summary with no duplicated points.",
});
async function synthesize(financeText: string, riskText: string): Promise<string> {
const prompt = `
Combine these two analyses into one concise summary:
[Finance]
${financeText}
[Risk]
${riskText}
`;
return runAgent(synthesisAgent, prompt);
}
Testing It
Run the script with node or your TypeScript runner after setting OPENAI_API_KEY. If both specialist agents print output at roughly the same time, your parallel execution is working.
A good smoke test is to compare total runtime against sequential execution; Promise.all should reduce wall-clock time when both calls take similar time. Also check that each agent stays within its role boundaries — finance should sound like finance, risk should sound like risk.
If you add timeouts, force one request to use an invalid model name or an intentionally long prompt and confirm the timeout path triggers cleanly. In production code, also log per-agent latency so you can see which role is slowing down your pipeline.
Next Steps
- •Add structured outputs so each agent returns JSON instead of free text
- •Introduce retry logic with exponential backoff for transient API failures
- •Move from
Promise.allto a bounded concurrency queue when you have many agents
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