Subagents - Task Delegation
Level: Enhancement (beyond minimal agent) Prerequisites: Agent loop, tool system, streaming
What This Adds
Specialized subagents that handle tasks benefiting from:
- Different models (e.g., GPT for deep reasoning)
- Parallel execution (multiple tasks simultaneously)
- Focused context (isolated from main conversation)
- Specialized toolsets (restricted tool access)
Critical Design: Complete Isolation
Subagents operate in COMPLETE ISOLATION from the parent conversation.
This is counterintuitive but crucial:
- No Conversation History - Subagents start fresh. They do NOT see prior conversation.
- Context Must Be Explicit - Everything needed must be in the prompt parameter.
- Final Message Only - Internal tool calls and reasoning are hidden. Only the last message returns.
- Tool Restrictions - Each subagent type has a restricted tool list.
What Transfers Automatically
Limited automatic inheritance:
- Thread ID (link back to parent)
- Agent mode (smart/rush/free)
- Workspace environment
- Active skills
What Does NOT Transfer
- Conversation history
- Previous tool results
- User instructions (unless re-stated)
- File contents (unless included in prompt)
Subagent Types
Finder (Semantic Search)
Purpose: Fast, parallel code search for conceptual queries.
| Attribute | Value |
|---|---|
| Model | Registry: Haiku 4.5; runtime override: Gemini 3 Flash Preview |
| Tools | Grep, glob, Read |
| Use Case | "Find where JWT auth is implemented" |
Key Instruction: "Make 8+ parallel tool calls with diverse search strategies"
When to Use:
- Mapping features by concept
- Finding related code
- Unknown filenames
When NOT to Use:
- Simple exact text search (use Grep directly)
- Code changes
- Design decisions
Oracle (Deep Analysis)
Purpose: Senior engineering advisor for complex decisions.
| Attribute | Value |
|---|---|
| Model | GPT-5.2 |
| Tools | Read, Grep, glob, web_search, read_web_page |
| Use Case | Architecture decisions, code review, planning |
Key Instruction: "Zero-shot, simplicity-first. Only your last message is returned."
Response Format:
1) TL;DR: 1-3 sentences with recommended approach
2) Recommended approach: numbered steps
3) Rationale and trade-offs
4) Risks and guardrails
5) When to consider advanced path
Effort Signals: S (<1h), M (1-3h), L (1-2d), XL (>2d)
Librarian (Multi-Repo Search)
Purpose: Cross-repository codebase understanding.
| Attribute | Value |
|---|---|
| Model | Haiku 4.5 |
| Tools | read_github, search_github, commit_search, list_directory_github |
| Use Case | Understanding code across repositories |
Key Instruction: "Fluent linking style. MUST link to files by name."
Task (General Execution)
Purpose: Fire-and-forget executor for multi-step implementations.
| Attribute | Value |
|---|---|
| Model | Inherited from parent |
| Tools | Full development toolset |
| Use Case | Feature scaffolding, migrations, boilerplate |
Description: "Think of it as a productive junior engineer who can't ask follow-ups once started."
When to Use:
- Feature scaffolding
- Cross-layer refactors
- Mass migrations
When NOT to Use:
- Exploratory work
- Architectural decisions
- Debugging
Subagent Selection Logic
From the system prompt:
"I need a senior engineer to think with me" → Oracle
"I need to find code that matches a concept" → Finder
"I know what to do, need large multi-step execution" → Task
Recommended workflow:
Oracle (plan) → Finder (validate scope) → Task (execute)
Implementation Pattern
Spawning a Subagent
interface SubagentConfig {
type: "finder" | "oracle" | "librarian" | "task";
prompt: string; // MUST include all needed context
model?: string; // Override default model
maxTokens?: number; // Default: 8,000
}
async function spawnSubagent(
config: SubagentConfig,
parentThread: Thread
): Promise<string> {
// 1. Create isolated context
const subagentThread = createIsolatedThread({
mainThreadId: parentThread.id,
agentMode: parentThread.agentMode,
environment: parentThread.environment
});
// 2. Get restricted tools
const tools = SUBAGENT_TOOLS[config.type];
// 3. Get subagent prompt
const systemPrompt = SUBAGENT_PROMPTS[config.type];
// 4. Run inference loop
const messages: Message[] = [{
role: "user",
content: [{ type: "text", text: config.prompt }]
}];
let result: string = "";
while (true) {
const response = await inference({
model: config.model ?? SUBAGENT_MODELS[config.type],
system: systemPrompt,
messages,
tools,
maxTokens: config.maxTokens ?? 8000
});
messages.push({ role: "assistant", content: response.content });
if (response.stopReason === "end_turn") {
// Extract final text as result
result = extractText(response.content);
break;
}
// Execute tools, add results
const toolResults = await executeTools(response.toolUses);
messages.push({
role: "user",
content: toolResults
});
}
// 5. Return ONLY the final message
return result;
}
Tool Access by Subagent
const SUBAGENT_TOOLS = {
finder: ["Grep", "glob", "Read"],
oracle: ["Read", "Grep", "glob", "web_search", "read_web_page"],
librarian: ["read_github", "search_github", "commit_search", "list_directory_github"],
task: ["Grep", "glob", "Read", "Bash", "edit_file", "create_file", "format_file"]
};
Model Routing
const SUBAGENT_MODELS = {
finder: "claude-haiku-4-5", // Registry default; runtime overrides to Gemini 3 Flash Preview
oracle: "gpt-5.2",
librarian: "claude-haiku-4-5",
task: null // Inherited from parent mode
};
Parallel Execution
Multiple subagents can run in parallel when:
- Tasks are independent
- Write targets are disjoint
- No shared contract mutations
Must serialize when:
- Plan → Code dependency
- Same file edits
- Shared contract mutations (types, DB schema)
// Parallel: different search queries
await Promise.all([
spawnSubagent({ type: "finder", prompt: "Find validation logic" }),
spawnSubagent({ type: "finder", prompt: "Find timeout handling" })
]);
// Sequential: plan then execute
const plan = await spawnSubagent({ type: "oracle", prompt: "Plan the refactor" });
await spawnSubagent({ type: "task", prompt: `Execute this plan: ${plan}` });
Prompt Guidelines
Since subagents have no context, prompts must be comprehensive:
Good Prompt:
Refactor the authentication module to use JWT.
Current implementation:
- Auth logic in src/auth/session.ts
- Uses cookie-based sessions
- Session store in Redis
Requirements:
- Replace cookies with JWT tokens
- Keep Redis for token blacklist
- Don't change the public API
Constraints:
- Follow existing patterns in the codebase
- Run tests after changes (pnpm test)
- TypeScript strict mode
Files to modify:
- src/auth/session.ts
- src/middleware/auth.ts
- src/types/auth.d.ts
Bad Prompt:
Finish the refactoring we discussed.
When to Add Subagents
Add subagents when you need:
- Model Specialization - Different tasks need different models
- Context Isolation - Focused work without conversation noise
- Parallel Processing - Multiple independent tasks
- Tool Restriction - Limit what operations can happen
Without these needs, direct tool calls in the main agent are simpler.
Key Constraints
- No Follow-ups - Subagents are "zero-shot". They can't ask clarifying questions.
- Final Message Only - All intermediate work is hidden.
- Max Tokens - Default 8,000 output tokens.
- Tool Limits - Only tools in the allowlist work.
Enhancement based on Amp Code v0.0.1769212917 patterns