子智能体与上下文隔离:保持思维清晰的关键
"大任务拆小,每个小任务干净的上下文" —— 子智能体用独立 messages[],不污染主对话。
随着 Agent 工作,messages 数组越来越胖。每次读文件、跑命令的输出都永久留在上下文里。
"这个项目用什么测试框架?" 这个问题可能需要读 5 个文件,但父智能体只需要一个词:"pytest"。
如何把探索的细节隔离,只把结论带回?
一、问题:上下文膨胀
想象这个场景:
父 Agent 正在做大型重构,上下文里已经累积了:
- 20 个文件的读取结果
- 10 次测试运行输出
- 5 次 Git 状态检查
- 各种中间文件的 diff
现在它想知道:" utils.py 里的 parse_data 函数是做什么的?"
为此它需要:
- 读取 utils.py
- 查看相关依赖
- 分析函数逻辑
- 返回结论
这些探索过程会进一步膨胀父 Agent 的上下文,稀释真正重要的信息。
二、解决方案:子智能体
Parent agent Subagent
+------------------+ +------------------+
| messages=[...] | | messages=[] | <-- fresh
| | dispatch | |
| tool: task | ----------> | while tool_use: |
| prompt="..." | | call tools |
| | summary | append results |
| result = "..." | <---------- | return last text |
+------------------+ +------------------+
Parent context stays clean. Subagent context is discarded.
父智能体有一个 task 工具。子智能体运行自己的循环,只有最终文本返回给父智能体。
三、核心机制
1. 工具分离
父智能体拥有所有基础工具 + task:
PARENT_TOOLS = CHILD_TOOLS + [
{
"name": "task",
"description": "Spawn a subagent with fresh context.",
"input_schema": {
"type": "object",
"properties": {"prompt": {"type": "string"}},
"required": ["prompt"],
}
},
]
子智能体拥有除 task 外的所有基础工具(禁止递归生成)。
2. 独立循环
子智能体以 messages=[] 启动,运行自己的循环:
def run_subagent(prompt: str) -> str:
sub_messages = [{"role": "user", "content": prompt}]
for _ in range(30): # 安全限制
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)
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)"
3. 上下文隔离
子智能体可能跑了 30+ 次工具调用,但整个消息历史直接丢弃。父智能体收到的只是一段摘要文本,作为普通 tool_result 返回。
四、使用场景
场景 1:信息检索
父 Agent:这个项目用什么测试框架?
↓
子 Agent(独立上下文):
- 读取 pytest.ini
- 读取 setup.py
- 检查测试目录结构
- 分析依赖
↓
返回:"pytest"
父 Agent 的上下文保持干净,只有结论。
场景 2:多文件分析
父 Agent:分析所有 Python 文件的依赖关系
↓
子 Agent:
- 遍历所有 .py 文件
- 提取 import 语句
- 构建依赖图
- 生成报告
↓
返回:精简的依赖关系摘要
场景 3:代码生成
父 Agent:创建一个数据处理模块
↓
子 Agent:
- 设计 API
- 实现核心函数
- 添加错误处理
- 编写测试
↓
返回:模块完成确认 + 文件路径
五、试一试
cd learn-claude-code
python agents/s04_subagent.py
试试这些 prompt:
Use a subtask to find what testing framework this project usesDelegate: read all .py files and summarize what each one doesUse a task to create a new module, then verify it from here
观察父 Agent 如何派发子任务,子 Agent 独立工作,最后只返回简洁的结果。
六、对比无隔离 vs 有隔离
| 场景 | 无子智能体 | 有子智能体 |
|---|---|---|
| 探索性任务 | 上下文膨胀,主任务迷失 | 探索细节隔离,主任务清晰 |
| 多文件分析 | 所有文件内容留在上下文 | 只保留分析结论 |
| 长对话 | 后期上下文窗口溢出 | 定期清理,保持高效 |
七、进阶:递归与层级
本文的子智能体是单层的。更复杂的系统可以支持:
- 递归子智能体:子智能体也可以派发孙智能体
- 层级架构:父-子-孙三级结构,每层有不同职责
- 并行子智能体:同时派发多个子任务,聚合结果
但要注意:层级越深,协调成本越高。对于多数场景,单层子智能体已经足够。
八、Harness 层的职责
守护模型的思维清晰度——这是 Harness 的核心职责之一。
- 子智能体隔离是机制
- 模型决定什么时候用、用来做什么
- Harness 保证隔离的执行
这种设计模式不仅适用于编程 Agent,也适用于任何需要复杂推理的场景:
- 研究 Agent:主 Agent 协调,子 Agent 深入具体领域
- 客服 Agent:主 Agent 处理对话,子 Agent 查询知识库
- 创意 Agent:主 Agent 把控方向,子 Agent 探索具体方案
好的 Harness 像一个好的工作环境——提供清晰的边界,让智能高效运转。
Bash 就够了。真正的 Agent 是宇宙所需要的全部。