好,这一部分是从"会写单个 Agent"到"看懂复杂 Agent 系统"的关键一课。我按"先推理技术(CoT→ToT),再行动范式(ReAct),再架构(多智能体),最后协议(A2A)"的顺序讲,这也是这些概念被发明的历史顺序。最后用一个完整可运行的多智能体项目把所有东西串起来。

第四课:CoT、ToT、ReAct、多智能体与 A2A 详解

0. 先建立全局地图:这五个概念不在同一层

初学者最容易犯的错是把它们当成五个并列的"技术"。实际上它们分属四个不同层次:

┌─────────────────────────────────────────────────┐
│  第4层:协议层      A2A(Agent 之间怎么互相通信)   │
├─────────────────────────────────────────────────┤
│  第3层:架构层      多智能体(怎么组织多个 Agent)  │
├─────────────────────────────────────────────────┤
│  第2层:行动层      ReAct(单个 Agent 怎么边想边做)│
├─────────────────────────────────────────────────┤
│  第1层:推理层      CoT / ToT(模型怎么"想"问题)  │
└─────────────────────────────────────────────────┘

一句话版本:

概念 一句话 提出时间 2026 年现状
CoT 思维链 让模型一步步想,而不是直接给答案 2022 已内化进模型(thinking 模式)
ToT 思维树 同时探索多条思路,评估、回溯、选最优 2023 思想被吸收,原始形式少用
ReAct 想一步 → 做一步 → 看结果 → 再想,循环 2022 就是你写过的 Agent 循环
多智能体 把大任务拆给多个专职 Agent 协作 生产系统主流架构之一
A2A 不同公司/框架的 Agent 互相通信的开放协议 2025 生态早期,理解概念即可

下面逐层展开。


1. CoT(Chain of Thought,思维链)

1.1 它解决什么问题

早期大模型有个怪现象:你问"23 × 17 等于多少?“,它直接吐一个错误答案;但你让它"一步步算”,它就对了。

2022 年 Google 的论文(Wei et al.)把这个现象系统化,叫 Chain-of-Thought Prompting:在给出最终答案前,先生成中间推理步骤,准确率大幅提升。原理直观——模型每生成一个 token 只做"一小步"计算,把复杂问题摊开成多个小步,每步都在模型能力范围内。

1.2 三种经典形式

① Zero-shot CoT —— 加一句魔法咒语:

用户:一个停车场有3排车位,每排15个,现在停了31辆车,还剩几个空位?
请一步步思考。     ← 就这一句,"Let's think step by step"

② Few-shot CoT —— 给带推理过程的例子:

问:小明有5个苹果,吃了2个,又买了3个,现在有几个?
答:开始有5个。吃了2个,剩 5-2=3 个。又买3个,3+3=6 个。答案是6。

问:一个停车场有3排车位...(你的真实问题)
答:

③ Self-Consistency(自洽性) —— 同一个问题采样多次,对多个推理链的答案投票取多数。这是 CoT 到 ToT 之间的过渡形态。

1.3 2026 年的重要更新:你基本不用手写 CoT 了

这是很多旧教程不会告诉你的:CoT 已经被"内化"进模型训练里了。现在的推理模型(Claude 的 thinking 模式、OpenAI 的 o 系列)在内部自动做思维链,而且质量远超你手工 prompt 出来的。

在 Claude 新模型上,正确做法是开自适应思考,而不是在 prompt 里写"请一步步思考":

import anthropic
from dotenv import load_dotenv

load_dotenv()
client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=16000,
    thinking={"type": "adaptive"},        # 模型自己决定要不要想、想多深
    output_config={"effort": "high"},     # 控制思考深度:low/medium/high/max
    messages=[{"role": "user", "content": "一个停车场有3排车位,每排15个,停了31辆车,还剩几个空位?"}],
)

for block in response.content:
    if block.type == "thinking":
        print(f"[内部思考] {block.thinking}")   # 这就是模型内置的 CoT
    elif block.type == "text":
        print(f"[最终回答] {block.text}")

那 CoT 还要不要学?要。 三个原因:

  1. 读懂代码 —— 大量现有 Agent 框架、论文、面试题都建立在 CoT 概念上;
  2. 用在小模型上 —— 本地部署的小模型没有内置思考,手动 CoT 依然有效;
  3. 结构化输出场景 —— 让模型先输出 分析: 再输出 结论: 这种字段设计,本质就是 CoT 思想,能明显提升提取/分类任务的质量。

2. ToT(Tree of Thoughts,思维树)

2.1 CoT 的缺陷引出 ToT

CoT 是一条单行道:一步错,步步错,没有回头路。

2023 年的 Tree of Thoughts 论文(Yao et al.)提出:把推理组织成树搜索——

                问题
              /  |  \
         思路A 思路B 思路C        ← 生成:每步产生多个候选
           |     |     ×
        (8分) (6分) (2分,剪枝)   ← 评估:给每个候选打分
         / \     |
       A1   A2   B1               ← 搜索:沿高分分支继续,可回溯
       ×    ✓

三个核心组件:

  • 生成器(Generator):对当前状态,生成 k 个下一步候选思路
  • 评估器(Evaluator):给每个候选打分(通常也是用 LLM 自己评)
  • 搜索策略:BFS(每层保留 top-b 个)或 DFS(走到底,不行就回溯)

经典战绩:在"24 点游戏"(用 4 个数字凑出 24)上,GPT-4 用 CoT 成功率只有 4%,用 ToT 达到 74%。

2.2 动手实现一个简化版 ToT

下面是一个能跑的"生成 → 评估 → 选优"单层 ToT,这是理解 ToT 的最小内核:

"""简化版 Tree of Thoughts:为一个难题生成多个思路,评估后选最优深入"""
import anthropic
from dotenv import load_dotenv
from pydantic import BaseModel

load_dotenv()
client = anthropic.Anthropic()
MODEL = "claude-opus-4-8"

PROBLEM = "我们的开源项目文档很全但新用户流失率80%,如何在不增加人力的前提下改善新手体验?"


# ---------- 第1步:生成器 —— 产生 3 个截然不同的思路 ----------
class Thoughts(BaseModel):
    approaches: list[str]   # 每个元素是一个完整的解题思路

gen = client.messages.parse(
    model=MODEL,
    max_tokens=16000,
    messages=[{
        "role": "user",
        "content": f"针对这个问题,给出3个【彼此截然不同】的解决思路,每个思路100字左右:\n{PROBLEM}",
    }],
    output_format=Thoughts,
)
approaches = gen.parsed_output.approaches


# ---------- 第2步:评估器 —— 给每个思路打分 ----------
class Score(BaseModel):
    score: int        # 1-10 分
    reason: str       # 一句话理由

scored = []
for i, approach in enumerate(approaches):
    ev = client.messages.parse(
        model=MODEL,
        max_tokens=16000,
        messages=[{
            "role": "user",
            "content": (
                f"问题:{PROBLEM}\n候选思路:{approach}\n"
                "从可行性、成本、预期效果三方面严格评分(1-10),给出一句话理由。"
            ),
        }],
        output_format=Score,
    )
    scored.append((ev.parsed_output.score, approach, ev.parsed_output.reason))
    print(f"思路{i+1}:{ev.parsed_output.score}分 —— {ev.parsed_output.reason}")


# ---------- 第3步:搜索 —— 沿最高分分支深入(这里只展开一层) ----------
best = max(scored, key=lambda x: x[0])
print(f"\n>>> 选中最高分思路({best[0]}分),深入展开:\n")

final = client.messages.create(
    model=MODEL,
    max_tokens=16000,
    thinking={"type": "adaptive"},
    messages=[{
        "role": "user",
        "content": f"问题:{PROBLEM}\n已确定采用思路:{best[1]}\n请展开成一份可落地的具体执行方案。",
    }],
)
print(next(b.text for b in final.content if b.type == "text"))

把"第3步"改成递归(对展开结果再生成 3 个分支、再评估),就是完整的 ToT。

2.3 ToT 的现实定位

诚实地说:原始形态的 ToT 在 2026 年的生产环境里很少见,因为:

  • 成本是 CoT 的 5~20 倍(每个节点都要调一次 API)
  • 推理模型内置的 thinking 已经会在内部"考虑多种可能再否定",吃掉了 ToT 的大部分收益

但 ToT 的思想活在到处:

  • Best-of-N:同一任务并行跑 N 次,挑最好的(代码生成常用)
  • 生成器-评审器分离:一个模型写,另一个模型挑毛病(后面多智能体会用到)
  • Claude Code 的 plan mode:先生成方案、确认、再执行,就是"先展开分支再选择"

记住这个判断:任务有明确的"评估标准"且单次尝试成功率低时,ToT 式的多分支+评估才值得花钱。


3. ReAct(Reasoning + Acting)

3.1 惊喜:你早就实现过 ReAct 了

ReAct 论文(Yao et al., 2022)的核心主张:让模型交替进行推理(Thought)行动(Action),行动产生的**观察(Observation)**反馈给下一轮推理:

Thought:  我需要知道现在几点才能回答
Action:   get_current_time()
Observation: 2026-06-11 15:30:00
Thought:  拿到时间了,还需要算一下数学题
Action:   calculate("365*24*60+999")
Observation: 526599
Thought:  两个信息都有了,可以回答了
Answer:   现在是15:30,计算结果是526599

看着眼熟吗?这就是你在第一课 05_agent_loop.py 里手写的 Agent 循环。 ReAct 不是什么新东西要学,它是你已会的东西的学名。

3.2 历史形态 vs 现代形态(重要,面试常考)

2022 年的原始 ReAct 是在模型没有原生工具调用能力时,用纯 prompt 工程模拟出来的:

# 当年的 ReAct 系统提示词(只需理解,不要照抄去用)
你可以使用以下工具:search[query], calculate[expression]
请严格按以下格式回答:
Thought: 你的思考
Action: 工具名[参数]
Observation: (这里会填入工具结果)
... 重复直到能回答 ...
Final Answer: 最终答案

宿主程序用正则表达式解析 Action: search[天气] 这样的文本,执行后把结果拼回 prompt。缺点显而易见:模型格式稍微写歪一点,正则就解析失败,整个循环崩掉。

2026 年的现代形态,三个组件分别被原生能力替代:

ReAct 组件 2022 实现 2026 实现
Thought prompt 里的 Thought: 文本 thinking 块(adaptive thinking)
Action 正则解析 Action: xxx[yyy] 原生 tool_use 块(结构化 JSON,不会解析失败)
Observation 字符串拼接回 prompt tool_result
循环 手写字符串循环 stop_reason == "tool_use" 判断的 while 循环

所以当你看到 LangGraph 的 create_react_agent、各框架的 “ReAct Agent”,指的都是这个推理↔行动交替循环,内部早就是原生 tool use 了,只是名字留下了历史痕迹。

结论:ReAct 不需要额外学习成本,你写的 05_agent_loop.py 就是现代 ReAct 的标准实现。 需要补充的只有一个工程细节——给循环加安全阀:

MAX_ROUNDS = 10   # 防止模型陷入"调工具→不满意→再调"的死循环烧钱

for round_num in range(MAX_ROUNDS):
    response = client.messages.create(...)
    if response.stop_reason != "tool_use":
        break
    ...
else:
    print("警告:达到最大轮数,强制终止")

4. 多智能体(Multi-Agent Systems)

4.1 为什么一个 Agent 不够用

单 Agent 在任务变复杂时会撞上三堵墙:

  1. 上下文污染 —— 研究任务搜了 20 个网页,上下文塞满了原始资料,模型开始"迷失",忘记最初目标
  2. 角色冲突 —— 同一个系统提示词又要它"大胆发散创意"又要它"严格挑错",两种行为互相干扰
  3. 无法并行 —— 要调研 5 家竞品,单 Agent 只能一家一家串行做

多智能体的本质解法是:每个子 Agent 有独立的上下文窗口、独立的系统提示词、独立的工具集。子 Agent 干完活只把"结论"交回来,过程中的脏数据(20 个网页原文)留在它自己的上下文里,随它一起销毁。

4.2 四种经典拓扑

① Supervisor / Orchestrator-Worker(主管模式)★ 最常用

            ┌──────────────┐
            │  Orchestrator │  ← 理解任务、拆解、分派、汇总
            └───┬───┬───┬──┘
                ↓   ↓   ↓
           研究员  分析师  写手    ← 各自独立上下文,完成后只交结论

适合:大多数场景。Claude Code 的 Agent tool(子代理)就是这个模式。

② Pipeline(流水线)

  研究员 → 写手 → 审稿人 → 排版    ← 固定顺序,上家输出是下家输入

适合:流程固定的业务(内容生产、数据处理)。CrewAI 的 sequential 模式就是它。

③ Debate / Generator-Critic(辩论/生成-评审)

  生成者 ⇄ 评审者   ← 一个写,一个挑毛病,循环 N 轮直到通过

适合:质量要求高的产出(代码评审、法律文书)。注意这里面藏着 ToT 的思想。

④ Swarm / Handoff(移交模式)

  客服Agent --用户问技术问题--> 移交给技术Agent --要退款--> 移交给账务Agent

每个 Agent 可以把"控制权"整体移交给更合适的同伴。OpenAI Agents SDK 的招牌设计。

4.3 关键实现技巧:把子 Agent 包装成"工具"

多智能体听起来玄,实现上有个朴素到惊人的技巧:对 Orchestrator 来说,子 Agent 就是一个工具。调用工具 = 派活,工具返回值 = 子 Agent 的工作成果。这样你完全复用第一课学的 Agent 循环,不需要任何新机制。下面第 6 节的实战项目就用这个技巧。

4.4 泼一盆必要的冷水

行业两年实践下来的真实教训:

  • 大多数"需要多智能体"的场景,其实是单 Agent + 更好的工具/提示词就能解决
  • 多智能体让调试难度翻倍(错误发生在哪个 Agent?哪次交接丢了信息?)、成本翻几倍
  • 子 Agent 之间不共享记忆——A 查到的东西 B 不知道,除非显式传递。交接时信息丢失是多智能体系统的头号 bug 来源

正确的演进路径:单 Agent → 加工具 → 优化提示词 → 实在不行了 → 才上多智能体。


5. A2A(Agent2Agent Protocol)

5.1 它解决什么问题

设想 2027 年:你公司的采购 Agent(用 LangGraph 写的)需要和供应商的报价 Agent(用别的框架写的)谈生意。两个 Agent 属于不同公司、不同框架、互相看不到对方的内部实现——它们怎么对话?

这就是 Google 在 2025 年 4 月发布的 A2A 协议(现已捐给 Linux Foundation 中立管理)要解决的问题。

和 MCP 的关系一句话说清:

MCP:Agent ↔ 工具/数据        (Agent 怎么用锤子)
A2A:Agent ↔ Agent            (两个工匠怎么对话)

两者互补,不竞争。官方说法:Agent 用 MCP 获取能力,用 A2A 互相协作。

5.2 核心概念(四个就够)

① Agent Card(名片) —— 每个 A2A Agent 在固定地址 /.well-known/agent-card.json 挂一张 JSON 名片,声明"我是谁、我会什么、怎么联系我":

{
  "name": "酒店预订 Agent",
  "description": "查询和预订全球酒店",
  "url": "https://hotel-agent.example.com/a2a",
  "capabilities": { "streaming": true, "pushNotifications": true },
  "skills": [
    {
      "id": "search_hotels",
      "name": "搜索酒店",
      "description": "按城市、日期、预算搜索可订酒店"
    }
  ],
  "defaultInputModes": ["text"],
  "defaultOutputModes": ["text"]
}

其他 Agent 抓取这张名片就完成了"发现"——和 MCP 的 list_tools() 异曲同工。

② Task(任务) —— A2A 通信的基本单位。客户端 Agent 向服务端 Agent 提交任务,任务有生命周期:

submitted → working → (input-required?) → completed / failed / canceled
                ↑____________|
          服务端可以中途反问"你预算多少?",等客户端补充

③ Message / Artifact —— 任务过程中的对话是 Message,最终产出物(报告、订单确认)是 Artifact。

④ 传输层 —— JSON-RPC 2.0 over HTTPS,长任务用 SSE 流式推送进度,超长任务(几小时)用 Webhook 推送通知。你在 MCP 那课学的 Streamable HTTP 概念在这里完全复用。

5.3 一次 A2A 交互的完整流程

你的Agent                                  酒店Agent
   │  GET /.well-known/agent-card.json        │
   │ ────────────────────────────────────────>│   ① 发现:读名片
   │ <──────────────── Agent Card ────────────│
   │                                          │
   │  POST message/send                       │
   │  {"message": "订6月20日东京的酒店"}        │   ② 提交任务
   │ ────────────────────────────────────────>│
   │ <──── Task(state: input-required) ───────│   ③ 反问:"预算多少?"
   │                                          │
   │  POST message/send {"预算1000元"}         │   ④ 补充信息
   │ ────────────────────────────────────────>│
   │ <──── SSE: working... working... ────────│   ⑤ 流式进度
   │ <──── Task(state: completed) + Artifact ─│   ⑥ 返回订单确认

Python 有官方 a2a-sdk 包可以搭建 A2A 服务端/客户端,不过——

5.4 现实定位

直说:A2A 目前(2026 年中)生态远不如 MCP 成熟。MCP 已是事实标准、有几千个现成 Server;A2A 还在"大公司站台、实际部署少"的阶段,主要落地在大型企业内部跨部门 Agent 互联。

你现在的正确投入是:深刻理解概念和它与 MCP 的分工(面试和架构讨论必备),动手实践等生态成熟。跨 Agent 协作如果发生在你自己的代码内部,根本不需要 A2A——直接函数调用就行(见下面实战)。A2A 只在跨组织、跨信任边界时才必要。


6. 实战项目:多智能体研究助手(完整可运行)

把本课所有概念缝进一个项目:Supervisor 拓扑 + 子 Agent 即工具 + ReAct 循环 + Generator-Critic(ToT 思想)

任务场景:用户提一个问题 → 协调者派研究员(带搜索工具的 ReAct Agent)调研 → 派评审员(Critic)挑毛病 → 综合产出最终报告。

不需要任何外部 API(搜索是模拟的),配好 .env 就能跑:

"""多智能体研究助手 —— Supervisor + ReAct + Generator-Critic 完整示例

架构:
  用户 → [协调者 Orchestrator]
              │ 把子Agent当工具调用
              ├──> [研究员 Researcher]  独立上下文,自带搜索工具的 ReAct 循环
              └──> [评审员 Critic]      独立上下文,专职挑毛病

运行: python multi_agent_research.py
"""
import json
import anthropic
from dotenv import load_dotenv

load_dotenv()
client = anthropic.Anthropic()
MODEL = "claude-opus-4-8"   # 生产中子Agent常换成 claude-haiku-4-5 省钱,模式不变


# ============================================================
# 底层工具:模拟搜索(实际项目里替换成真实搜索 API)
# ============================================================
FAKE_WEB = {
    "电动车电池": "2026年固态电池量产成本降至$80/kWh,较2024年下降45%。主要厂商:宁德时代、丰田、QuantumScape。",
    "充电桩": "全国充电桩保有量突破1200万台,车桩比2.4:1,高速服务区覆盖率98%。",
    "销量": "2026年Q1中国新能源车渗透率达58%,纯电占比72%,插混28%。",
}

def web_search(query: str) -> str:
    for keyword, result in FAKE_WEB.items():
        if keyword in query:
            return result
    return f"关于'{query}'未找到相关结果,请换个关键词。"

SEARCH_TOOL = [{
    "name": "web_search",
    "description": "搜索互联网获取最新信息。查询应使用简短的中文关键词。",
    "input_schema": {
        "type": "object",
        "properties": {"query": {"type": "string", "description": "搜索关键词"}},
        "required": ["query"],
    },
}]


# ============================================================
# 通用子 Agent 运行器:每次调用 = 全新独立上下文 + 自己的 ReAct 循环
# ============================================================
def run_subagent(name: str, system: str, task: str, tools=None, max_rounds=8) -> str:
    print(f"\n  ┌── 子Agent [{name}] 启动,任务:{task[:40]}...")
    messages = [{"role": "user", "content": task}]
    kwargs = {"tools": tools} if tools else {}

    for _ in range(max_rounds):                      # 安全阀:限制最大轮数
        response = client.messages.create(
            model=MODEL,
            max_tokens=16000,
            thinking={"type": "adaptive"},           # Thought(现代CoT)
            system=system,
            messages=messages,
            **kwargs,
        )
        if response.stop_reason != "tool_use":       # 不再要工具 → 任务完成
            result = next((b.text for b in response.content if b.type == "text"), "")
            print(f"  └── 子Agent [{name}] 完成,返回 {len(result)} 字")
            return result

        messages.append({"role": "assistant", "content": response.content})
        tool_results = []
        for block in response.content:
            if block.type == "tool_use":             # Action
                print(f"  │   [{name}] 调用 {block.name}({json.dumps(block.input, ensure_ascii=False)})")
                output = web_search(**block.input)   # Observation
                tool_results.append({
                    "type": "tool_result",
                    "tool_use_id": block.id,
                    "content": output,
                })
        messages.append({"role": "user", "content": tool_results})

    return f"[{name}] 达到最大轮数限制,任务未完全完成"


# ============================================================
# 两个专职子 Agent(角色 = 系统提示词 + 工具集的组合)
# ============================================================
def researcher(task: str) -> str:
    return run_subagent(
        name="研究员",
        system="你是严谨的行业研究员。必须用 web_search 工具查证数据,不允许编造数字。"
               "对任务中每个要点至少搜索一次,最后输出带数据来源的调研纪要。",
        task=task,
        tools=SEARCH_TOOL,
    )

def critic(draft: str) -> str:
    return run_subagent(
        name="评审员",
        system="你是苛刻的评审员,专门挑报告的毛病:数据缺失、逻辑跳跃、结论草率。"
               "输出一份不超过5条的具体修改意见清单。不要客套,直接说问题。",
        task=f"请评审以下调研纪要:\n\n{draft}",
        tools=None,                                  # 评审员不需要工具
    )


# ============================================================
# 协调者:把子 Agent 包装成"工具",自己也跑一个 ReAct 循环
# ============================================================
ORCHESTRATOR_TOOLS = [
    {
        "name": "assign_research",
        "description": "把调研任务派给研究员子Agent,它会搜索资料并返回带数据的调研纪要。",
        "input_schema": {
            "type": "object",
            "properties": {"task": {"type": "string", "description": "具体的调研任务描述"}},
            "required": ["task"],
        },
    },
    {
        "name": "request_review",
        "description": "把草稿交给评审员子Agent,返回修改意见。重要报告应在定稿前评审一次。",
        "input_schema": {
            "type": "object",
            "properties": {"draft": {"type": "string", "description": "待评审的完整草稿"}},
            "required": ["draft"],
        },
    },
]

def dispatch(tool_name: str, tool_input: dict) -> str:
    if tool_name == "assign_research":
        return researcher(tool_input["task"])
    if tool_name == "request_review":
        return critic(tool_input["draft"])
    return f"未知工具: {tool_name}"


def run_orchestrator(user_request: str) -> str:
    print(f"[用户] {user_request}")
    messages = [{"role": "user", "content": user_request}]

    for _ in range(10):
        response = client.messages.create(
            model=MODEL,
            max_tokens=16000,
            thinking={"type": "adaptive"},
            system="你是研究项目协调者。工作流程:"
                   "1) 把用户问题拆成调研任务,用 assign_research 派给研究员;"
                   "2) 拿到调研纪要后整理成报告草稿,用 request_review 请评审员把关;"
                   "3) 根据评审意见修改,输出最终报告。"
                   "你自己不做调研、不编数据,只负责拆解、整合、定稿。",
            tools=ORCHESTRATOR_TOOLS,
            messages=messages,
        )
        if response.stop_reason != "tool_use":
            return next((b.text for b in response.content if b.type == "text"), "")

        messages.append({"role": "assistant", "content": response.content})
        tool_results = []
        for block in response.content:
            if block.type == "tool_use":
                result = dispatch(block.name, block.input)
                tool_results.append({
                    "type": "tool_result",
                    "tool_use_id": block.id,
                    "content": result,
                })
        messages.append({"role": "user", "content": tool_results})

    return "协调者达到最大轮数限制"


if __name__ == "__main__":
    report = run_orchestrator("帮我写一份2026年中国电动车市场简报,覆盖电池技术、充电设施、销量三方面。")
    print("\n" + "=" * 50 + "\n【最终报告】\n" + report)

跑起来后注意观察这几件事

  1. 上下文隔离:研究员搜索产生的所有中间内容,协调者完全看不到——它只收到最终纪要。这就是多智能体省上下文的核心机制。
  2. ReAct 嵌套:协调者在跑 ReAct 循环(派活→看结果→再派),研究员内部也在跑自己的 ReAct 循环(搜索→看结果→再搜)。Agent 套 Agent,每层都是同一个模式。
  3. Critic 环节就是 ToT 思想:生成 → 评估 → 修改,只是把"评估"独立成了一个专职 Agent。
  4. 没有任何协议开销:子 Agent 之间通过普通函数调用通信,因为它们在同一个进程里。只有当研究员部署在另一家公司的服务器上时,dispatch() 函数里的本地调用才需要换成 A2A 的 HTTP 请求——架构不变,只换通信方式。这是理解 A2A 定位的最佳视角。

练习题(按难度递增)

  1. 给协调者加第三个子 Agent"翻译官",把最终报告翻成英文
  2. 把研究员的三个调研方向改成并行执行(提示:协调者一次返回多个 tool_use 块时,你可以并发处理)
  3. 给 Critic 加"评分"输出(用第一课的结构化输出),低于 7 分自动退回重写,最多循环 2 轮——这就实现了一个完整的质量闭环

7. 总结:一张表收尾

概念 本质 你该掌握到什么程度
CoT 把推理摊开成步骤 理解原理;知道新模型用 thinking: adaptive 替代手写 CoT
ToT 推理变树搜索:生成→评估→回溯 能手写"生成N个方案→评估→选优";知道生产中常退化为 Best-of-N 和 Critic 模式
ReAct 想↔做交替循环 精通——它就是你的 05_agent_loop.py;能讲清 prompt 解析(旧)vs 原生 tool use(新)的演进
多智能体 多个独立上下文的 Agent 分工协作 精通 Supervisor 模式和"子Agent即工具"技巧;能说出何时不该用多智能体
A2A 跨组织 Agent 互通的开放协议 理解 Agent Card / Task 生命周期、与 MCP 的分工;动手可以等生态成熟

这一课和之前三课的关系:第一课给了你原子能力(API + 循环),第二课给了你工具标准(MCP),第三课给了你框架视野,这一课给了你架构词汇和组织模式。下一步如果想继续深入,优先级最高的是上一条消息里说的评估(Evals)——多智能体系统不接评估,你永远不知道加了 Critic 之后到底是变好了还是白烧钱。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐