Learn Claude Code
s04

子 Agent

规划与协调

Clean Context Per Subtask

288 LOC5 个工具TypeScriptSubagent spawn with isolated messages[]
Subagents use independent messages[], keeping the main conversation clean

s01 > s02 > s03 > [ s04 ] s05 > s06 | s07 > s08 > s09 > s10 > s11 > s12

"大任务拆小, 每个小任务干净的上下文" -- 子智能体用独立 messages[], 不污染主对话。

Harness 层: 上下文隔离 -- 守护模型的思维清晰度。

问题

智能体工作越久, messages 数组越胖。每次读文件、跑命令的输出都永久留在上下文里。"这个项目用什么测试框架?" 可能要读 5 个文件, 但父智能体只需要一个词: "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.

工作原理

  1. 父智能体有一个 task 工具。子智能体拥有除 task 外的所有基础工具 (禁止递归生成)。
const PARENT_TOOLS = [
  ...CHILD_TOOLS,
  {
    name: "task",
    description: "Spawn a subagent with fresh context.",
    input_schema: {
      type: "object",
      properties: {
        prompt: { type: "string" },
        description: { type: "string" },
      },
      required: ["prompt"],
    },
  },
];
  1. 子智能体以 messages=[] 启动, 运行自己的循环。只有最终文本返回给父智能体。
async function runSubagent(prompt: string): Promise<string> {
  const subMessages: Message[] = [{ role: "user", content: prompt }];

  for (let attempt = 0; attempt < 30; attempt += 1) {
    const response = await client.messages.create({
      model: MODEL,
      system: SUBAGENT_SYSTEM,
      messages: subMessages,
      tools: CHILD_TOOLS,
      max_tokens: 8000,
    });

    subMessages.push({ role: "assistant", content: response.content });
    if (response.stop_reason !== "tool_use") {
      return response.content
        .filter((block) => block.type === "text")
        .map((block) => block.text)
        .join("") || "(no summary)";
    }

    const results = [];
    for (const block of response.content) {
      if (block.type !== "tool_use") continue;
      const handler = TOOL_HANDLERS[block.name as ToolUseName];
      const output = handler(block.input as Record<string, unknown>);
      results.push({
        type: "tool_result" as const,
        tool_use_id: block.id,
        content: String(output).slice(0, 50000),
      });
    }

    subMessages.push({ role: "user", content: results });
  }

  return "(no summary)";
}

子智能体可能跑了 30+ 次工具调用, 但整个消息历史直接丢弃。父智能体收到的只是一段摘要文本, 作为普通 tool_result 返回。

相对 s03 的变更

组件之前 (s03)之后 (s04)
Tools55 (基础) + task (仅父端)
上下文单一共享父 + 子隔离
Subagentrun_subagent() 函数
返回值不适用仅摘要文本

试一试

cd learn-claude-code
cd agents-ts
npm install
npm run s04

试试这些 prompt (英文 prompt 对 LLM 效果更好, 也可以用中文):

  1. Use a subtask to find what testing framework this project uses
  2. Delegate: read all .ts files and summarize what each one does
  3. Use a task to create a new module, then verify it from here