vault backup: 2026-04-17 13:16:15
This commit is contained in:
parent
0145de8439
commit
f471801ba3
3 changed files with 191 additions and 0 deletions
BIN
raw/home-server-101.pdf
Normal file
BIN
raw/home-server-101.pdf
Normal file
Binary file not shown.
|
|
@ -38,3 +38,4 @@ Build production AI agents using the same tools, agent loop, and context managem
|
|||
| [[wiki/agent-sdk/slash-commands\|slash-commands]] | Built-in & custom slash commands via SDK: discovery, /compact, custom .claude/commands/ files, arguments, bash/file interpolation | raw/Slash Commands in the SDK.md | 2026-04-17 |
|
||||
| [[wiki/agent-sdk/streaming-output\|streaming-output]] | Real-time token/tool streaming: StreamEvent structure, text_delta, input_json_delta, UI patterns, limitations | raw/Stream responses in real-time.md | 2026-04-17 |
|
||||
| [[wiki/agent-sdk/streaming-input\|streaming-input]] | Two input modes: AsyncGenerator (streaming, default) vs string (single message); capabilities, limitations, session resuming | raw/Streaming Input.md | 2026-04-17 |
|
||||
| [[wiki/agent-sdk/subagents\|subagents]] | Spawn subagents programmatically or via filesystem; context isolation, parallelization, tool restrictions, resuming, detection | raw/Subagents in the SDK.md | 2026-04-17 |
|
||||
|
|
|
|||
190
wiki/agent-sdk/subagents.md
Normal file
190
wiki/agent-sdk/subagents.md
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
---
|
||||
title: "Subagents in the SDK"
|
||||
aliases: [subagents, sdk-subagents, agent-spawning]
|
||||
tags: [agent-sdk, subagents, parallelization, context-isolation, python, typescript]
|
||||
sources: [raw/Subagents in the SDK.md]
|
||||
created: 2026-04-17
|
||||
updated: 2026-04-17
|
||||
---
|
||||
|
||||
# Subagents in the SDK
|
||||
|
||||
Subagents are separate agent instances spawned by a main agent to handle focused subtasks. Core use cases: context isolation, parallel execution, specialized instructions, and tool restriction.
|
||||
|
||||
## Three Ways to Create Subagents
|
||||
|
||||
| Method | When to use |
|
||||
|--------|-------------|
|
||||
| **Programmatic** (`agents` param in `query()`) | Recommended for SDK apps — full control, dynamic config |
|
||||
| **Filesystem-based** (`.claude/agents/*.md`) | Static definitions, loaded at startup |
|
||||
| **Built-in `general-purpose`** | Available automatically when `Agent` is in `allowedTools` — no definition needed |
|
||||
|
||||
Programmatic agents take precedence over filesystem agents with the same name.
|
||||
|
||||
## Benefits
|
||||
|
||||
### Context Isolation
|
||||
Each subagent runs in a **fresh conversation**. Only the final message returns to the parent — not intermediate tool calls or reasoning. Parent receives a concise summary, not every file the subagent read.
|
||||
|
||||
### Parallelization
|
||||
Multiple subagents run concurrently. Example: `style-checker`, `security-scanner`, and `test-coverage` can run simultaneously during a code review.
|
||||
|
||||
### Specialized Instructions
|
||||
Each subagent has its own system prompt with domain-specific knowledge — without bloating the main agent's prompt.
|
||||
|
||||
### Tool Restrictions
|
||||
Limit subagents to specific tools. A `doc-reviewer` with only `Read` + `Grep` can analyze but never modify files.
|
||||
|
||||
## AgentDefinition Fields
|
||||
|
||||
| Field | Type | Required | Notes |
|
||||
|-------|------|----------|-------|
|
||||
| `description` | string | Yes | Tells Claude when to use this subagent — write clearly |
|
||||
| `prompt` | string | Yes | Subagent's system prompt |
|
||||
| `tools` | string[] | No | If omitted, inherits all parent tools |
|
||||
| `model` | `sonnet\|opus\|haiku\|inherit` | No | Defaults to main model |
|
||||
| `skills` | string[] | No | Skills available to this subagent |
|
||||
| `memory` | `user\|project\|local` | No | Python only |
|
||||
| `mcpServers` | array | No | MCP servers by name or inline config |
|
||||
|
||||
> **Important:** Subagents cannot spawn their own subagents — never include `Agent` in a subagent's `tools`.
|
||||
|
||||
## Python Example
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition
|
||||
|
||||
async def main():
|
||||
async for message in query(
|
||||
prompt="Review the authentication module for security issues",
|
||||
options=ClaudeAgentOptions(
|
||||
# Agent tool is required — Claude invokes subagents through it
|
||||
allowed_tools=["Read", "Grep", "Glob", "Agent"],
|
||||
agents={
|
||||
"code-reviewer": AgentDefinition(
|
||||
description="Expert code review specialist. Use for quality, security, and maintainability reviews.",
|
||||
prompt="""You are a code review specialist with expertise in security, performance, and best practices.
|
||||
When reviewing code:
|
||||
- Identify security vulnerabilities
|
||||
- Check for performance issues
|
||||
- Verify adherence to coding standards
|
||||
- Suggest specific improvements""",
|
||||
tools=["Read", "Grep", "Glob"], # read-only
|
||||
model="sonnet",
|
||||
),
|
||||
"test-runner": AgentDefinition(
|
||||
description="Runs and analyzes test suites. Use for test execution and coverage analysis.",
|
||||
prompt="You are a test execution specialist. Run tests and provide clear analysis of results.",
|
||||
tools=["Bash", "Read", "Grep"],
|
||||
),
|
||||
},
|
||||
),
|
||||
):
|
||||
if hasattr(message, "result"):
|
||||
print(message.result)
|
||||
|
||||
asyncio.run(main())
|
||||
```
|
||||
|
||||
## What Subagents Inherit
|
||||
|
||||
| Receives | Does NOT receive |
|
||||
|----------|-----------------|
|
||||
| Own system prompt + Agent tool prompt | Parent's conversation history or tool results |
|
||||
| Project CLAUDE.md | Skills (unless listed in `AgentDefinition.skills`) |
|
||||
| Tool definitions (parent's or restricted subset) | Parent's system prompt |
|
||||
|
||||
The only channel from parent → subagent is the **Agent tool's prompt string**. Include file paths, error messages, or decisions directly in that prompt.
|
||||
|
||||
## Invocation
|
||||
|
||||
- **Automatic**: Claude matches tasks to subagents based on `description` field
|
||||
- **Explicit**: Mention by name in prompt — `"Use the code-reviewer agent to check auth module"`
|
||||
|
||||
## Dynamic Agent Configuration
|
||||
|
||||
Factory pattern for runtime customization:
|
||||
|
||||
```python
|
||||
def create_security_agent(security_level: str) -> AgentDefinition:
|
||||
is_strict = security_level == "strict"
|
||||
return AgentDefinition(
|
||||
description="Security code reviewer",
|
||||
prompt=f"You are a {'strict' if is_strict else 'balanced'} security reviewer...",
|
||||
tools=["Read", "Grep", "Glob"],
|
||||
model="opus" if is_strict else "sonnet", # more capable model for high-stakes
|
||||
)
|
||||
```
|
||||
|
||||
## Detecting Subagent Invocation
|
||||
|
||||
Subagents are invoked via the `Agent` tool. Detect by checking `tool_use` blocks where `name` is `"Agent"` (or `"Task"` for SDK < v2.1.63). Messages from inside a subagent include `parent_tool_use_id`.
|
||||
|
||||
```python
|
||||
for block in message.content:
|
||||
if getattr(block, "type", None) == "tool_use" and block.name in ("Task", "Agent"):
|
||||
print(f"Subagent invoked: {block.input.get('subagent_type')}")
|
||||
|
||||
if hasattr(message, "parent_tool_use_id") and message.parent_tool_use_id:
|
||||
print(" (running inside subagent)")
|
||||
```
|
||||
|
||||
## Resuming Subagents
|
||||
|
||||
Resumed subagents retain full conversation history. Flow:
|
||||
|
||||
1. Capture `session_id` from `ResultMessage` during first query
|
||||
2. Parse `agentId` from message content (appears in Agent tool results)
|
||||
3. Pass `resume: sessionId` in second query's options
|
||||
4. Include agent ID in prompt
|
||||
|
||||
```typescript
|
||||
// Resume example (TypeScript)
|
||||
for await (const message of query({
|
||||
prompt: `Resume agent ${agentId} and list the top 3 most complex endpoints`,
|
||||
options: { allowedTools: ["Read", "Grep", "Glob", "Agent"], resume: sessionId }
|
||||
})) {
|
||||
if ("result" in message) console.log(message.result);
|
||||
}
|
||||
```
|
||||
|
||||
Transcripts persist independently of the main conversation and are cleaned up after `cleanupPeriodDays` (default: 30 days).
|
||||
|
||||
## Common Tool Combinations
|
||||
|
||||
| Use case | Tools |
|
||||
|----------|-------|
|
||||
| Read-only analysis | `Read`, `Grep`, `Glob` |
|
||||
| Test execution | `Bash`, `Read`, `Grep` |
|
||||
| Code modification | `Read`, `Edit`, `Write`, `Grep`, `Glob` |
|
||||
| Full access | Omit `tools` field |
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Problem | Fix |
|
||||
|---------|-----|
|
||||
| Claude not delegating to subagents | Add `Agent` to `allowedTools`; use explicit name in prompt; write clearer `description` |
|
||||
| Filesystem agents not loading | Restart session — agents are loaded at startup only |
|
||||
| Windows long prompt failures | Keep prompts concise (<8191 chars) or use filesystem-based agents |
|
||||
|
||||
## Key Takeaways
|
||||
|
||||
- `Agent` tool **must** be in `allowedTools` — subagents are invoked through it
|
||||
- Subagents **cannot** spawn sub-subagents (no `Agent` in subagent's `tools`)
|
||||
- Context isolation means only the **final message** returns to parent — include all needed context in the Agent tool prompt
|
||||
- `description` field drives automatic delegation — write it carefully
|
||||
- Dynamic factory functions enable runtime customization (different models per security level, etc.)
|
||||
- Tool name changed from `"Task"` → `"Agent"` in v2.1.63 — check both for compatibility
|
||||
|
||||
## Related Articles
|
||||
|
||||
- [[wiki/agent-sdk/agent-loop|Agent Loop]] — how turns, tool execution, and context management work
|
||||
- [[wiki/agent-sdk/configure-permissions|Configure Permissions]] — permission modes and subagent inheritance
|
||||
- [[wiki/agent-sdk/agent-skills-plugins|Agent Skills & Plugins]] — loading skills into subagents
|
||||
- [[wiki/agent-sdk/hosting-production|Hosting in Production]] — multi-agent deployment patterns
|
||||
- [[wiki/agent-sdk/sdk-hooks|SDK Hooks]] — intercept tool calls including Agent tool invocations
|
||||
|
||||
## Sources
|
||||
|
||||
- [Subagents in the SDK](https://code.claude.com/docs/en/agent-sdk/subagents) — official Anthropic docs
|
||||
Loading…
Add table
Reference in a new issue