Skip to content

并行 / 群体 / 网络化架构

与 supervisor 对比:没有中央决策者。智能体读取共享事件总线,异步领取工作,再把结果写回。LangGraph 明确支持适用于去中心化、动态环境的“Swarm Architecture”。Matrix(arXiv:2511.21686)将控制流和数据流都表示为通过分布式队列传递的序列化消息,从而消除编排器瓶颈。这里的权衡非常明确:用确定性和可追踪性换取可扩展性。群体适合包含大量独立子问题的任务;不适合需要单一一致计划的任务。

Type: 学习 + 构建 Languages: Python(stdlib、threadingqueuePrerequisites: 第 16 阶段 · 05(Supervisor Pattern),第 16 阶段 · 04(Primitive Model) Time: ~75 分钟

问题

Supervisor 可以扩展到少量 worker。那几百个呢?Supervisor 本身会变成瓶颈:关于谁做什么的每一个决策都要经过这一个智能体。某个缓慢的计划步骤就会拖住整个系统。

群体架构 (swarm architecture) 则把设计反过来。不是由中央规划器分发工作,而是由 worker 从共享队列中自行领取工作。“协调”被直接编码进事件总线语义中。没有编排器;系统能扩展到什么程度,取决于队列本身能扩展到什么程度。

概念

结构形态

                ┌──── 共享队列 ────┐
                │                  │
       ┌────────┼────────┐  ◄────┬───┘
       ▼        ▼        ▼       │
     工作者    工作者    工作者  工作者
      A         B         C       D
       │        │        │       │
       └────────┴────────┴───────┘


               结果池

没有编排器。每个 worker 都重复同样流程:拉取一个任务、处理它、写回结果(并可选择将后续任务重新入队)。

群体适用的场景

  • 大量独立任务。 抓取、转换、分类。任务彼此不依赖。
  • 时长差异很大的工作。 如果有些任务耗时 100ms,而另一些耗时 10s,群体会自动平衡负载——快的 worker 会继续领取下一个任务。Supervisor 则必须提前预估时长。
  • 吞吐量优先于确定性。 你关心的是总体完成时间,而不是严格顺序。

群体失效的场景

  • 有序工作流。 如果第 3 步需要第 2 步的输出,群体就有可能在第 2 步完成前触发第 3 步。
  • 全局规划型任务。 复杂研究问题更适合规划器。一个由研究员组成的群体会产出相互独立的事实,而不是一份连贯报告。
  • 调试。 没有中央日志且工作异步执行时,复现 bug 的成本很高。

Matrix(arXiv:2511.21686)

Matrix 是 2025 年的一篇论文,它把群体推到了自然终点:控制流和数据流都作为分布式队列上的序列化消息来处理。没有中央协调器。容错能力来自消息持久化。可扩展性成为消息代理的问题,而不是系统本身的问题。

它的贡献在于一种编程模型:多智能体协调不再是“supervisor 下一步该选哪个智能体?”,而是“这个智能体订阅了哪个消息主题?”。这让系统看起来像一个发布/订阅(pub/sub)事件网格。

LangGraph 的 Swarm Architecture

LangGraph 2025 文档明确把 “Swarm Architecture” 描述为一种多智能体模式:智能体是节点,但边组成的是一个带环的有向图,而且池中的任意节点都可以被激活。worker 根据条件从可用工作中领取任务,而不是由 supervisor 指派。

失败模式:饥饿与热点集中

如果所有 worker 都去领取当前最容易拿到的任务,那么长时间运行的任务就永远不会被领取,直到它们成为队列里仅剩的任务。这就是经典的队列饥饿 (starvation)。

缓解方式:

  • 采用带显式老化机制的优先队列(等待时间越长,优先级越高)。
  • 工作者专业化:部分 worker 只接“长任务”。
  • 背压 (back-pressure):限制有多少快速任务可以进入队列。

与基于内容路由的联系

群体天然适合与基于内容的路由(第 22 课)配合使用。与其使用一个通用队列,不如为每种消息类型准备一个队列。专家型 worker 只订阅自己负责的类型。这正是能够扩展到数千个智能体的消息总线架构基础。

动手构建

code/main.py 实现了一个由 4 个 worker 线程组成的群体,它们从共享 queue.Queue 中领取任务。任务具有可变时长(有些快,有些慢)。该示例对比了:

  • 顺序基线: 一个 worker 串行处理所有任务。
  • 固定分配: 每个任务预先分配给特定 worker(supervisor 风格)。
  • 群体: worker 从共享队列中领取任务。

群体会自动平衡负载;而固定分配会让快速 worker 在自己分到的任务较慢时空闲下来。

运行:

python3 code/main.py

输出会显示每个 worker 处理的任务数量(群体的分配并不均匀,但却是最优的)以及整体墙钟时间。

使用它

outputs/skill-swarm-fit.md 用于评估一个任务应该使用群体还是 supervisor。输入包括:任务独立性、时长方差、顺序要求和可调试性需求。

交付它

检查清单:

  • 带老化机制的优先队列。 防止长任务发生饥饿。
  • 幂等 worker。 如果 worker 在运行中途崩溃,一个任务可能会被领取不止一次。worker 必须是幂等的。
  • 持久队列。 生产环境应使用 Kafka、Redis Streams 或数据库支撑的队列。queue.Queue 只存在于内存中。
  • 按任务维度的可观测性。 每个任务都要有 trace ID;每个 worker 都要用该 ID 记录开始/结束日志。
  • 背压。 如果队列增长速度快于 worker 清空它的速度,就要让生产者放慢速度。

练习

  1. 运行 code/main.py。在这种可变时长负载下,群体比顺序执行快多少?比固定分配快多少?
  2. 添加一个优先队列变体(使用 queue.PriorityQueue)。根据任务的“importance”字段分配优先级。观察在持续负载下,低优先级任务是否会一直饥饿。
  3. 实现一个热点检测器:当某个 worker 处理的任务数达到最慢 worker 的 3× 时进行记录。这说明任务时长分布有什么特征?
  4. 阅读 Matrix 论文(arXiv:2511.21686)的摘要和第 3 节。指出 Matrix 接受的一项具体权衡(可扩展性收益)以及它放弃的一项能力(可追踪性、确定性)。
  5. 将群体示例改为使用一个由 (task_type, payload) 元组构成的 queue.Queue,并让 worker 只订阅特定类型。任务具有异质性时,什么样的路由规则才合理?

关键术语

术语人们怎么说实际含义
群体架构“去中心化智能体”worker 从共享队列中领取任务;没有中央编排器。
事件总线“智能体订阅主题”按类型或内容把任务路由给 worker 的消息代理。
饥饿“任务永远不运行”低优先级任务因为高优先级工作持续到来而始终无法被领取。
热点集中“某个 worker 被淹没”一种负载不均衡现象:某个 worker 获得了大多数任务。
背压“让生产者慢下来”当队列被填满时,向上游发出停止生产信号的机制。
幂等 worker“可安全重跑”一个任务被处理两次也会产生相同结果。之所以需要这样,是因为 worker 可能在运行中途崩溃。
持久队列“崩溃后也能保留”由磁盘或复制存储支撑的队列;worker 崩溃时任务不会丢失。
Matrix 框架“完全基于消息传递的群体”数据流和控制流都表现为分布式队列上的序列化消息。

延伸阅读