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:

  1. No Conversation History - Subagents start fresh. They do NOT see prior conversation.
  2. Context Must Be Explicit - Everything needed must be in the prompt parameter.
  3. Final Message Only - Internal tool calls and reasoning are hidden. Only the last message returns.
  4. 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:

  1. Model Specialization - Different tasks need different models
  2. Context Isolation - Focused work without conversation noise
  3. Parallel Processing - Multiple independent tasks
  4. Tool Restriction - Limit what operations can happen

Without these needs, direct tool calls in the main agent are simpler.


Key Constraints

  1. No Follow-ups - Subagents are "zero-shot". They can't ask clarifying questions.
  2. Final Message Only - All intermediate work is hidden.
  3. Max Tokens - Default 8,000 output tokens.
  4. Tool Limits - Only tools in the allowlist work.

Enhancement based on Amp Code v0.0.1769212917 patterns