5
Subagents: Building Agent Teams

Create specialized agents that work together to solve complex problems

The Problem: One Agent Can't Do Everything

You've built an agent with tools and memory, but as requirements grow, you realize one agent trying to do everything becomes a nightmare to maintain.

Single Agent Problems

Conflicting instructions
Too many tools to manage
Mixed responsibilities

Subagent Benefits

Specialized expertise
Clean separation of concerns
Easier to maintain and debug

Simple Example: Story Writing & Translation Team

Let's build a creative team: one agent writes stories, another translates them. Much simpler than customer support!

src/index.ts
import { VoltAgent, Agent, createTool } from "@voltagent/core";
import { VercelAIProvider } from "@voltagent/vercel-ai";
import { openai } from "@ai-sdk/openai";
import { z } from "zod";

// Story Writer Agent
const writerAgent = new Agent({
name: "writer",
instructions: `You are a creative story writer. You write engaging short stories based on user requests.

Keep stories between 2-3 paragraphs.
Make them interesting and creative.
Always include vivid descriptions and engaging characters.`,
llm: new VercelAIProvider(),
model: openai("gpt-4o-mini"),
tools: [
createTool({
name: "save_story",
description: "Save a completed story",
parameters: z.object({
title: z.string().describe("Title of the story"),
content: z.string().describe("The story content"),
genre: z.string().describe("Genre of the story")
}),
execute: async ({ title, content, genre }) => {
console.log("Saving story:", { title, genre });
return {
storyId: "STORY-" + Date.now(),
status: "saved",
wordCount: content.split(' ').length
};
},
})
]
});

// Translator Agent
const translatorAgent = new Agent({
name: "translator",
instructions: `You are a professional translator. You translate text into multiple languages:
- German (Deutsch)
- Japanese (日本語)
- Italian (Italiano)

Provide accurate, natural translations that maintain the story's tone and meaning.`,
llm: new VercelAIProvider(),
model: openai("gpt-4o-mini"),
tools: [
createTool({
name: "save_translation",
description: "Save a translation",
parameters: z.object({
originalText: z.string().describe("Original text"),
translatedText: z.string().describe("Translated text"),
language: z.string().describe("Target language")
}),
execute: async ({ originalText, translatedText, language }) => {
console.log("Saving translation to", language);
return {
translationId: "TRANS-" + Date.now(),
language: language,
status: "saved"
};
},
})
]
});

// Creative Director - Coordinates the team
const creativeDirector = new Agent({
name: "creative-director",
instructions: `You are a creative director managing a story writing and translation team.

When users request stories:
1. First use the WRITER agent to create the story
2. Then use the TRANSLATOR agent to translate it into German, Japanese, and Italian
3. Present the original story and all translations

ALWAYS delegate - don't write stories or translate yourself.
Your job is coordination only.

Example flow:
User: "Write a story about a magic cat"
→ Use writer agent to create story
→ Use translator agent for German version
→ Use translator agent for Japanese version
→ Use translator agent for Italian version
→ Present all versions to user`,
llm: new VercelAIProvider(),
model: openai("gpt-4o-mini"),
subAgents: [writerAgent, translatorAgent],
});

new VoltAgent({
agents: {
"creative-director": creativeDirector,
writer: writerAgent,
translator: translatorAgent,
},
});

How Subagents Work

The supervisor agent automatically knows how to use subagents based on the conversation context. Here's what happens:

Creative Workflow

1
User:"Write a story about a magical forest"
2
Creative Director:"I'll coordinate our team to create this story and translate it"
3
Writer Agent:Creates an engaging story about magical forest and saves it
4
Translator Agent:Translates the story into German, Japanese, and Italian
5
Creative Director:Presents the original story and all 3 translations to user

Testing Your Agent Team in VoltOps

Let's test your customer support team in VoltOps console to see how subagents coordinate automatically.

Step-by-Step Testing

1

Update your code with the story writing team (above) and save the file

Your agents will automatically reload with the new creative team configuration

2

Go to VoltOps Console and set userId:

console.voltagent.dev
userId: "writer-123"
conversationId: "creative-session"
3

Try these test scenarios to see immediate subagent routing:

Story Request (Should coordinate writer + translator):
"Write a story about a magical cat"
Expected: Writer creates story, translator translates to 3 languages
Simple Story Request:
"Tell me a story about space adventure"
Expected: Complete story + translations workflow
Themed Story Request:
"Create a mystery story set in Victorian London"
Expected: Themed story creation + multilingual output
✨ What You'll See:
The creative director will coordinate: Original English story + German + Japanese + Italian translations!

See Subagents in Action

Watch how the creative director coordinates the writer and translator agents:

VoltOps Subagents Demo - Story writing and translation workflow

Creative coordination: Story creation followed by multilingual translation

Debug & Monitor Creative Workflow

In the VoltOps console, you'll see the complete creative process:

Creative director coordination
Story creation and saving
Translation workflow tracking
Multi-language output generation

Pro Tips: Supercharge Your Creative Director

Here are some powerful tricks from the VoltAgent docs to make your subagents even better:

Custom Guidelines

Add custom rules to your creative director's behavior:

Add Custom Rules
const creativeDirector = new Agent({
name: "creative-director",
subAgents: [writerAgent, translatorAgent],

// Add custom guidelines
supervisorConfig: {
customGuidelines: [
"Always ask user about preferred story genre first",
"Include word count in final response",
"Thank the team members by name",
"Offer to create illustrations for stories"
]
}
});

Monitor Delegation

See exactly when tasks are handed off between agents:

Track Handoffs
const creativeDirector = new Agent({
name: "creative-director",
subAgents: [writerAgent, translatorAgent],

// Monitor delegation flow
hooks: {
onHandoff: ({ agent, source }) => {
console.log(`${source.name}${agent.name}`);
// Output: "creative-director → writer"
// Output: "creative-director → translator"
}
}
});

Control Workflow Steps

Prevent infinite loops and control complexity:

Step Limits
// Global step limit for all subagents
const creativeDirector = new Agent({
name: "creative-director",
subAgents: [writerAgent, translatorAgent],
maxSteps: 15 // Prevents runaway workflows
});

// Or per-request control
const response = await creativeDirector.generateText(
"Write a story about time travel",
{
maxSteps: 8, // Override for this request
userId: "user123"
}
);

Dynamic Team Management

Add or remove team members on the fly:

Dynamic Teams & createSubAgent
import { createSubAgent } from "@voltagent/core";

// Method 1: Traditional subAgent array
const creativeDirector = new Agent({
name: "creative-director",
subAgents: [writerAgent, translatorAgent]
});

// Method 2: Using createSubAgent function (more powerful!)
const managerAgent = new Agent({
name: "project-manager",
instructions: "Coordinate creative projects and manage team workflows",
llm: new VercelAIProvider(),
model: openai("gpt-4o-mini"),
tools: [
// This creates a tool that can delegate to writer
createSubAgent(writerAgent),
// This creates a tool that can delegate to translator
createSubAgent(translatorAgent),
// Add other business tools
createTool({
name: "schedule_meeting",
description: "Schedule team meetings",
parameters: z.object({
time: z.string(),
attendees: z.array(z.string())
}),
execute: async ({ time, attendees }) => {
return { meetingId: "MTG-" + Date.now(), scheduled: true };
}
})
]
});

// Dynamic team management
const illustratorAgent = new Agent({
name: "illustrator",
instructions: "Create visual content and illustrations"
});

// Add new team member dynamically
managerAgent.addTool(createSubAgent(illustratorAgent));

// Remove team member
managerAgent.removeTool("illustrator");

Pro Tip: Combine All Tricks

Use custom guidelines + monitoring + step control for production-ready agent teams:

Guidelines ensure consistent behavior
Hooks provide debugging visibility
Step limits prevent runaway costs
Dynamic teams adapt to requirements

Context-Aware Tools: Solving the Parameter Problem

Notice how our billing tools don't ask for email addresses? This is a crucial UX principle: tools should use context (userId) instead of asking users for information we already have.

❌ Bad UX: Asking for Known Info

User:
"I need to cancel my subscription"
Bad Agent:
"What's your email address?"
User thinks: "You should know this already!"

✅ Good UX: Using Context

User:
"I need to cancel my subscription"
Smart Agent:
"I found your Pro plan subscription. Would you like me to process the cancellation?"
User thinks: "This is smart and convenient!"

How Context-Aware Tools Work

userId is automatically passed to all tool executions
Tools use context.userId to lookup user data
No need to ask users for information we already have
Much better user experience and faster resolution

Best Practices for Subagents

Here are the key principles for designing effective agent teams:

Do This

Single Responsibility: Each agent should have one clear job
Clear Instructions: Define exactly what each agent does
Proper Tools: Give agents only the tools they need
Logical Hierarchy: Supervisor coordinates, specialists execute

Avoid This

Overlapping Roles: Agents with similar or conflicting jobs
Too Many Layers: Agents managing other agents managing agents
Circular Dependencies: Agents that depend on each other
Generic Agents: Agents that try to do everything

Testing Your Agent Team

Once you've built your agent team, test it with realistic scenarios to make sure the coordination works smoothly.

test-creative-team.ts
// Test the creative team
const testCreativeTeam = async () => {
console.log("Testing creative writing team...");

// Scenario 1: Simple story request
const magicalStory = await creativeDirector.generateText(
"Write a story about a magical cat",
{ userId: "writer123" }
);

// Scenario 2: Themed story
const mysteryStory = await creativeDirector.generateText(
"Create a mystery story set in Victorian London",
{ userId: "writer123" }
);

// Scenario 3: Adventure story
const spaceAdventure = await creativeDirector.generateText(
"Tell me an exciting space adventure story",
{ userId: "writer123" }
);

console.log("All creative scenarios completed!");
console.log("Each story created in English + German + Japanese + Italian!");
};

// Test individual agents
const testIndividualAgents = async () => {
// Test writer directly
const story = await writerAgent.generateText(
"Write a short story about friendship",
{ userId: "writer123" }
);

// Test translator directly
const translation = await translatorAgent.generateText(
"Translate this to German: 'Once upon a time, there was a brave knight.'",
{ userId: "writer123" }
);
};

// Run tests
testCreativeTeam();
testIndividualAgents();

Using Creative Team via REST API

In production, you can integrate your creative team into apps or websites. Here's how to call your creative director via REST API to get stories with translations.

Creative Team API Calls
# Story request - creative director coordinates writer + translator
curl -X POST http://localhost:3141/agents/creative-director/text \
-H "Content-Type: application/json" \
-d '{
"input": "Write a story about a magical cat",
"options": {
"userId": "writer-123",
"conversationId": "creative-session-001"
}
}'

# Themed story request - full creative workflow
curl -X POST http://localhost:3141/agents/creative-director/text \
-H "Content-Type: application/json" \
-d '{
"input": "Create a mystery story set in Victorian London",
"options": {
"userId": "writer-123",
"conversationId": "creative-session-001"
}
}'

# Adventure story - writer creates, translator translates to 3 languages
curl -X POST http://localhost:3141/agents/creative-director/text \
-H "Content-Type: application/json" \
-d '{
"input": "Tell me an exciting space adventure story",
"options": {
"userId": "writer-123",
"conversationId": "creative-session-001"
}
}'

The Power of Creative Team Coordination

With this creative team setup:

One request → Story + 3 translations
Automatic workflow coordination
Specialized agents for quality output
Perfect for content generation apps

What's Next?

Congratulations! You've built a complete AI agent system with:

Your Agent Journey

Step 1: Built your first agent
Step 2: Added tools to make it useful
Step 3: Implemented memory for conversations
Step 4: Connected to external systems with MCP
Step 5: Created specialized agent teams

Ready to Build Something Amazing?

You now have all the tools to build production-ready AI agents. Whether you're creating a customer support system, content creation team, or something completely new, you're ready to go.