子智能体机制深度解析:从S02到S04的演进
一、核心概念:上下文隔离的必要性
1.1 问题背景
在 S02 的单智能体架构中,所有的交互都发生在同一个 messages 上下文中:
python
# S02: 单一上下文
messages = [
{"role": "user", "content": "用户请求1"},
{"role": "assistant", "content": "响应1"},
{"role": "user", "content": "工具结果1"},
{"role": "assistant", "content": "响应2"},
{"role": "user", "content": "工具结果2"},
# ... 上下文不断累积
]
问题:
- 📈 上下文无限增长,消耗token
- 🧠 不同任务的信息混杂,干扰LLM判断
- 🔄 难以并行处理独立任务
- 💾 历史信息污染当前任务
1.2 解决方案:子智能体
子智能体的核心思想是:
- 🆕 每个子任务有独立的 fresh context
- 📊 只返回摘要,不返回完整上下文
- 🔄 父子智能体通过 task tool 通信
- 🛡️ 上下文隔离,保持思维清晰
二、S04架构设计
2.1 整体架构图
┌─────────────────────────────────────────────────────────────┐
│ 父智能体 (Parent Agent) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ messages = [主任务上下文] │ │
│ │ │ │
│ │ 系统提示: "Use the task tool to delegate..." │ │
│ │ │ │
│ │ 工具集合: │ │
│ │ • bash, read_file, write_file, edit_file │ │
│ │ • task ← 新增!用于生成子智能体 │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
↓ task 工具调用
┌─────────────────┐
│ fork() 子智能体 │
│ fresh context │
└─────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 子智能体 (Subagent) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ messages = [{"role": "user", "content": prompt}] │ │
│ │ │ │
│ │ 系统提示: "Complete the given task, then..." │ │
│ │ │ │
│ │ 工具集合: │ │
│ │ • bash, read_file, write_file, edit_file │ │
│ │ • (没有 task 工具,防止递归) │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
↓ 独立执行
┌─────────────────┐
│ while loop: │
│ - 调用工具 │
│ - 收集结果 │
│ - 迭代执行 │
└─────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 返回摘要 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ return "任务完成,发现3个文件,修改了2个配置..." │ │
│ │ │ │
│ │ • 只返回最终文本摘要 │ │
│ │ • 完整子上下文被丢弃 │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 父智能体接收摘要 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ messages.append({ │ │
│ │ "role": "user", │ │
│ │ "content": "任务完成,发现3个文件..." │ │
│ │ }) │ │
│ │ │ │
│ │ 父上下文保持清洁,只有摘要信息 │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
2.2 代码结构对比
S02: 单智能体结构
python
# 只有一套工具和处理器
TOOL_HANDLERS = {
"bash": lambda **kw: run_bash(kw["command"]),
"read_file": lambda **kw: run_read(kw["path"], kw.get("limit")),
"write_file": lambda **kw: run_write(kw["path"], kw["content"]),
"edit_file": lambda **kw: run_edit(kw["path"], kw["old_text"], kw["new_text"]),
}
TOOLS = [
{"name": "bash", ...},
{"name": "read_file", ...},
{"name": "write_file", ...},
{"name": "edit_file", ...},
]
def agent_loop(messages: list):
while True:
response = client.messages.create(
model=MODEL, system=SYSTEM, messages=messages,
tools=TOOLS, max_tokens=8000,
)
# ... 统一处理所有工具
S04: 双层智能体结构
python
# 共享的基础工具
TOOL_HANDLERS = {
"bash": lambda **kw: run_bash(kw["command"]),
"read_file": lambda **kw: run_read(kw["path"], kw.get("limit")),
"write_file": lambda **kw: run_write(kw["path"], kw["content"]),
"edit_file": lambda **kw: run_edit(kw["path"], kw["old_text"], kw["new_text"]),
}
# 子智能体工具(不含task,防止递归)
CHILD_TOOLS = [
{"name": "bash", ...},
{"name": "read_file", ...},
{"name": "write_file", ...},
{"name": "edit_file", ...},
]
# 父智能体工具(包含task用于生成子智能体)
PARENT_TOOLS = CHILD_TOOLS + [
{"name": "task", "description": "Spawn a subagent with fresh context..."}
]
# 子智能体执行函数
def run_subagent(prompt: str) -> str:
sub_messages = [{"role": "user", "content": prompt}] # fresh context
for _ in range(30): # safety limit
response = client.messages.create(
model=MODEL, system=SUBAGENT_SYSTEM, messages=sub_messages,
tools=CHILD_TOOLS, max_tokens=8000,
)
sub_messages.append({"role": "assistant", "content": response.content})
if response.stop_reason != "tool_use":
break
results = []
for block in response.content:
if block.type == "tool_use":
handler = TOOL_HANDLERS.get(block.name)
output = handler(**block.input) if handler else f"Unknown tool: {block.name}"
results.append({"type": "tool_result", "tool_use_id": block.id, "content": str(output)[:50000]})
sub_messages.append({"role": "user", "content": results})
# 只返回摘要,丢弃完整上下文
return "".join(b.text for b in response.content if hasattr(b, "text")) or "(no summary)"
# 父智能体循环(改造过的agent_loop)
def agent_loop(messages: list):
while True:
response = client.messages.create(
model=MODEL, system=SYSTEM, messages=messages,
tools=PARENT_TOOLS, max_tokens=8000,
)
messages.append({"role": "assistant", "content": response.content})
if response.stop_reason != "tool_use":
return
results = []
for block in response.content:
if block.type == "tool_use":
if block.name == "task": # 特殊处理task工具
desc = block.input.get("description", "subtask")
prompt = block.input.get("prompt", "")
print(f"> task ({desc}): {prompt[:80]}")
output = run_subagent(prompt)
else: # 普通工具处理
handler = TOOL_HANDLERS.get(block.name)
output = handler(**block.input) if handler else f"Unknown tool: {block.name}"
print(f" {str(output)[:200]}")
results.append({"type": "tool_result", "tool_use_id": block.id, "content": str(output)})
messages.append({"role": "user", "content": results})
三、详细执行流程
3.1 完整交互流程图
用户: "分析项目结构,找出所有的Python文件,然后创建一个README"
↓
┌─────────────────────────────────────────────────────────────┐
│ 第1轮:父智能体分析任务 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 父LLM分析: 任务可以分为两个子任务 │ │
│ │ 1. 分析项目结构,找出Python文件 │ │
│ │ 2. 创建README │ │
│ │ │ │
│ │ 决定先调用 task 工具处理第一个子任务 │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 父智能体调用 task 工具 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ task( │ │
│ │ prompt="分析项目结构,找出所有的Python文件", │ │
│ │ description="分析Python文件" │ │
│ │ ) │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ agent_loop 检测到 task 工具 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ if block.name == "task": │ │
│ │ desc = block.input.get("description", "subtask")│ │
│ │ prompt = block.input.get("prompt", "") │ │
│ │ output = run_subagent(prompt) ← fork子智能体 │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 子智能体启动:Fresh Context │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ def run_subagent(prompt: str) -> str: │ │
│ │ sub_messages = [{ │ │
│ │ "role": "user", │ │
│ │ "content": "分析项目结构,找出所有的Python文件"│ │
│ │ }] # ← 全新的上下文,没有历史污染 │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 子智能体第1轮:开始执行 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 子LLM: 我需要先查看项目结构 │ │
│ │ 决定调用: bash("find . -name '*.py' -type f") │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 子智能体工具执行 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ bash: find . -name '*.py' -type f │ │
│ │ Output: │ │
│ │ ./main.py │ │
│ │ ./utils/helpers.py │ │
│ │ ./config/settings.py │ │
│ │ ./tests/test_main.py │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 子智能体第2轮:分析文件内容 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 子LLM: 找到了4个Python文件,现在分析它们的内容 │ │
│ │ 决定调用: read_file("main.py") │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 子智能体继续迭代... │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 第3轮: read_file("utils/helpers.py") │ │
│ │ 第4轮: read_file("config/settings.py") │ │
│ │ 第5轮: read_file("tests/test_main.py") │ │
│ │ ... │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 子智能体完成任务,返回摘要 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 子LLM: 分析完成,现在总结发现 │ │
│ │ stop_reason: "end_turn" │ │
│ │ │ │
│ │ 返回文本: "项目包含4个Python文件: │ │
│ │ • main.py - 主程序入口 │ │
│ │ • utils/helpers.py - 工具函数 │ │
│ │ • config/settings.py - 配置管理 │ │
│ │ • tests/test_main.py - 单元测试 │ │
│ │ 项目结构清晰,功能模块化。" │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ run_subagent 返回摘要 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ return "".join(b.text for b in response.content │ │
│ │ if hasattr(b, "text")) │ │
│ │ │ │
│ │ # 完整的子上下文被丢弃! │ │
│ │ # sub_messages 包含的所有轮次都被丢弃 │ │
│ │ # 只返回上面的摘要文本 │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 父智能体接收摘要 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ results.append({ │ │
│ │ "type": "tool_result", │ │
│ │ "tool_use_id": "toolu_01", │ │
│ │ "content": "项目包含4个Python文件:..." │ │
│ │ }) │ │
│ │ │ │
│ │ messages.append({ │ │
│ │ "role": "user", │ │
│ │ "content": results │ │
│ │ }) │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 父智能体第2轮:根据摘要继续任务 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 父LLM: 子任务1完成,现在处理子任务2 │ │
│ │ 根据摘要信息,创建README │ │
│ │ 决定调用: write_file("README.md", content) │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 父智能体完成任务 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 父LLM: README创建完成,任务全部完成 │ │
│ │ stop_reason: "end_turn" │ │
│ │ │ │
│ │ 返回: "已分析项目结构并创建README: │ │
│ │ • 发现4个Python文件 │ │
│ │ • 已生成README.md包含项目概述 │ │
│ │ • 任务完成!" │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
3.2 上下文对比
S02 单智能体上下文:
python
messages = [
{"role": "user", "content": "分析项目结构,找出所有的Python文件,然后创建一个README"},
# 轮次1
{"role": "assistant", "content": [tool_use: bash("find . -name '*.py'")]},
{"role": "user", "content": [tool_result: "./main.py\n./utils/helpers.py..."]},
# 轮次2
{"role": "assistant", "content": [tool_use: read_file("main.py")]},
{"role": "user", "content": [tool_result: "main.py的内容..."]},
# 轮次3
{"role": "assistant", "content": [tool_use: read_file("utils/helpers.py")]},
{"role": "user", "content": [tool_result: "helpers.py的内容..."]},
# 轮次4
{"role": "assistant", "content": [tool_use: read_file("config/settings.py")]},
{"role": "user", "content": [tool_result: "settings.py的内容..."]},
# 轮次5
{"role": "assistant", "content": [tool_use: read_file("tests/test_main.py")]},
{"role": "user", "content": [tool_result: "test_main.py的内容..."]},
# 轮次6
{"role": "assistant", "content": [tool_use: write_file("README.md", "...")]},
{"role": "user", "content": [tool_result: "Wrote 1234 bytes"]},
# 轮次7
{"role": "assistant", "content": "任务完成!"},
]
# 总共15条消息,包含大量中间细节
S04 父智能体上下文:
python
messages = [
{"role": "user", "content": "分析项目结构,找出所有的Python文件,然后创建一个README"},
# 轮次1
{"role": "assistant", "content": [tool_use: task(prompt="分析项目结构...", description="分析Python文件")]},
{"role": "user", "content": [tool_result: "项目包含4个Python文件:\n• main.py - 主程序入口\n• utils/helpers.py - 工具函数\n• config/settings.py - 配置管理\n• tests/test_main.py - 单元测试\n项目结构清晰,功能模块化。"]},
# 轮次2
{"role": "assistant", "content": [tool_use: write_file("README.md", "...")]},
{"role": "user", "content": [tool_result: "Wrote 1234 bytes"]},
# 轮次3
{"role": "assistant", "content": "任务完成!"},
]
# 总共7条消息,只包含摘要信息
S04 子智能体上下文(独立且被丢弃):
python
sub_messages = [
{"role": "user", "content": "分析项目结构,找出所有的Python文件"},
# 子轮次1
{"role": "assistant", "content": [tool_use: bash("find . -name '*.py'")]},
{"role": "user", "content": [tool_result: "./main.py\n./utils/helpers.py..."]},
# 子轮次2-5...(详细执行过程)
# 最后轮次
{"role": "assistant", "content": "项目包含4个Python文件:..."},
]
# 这个上下文在run_subagent返回后被丢弃!
四、核心要点分析
4.1 为什么需要改造 Agent Loop?
S02 的 agent_loop 无法处理子智能体:
python
# S02: 统一工具处理
def agent_loop(messages: list):
while True:
# ... LLM调用
for block in response.content:
if block.type == "tool_use":
handler = TOOL_HANDLERS.get(block.name)
output = handler(**block.input) # 所有工具统一处理
results.append(tool_result)
# ...
问题:
- ❌ task 工具不是普通工具,它需要 fork 子智能体
- ❌ 子智能体需要独立的上下文和执行循环
- ❌ 需要特殊的摘要提取逻辑
S04 的改造:
python
# S04: 区分 task 工具和普通工具
def agent_loop(messages: list):
while True:
# ... LLM调用
for block in response.content:
if block.type == "tool_use":
if block.name == "task": # 特殊处理
prompt = block.input.get("prompt", "")
output = run_subagent(prompt) # fork子智能体
else: # 普通工具处理
handler = TOOL_HANDLERS.get(block.name)
output = handler(**block.input)
results.append(tool_result)
# ...
4.2 本质上还是利用 Tool 机制
子智能体是通过 task tool 实现的:
python
# task tool 的定义
PARENT_TOOLS = CHILD_TOOLS + [
{
"name": "task",
"description": "Spawn a subagent with fresh context. It shares the filesystem but not conversation history.",
"input_schema": {
"type": "object",
"properties": {
"prompt": {"type": "string"},
"description": {"type": "string", "description": "Short description of the task"}
},
"required": ["prompt"]
}
}
]
关键洞察:
- 🔧 子智能体不是新的架构概念,而是特殊的工具
- 🔄 工具的本质是扩展LLM能力的接口
- 🎯 task tool 扩展了LLM的"并行处理"能力
- 📦 通过工具机制保持了架构的一致性
4.3 上下文隔离的实现
Fresh Context 机制:
python
def run_subagent(prompt: str) -> str:
# 关键:全新的上下文,没有任何历史
sub_messages = [{"role": "user", "content": prompt}]
# 独立的执行循环
for _ in range(30): # safety limit
response = client.messages.create(
model=MODEL,
system=SUBAGENT_SYSTEM, # 不同的系统提示
messages=sub_messages, # 独立的上下文
tools=CHILD_TOOLS, # 过滤的工具集
max_tokens=8000,
)
# ... 执行逻辑
# 只返回摘要,丢弃完整上下文
return "".join(b.text for b in response.content if hasattr(b, "text"))
隔离的层次:
- 上下文隔离 :
sub_messages独立于父messages - 系统提示隔离 :
SUBAGENT_SYSTEMvsSYSTEM - 工具隔离 :
CHILD_TOOLS不包含task工具 - 执行隔离 : 独立的
while循环 - 结果隔离: 只返回摘要,不返回完整上下文
4.4 防止递归的设计
子智能体工具集过滤:
python
# 子智能体不包含 task 工具
CHILD_TOOLS = [
{"name": "bash", ...},
{"name": "read_file", ...},
{"name": "write_file", ...},
{"name": "edit_file", ...},
# 注意:没有 task 工具!
]
# 父智能体包含 task 工具
PARENT_TOOLS = CHILD_TOOLS + [
{"name": "task", ...} # 只有父智能体能生成子智能体
]
安全限制:
python
def run_subagent(prompt: str) -> str:
# 最多30轮迭代,防止无限循环
for _ in range(30):
# ...
if response.stop_reason != "tool_use":
break
4.5 共享文件系统
设计权衡:
python
# 父子智能体共享工作目录
WORKDIR = Path.cwd() # 全局变量,共享
# 所有工具都使用同一个 WORKDIR
def run_read(path: str) -> str:
fp = safe_path(path) # 使用 WORKDIR
return fp.read_text()
def run_write(path: str, content: str) -> str:
fp = safe_path(path) # 使用 WORKDIR
fp.write_text(content)
优点:
- ✅ 子智能体可以操作父智能体创建的文件
- ✅ 父智能体可以看到子智能体的工作成果
- ✅ 简化了状态管理
缺点:
- ⚠️ 需要协调文件访问,避免冲突
- ⚠️ 缺乏真正的进程隔离
五、S02 vs S04 详细对比
5.1 架构对比
| 维度 | S02 单智能体 | S04 子智能体 |
|---|---|---|
| 上下文管理 | 单一上下文,不断累积 | 父子分离,摘要返回 |
| 工具集合 | 单一工具集 | 父子工具集分离 |
| 任务执行 | 顺序执行 | 可并行执行子任务 |
| Token消耗 | 随任务复杂度线性增长 | 摘要机制控制增长 |
| 上下文污染 | 容易发生 | 通过隔离避免 |
| 复杂度 | 简单 | 中等 |
| 扩展性 | 有限 | 良好 |
5.2 代码对比
消息管理:
python
# S02: 单一消息列表
messages = []
agent_loop(messages)
# S04: 父子消息分离
parent_messages = []
agent_loop(parent_messages) # 可能fork多个子智能体
# 子智能体有独立的消息
sub_messages = [{"role": "user", "content": prompt}]
# 子消息在返回摘要后被丢弃
工具处理:
python
# S02: 统一处理
for block in response.content:
if block.type == "tool_use":
handler = TOOL_HANDLERS.get(block.name)
output = handler(**block.input)
# S04: 区分处理
for block in response.content:
if block.type == "tool_use":
if block.name == "task":
output = run_subagent(block.input["prompt"])
else:
handler = TOOL_HANDLERS.get(block.name)
output = handler(**block.input)
系统提示:
python
# S02: 单一系统提示
SYSTEM = "You are a coding agent..."
# S04: 双层系统提示
SYSTEM = "You are a coding agent. Use the task tool to delegate..."
SUBAGENT_SYSTEM = "You are a coding subagent. Complete the given task, then summarize..."
5.3 执行效率对比
场景:分析10个文件并生成报告
S02 执行:
轮次1: find文件 (10个结果)
轮次2-11: 逐个read_file (10轮)
轮次12: write_file生成报告
总计: 12轮,上下文包含22条消息
S04 执行:
父轮次1: task工具 (fork子智能体分析文件)
子轮次1-11: find + 10次read_file
子返回摘要: "发现10个文件,分别是..."
父轮次2: write_file生成报告 (基于摘要)
总计: 父2轮 + 子11轮 = 13轮
但父上下文只包含4条消息!
六、设计模式分析
6.1 策略模式(Strategy Pattern)
task tool 作为特殊策略:
python
# 工具策略接口
def handler(**kwargs) -> str:
pass
# 普通策略
def run_bash(**kwargs) -> str:
pass
# 特殊策略:fork子智能体
def run_subagent(prompt: str) -> str:
# 完全不同的执行逻辑
sub_messages = [{"role": "user", "content": prompt}]
# ... 独立循环
return summary
6.2 外观模式(Facade Pattern)
run_subagent 作为子智能体的外观:
python
# 复杂的子智能体执行逻辑被封装
def run_subagent(prompt: str) -> str:
# 隐藏内部复杂性:
# - 上下文管理
# - 循环控制
# - 工具分发
# - 摘要提取
return summary
6.3 模板方法模式(Template Method Pattern)
agent_loop 作为模板:
python
def agent_loop(messages: list):
while True: # 模板骨架
response = client.messages.create(...) # 固定步骤
messages.append(...)
if response.stop_reason != "tool_use":
return
results = []
for block in response.content:
if block.type == "tool_use":
# 可变步骤:工具处理
if block.name == "task":
output = run_subagent(...)
else:
output = handler(...)
results.append(...)
messages.append(...)
七、实际应用场景
7.1 代码审查场景
任务:审查整个项目的代码质量
S02 处理:
轮次1: 找到所有文件 (50个)
轮次2-51: 逐个读取并分析
轮次52: 生成审查报告
问题: 上下文包含100+条消息,token消耗巨大
S04 处理:
父轮次1: task("审查src目录")
子智能体1: 分析src/... (20个文件) → 摘要
父轮次2: task("审查tests目录")
子智能体2: 分析tests/... (30个文件) → 摘要
父轮次3: 整合两个摘要,生成最终报告
优势: 父上下文只包含6条消息
7.2 并行任务场景
任务:同时更新多个配置文件
S02 处理:
轮次1: read_file(config1.json)
轮次2: edit_file(config1.json, ...)
轮次3: read_file(config2.json)
轮次4: edit_file(config2.json, ...)
轮次5: read_file(config3.json)
轮次6: edit_file(config3.json, ...)
问题: 顺序执行,效率低
S04 处理:
父轮次1:
- task("更新config1.json")
- task("更新config2.json")
- task("更新config3.json")
(理论上可以并行调用多个task)
子智能体1-3: 并行处理各自的配置文件
父轮次2: 整合结果
优势: 并行执行,效率高
7.3 探索性任务场景
任务:探索一个未知的项目结构
S02 处理:
轮次1: ls -la
轮次2: cd src && ls
轮次3: cat README.md
轮次4: find . -name "*.py"
轮次5-15: 读取各种文件...
问题: 探索过程会污染主任务上下文
S04 处理:
父轮次1: task("探索项目结构")
子智能体: 自由探索,尝试各种命令
子返回摘要: "项目是Web应用,包含前端、后端、测试..."
父轮次2: 基于摘要进行主任务
优势: 探索过程不影响主任务上下文
八、演进路径总结
S01: 基础永动机
↓
+ 单一上下文
+ 单一工具集
+ 顺序执行
↓
S02: 工具扩展
↓
+ 多工具支持
+ 分发机制
+ 仍然单一上下文
↓
S03: 状态跟踪
↓
+ TodoManager
+ 进度管理
+ Nag reminder
↓
S04: 子智能体
↓
+ 上下文隔离
+ 任务分解
+ 摘要返回
+ 防止递归
九、核心洞察
"Process isolation gives context isolation for free."
这个设计的精髓在于:
- 上下文隔离是核心问题: 单一上下文会无限增长,污染思维
- 子智能体是解决方案: 通过 fork 提供独立的执行环境
- 工具机制保持一致性: task tool 本质上还是工具
- 摘要返回控制复杂度: 只传递必要信息,丢弃中间细节
- 共享文件系统简化设计: 避免复杂的状态传递机制
9.1 设计哲学
python
# 好的设计
父智能体 = 决策者 + 协调者
子智能体 = 执行者 + 探索者
task tool = 通信桥梁
摘要 = 信息过滤
# 坏的设计
单一智能体 = 承担所有职责
无限上下文 = 思维混乱
无序执行 = 效率低下
9.2 实践建议
✅ 推荐做法:
- 使用子智能体处理独立的子任务
- 让子智能体返回简洁的摘要
- 防止子智能体递归生成子智能体
- 共享文件系统但不共享上下文
❌ 避免做法:
- 在单一上下文中处理复杂任务
- 让子智能体返回大量细节
- 允许无限递归
- 过度使用子智能体(增加复杂度)
十、总结
S04通过引入子智能体机制,解决了S02单智能体架构中的上下文管理问题:
- 改造Agent Loop的必要性: task工具需要特殊处理,无法统一分发
- 工具机制的本质: 子智能体通过task tool实现,保持了架构一致性
- 上下文隔离的价值: fresh context + 摘要返回 = 清洁的思维环境
- 设计权衡: 共享文件系统但隔离上下文,平衡了简单性和功能性
关键要点:Subagent的实现由于messages上下文的缘故,且为了维护好,需要改造agent loop,但是本质上来说还是利用tool机制实现了subagent。
这种设计让系统既能处理复杂任务,又能保持上下文的清洁和可控,是构建大型AI代理系统的重要模式。