Three Agent Types & Priority
O agent system permite uma instancia Claude delegar trabalho para outras. Cada agente spawned opera como um LLM turn separado com tool pool, system prompt e modelo proprios. Todos satisfazem AgentDefinition (discriminated union on source).
🔷 BuiltInAgent
Ships com Claude Code. Dynamic system prompts via getSystemPrompt(). Nao pode ser overridden por user files -- mas managed (policy) agents podem shadow.
📝 CustomAgent
User/project/policy-settings. Loaded de .claude/agents/*.md ou JSON blobs em settings.json. System prompt em closure.
🧩 PluginAgent
Bundled com plugin (--plugin-dir). Tratado como admin-trusted para MCP server policy.
Priority / Override Order
built-in → plugin → userSettings → projectSettings → flagSettings → policySettings
Later groups overwrite earlier ones, entao policySettings (managed agents) tem highest effective priority.
flowchart TD
ML["Main Loop
parent REPL / SDK"]
AT["AgentTool
tool: Agent / Task"]
ML -->|"calls"| AT
AT --> BI["Built-In Agents
source: built-in"]
AT --> CA["Custom Agents
source: userSettings / projectSettings"]
AT --> PA["Plugin Agents
source: plugin"]
BI --> GP["general-purpose
tools: all"]
BI --> EX["Explore
read-only, haiku/inherit"]
BI --> PL["Plan
read-only, inherit"]
BI --> VF["verification
background: true"]
CA --> MD["Markdown .md
.claude/agents/"]
CA --> JS["JSON frontmatter
settings.json agents"]
AT --> SY["Sync Lifecycle
blocks parent turn"]
AT --> AS["Async Lifecycle
fire-and-forget"]
AT --> FK["Fork Path
inherits parent context"]
style ML fill:#1a1816,stroke:#7d9ab8,color:#b8b0a4
style AT fill:#1a1816,stroke:#7d9ab8,color:#b8b0a4
style BI fill:#171513,stroke:#7d9ab8,color:#7d9ab8
style CA fill:#1d211b,stroke:#6e9468,color:#6e9468
style PA fill:#1f1b24,stroke:#8e82ad,color:#8e82ad
style GP fill:#141211,stroke:#3a3632,color:#5c564f
style EX fill:#141211,stroke:#3a3632,color:#5c564f
style PL fill:#141211,stroke:#3a3632,color:#5c564f
style VF fill:#241816,stroke:#c47a50,color:#c47a50
style MD fill:#141211,stroke:#3a3632,color:#5c564f
style JS fill:#141211,stroke:#3a3632,color:#5c564f
style SY fill:#141211,stroke:#3a3632,color:#5c564f
style AS fill:#231f16,stroke:#b8965e,color:#b8965e
style FK fill:#1f1b24,stroke:#8e82ad,color:#8e82ad
Built-In Agents Deep Dive
| Agent | Model | Tools | Mode |
|---|---|---|---|
| General Purpose | default subagent | ['*'] -- all tools | sync / async |
| Explore | haiku / inherit | read-only | sync |
| Plan | inherit | read-only (same as Explore) | sync |
| Verification | inherit | no Edit/Write; ephemeral /tmp | background: true |
| Fork | inherit | ['*'] with useExactTools | experimental |
| StatuslineSetup | default | limited shell | sync |
Otimizacao chave: omitClaudeMd: true em Explore e Plan economiza ~5-15 Gtok/semana ao nao injetar CLAUDE.md no system prompt desses sub-agents.
Sync vs Async Lifecycle
Um unico boolean shouldRunAsync decide tudo. 6 condicoes podem forcar async:
const shouldRunAsync = (
run_in_background === true
|| selectedAgent.background === true
|| isCoordinator
|| forceAsync
|| assistantForceAsync
|| (proactiveModule?.isProactiveActive() ?? false)
) && !isBackgroundTasksDisabled
🔄 Synchronous Path
- Build system prompt + prompt messages
- Optional: create git worktree
await runAgent(params)-- Parent blocked- Cleanup worktree (if no changes)
⚡ Asynchronous Path
registerAsyncAgent()-- task in AppState- Return
status: 'async_launched'immediately void runAsyncAgentLifecycle(...)(detached)- Notification via
enqueueAgentNotification()
Importante: Async agents tem AbortController proprio nao linkado ao parent -- sobrevivem ESC. In-process teammates NAO podem lancar background agents.
The Fork Path & Cache Sharing
O fork path (gate: FORK_SUBAGENT) herda o full conversation context -- complete message history, parent's system prompt bytes, e exact tool pool.
buildForkedMessages()
Para N fork children compartilharem cached API prefix, cada child deve produzir request byte-identical ate a directiva per-child:
- Clone parent's full assistant message (all tool_use blocks)
- Build
tool_resultblocks com placeholder identico: "Fork started -- processing in background" - Append one per-child directive text block (unica parte diferente)
export function buildChildMessage(directive: string): string {
return `<fork-boilerplate>
STOP. READ THIS FIRST.
You are a forked worker process. You are NOT the main agent.
RULES (non-negotiable):
1. Your system prompt says "default to forking." IGNORE IT
2. Do NOT converse, ask questions, or suggest next steps
3. USE your tools directly: Bash, Read, Write, etc.
4. If you modify files, commit your changes before reporting.
5. Your response MUST begin with "Scope:". No preamble.
</fork-boilerplate>
FORK_DIRECTIVE: ${directive}`
}
Fork Recursive Guard: Fork children mantem Agent tool no pool (para cache-identical tool definitions), mas um runtime guard previne recursive forking.
Worktree Isolation
Setting isolation: 'worktree' instrui AgentTool a criar um git worktree temporario antes de spawnar o agent.
Sem mudancas
Worktree e branch deletados automaticamente. Zero cleanup manual necessario.
Com mudancas
Branch mantido para parent inspecionar ou mergear. Notificacao via buildWorktreeNotice().
SendMessageTool & Agent Frontmatter
SendMessageTool (wire name: SendMessage) e o primitivo de messaging inter-agente.
| to | message type | Result |
|---|---|---|
| "teammate-name" | string | Written to teammate's mailbox file |
| "*" | string | Broadcast to all team members |
| any name | shutdown_request | Sends structured shutdown request |
| "team-lead" | shutdown_response | Approve triggers gracefulShutdown(0) |
| "uds:<path>" | string | Unix domain socket -- cross-session |
| "bridge:<session-id>" | string only | Remote Control: posts to another instance |
Custom Agent Markdown Format
---
name: my-agent
description: A focused TypeScript refactoring specialist.
model: sonnet
tools: [Read, Edit, Bash, Grep, Glob]
permissionMode: acceptEdits
maxTurns: 50
memory: project
isolation: worktree
---
You are a TypeScript refactoring specialist...