s04
Subagent
规划与协调Clean Context Per Subtask
154 LOC5 个工具Subagent spawn with isolated messages[]
机制概览
大任务比如把 7 种耐心资本测算口径都跑一遍并行回归对比,一个会话连着跑会把工作内存撑爆。Claude Code 让主会话派几个"子会话"各自独立处理一种口径。子会话跑完只把一段总结回传,中间产生的几万字过程数据不进主会话。
本节贯穿示例
研究项目
耐心资本对企业 ESG 表现的实证项目 do10 稳健性表 10A
在这一节里做的事
要把 A2 主测度、A1 经典版、B2 中位数门槛、C 熵值法、仅股权侧 Stequity、仅 Bank(A2 债权侧)、仅 Rdebt(A1 债权侧)共 7 种 PC 测度并行跑 firm+year FE 基准回归,主会话只接每个口径的 β、SE、obs 与显著性结论,合成 table10A_pc_swap.csv。
s01 > s02 > s03 > [ s04 ] s05 > s06 | s07 > s08 > s09 > s10 > s11 > s12
"大任务拆小, 每个小任务干净的上下文" -- Subagent 用独立 messages[], 不污染主对话。
Harness 层: 上下文隔离 -- 守护模型的思维清晰度。
问题
Agent 工作越久, messages 数组越臃肿。每次读文件、跑命令的输出都永久留在上下文里。"这个项目用什么测试框架?" 可能要读 5 个文件, 但父 Agent 只需要一个词: "pytest。"
解决方案
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.
工作原理
- 父 Agent 有一个
task工具。Subagent 拥有除task外的所有基础工具 (禁止递归生成)。
PARENT_TOOLS = CHILD_TOOLS + [
{"name": "task",
"description": "Spawn a subagent with fresh context.",
"input_schema": {
"type": "object",
"properties": {"prompt": {"type": "string"}},
"required": ["prompt"],
}},
]
- Subagent 以
messages=[]启动, 运行自己的循环。只有最终文本返回给父 Agent。
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,
)
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)"
Subagent 可能跑了 30+ 次工具调用, 但整个消息历史直接丢弃。父 Agent 收到的只是一段摘要文本, 作为普通 tool_result 返回。
相对 s03 的变更
| 组件 | 之前 (s03) | 之后 (s04) |
|---|---|---|
| Tools | 5 | 5 (基础) + task (仅父端) |
| 上下文 | 单一共享 | 父 + 子隔离 |
| Subagent | 无 | run_subagent() 函数 |
| 返回值 | 不适用 | 仅摘要文本 |
试一试
cd claude-code-for-researchers
python agents/s04_subagent.py
试试这些 prompt (英文 prompt 对 LLM 效果更好, 也可以用中文):
Spawn one subagent per PC measure (A1/A2/A3/A4/B1/B2/C/D); each runs the baseline reghdfe and returns β, t, obsDelegate: read every paper under 01_文献/A_主流框架(股权+债权)/ and summarize each in one sentenceUse a subagent to construct PC_A2 from raw CSMAR fields and report the resulting field summary