【claude code agent 实践3】Subagent子智能体机制深度解析:从S02到S04的演进

子智能体机制深度解析:从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"))

隔离的层次:

  1. 上下文隔离 : sub_messages 独立于父 messages
  2. 系统提示隔离 : SUBAGENT_SYSTEM vs SYSTEM
  3. 工具隔离 : CHILD_TOOLS 不包含 task 工具
  4. 执行隔离 : 独立的 while 循环
  5. 结果隔离: 只返回摘要,不返回完整上下文

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."

这个设计的精髓在于:

  1. 上下文隔离是核心问题: 单一上下文会无限增长,污染思维
  2. 子智能体是解决方案: 通过 fork 提供独立的执行环境
  3. 工具机制保持一致性: task tool 本质上还是工具
  4. 摘要返回控制复杂度: 只传递必要信息,丢弃中间细节
  5. 共享文件系统简化设计: 避免复杂的状态传递机制

9.1 设计哲学

python 复制代码
# 好的设计
父智能体 = 决策者 + 协调者
子智能体 = 执行者 + 探索者
task tool = 通信桥梁
摘要 = 信息过滤

# 坏的设计
单一智能体 = 承担所有职责
无限上下文 = 思维混乱
无序执行 = 效率低下

9.2 实践建议

✅ 推荐做法:

  • 使用子智能体处理独立的子任务
  • 让子智能体返回简洁的摘要
  • 防止子智能体递归生成子智能体
  • 共享文件系统但不共享上下文

❌ 避免做法:

  • 在单一上下文中处理复杂任务
  • 让子智能体返回大量细节
  • 允许无限递归
  • 过度使用子智能体(增加复杂度)

十、总结

S04通过引入子智能体机制,解决了S02单智能体架构中的上下文管理问题:

  1. 改造Agent Loop的必要性: task工具需要特殊处理,无法统一分发
  2. 工具机制的本质: 子智能体通过task tool实现,保持了架构一致性
  3. 上下文隔离的价值: fresh context + 摘要返回 = 清洁的思维环境
  4. 设计权衡: 共享文件系统但隔离上下文,平衡了简单性和功能性

关键要点:Subagent的实现由于messages上下文的缘故,且为了维护好,需要改造agent loop,但是本质上来说还是利用tool机制实现了subagent。

这种设计让系统既能处理复杂任务,又能保持上下文的清洁和可控,是构建大型AI代理系统的重要模式。

相关推荐
维元码簿2 小时前
Claude Code 深度拆解:远程模式 4 — 无环境直连架构
ai·agent·claude code·ai coding
爱奥尼欧4 小时前
MetaBot-用飞书远程操控Claude Code
飞书·claude code
linshutao4 小时前
VS Code 配置 Claude Code插件和 DeepSeek
ai编程·deepseek·claude code
维元码簿4 小时前
Claude Code 深度拆解:远程模式 3 — 消息路由与传输层
ai·agent·claude code·ai coding
秋堂主5 小时前
Claude Code斜杠命令
cc·claude code
Zale_J21 小时前
Claude Code 安装与配置
ai·claude·claude code
秋堂主1 天前
Claude Code安装指南
cc·claude code
周易宅1 天前
将 DeepSeek-V4-Pro 接入 Claude Code:从 CC Switch 到实战的完整指南
ai·claude code·cc switch
走马走马1 天前
Claude Code 安装完全指南
claude code