代理群 #
本文档中引用的文件
目录 #
简介 #
Swarm 是一种去中心化的多代理协作模式,灵感来源于 OpenAI 的 Swarm 框架。与传统的 Supervisor 中央调度模式不同,Swarm 允许代理之间直接进行控制权转移,模拟真实专家团队的协作方式——根据各自的专业能力来回传递任务。
在 Swarm 模式中,代理通过特殊的 Handoff 工具实现代理间的直接控制权转移,而 Router 函数则根据状态中的 ‘next’ 字段进行动态路由决策。这种设计使得代理群能够灵活地处理复杂的协作场景,无需中央协调器的介入。
项目结构 #
Swarm 实现位于 examples/swarm 目录下,包含以下关键文件:
graph TD
A["examples/swarm/"] --> B["main.go<br/>主要实现"]
A --> C["README.md<br/>英文文档"]
A --> D["README_CN.md<br/>中文文档"]
E["graph/"] --> F["state_graph.go<br/>状态图实现"]
E --> G["schema.go<br/>状态模式定义"]
H["prebuilt/"] --> I["supervisor.go<br/>监督者模式"]
J["examples/supervisor/"] --> K["main.go<br/>监督者示例"]
图表来源
- [examples/swarm/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/swarm/main.go#L1-L244)
- [graph/state_graph.go](https://github.com/smallnest/langgraphgo/blob/main/graph/state_graph.go#L1-L200)
- [prebuilt/supervisor.go](https://github.com/smallnest/langgraphgo/blob/main/prebuilt/supervisor.go#L1-L153)
章节来源
- [examples/swarm/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/swarm/main.go#L1-L244)
- [examples/swarm/README.md](https://github.com/smallnest/langgraphgo/blob/main/examples/swarm/README.md#L1-L78)
核心组件 #
Swarm 模式的核心组件包括:
AgentState 结构体 #
定义了代理的状态结构,包含消息历史和下一个执行的代理标识:
classDiagram
class AgentState {
+[]MessageContent Messages
+string Next
}
class HandoffTool {
+string Type
+FunctionDefinition Function
}
class StateGraph {
+map~string,Node~ nodes
+[]Edge edges
+map~string,func~ conditionalEdges
+string entryPoint
+StateSchema Schema
}
AgentState --> StateGraph : "使用"
HandoffTool --> StateGraph : "提供给"
图表来源
- [examples/swarm/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/swarm/main.go#L15-L19)
- [examples/swarm/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/swarm/main.go#L21-L38)
HandoffTool 工具 #
实现了代理间控制权转移的特殊工具,具有预定义的参数结构:
- 名称:
handoff - 描述: 将控制权移交给另一个代理
- 参数: 必需的
to字段,可选值为"Researcher"或"Writer"
章节来源
- [examples/swarm/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/swarm/main.go#L15-L38)
架构概览 #
Swarm 模式的整体架构采用去中心化设计理念:
graph TB
subgraph "Swarm 架构"
A["用户输入"] --> B["Researcher"]
B --> C["Handoff 检测"]
C --> D{"是否需要移交?"}
D --> |是| E["设置 Next 字段"]
D --> |否| F["正常响应"]
E --> G["Router 函数"]
F --> G
G --> H{"Next 字段"}
H --> |"Writer"| I["Writer"]
H --> |"END"| J["结束"]
I --> K["Handoff 检测"]
K --> L{"是否完成?"}
L --> |是| M["设置 Next='END'"]
L --> |否| N["正常响应"]
M --> G
N --> G
end
图表来源
- [examples/swarm/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/swarm/main.go#L66-L190)
- [examples/swarm/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/swarm/main.go#L192-L200)
详细组件分析 #
研究员 (Researcher) 组件 #
研究员是负责信息检索和研究的代理节点:
sequenceDiagram
participant U as 用户
participant R as 研究员
participant M as 模型
participant W as 写作器
U->>R : 发送请求
R->>M : 处理消息并添加系统提示
M-->>R : 返回响应或工具调用
alt 需要写作
R->>R : 解析 handoff 工具调用
R->>R : 更新状态中的 Next 字段
R->>W : 移交控制权
else 继续研究
R->>R : 正常响应
R->>U : 返回结果
end
图表来源
- [examples/swarm/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/swarm/main.go#L67-L132)
写作器 (Writer) 组件 #
写作器负责基于收集的信息撰写报告:
flowchart TD
A["接收移交"] --> B["检查消息历史"]
B --> C["应用系统提示"]
C --> D["调用模型"]
D --> E{"是否有工具调用?"}
E --> |是| F["解析 handoff 工具"]
F --> G["更新状态 Next 字段"]
G --> H["返回工具调用和消息"]
E --> |否| I["生成普通响应"]
I --> J["设置 Next='END'"]
H --> K["等待 Router 路由"]
J --> K
图表来源
- [examples/swarm/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/swarm/main.go#L135-L189)
章节来源
- [examples/swarm/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/swarm/main.go#L67-L189)
Handoff 移交机制 #
Handoff 机制是 Swarm 模式的核心创新,它允许代理之间直接进行控制权转移:
移交工具的实现 #
Handoff 工具的设计遵循以下原则:
- 类型安全: 使用预定义的参数结构确保类型安全
- 枚举验证: 限制目标代理只能是预定义的选项
- JSON 序列化: 支持工具参数的 JSON 序列化和反序列化
移交流程详解 #
sequenceDiagram
participant A as 当前代理
participant S as 状态管理
participant R as Router
participant N as 下一代理
A->>A : 分析当前状态
A->>A : 判断是否需要移交
alt 需要移交
A->>A : 创建工具调用
A->>A : 解析参数 (to : 目标代理)
A->>S : 更新状态
Note over S : 设置 Next 字段为目标代理
A->>N : 返回工具调用和消息
N->>R : 接收状态
R->>R : 检查 Next 字段
R->>N : 路由到目标代理
else 不需要移交
A->>A : 生成正常响应
A->>S : 更新状态
Note over S : 设置 Next='END'
A->>A : 结束执行
end
图表来源
- [examples/swarm/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/swarm/main.go#L83-L118)
- [examples/swarm/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/swarm/main.go#L151-L177)
移交状态更新 #
移交操作涉及两个关键状态更新:
- 消息历史: 记录工具调用和响应
- 路由指示: 更新
next字段为目标代理
章节来源
- [examples/swarm/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/swarm/main.go#L83-L118)
- [examples/swarm/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/swarm/main.go#L151-L177)
Router 动态路由 #
Router 函数是 Swarm 模式中负责动态路由的核心组件:
路由逻辑实现 #
flowchart TD
A["Router 函数调用"] --> B["提取状态中的 Next 字段"]
B --> C{"Next 字段检查"}
C --> |"END" 或空| D["返回 graph.END"]
C --> |有效代理名| E["返回代理名称"]
D --> F["结束执行"]
E --> G["路由到指定代理"]
style D fill:#ffcccc
style E fill:#ccffcc
图表来源
- [examples/swarm/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/swarm/main.go#L192-L200)
条件边机制 #
Swarm 使用条件边来实现动态路由:
graph LR
A["Researcher"] --> B["Router"]
C["Writer"] --> B
B --> D["Conditional Edge"]
D --> E["Next Agent"]
subgraph "路由决策"
F["检查 Next 字段"]
F --> G{"字段值"}
G --> |"Researcher"| H["路由到 Researcher"]
G --> |"Writer"| I["路由到 Writer"]
G --> |"END"| J["结束"]
end
图表来源
- [examples/swarm/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/swarm/main.go#L202-L203)
- [graph/state_graph.go](https://github.com/smallnest/langgraphgo/blob/main/graph/state_graph.go#L240-L268)
路由函数的具体实现 #
路由函数的逻辑非常简洁但功能强大:
- 状态解析: 从传入的状态中提取
next字段 - 有效性检查: 验证字段值的有效性
- 默认处理: 对于无效或空值返回
END - 代理路由: 返回有效的代理名称作为下一节点
章节来源
- [examples/swarm/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/swarm/main.go#L192-L200)
- [graph/state_graph.go](https://github.com/smallnest/langgraphgo/blob/main/graph/state_graph.go#L240-L268)
共享状态管理 #
Swarm 模式中的共享状态是实现代理协作的关键基础设施:
状态结构设计 #
classDiagram
class SharedState {
+[]MessageContent messages
+string next
}
class MessageContent {
+ChatMessageType Role
+[]ContentPart Parts
}
class ContentPart {
<<interface>>
}
class TextContent {
+string Text
}
class ToolCall {
+string ID
+FunctionCall FunctionCall
}
class ToolCallResponse {
+string ToolCallID
+string Name
+string Content
}
SharedState --> MessageContent : "包含"
MessageContent --> ContentPart : "包含"
ContentPart <|-- TextContent
ContentPart <|-- ToolCall
ContentPart <|-- ToolCallResponse
图表来源
- [examples/swarm/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/swarm/main.go#L15-L19)
- [graph/schema.go](https://github.com/smallnest/langgraphgo/blob/main/graph/schema.go#L62-L99)
消息历史管理 #
共享状态中的消息历史通过 AppendReducer 进行管理:
- 累积机制: 新的消息自动追加到现有消息列表
- 类型安全: 确保消息内容的一致性和完整性
- 历史可见性: 后续代理可以访问完整的交互历史
状态 Schema 定义 #
graph TD
A["MapSchema"] --> B["注册 Reducer"]
B --> C["messages: AppendReducer"]
A --> D["设置 Schema"]
D --> E["StateGraph"]
F["状态更新流程"] --> G["检查现有值"]
G --> H["应用 Reducer"]
H --> I["合并新值"]
I --> J["返回更新后状态"]
图表来源
- [examples/swarm/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/swarm/main.go#L61-L65)
- [graph/schema.go](https://github.com/smallnest/langgraphgo/blob/main/graph/schema.go#L44-L47)
章节来源
- [examples/swarm/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/swarm/main.go#L61-L65)
- [graph/schema.go](https://github.com/smallnest/langgraphgo/blob/main/graph/schema.go#L62-L99)
与 Supervisor 模式的对比 #
Swarm 模式与传统的 Supervisor 模式在架构设计上存在根本差异:
架构对比 #
| 特性 | Swarm 模式 | Supervisor 模式 |
|---|---|---|
| 控制结构 | 去中心化,代理间直接协作 | 中心化,通过监督者协调 |
| 路由机制 | 基于状态的动态路由 | 基于工具调用的静态路由 |
| 状态共享 | 所有代理共享同一状态 | 状态独立,通过监督者协调 |
| 灵活性 | 高度灵活,支持复杂协作模式 | 结构固定,适合简单流水线 |
| 复杂度 | 较高,需要精心设计状态 | 较低,框架提供标准化接口 |
协作模式差异 #
graph TB
subgraph "Swarm 模式"
A1["Researcher"] --> B1["Handoff 工具"]
B1 --> C1["Writer"]
C1 --> D1["Handoff 工具"]
D1 --> A1
A1 -.-> E1["共享状态"]
C1 -.-> E1
end
subgraph "Supervisor 模式"
A2["Supervisor"] --> B2["Route 工具"]
B2 --> C2["Worker A"]
B2 --> D2["Worker B"]
C2 --> A2
D2 --> A2
A2 -.-> E2["共享状态"]
C2 -.-> E2
D2 -.-> E2
end
图表来源
- [examples/swarm/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/swarm/main.go#L192-L200)
- [prebuilt/supervisor.go](https://github.com/smallnest/langgraphgo/blob/main/prebuilt/supervisor.go#L130-L150)
优势对比 #
Swarm 模式的优势: #
- 真实模拟: 更接近真实专家团队的协作方式
- 灵活性: 支持复杂的双向协作模式
- 去中心化: 无需中央协调器,减少单点故障
- 动态适应: 能够根据上下文动态调整协作策略
Supervisor 模式的适用场景: #
- 简单流水线: 适用于线性、可预测的工作流程
- 标准化任务: 适合需要严格控制的任务分配
- 监控友好: 中央控制便于监控和审计
章节来源
- [examples/swarm/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/swarm/main.go#L1-L244)
- [prebuilt/supervisor.go](https://github.com/smallnest/langgraphgo/blob/main/prebuilt/supervisor.go#L1-L153)
性能考虑 #
Swarm 模式在性能方面具有以下特点:
并发执行优势 #
- 并行处理: 多个代理可以同时处理不同的任务分支
- 状态隔离: 每个代理维护自己的状态副本,避免锁竞争
- 快速切换: 通过状态标记实现快速的代理间切换
内存管理 #
- 增量更新: 只更新必要的状态部分,减少内存占用
- 垃圾回收: 及时清理不再需要的状态数据
- 缓存策略: 合理利用缓存提高重复查询的效率
扩展性设计 #
- 水平扩展: 新增代理只需添加节点和条件边
- 插件化: 支持动态添加新的协作模式
- 配置驱动: 通过配置文件轻松调整协作策略
故障排除指南 #
常见问题及解决方案 #
1. 移交失败 #
症状: 代理无法正确移交控制权 原因:
next字段设置错误- 目标代理不存在
- 状态更新不完整
解决方案:
- 检查
next字段的值是否正确 - 验证目标代理已正确定义
- 确保状态更新包含所有必要字段
2. 路由循环 #
症状: 系统陷入无限循环 原因:
- 代理间相互移交导致循环
- 路由条件设计不当
解决方案:
- 添加循环检测机制
- 设计明确的终止条件
- 使用有限状态机模式
3. 状态不一致 #
症状: 代理看到不一致的消息历史 原因:
- 并发更新冲突
- 状态同步延迟
解决方案:
- 实现状态版本控制
- 使用乐观锁机制
- 增加状态验证步骤
章节来源
- [examples/swarm/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/swarm/main.go#L192-L200)
- [graph/state_graph.go](https://github.com/smallnest/langgraphgo/blob/main/graph/state_graph.go#L240-L268)
结论 #
Swarm 去中心化协作模式代表了多代理系统设计的重要创新。通过 Handoff 机制实现的代理间直接控制权转移,以及 Router 函数基于状态的动态路由决策,使得 Swarm 能够模拟真实专家团队的灵活协作方式。
与传统的 Supervisor 模式相比,Swarm 提供了更高的灵活性和更真实的协作体验,特别适合需要复杂交互和动态调整的场景。共享状态机制确保了代理间的信息同步,而去中心化的架构设计减少了系统复杂性和单点故障风险。
这种模式在实际应用中展现了强大的潜力,特别是在需要多个专业领域协作的复杂任务处理场景中。随着多代理系统的不断发展,Swarm 模式有望成为构建智能协作系统的重要基础架构。