<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>演进路径 on AI博士 万戈</title>
        <link>https://www.yesmiracle.net/tags/%E6%BC%94%E8%BF%9B%E8%B7%AF%E5%BE%84/</link>
        <description>AI博士万戈的技术博客，聚焦 Agentic AI、AI Infra 与 Agent Security，分享 AI 基础设施与工程落地实践。</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-cn</language>
        <managingEditor>admin@yesmiracle.net (万戈)</managingEditor>
        <webMaster>admin@yesmiracle.net (万戈)</webMaster>
        <lastBuildDate>Thu, 06 Aug 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://www.yesmiracle.net/tags/%E6%BC%94%E8%BF%9B%E8%B7%AF%E5%BE%84/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>多Agent 系统架构设计（三）：从单 Agent 到多 Agent，什么情况该拆？</title>
        <link>https://www.yesmiracle.net/post/20260806-multi-agent-evolution-path/</link>
        <pubDate>Thu, 06 Aug 2026 00:00:00 +0000</pubDate>
        <author>admin@yesmiracle.net (万戈)</author>
        <guid>https://www.yesmiracle.net/post/20260806-multi-agent-evolution-path/</guid>
        <description>&lt;img src="https://www.yesmiracle.net/post/20260806-multi-agent-evolution-path/cover.svg" alt="Featured image of post 多Agent 系统架构设计（三）：从单 Agent 到多 Agent，什么情况该拆？" /&gt;&lt;p&gt;如果你正在搭一个 Agent 系统，你一定经历过这个纠结时刻：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;「我的系统，要不要拆成多 Agent？」&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;一边是单 Agent 的简单美好——一个循环、一个上下文、一个入口，调试起来清清楚楚。但上下文窗口就那么大，模型处理能力就那么多，用户需求一复杂，它就开始「忘了之前说过什么」。&lt;/p&gt;
&lt;p&gt;另一边是多 Agent 的灵活强大——各司其职、可以并行、可以专业分工。但一拆开，协调成本飞升、调试变得像大海捞针、状态一致性变成了噩梦。&lt;/p&gt;
&lt;p&gt;这不是一个「选哪个」的问题，而是一个 &lt;strong&gt;「什么时候该拆，拆了以后怎么应对新问题」&lt;/strong&gt; 的问题。&lt;/p&gt;
&lt;p&gt;这篇文章是这个系列的第三篇。前两篇讲了编排模式和通信层，那是「假设你已经决定拆了」。这一篇我们回到原点：&lt;strong&gt;你真的需要拆吗？如果需要，怎么拆？拆了以后，那些新问题怎么应对？&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;决策框架什么时候该拆&#34;&gt;决策框架：什么时候该拆？&lt;/h2&gt;
&lt;p&gt;先给一个简单的判断标准。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;单 Agent 够用的情况：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;条件&lt;/th&gt;
          &lt;th&gt;说明&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;任务线性的&lt;/td&gt;
          &lt;td&gt;一个任务接一个任务，没有并发需求&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;上下文能在窗口内&lt;/td&gt;
          &lt;td&gt;所有信息塞进一个 LLM 上下文窗口就够了&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;不需要专业角色&lt;/td&gt;
          &lt;td&gt;你不需要一个 Agent 专门查数据库、另一个专门做分析&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;权限不复杂&lt;/td&gt;
          &lt;td&gt;所有操作都在同一个安全边界内&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;必须拆成多 Agent 的情况：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;条件&lt;/th&gt;
          &lt;th&gt;说明&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;超出上下文窗口&lt;/td&gt;
          &lt;td&gt;长期对话、多文档处理、需要持续记忆的场景&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;需要并行&lt;/td&gt;
          &lt;td&gt;同时查 5 个数据源、同时分析 3 份报告&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;需要专业分工&lt;/td&gt;
          &lt;td&gt;不同的 Agent 用不同的模型、不同的工具集、不同的 prompt&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;需要隔离权限&lt;/td&gt;
          &lt;td&gt;一个 Agent 只能读数据库，另一个只能写文件系统&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;这个决策框架的关键在于：&lt;strong&gt;不要为了「技术时髦」而拆。&lt;/strong&gt; 我见过太多团队，系统只有 3 个 Agent 就上了 A2A + Kafka + 事件总线，最后花了两周调试通信问题，而单 Agent 加几个工具一天就能搞定同样的事。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心原则&lt;/strong&gt;：从单 Agent 出发，被一个具体问题逼到墙角了，再拆。不要预判性地拆。&lt;/p&gt;
&lt;h2 id=&#34;拆分的三种粒度&#34;&gt;拆分的三种粒度&lt;/h2&gt;
&lt;p&gt;当你确定需要拆了，下一个问题是：&lt;strong&gt;按什么维度拆？&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;按能力域skill-domain&#34;&gt;按能力域（Skill Domain）&lt;/h3&gt;
&lt;p&gt;最常见的方式。每个 Agent 负责一类能力：搜索 Agent 只做搜索、分析 Agent 只做分析、生成 Agent 只做生成。&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-ascii&#34; data-lang=&#34;ascii&#34;&gt;┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│  搜索 Agent  │     │  分析 Agent  │     │  生成 Agent  │
│  工具: 搜索  │     │  工具: 计算  │     │  工具: 写作  │
│  Model: 轻量 │     │  Model: 强  │     │  Model: 创意 │
└─────────────┘     └─────────────┘     └─────────────┘
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：职责清晰，每个 Agent 的 prompt 和工具集可以针对性优化。
&lt;strong&gt;缺点&lt;/strong&gt;：Agent 之间需要频繁传递数据，通信开销大。&lt;/p&gt;
&lt;h3 id=&#34;按数据域data-domain&#34;&gt;按数据域（Data Domain）&lt;/h3&gt;
&lt;p&gt;每个 Agent 负责处理一个数据源或一个数据流。常见于数据管道类系统。&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-ascii&#34; data-lang=&#34;ascii&#34;&gt;┌──────────────┐    ┌──────────────┐    ┌──────────────┐
│ 订单数据Agent │    │ 用户数据Agent │    │ 库存数据Agent │
│  只读订单表   │    │  只读用户表   │    │  只读库存表   │
└──────────────┘    └──────────────┘    └──────────────┘
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：数据隔离性好，每个 Agent 的数据源清晰。
&lt;strong&gt;缺点&lt;/strong&gt;：跨数据源的查询需要多步协调，延迟高。&lt;/p&gt;
&lt;h3 id=&#34;按安全域security-domain&#34;&gt;按安全域（Security Domain）&lt;/h3&gt;
&lt;p&gt;每个 Agent 运行在不同的权限边界内。这是最容易被忽视但最重要的拆分维度。&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;┌──────────────────────────────────────┐
│         公共域 Agent                   │
│  权限: 只读公开数据, 无敏感操作        │
└──────────────────────────────────────┘
          │
          ▼
┌──────────────────────────────────────┐
│         内部域 Agent                   │
│  权限: 读写业务数据, 需认证调用        │
└──────────────────────────────────────┘
          │
          ▼
┌──────────────────────────────────────┐
│         敏感域 Agent                   │
│  权限: 支付/财务/个人数据, 强审计      │
└──────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：安全隔离，一个 Agent 被攻破不会波及全系统。
&lt;strong&gt;缺点&lt;/strong&gt;：跨域通信需要认证和审计，增加了延迟。&lt;/p&gt;
&lt;h3 id=&#34;实际系统中通常是混合拆分&#34;&gt;实际系统中通常是混合拆分&lt;/h3&gt;
&lt;p&gt;一个真实的 Agent 系统不会只用一种粒度。比如一个客服系统：按安全域拆出「公开咨询 Agent」和「账户操作 Agent」；后者内部再按能力域拆出「订单查询 Agent」和「退款处理 Agent」；订单查询 Agent 内部再按数据域拆出「MySQL 查询 Agent」和「Redis 缓存 Agent」。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;拆分粒度没有标准答案，但有指导原则：先按安全域拆（最刚性），再按能力域拆（最灵活），最后按数据域拆（最细化）。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;拆了以后的新问题&#34;&gt;拆了以后的新问题&lt;/h2&gt;
&lt;p&gt;拆完以后，你以为问题解决了？才刚开始。多 Agent 系统引入的新问题，比单 Agent 时代多得多。&lt;/p&gt;
&lt;h3 id=&#34;协调开销token-成本--延迟&#34;&gt;协调开销（Token 成本 + 延迟）&lt;/h3&gt;
&lt;p&gt;这是最直观的代价。单 Agent 时代，一个 LLM 调用完成所有推理。多 Agent 时代，每个 Agent 各调用一次，再加上协调 Agent 的调用，Token 消耗翻倍甚至翻三倍。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实测数据：&lt;/strong&gt; 一个三 Agent 系统（Orchestrator + 2 Workers）完成一个简单任务，总 Token 消耗是单 Agent 的 2.5-3 倍。其中 30-40% 的 Token 消耗在协调本身（任务分解、结果汇总、状态同步），而不是在「干活」上。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;应对策略：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;不要什么任务都走多 Agent&lt;/strong&gt;。简单的「查一下天气」这种问题，单 Agent 直接返回，不需要走完整编排流程。只有复杂任务才走多 Agent 路径。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;用缓存减少重复协调&lt;/strong&gt;。同一个任务类型，协调 Agent 的分解策略可以缓存，不需要每次都重新推理。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;选择轻量协调协议&lt;/strong&gt;。MCP 的请求-响应比 A2A 的任务状态机更轻量，因为后者需要维护任务状态。如果 Agent 之间只需要「你给我一个结果」，用 MCP 就够了。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;调试困难因果链断裂&#34;&gt;调试困难（因果链断裂）&lt;/h3&gt;
&lt;p&gt;单 Agent 时代，debug 就是看一个 LLM 的完整推理日志。「为什么它返回这个结果？」——看完整对话就知道了。&lt;/p&gt;
&lt;p&gt;多 Agent 时代，一个结果经过了 Agent A → Agent B → Agent C，中间还有三个队列、两个超时重试、一个降级策略。你看到最终结果错了，但根本不知道是哪个环节出了问题。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;这就是多 Agent 系统最致命的可观测性问题。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;应对策略：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;每个 Agent 请求都带 Trace ID&lt;/strong&gt;。这是分布式 Tracing 101，但在 Agent 系统里经常被忽略。每个用户请求生成一个 Trace ID，贯穿所有 Agent 调用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;记录每个 Agent 的「输入 + 输出 + 推理过程」&lt;/strong&gt;。不只是日志，而是结构化的追踪数据——Agent 收到了什么、想了什么、做了什么、返回了什么。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;用事件总线做审计日志&lt;/strong&gt;。所有 Agent 之间的通信都写入审计 Topic，出了问题可以回放整个调用链。这比查分散的日志文件高效得多。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;状态一致性问题&#34;&gt;状态一致性问题&lt;/h3&gt;
&lt;p&gt;多个 Agent 共享状态时，一切分布式系统的坑都会出现：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;竞态条件&lt;/strong&gt;：Agent A 和 Agent B 同时更新同一个状态，谁覆盖谁？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;过期读&lt;/strong&gt;：Agent A 读到的状态已经被 Agent B 更新了，但 A 不知道。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;部分失败&lt;/strong&gt;：Agent A 成功了，但 Agent B 失败了，整个任务的状态怎么算？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;应对策略：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;限制共享状态范围&lt;/strong&gt;。不是所有 Agent 都需要访问所有状态。按数据域拆分的好处就在这里——每个 Agent 只处理自己的数据，不需要共享。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;用事件驱动代替状态共享&lt;/strong&gt;。A2A 的 Task 状态机是一种不错的方案——Agent A 把任务交给 Agent B 后，不再关心 Agent B 的内部状态，只关心任务的最终状态（Completed / Failed / Cancelled）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;接受最终一致性&lt;/strong&gt;。大多数 Agent 场景不需要强一致性。一个 Agent 晚了几秒看到最新状态，通常不会导致灾难性后果。不要为了强一致性去引入分布式事务，那会复杂得让你怀疑人生。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;攻击面扩大&#34;&gt;攻击面扩大&lt;/h3&gt;
&lt;p&gt;每个 Agent 都是一个潜在的攻击入口。单 Agent 时代，你只需要保护一个入口。多 Agent 时代，N 个 Agent 就有 N 个入口。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;安全风险清单：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Agent 冒充&lt;/strong&gt;：攻击者伪装成合法 Agent 发送恶意请求&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prompt 注入跨 Agent 传播&lt;/strong&gt;：一个 Agent 被注入后，通过通信把恶意 prompt 传给其他 Agent&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据泄露&lt;/strong&gt;：Agent A 没有权限访问的数据，通过 Agent B 的返回间接泄露&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;拒绝服务&lt;/strong&gt;：一个 Agent 被大量请求压垮，导致依赖它的其他 Agent 也超时&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;应对策略：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;网关层做认证和审计&lt;/strong&gt;（见第二篇关于网关层的讨论）。所有 Agent 之间的通信经过网关，网关验证身份、记录日志、做限流。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;最小权限原则&lt;/strong&gt;。每个 Agent 只拥有完成任务所需的最小权限。不要在 Agent 间共享 API Key。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;通信加密&lt;/strong&gt;。Agent 之间的所有通信使用 mTLS 或类似机制加密。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;输入输出过滤&lt;/strong&gt;。每个 Agent 在接收输入和发送输出时，做基本的 prompt 注入检测。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;对比分析从开源项目中学习&#34;&gt;对比分析：从开源项目中学习&lt;/h2&gt;
&lt;p&gt;前几个月我拆解了好几个开源 Agent 项目，现在回头看，它们各自展示了「单 Agent 到多 Agent」演进过程中的不同解法。&lt;/p&gt;
&lt;h3 id=&#34;pi-agent-的双队列单-agent-内部的并行&#34;&gt;Pi Agent 的双队列：单 Agent 内部的并行&lt;/h3&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.yesmiracle.net/20260719-pi-agent-architecture/&#34; &gt;《Pi Agent 深度拆解》&lt;/a&gt; 中我详细分析了它的 Steering Queue + Follow-up Queue 设计。&lt;/p&gt;
&lt;p&gt;Pi Agent 本质上是&lt;strong&gt;单 Agent 架构&lt;/strong&gt;，但通过双队列在单 Agent 内部实现了类似多 Agent 的并行能力：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Steering Queue&lt;/strong&gt;：处理高优先级任务（用户当前指令）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Follow-up Queue&lt;/strong&gt;：处理低优先级任务（后台分析、上下文补充）&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;           ┌────────────────────────────────┐
           │        Pi Agent (单 Agent)      │
           │                                  │
           │  ┌─────────┐    ┌──────────────┐│
           │  │Steering │    │Follow-up     ││
           │  │ Queue   │    │   Queue      ││
           │  └────┬────┘    └──────┬───────┘│
           │       │                │         │
           │       ▼                ▼         │
           │  ┌──────────────────────────┐   │
           │  │      LLM 推理循环         │   │
           │  └──────────────────────────┘   │
           └────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;这个设计的启示&lt;/strong&gt;：&lt;strong&gt;不是所有「并行」都需要拆成多 Agent。&lt;/strong&gt; 如果你的并行需求只是「不同优先级任务的调度」，单 Agent 内部用队列就能解决，完全不需要引入多 Agent 的协调复杂度。&lt;/p&gt;
&lt;h3 id=&#34;nanobot-的-messagebus轻量级多-agent-编排&#34;&gt;Nanobot 的 MessageBus：轻量级多 Agent 编排&lt;/h3&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.yesmiracle.net/20260719-nanobot-architecture/&#34; &gt;《Nanobot 源码深度拆解》&lt;/a&gt; 展示了一个完全不同的思路——用 Python 异步 MessageBus 做轻量级 Agent 编排。&lt;/p&gt;
&lt;p&gt;Nanobot 的核心是 &lt;code&gt;MessageBus&lt;/code&gt;——一个内存中的事件总线，Agent 通过发布/订阅模式通信：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Nanobot 的简化模型&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;MessageBus&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; __init__(self):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;subscribers &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {}  &lt;span style=&#34;color:#75715e&#34;&gt;# event_type -&amp;gt; [handlers]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;publish&lt;/span&gt;(self, event_type, payload):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; handler &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;subscribers&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;get(event_type, []):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            handler(payload)  &lt;span style=&#34;color:#75715e&#34;&gt;# 异步执行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;subscribe&lt;/span&gt;(self, event_type, handler):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;subscribers&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;setdefault(event_type, [])&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append(handler)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;这个设计的启示&lt;/strong&gt;：&lt;strong&gt;轻量级事件总线可以解决大部分多 Agent 的协调问题，不需要上 Kafka。&lt;/strong&gt; 如果你的 Agent 数量在 10 个以内，且都在同一个进程内，Nanobot 的 MessageBus 模式比 Kafka 简单 100 倍。&lt;/p&gt;
&lt;p&gt;但 MessageBus 的局限也很明显：没有持久化、没有分区、不支持跨进程通信。一旦 Agent 需要跨机器部署，MessageBus 就不够用了。&lt;/p&gt;
&lt;h3 id=&#34;opentag-的双运行时协议驱动的多-agent-架构&#34;&gt;OpenTag 的双运行时：协议驱动的多 Agent 架构&lt;/h3&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.yesmiracle.net/20260728-opentag-copilotkit-slack-agent/&#34; &gt;《CopilotKit 开源了 OpenTag！》&lt;/a&gt; 展示了一种更工程化的多 Agent 架构。&lt;/p&gt;
&lt;p&gt;OpenTag 的核心是&lt;strong&gt;AG-UI 协议 + 双运行时&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CopilotKit Runtime&lt;/strong&gt;：负责聊天 UI、用户交互、会话管理&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agent Runtime&lt;/strong&gt;：负责 Agent 推理、工具调用、任务执行&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;┌──────────────────────────────────────────────────┐
│                  OpenTag 架构                      │
│                                                    │
│  ┌────────────────────┐  ┌──────────────────────┐ │
│  │  CopilotKit Runtime │  │   Agent Runtime      │ │
│  │  (UI + 会话管理)    │  │   (推理 + 工具执行)   │ │
│  │                     │  │                       │ │
│  │  ┌───────────────┐  │  │  ┌───────────────┐   │ │
│  │  │ Slack/Web/Line │  │  │  │ Agent A      │   │ │
│  │  └───────────────┘  │  │  │ Agent B      │   │ │
│  │                     │  │  │ Agent C      │   │ │
│  └──────────┬──────────┘  │  └───────────────┘   │
│             │             └──────────────────────┘
│             │  AG-UI 协议 (JSON-RPC)
│             ▼
│  ┌──────────────────────────────────────────────┐
│  │          可替换的 Agent Runtime                 │
│  │  原生 Agent / OpenAI Assistants / Anthropic   │
│  └──────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;这个设计的启示&lt;/strong&gt;：&lt;strong&gt;协议驱动 + 可替换运行时的模式，是「从单 Agent 到多 Agent」演进中最优雅的中间态。&lt;/strong&gt; 你不需要一开始就决定用多个 Agent 还是一个 Agent——运行时是可替换的。今天用单 Agent 的原生运行时，明天换成多 Agent 的编排运行时，CopilotKit Runtime 完全不需要改。&lt;/p&gt;
&lt;h3 id=&#34;对比总结&#34;&gt;对比总结&lt;/h3&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;维度&lt;/th&gt;
          &lt;th&gt;Pi Agent&lt;/th&gt;
          &lt;th&gt;Nanobot&lt;/th&gt;
          &lt;th&gt;OpenTag&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;架构类型&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;单 Agent + 内部队列&lt;/td&gt;
          &lt;td&gt;轻量多 Agent + 事件总线&lt;/td&gt;
          &lt;td&gt;协议驱动 + 可替换运行时&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;解决的问题&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;单 Agent 内的优先级调度&lt;/td&gt;
          &lt;td&gt;多 Agent 的轻量协调&lt;/td&gt;
          &lt;td&gt;UI 与 Agent 逻辑的解耦&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;引入的复杂度&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;低（队列管理）&lt;/td&gt;
          &lt;td&gt;中（事件路由）&lt;/td&gt;
          &lt;td&gt;中（协议定义）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;适用规模&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;1-2 Agent&lt;/td&gt;
          &lt;td&gt;2-10 Agent&lt;/td&gt;
          &lt;td&gt;1-50 Agent&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;可观测性&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;好（单进程日志）&lt;/td&gt;
          &lt;td&gt;中（事件追踪）&lt;/td&gt;
          &lt;td&gt;好（协议层拦截）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;演进方向&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;可拆为多 Agent&lt;/td&gt;
          &lt;td&gt;可升级到 Kafka&lt;/td&gt;
          &lt;td&gt;可替换运行时实现多 Agent&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;核心差异点&lt;/strong&gt;：Pi Agent 代表「单 Agent 内部优化」的极致，Nanobot 代表「轻量多 Agent」的实用主义，OpenTag 代表「协议驱动」的工程化——在 Agent 之间、在 UI 与 Agent 之间、在运行时与运行时之间，都用协议解耦。对于大多数从单 Agent 起步的团队，OpenTag 的「协议驱动 + 可替换运行时」模式是最值得参考的中间态。&lt;/p&gt;
&lt;h2 id=&#34;演进路线图别一步到位&#34;&gt;演进路线图：别一步到位&lt;/h2&gt;
&lt;p&gt;这是我觉得最重要的部分。&lt;strong&gt;不要试图一步到位。&lt;/strong&gt; 多 Agent 系统的复杂度是逐渐显现的，你的架构也应该是逐渐演进的。&lt;/p&gt;
&lt;h3 id=&#34;阶段-1单-agent--更多工具&#34;&gt;阶段 1：单 Agent + 更多工具&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;状态&lt;/strong&gt;：一个 Agent，通过 MCP 连接 5-10 个工具。
&lt;strong&gt;目标&lt;/strong&gt;：把单 Agent 的能力推到极限。
&lt;strong&gt;关注点&lt;/strong&gt;：工具选择、Prompt 优化、上下文窗口管理。&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;  ┌──────────────┐
  │   单 Agent    │
  │  （一个 LLM） │
  └──────┬───────┘
         │
    ┌────┼────┐
    │    │    │
    ▼    ▼    ▼
  工具1 工具2 工具3
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;什么时候可以进入下一阶段？&lt;/strong&gt; 当你的 Agent 开始频繁「忘记」上下文，或者你发现一个 prompt 里塞了太多角色定义，导致模型在角色间切换时出错。&lt;/p&gt;
&lt;h3 id=&#34;阶段-2单-agent--子-agent局部并行&#34;&gt;阶段 2：单 Agent + 子 Agent（局部并行）&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;状态&lt;/strong&gt;：主 Agent 保持整体协调，局部任务委派给子 Agent。
&lt;strong&gt;目标&lt;/strong&gt;：只拆必须拆的部分，保持整体架构简单。
&lt;strong&gt;关注点&lt;/strong&gt;：子 Agent 的边界定义、结果汇总策略。&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;  ┌──────────────────────────────┐
  │        主 Agent               │
  │  (协调 + 简单任务自己做)       │
  └──────┬──────────────┬────────┘
         │              │
    ┌────▼────┐    ┌────▼────┐
    │ 子Agent 1│    │ 子Agent 2│
    │ (搜索)   │    │ (分析)   │
    └─────────┘    └─────────┘
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;什么时候可以进入下一阶段？&lt;/strong&gt; 当子 Agent 数量超过 5 个，或者子 Agent 之间需要互相通信时，局部并行模式就撑不住了。&lt;/p&gt;
&lt;h3 id=&#34;阶段-3多-agent-编排&#34;&gt;阶段 3：多 Agent 编排&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;状态&lt;/strong&gt;：完整的 Ochestrator-Worker 或 Supervisor 模式。
&lt;strong&gt;目标&lt;/strong&gt;：系统化地管理 Agent 生命周期。
&lt;strong&gt;关注点&lt;/strong&gt;：编排模式选择、通信协议选择、状态管理策略。&lt;/p&gt;
&lt;p&gt;这个阶段就是前两篇文章的内容了。选好编排模式（第一篇）、搭好通信层（第二篇），然后跑起来。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;什么时候可以进入下一阶段？&lt;/strong&gt; 当 Agent 数量超过 20 个，或者需要跨团队共享 Agent 时。&lt;/p&gt;
&lt;h3 id=&#34;阶段-4分层管理&#34;&gt;阶段 4：分层管理&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;状态&lt;/strong&gt;：Supervisor 层级 + 事件总线 + 网关层。
&lt;strong&gt;目标&lt;/strong&gt;：面向大规模、多团队、多环境。
&lt;strong&gt;关注点&lt;/strong&gt;：网关治理、跨域通信、安全策略。&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;  ┌──────────────────────────────────┐
  │        顶层 Supervisor            │
  │   (策略下发 + 全局监控)           │
  └──────┬──────────────────┬───────┘
         │                  │
    ┌────▼────┐        ┌────▼────┐
    │ 域A Supv│        │ 域B Supv│
    │ (搜索)  │        │ (分析)  │
    └────┬────┘        └────┬────┘
         │                  │
    ┌────┼────┐        ┌────┼────┐
    │    │    │        │    │    │
    ▼    ▼    ▼        ▼    ▼    ▼
   W1   W2   W3       W4   W5   W6
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;关键原则&lt;/strong&gt;：&lt;strong&gt;每一个阶段都应该能独立运行，并且能回退到上一阶段。&lt;/strong&gt; 如果你在阶段 3 发现「这个任务其实单 Agent 就够了」，你应该能轻松回退到阶段 2，而不是被自己的架构卡住。&lt;/p&gt;
&lt;h2 id=&#34;实战建议&#34;&gt;实战建议&lt;/h2&gt;
&lt;h3 id=&#34;先跑通再拆&#34;&gt;先跑通再拆&lt;/h3&gt;
&lt;p&gt;这是最务实的建议。先把整个流程用单 Agent 跑通，确认业务逻辑正确、数据流清晰。然后找出瓶颈点——是上下文不够用了？是响应太慢了？是某个工具调用太频繁了？——针对性地拆。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;不要「先拆了再说」&lt;/strong&gt;。拆完发现不是预期的问题，又费劲合并回来，是最大的浪费。&lt;/p&gt;
&lt;h3 id=&#34;用可观测性兜底&#34;&gt;用可观测性兜底&lt;/h3&gt;
&lt;p&gt;不管你处在哪个阶段，&lt;strong&gt;可观测性是最重要的基础设施&lt;/strong&gt;。没有它，你根本不知道拆了以后是变好了还是变坏了。&lt;/p&gt;
&lt;p&gt;需要关注的三件事：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Trace ID&lt;/strong&gt;：贯穿所有 Agent 调用，能追踪一个请求的完整生命周期&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Token 成本追踪&lt;/strong&gt;：每个 Agent 每次调用消耗了多少 Token，是评估「拆了值不值」的关键数据&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agent 调用拓扑&lt;/strong&gt;：谁调用了谁？调用频率如何？失败率如何？——这能帮你发现「这个 Agent 其实不需要」的证据&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;控制拆分的度&#34;&gt;控制拆分的「度」&lt;/h3&gt;
&lt;p&gt;一个经验法则：&lt;strong&gt;一个 Agent 系统里，Agent 数量不应该超过人类团队规模。&lt;/strong&gt; 如果你的系统有 10 个 Agent，但你们团队只有 3 个工程师，你大概率管不过来。&lt;/p&gt;
&lt;p&gt;另一个经验法则：&lt;strong&gt;如果某个 Agent 的职责需要 3 句话以上才能说清楚，它应该被拆成两个。&lt;/strong&gt; Agent 的职责边界模糊，是系统混乱的第一信号。&lt;/p&gt;
&lt;h2 id=&#34;写在最后&#34;&gt;写在最后&lt;/h2&gt;
&lt;p&gt;这篇文章我们讨论了从单 Agent 到多 Agent 的整个演进路径。核心观点其实很简单：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;单 Agent 不是缺陷，多 Agent 不是目标。合适的复杂度才是。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;从单 Agent 出发，被具体问题逼到墙角了再拆。拆的时候，先按安全域拆，再按能力域拆，最后按数据域拆。拆完以后，用可观测性来验证「拆了是否真的更好」。如果 Token 消耗翻倍了但响应质量只提升了 10%，那可能不值得拆。&lt;/p&gt;
&lt;p&gt;这个系列走到第三篇，我们已经覆盖了编排模式、通信层、演进路径三个维度。下一篇是这个系列的收官篇，我们来聊聊&lt;strong&gt;未来的方向&lt;/strong&gt;——Agent 即服务（Agent as a Service）和 Agent Mesh。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;📌 本系列连载：一、&lt;a class=&#34;link&#34; href=&#34;https://www.yesmiracle.net/20260804-multi-agent-orchestration-patterns/&#34; &gt;《编排模式》&lt;/a&gt; → 二、&lt;a class=&#34;link&#34; href=&#34;https://www.yesmiracle.net/20260805-multi-agent-communication-layer/&#34; &gt;《通信层》&lt;/a&gt; → 三、演进路径（本篇）→ 四、Agent 即服务&lt;/p&gt;&lt;/blockquote&gt;
</description>
        </item>
        
    </channel>
</rss>
