Harness Engineering

第2章 Agent 架构模式全景

作者 杨艺韬 · 7,052 字

第2章 Agent 架构模式全景

在上一章中我们讨论了为什么需要 Harness 工程——LLM 本身只是引擎,真正让它在复杂任务中跑起来的,是围绕它搭建的架构骨架。本章将系统梳理当前业界主流的六种 Agent 架构模式。对于每一种模式,我们会回答三个问题:它是什么怎么实现什么时候该用

这六种模式并非互斥。在实际系统中,你经常会看到它们的组合——例如一个 Multi-Agent 系统中的每个子 Agent 可能各自采用 ReAct 模式,而整个协作流程则由一个状态机来编排。理解每种模式的核心思想和取舍,是做出正确架构决策的前提。

2.1 Tool-Augmented LLM:最简模式

核心思想

这是最朴素的 Agent 形态:给 LLM 提供一组工具(函数),让它根据用户输入决定是否调用工具、调用哪个工具、传什么参数。整个流程只有一轮决策。

sequenceDiagram
    participant U as 用户
    participant L as LLM
    participant T as 工具

    U->>L: 用户输入 + 工具定义
    L->>L: 选择工具 + 生成参数
    L->>T: 调用工具
    T-->>L: 返回结果
    L->>L: 整合结果
    L-->>U: 最终输出

这就是 OpenAI Function Calling 和 Claude Tool Use 最基础的使用方式。很多开发者在第一次接触 Agent 概念时,其实已经在不知不觉中使用了这种模式——你定义了一组函数签名,LLM 选择调用哪个函数,你执行函数并把结果返回给 LLM,然后 LLM 组织最终回答。整个过程非常直观,没有复杂的状态管理,也不需要额外的框架支持。

值得注意的是,即便是这个最简模式,工具定义的质量也至关重要。一个好的工具 schema 应该包含清晰的描述、准确的参数类型以及有意义的示例值。这决定了 LLM 能否正确选择工具并传入合理的参数。我们会在第5章详细讨论工具设计的最佳实践。

伪代码实现

def tool_augmented_llm(user_message: str, tools: list[Tool]) -> str:
    """最简单的 Tool-Augmented LLM 模式"""
    # 第一步:把用户消息和工具定义一起发给 LLM
    response = llm.chat(
        messages=[{"role": "user", "content": user_message}],
        tools=[t.schema for t in tools],
    )

    # 第二步:如果 LLM 决定调用工具
    if response.tool_calls:
        tool_results = []
        for call in response.tool_calls:
            tool = find_tool(call.name, tools)
            result = tool.execute(**call.arguments)
            tool_results.append(result)

        # 第三步:把工具结果返回给 LLM,生成最终回答
        final = llm.chat(
            messages=[
                {"role": "user", "content": user_message},
                {"role": "assistant", "content": response},
                {"role": "tool", "content": tool_results},
            ],
        )
        return final.content

    return response.content

适用场景

局限性

这个模式最大的问题是没有循环。如果第一次工具调用的结果不够好,或者任务需要多步操作,它就束手无策了。举一个具体的例子:用户问"帮我查一下北京明天的天气,如果会下雨就提醒我带伞"。单轮模式可以查到天气,但"判断是否下雨 → 决定是否提醒"这个条件逻辑就需要在一轮调用中全部完成,稍微复杂一点的条件分支就会超出它的能力范围。这正是后续模式要解决的问题。

尽管如此,优先从最简模式开始是一个重要的工程原则。如果你的需求用 Tool-Augmented LLM 就能满足,那就不要引入更复杂的架构。过度设计是 Agent 工程中最常见的错误之一。

2.2 ReAct:推理与行动交织

核心思想

ReAct(Reasoning + Acting)是最常见的 Agent 模式之一,由 Yao 等人于 2022 年提出。其核心是让 LLM 在一个循环中交替进行推理(Thought)行动(Action),每次行动后观察结果(Observation),再决定下一步。

flowchart TD
    A["用户输入"] --> B["Thought: 推理\n我需要查询订单信息"]
    B --> C["Action: 调用工具\nquery_orders(user_id)"]
    C --> D["Observation: 观察结果\n返回 3 个订单"]
    D --> E["Thought: 推理\n需要找最新的那个"]
    E --> F["Action: 调用工具\nget_order_detail(order_id)"]
    F --> G["Observation: 观察结果\n订单详情..."]
    G --> H["Thought: 推理\n信息足够,可以回答了"]
    H --> I["最终输出"]

    style B fill:#fef3c7,stroke:#f59e0b
    style E fill:#fef3c7,stroke:#f59e0b
    style H fill:#fef3c7,stroke:#f59e0b
    style C fill:#dbeafe,stroke:#3b82f6
    style F fill:#dbeafe,stroke:#3b82f6

LangChain 的标准 Agent、Claude Code 的主循环,都是这个模式的变体。

相比于 Tool-Augmented LLM,ReAct 的关键进步在于引入了循环。LLM 不再是一次性决策,而是在一个 while 循环中持续运行,直到它判断任务已完成或外部条件触发终止。这个循环就是我们常说的 "Agent Loop"(Agent 主循环),它是几乎所有复杂 Agent 系统的基础构件。

ReAct 模式之所以有效,还有一个重要原因:推理过程(Thought)本身就是一种"自我提示"。当 LLM 在输出中写下"我需要先查询用户的订单信息"时,这段文字会出现在下一轮的输入上下文中,相当于给自己设定了一个明确的短期目标。这种思维链(Chain-of-Thought)与行动的交织,能帮助模型在多步任务中保持局部目标。

伪代码实现

def react_agent(user_message: str, tools: list[Tool], max_steps: int = 10) -> str:
    """ReAct 模式:推理-行动循环"""
    messages = [{"role": "user", "content": user_message}]

    for step in range(max_steps):
        # LLM 同时输出推理过程和工具调用决策
        response = llm.chat(messages=messages, tools=[t.schema for t in tools])
        messages.append({"role": "assistant", "content": response})

        # 如果 LLM 没有调用工具,说明它认为任务完成了
        if not response.tool_calls:
            return response.content

        # 执行所有工具调用,把结果追加到对话历史
        for call in response.tool_calls:
            tool = find_tool(call.name, tools)
            result = tool.execute(**call.arguments)
            messages.append({
                "role": "tool",
                "tool_call_id": call.id,
                "content": str(result),
            })

    return "达到最大步数限制,任务未完成"

关键设计要素

循环终止条件是 ReAct 模式最重要的工程问题之一。上面的代码用了两个条件:LLM 不再调用工具(自然终止),或达到最大步数(强制终止)。实际系统中还需要考虑:

适用场景

局限性

ReAct 的推理是逐步的,每一步只看当前状态决定下一步。对于需要全局规划的复杂任务(比如"把这个 Python 项目重构为微服务架构"),逐步推理容易迷失在细节中,忘记全局目标。这就好比一个人在迷宫中只看脚下一步,虽然每一步都是合理的,但可能走了很多弯路甚至走进死胡同。

另一个实际问题是上下文窗口的压力。ReAct 循环中,每一轮的推理文本和工具返回结果都会累积在对话历史中。当任务需要几十步操作时,对话历史可能会膨胀到数万甚至数十万 Token,逼近模型的上下文窗口限制。如何在循环中管理上下文——何时截断、何时做摘要、何时丢弃旧的工具结果——是 ReAct 模式落地时必须解决的工程问题。我们会在第11章(短期记忆)中深入讨论这个话题。

2.3 Plan-and-Execute:先规划,后执行

核心思想

Plan-and-Execute 模式将任务分为两个阶段:先由一个 Planner 生成完整计划,再由一个 Executor 逐步执行。BabyAGI 和 AutoGPT 是这个模式的早期代表。

flowchart LR
    U["用户输入"] --> P["Planner\n(LLM)"]
    P -->|"步骤列表"| E["Executor\n(LLM + Tools)"]
    E -->|"步骤结果"| Check{"全部完成?"}
    Check -->|"否"| E
    Check -->|"需要重规划"| P
    Check -->|"是"| O["最终输出"]

    style P fill:#fef3c7,stroke:#f59e0b
    style E fill:#dbeafe,stroke:#3b82f6

伪代码实现

def plan_and_execute(user_message: str, tools: list[Tool]) -> str:
    """Plan-and-Execute 模式"""
    # 阶段一:生成计划
    plan = planner_llm.chat(
        messages=[{
            "role": "user",
            "content": f"""请为以下任务制定执行计划,输出为步骤列表。
任务:{user_message}
可用工具:{[t.name for t in tools]}"""
        }]
    )
    steps = parse_plan(plan.content)  # 解析为结构化步骤列表

    # 阶段二:逐步执行
    results = []
    for i, step in enumerate(steps):
        # 每一步都可以是一个小型 ReAct 循环
        step_result = react_agent(
            user_message=f"执行以下步骤:{step}\n\n背景:{user_message}\n已完成步骤:{results}",
            tools=tools,
            max_steps=5,
        )
        results.append({"step": step, "result": step_result})

        # 可选:检查是否需要重新规划
        if should_replan(results, steps[i+1:]):
            remaining_steps = replan(user_message, results, steps[i+1:])
            steps = steps[:i+1] + remaining_steps

    # 阶段三:汇总
    summary = llm.chat(
        messages=[{
            "role": "user",
            "content": f"任务:{user_message}\n执行结果:{results}\n请汇总最终答案。"
        }]
    )
    return summary.content

关键设计要素

**重规划(Replanning)**是这个模式的核心难点。计划一旦生成,执行过程中必然会遇到预期之外的情况——工具返回了意外结果、某个步骤失败了、甚至发现原始计划遗漏了关键步骤。好的 Plan-and-Execute 系统需要在以下时机触发重规划:

  1. 某一步执行失败且重试无效
  2. 某一步的结果与预期严重偏离
  3. 发现了新信息,使得后续步骤不再适用

重规划本身也有成本(额外的 LLM 调用),因此需要设定合理的重规划预算。

适用场景

局限性

2.4 Reflexion / Self-Critique:自我评估与迭代

核心思想

Reflexion 模式的核心洞察是:LLM 可以评估自己(或另一个 LLM)的输出质量,并基于评估结果进行改进。这形成了一个"生成 → 评估 → 改进"的迭代循环。

生成初始输出


┌──────────────────────────────────────┐
│  ┌──────────┐    评估意见    ┌─────┐ │
│  │ Critic   │ ────────────→ │生成器│ │
│  │ (评估LLM)│ ←──────────── │(LLM)│ │
│  └──────────┘   改进后输出   └─────┘ │
│              迭代循环                 │
└──────────────────────────────────────┘


质量达标 → 最终输出

伪代码实现

def reflexion_agent(
    user_message: str,
    max_iterations: int = 3,
    quality_threshold: float = 0.8,
) -> str:
    """Reflexion 模式:自我评估与迭代改进"""

    # 第一轮:生成初始输出
    output = generator_llm.chat(
        messages=[{"role": "user", "content": user_message}]
    ).content

    for iteration in range(max_iterations):
        # 评估当前输出
        critique = critic_llm.chat(
            messages=[{
                "role": "user",
                "content": f"""请评估以下输出的质量。
原始任务:{user_message}
当前输出:{output}

请给出:
1. 质量评分(0-1)
2. 具体问题列表
3. 改进建议"""
            }]
        ).content

        score = parse_score(critique)
        if score >= quality_threshold:
            break  # 质量达标,退出循环

        # 基于评估意见改进输出
        output = generator_llm.chat(
            messages=[{
                "role": "user",
                "content": f"""请根据以下反馈改进你的输出。
原始任务:{user_message}
当前输出:{output}
评估反馈:{critique}

请输出改进后的版本。"""
            }]
        ).content

    return output

关键设计要素

**Critic 的质量决定了整个系统的上限。**一个糟糕的 Critic 会让系统在错误方向上迭代,越改越差。设计 Critic 时的关键考量:

适用场景

局限性

2.5 Multi-Agent:多智能体协作

核心思想

Multi-Agent 模式将一个复杂任务拆分给多个专门化的 Agent,每个 Agent 有自己的角色定义、工具集和系统提示词。Agent 之间通过某种协议进行通信和协作。

CrewAI、AutoGen、以及 Claude Code 的 subagent 系统都属于这一类。

graph TD
    C["🎯 Coordinator\n协调者 Agent"] -->|"分派研究任务"| R["🔍 研究 Agent\n搜索 / 阅读工具"]
    C -->|"分派编码任务"| D["💻 编码 Agent\n代码 / 文件工具"]
    C -->|"分派测试任务"| T["🧪 测试 Agent\n测试 / 运行工具"]
    R -->|"研究结果"| C
    D -->|"代码变更"| C
    T -->|"测试报告"| C

    style C fill:#f0f4ff,stroke:#3b82f6,stroke-width:2px
    style R fill:#fef3c7,stroke:#f59e0b
    style D fill:#dcfce7,stroke:#22c55e
    style T fill:#fce7f3,stroke:#ec4899

伪代码实现

@dataclass
class AgentConfig:
    name: str
    system_prompt: str
    tools: list[Tool]
    model: str  # 不同 Agent 可以用不同模型

def multi_agent_system(user_message: str, agents: list[AgentConfig]) -> str:
    """Multi-Agent 模式:多智能体协作"""

    # 协调者决定任务分配
    coordinator_response = coordinator_llm.chat(
        messages=[{
            "role": "system",
            "content": "你是任务协调者。根据用户任务和可用 Agent 列表,制定协作方案。",
        }, {
            "role": "user",
            "content": f"任务:{user_message}\n可用Agent:{[a.name for a in agents]}",
        }]
    )
    task_assignments = parse_assignments(coordinator_response.content)

    # 按依赖顺序执行各 Agent 的子任务
    context = {}  # 共享上下文
    for assignment in topological_sort(task_assignments):
        agent_config = find_agent(assignment.agent_name, agents)
        # 每个子 Agent 内部可以用 ReAct 模式
        result = react_agent(
            user_message=f"{assignment.task}\n\n共享上下文:{context}",
            tools=agent_config.tools,
            system_prompt=agent_config.system_prompt,
            model=agent_config.model,
        )
        context[assignment.agent_name] = result

    # 协调者汇总各 Agent 的输出
    final = coordinator_llm.chat(
        messages=[{
            "role": "user",
            "content": f"原始任务:{user_message}\n各Agent执行结果:{context}\n请汇总最终答案。",
        }]
    )
    return final.content

协作拓扑

Multi-Agent 系统的通信拓扑有几种典型形式:

星型拓扑(Hub-and-Spoke):一个协调者 Agent 管理所有子 Agent,子 Agent 之间不直接通信。Claude Code 的 subagent 模式就是这种——主 Agent 可以启动子 Agent 处理独立任务,子 Agent 完成后把结果返回给主 Agent。这是最容易理解和调试的拓扑。

链式拓扑(Pipeline):Agent A 的输出是 Agent B 的输入,形成流水线。适合有明确阶段的任务,例如"调研 → 撰写 → 审校"。

网状拓扑(Mesh):Agent 之间可以自由通信。AutoGen 的 GroupChat 模式就是这种——多个 Agent 在一个"聊天室"里讨论,轮流发言。这种拓扑表达力最强,但也最难控制。

适用场景

局限性

2.6 State Machine / Graph-based:显式状态转移

核心思想

前面的模式或多或少都有一个隐含假设:流程的走向由 LLM 动态决定。State Machine 模式则反其道而行——用显式的状态图来定义流程,LLM 在每个状态节点内执行具体任务,但状态之间的转移逻辑是预定义的。

LangGraph 是这个模式的代表性框架。

stateDiagram-v2
    [*] --> 理解意图
    理解意图 --> 搜索信息: 需要搜索
    理解意图 --> 直接回答: 可以直接回答
    搜索信息 --> 整合回答: 搜索完成
    搜索信息 --> 搜索信息: 需要更多信息
    直接回答 --> [*]
    整合回答 --> [*]

伪代码实现

from enum import Enum
from typing import Callable

class State(Enum):
    UNDERSTAND = "understand"
    SEARCH = "search"
    GENERATE_CODE = "generate_code"
    REVIEW = "review"
    RESPOND = "respond"
    END = "end"

@dataclass
class Node:
    state: State
    action: Callable  # 该状态要执行的动作(通常包含 LLM 调用)
    transitions: dict[str, State]  # condition_name → next_state

def state_machine_agent(user_message: str, graph: dict[State, Node]) -> str:
    """State Machine 模式:显式状态转移"""
    current_state = State.UNDERSTAND
    context = {"user_message": user_message, "history": []}

    while current_state != State.END:
        node = graph[current_state]

        # 在当前状态执行动作
        result, condition = node.action(context)
        context["history"].append({
            "state": current_state.value,
            "result": result,
        })

        # 根据条件转移到下一个状态
        next_state = node.transitions.get(condition)
        if next_state is None:
            raise ValueError(f"状态 {current_state} 没有条件 {condition} 的转移")
        current_state = next_state

    return context["history"][-1]["result"]

# 定义状态图
def understand_action(ctx):
    response = llm.chat(messages=[{
        "role": "user",
        "content": f"分析用户意图:{ctx['user_message']}\n输出:need_search / can_answer_directly",
    }])
    intent = parse_intent(response.content)
    return response.content, intent  # (结果, 转移条件)

graph = {
    State.UNDERSTAND: Node(
        state=State.UNDERSTAND,
        action=understand_action,
        transitions={
            "need_search": State.SEARCH,
            "can_answer_directly": State.RESPOND,
        },
    ),
    State.SEARCH: Node(
        state=State.SEARCH,
        action=search_action,
        transitions={"done": State.RESPOND},
    ),
    State.RESPOND: Node(
        state=State.RESPOND,
        action=respond_action,
        transitions={"done": State.END},
    ),
}

关键设计要素

确定性与灵活性的平衡是这个模式的核心张力。状态图越详细,系统行为越可预测,但灵活性越低。反之,状态节点越少、每个节点内的 LLM 自由度越高,系统越灵活但越难控制。

实践中的建议是:把流程层面的确定性交给状态机,把内容层面的灵活性交给 LLM。例如"先搜索再回答"这个流程是确定的,但"搜索什么关键词""如何组织回答"则由 LLM 自由发挥。

适用场景

局限性

2.7 架构模式横向对比

理解了每种模式的原理之后,关键问题是:在实际项目中,该如何选择?我们从四个维度来对比。

对比表

模式 延迟 Token 成本 可靠性 实现复杂度
Tool-Augmented LLM (1-2 轮 LLM 调用) 中 (无纠错机制) 极低
ReAct 中 (3-10 轮) 中高 (可以自我纠错)
Plan-and-Execute (规划 + 执行多轮) 中 (依赖计划质量)
Reflexion 高 (每次迭代翻倍) (显式质量把关)
Multi-Agent 极高 (多 Agent 协作) 极高 中 (协调是薄弱环节)
State Machine 中 (取决于图复杂度) 极高 (行为可预测) 中高

选择决策树

面对一个具体任务,可以按以下顺序思考:

**第一问:任务能在一轮工具调用中完成吗?**如果是,用 Tool-Augmented LLM。不要过度设计。一个查天气的功能不需要 Multi-Agent 架构。

**第二问:任务需要多步操作,但路径大致可预测吗?**如果路径可预测(比如"先查询数据库,再格式化结果,最后发邮件"),用 State Machine。明确的流程用明确的控制。

**第三问:任务需要多步操作,但路径不确定?**这是 ReAct 的主场。大多数通用型 Agent(聊天助手、代码助手)都该从 ReAct 起步。

**第四问:任务很复杂,需要全局规划?**在 ReAct 的基础上加一层 Planner,变成 Plan-and-Execute。但要注意重规划机制,否则一旦计划出错就全盘皆输。

**第五问:输出质量至关重要,可以牺牲速度?**叠加 Reflexion。让 Agent 生成初稿后自我审查并迭代。特别适合代码生成——写完代码跑测试,测试不过就改。

**第六问:任务涉及多个差异很大的领域?**考虑 Multi-Agent。但务必从最简单的星型拓扑开始,不要一上来就搞网状通信。

选择时不要只看"智能程度"

架构模式不是排行榜。更复杂的模式不一定更可靠,也不一定更智能。真正要比较的是"新增复杂度换来了什么控制能力":

你新增的东西 换来的能力 同时引入的成本
循环 可以根据工具结果继续行动 需要步数上限、预算控制、上下文裁剪
Planner 可以先暴露全局计划 计划错误会系统性传导,需要重规划
Critic 可以显式检查质量 评估标准本身可能不可靠,成本线性增长
多 Agent 可以角色分工和并行探索 通信、冲突合并、上下文隔离更难
状态机 可以控制流程和合规路径 需要提前建模状态,开放任务容易僵硬

一个实用判断是:如果你无法说明某个架构层新增了哪一种可观测、可测试、可回滚的控制能力,就先不要加。Agent 系统的复杂度会快速外溢:多一次 LLM 调用意味着更多延迟和更多失败点;多一个 Agent 意味着更多上下文复制和结果合并;多一个状态节点意味着更多转移条件和异常分支。

因此,选型时应该先写下三件事:

  1. 任务的不确定性在哪里:是工具结果不确定、用户意图不确定,还是执行路径不确定?
  2. 失败后如何恢复:重试、重规划、请求用户确认、降级输出,还是直接终止?
  3. 怎么证明它更好:用哪些评估用例比较新旧架构,而不是只看一次成功演示?

模式之间的接口契约

生产系统通常会组合多种模式,组合的关键不是把图画复杂,而是把接口契约写清楚。最小契约至少包含四类对象:

对象 作用 如果缺失会怎样
Task 描述用户目标、约束、输入来源 Planner、Executor、Critic 对任务理解不一致
StepResult 记录每一步状态、输出、错误和副作用 重规划时不知道哪些事实已经改变
Budget 限制步数、token、工具调用和时间 ReAct 或 Reflexion 容易无界循环
TraceEvent 记录决策、工具调用、状态转移 失败后只能猜测原因,无法复盘

比如 Plan-and-Execute 里的 Planner 不能只输出自然语言列表,最好输出结构化步骤:每步的目标、可用工具、前置条件、完成判据和失败处理。Executor 也不能只返回一段文本,应该返回本步是否完成、产生了哪些文件或外部副作用、后续计划是否仍然有效。这样一来,ReAct、Planner、Critic、State Machine 才能安全组合。

这个接口契约还有一个好处:你可以替换其中一个模式而不重写全系统。把单 Agent Executor 换成 Multi-Agent Executor,只要仍然产出同样的 StepResult;把自然语言 Critic 换成单元测试 Critic,只要仍然产出同样的质量判断。架构可演进的前提,就是模式之间不要靠隐式上下文传递所有信息。接口越明确,替换成本越低。

模式组合的实际案例

以 Claude Code 的架构为例,它实际上组合了多种模式:

  1. 主循环是 ReAct:用户输入 → 推理 → 调用工具(读文件、写文件、执行命令)→ 观察结果 → 继续推理
  2. 子任务用 Multi-Agent:遇到独立的子任务时,可以启动 subagent 并行处理
  3. 隐式的 Reflexion:当工具执行失败(比如代码编译报错),Agent 会分析错误信息并修正,这本质上就是一个 Reflexion 循环
  4. 权限控制是 State Machine:某些操作(如写文件、执行命令)需要用户确认,这部分是确定性的状态转移逻辑

这说明真正的生产系统很少只用一种模式。理解每种模式的核心思想,才能在合适的层次选择合适的模式。

本地快照:Claude Code 主仓库里这套组合的代码量

把上面 4 句话对应到本地 ../claude-code-main 仓库,可以看到这些模式不是概念图,而是落在具体文件里。统计命令为 wc -lfind ... -name '*.ts',结果对应当前本地快照:

论断 对应文件
主循环是 ReAct ../claude-code-main/src/query.ts 1729
主循环外的引擎层 ../claude-code-main/src/QueryEngine.ts 1295
子任务用 Multi-Agent——subagent 基础设施 ../claude-code-main/src/tools/AgentTool/*.ts 3804
subagent 执行核心 runAgent.ts 973
subagent 加载(用户定义 + 内置) loadAgentsDir.ts 755
subagent 工具 helpers agentToolUtils.ts 686
subagent prompt 模板 prompt.ts 287
resume / fork / memory snapshot resumeAgent.ts / forkSubagent.ts / agentMemorySnapshot.ts 265 + 210 + 197
Multi-Agent 并行 spawn ../claude-code-main/src/tools/shared/spawnMultiAgent.ts 1093
6 个内置 subagent 定义 ../claude-code-main/src/tools/AgentTool/built-in/*.ts 710

两条物理事实能支撑 §2.7.3 的判断:

  1. Claude Code 的 multi-agent 能力落在具体的内置 subagent 上:exploreAgent 83 行、generalPurposeAgent 34 行、planAgent 92 行、verificationAgent 152 行、claudeCodeGuideAgent 205 行、statuslineSetup 144 行。它们不是抽象口号,而是角色提示词、工具白名单和执行约束的组合。
  2. AgentTool/*.ts 的 3804 行加上 spawnMultiAgent.ts 的 1093 行,合计 4897 行。这些代码处理 subagent 加载、fork、resume、memory snapshot、调度和结果回收,说明 multi-agent 的主要成本并不在"让多个模型说话",而在隔离、协作和失败传播。

这把"Claude Code 组合多种模式"从印象变成可验证陈述。读者如果要复核,不需要相信本书结论,直接在本地仓库运行上面的 wc -l 统计即可。

2.8 从架构到工程

本章梳理的六种模式提供了一张"菜单"。但选好了菜式,还需要厨师的手艺。后续章节将深入每一个工程细节:

架构模式给出了骨架,而接下来的章节将为这个骨架填充血肉。

本章小结

  1. Tool-Augmented LLM 是最简模式,适合单轮工具调用场景,务必从这里开始,不要过度设计
  2. ReAct 是常见的 Agent 模式,通过推理-行动循环实现多步任务,是很多通用 Agent 的默认起点
  3. Plan-and-Execute 在 ReAct 之上增加了全局规划,适合复杂的多阶段任务,但要注意重规划机制
  4. Reflexion 通过自我评估和迭代来提升输出质量,特别适合有明确质量标准的任务(如代码生成)
  5. Multi-Agent 通过角色分工来应对跨领域复杂任务,但通信和协调的工程开销不可低估
  6. State Machine 通过显式状态图来确保行为可预测,适合合规性要求高或流程明确的场景
  7. 真实系统通常是多种模式的组合——在不同层次、不同模块选择最合适的模式