546 lines
14 KiB
Markdown
546 lines
14 KiB
Markdown
# A2N 协议(Agent-to-N Protocol)
|
||
|
||
> 版本:1.0.0
|
||
> 状态:草案
|
||
> 类型:实现规范
|
||
> 基于:[灵隙原始协议(Synapse Raw Protocol) v1.0.0](./01-synapse-raw-protocol.md)
|
||
|
||
---
|
||
|
||
## 1. 概述
|
||
|
||
A2N(Agent-to-N)组群协议定义了多个 Agent 组成群组进行协同工作的完整规范,包括群组管理、任务拆分与合并、群体决策、角色与权限等。
|
||
|
||
### 1.1 适用场景
|
||
- 复杂任务的拆分与并行执行(MapReduce 模式)
|
||
- 多 Agent 协同完成单一目标
|
||
- 群体投票与共识决策
|
||
- 临时或永久的 Agent 工作组
|
||
- 分级升级(escalation)机制
|
||
|
||
### 1.2 依赖
|
||
- 依赖 A2A 协议的点对点通信能力
|
||
- 群组内成员间的单播通信使用 A2A 协议
|
||
|
||
---
|
||
|
||
## 2. 核心概念
|
||
|
||
### 2.1 Group(群组)
|
||
由多个 Agent 组成的协作单元,具有明确的拓扑结构、角色分工与协作规则。
|
||
|
||
### 2.2 Topology(拓扑结构)
|
||
|
||
| 拓扑类型 | 说明 | 适用场景 |
|
||
|---------|------|---------|
|
||
| `star` | 星型,中心 coordinator 协调 | 简单任务分发 |
|
||
| `mesh` | 网状,成员间可直接通信 | 对等协作 |
|
||
| `chain` | 链式,流水线模式 | 顺序处理 |
|
||
| `hierarchical` | 层级型,多层管理 | 大型复杂任务 |
|
||
| `fullmesh` | 全连接网状 | 高可靠协作 |
|
||
|
||
### 2.3 Role(角色)
|
||
|
||
| 角色 | 说明 | 权限 |
|
||
|------|------|------|
|
||
| `coordinator` | 协调者 | 创建/解散群组、任务拆分、发起投票 |
|
||
| `worker` | 工作者 | 执行子任务、提交结果 |
|
||
| `reviewer` | 审核者 | 审核结果、发起投票 |
|
||
| `observer` | 观察者 | 只读,查看进度 |
|
||
|
||
### 2.4 GroupStatus(群组状态)
|
||
|
||
| 状态 | 说明 |
|
||
|------|------|
|
||
| `creating` | 创建中 |
|
||
| `active` | 活跃 |
|
||
| `frozen` | 冻结(不可执行新任务) |
|
||
| `disbanded` | 已解散(终态) |
|
||
|
||
---
|
||
|
||
## 3. 消息类型
|
||
|
||
### 3.1 消息类型清单
|
||
|
||
所有消息类型前缀:`group:` 或 `inter_group:`
|
||
|
||
#### 群组管理
|
||
|
||
| 消息类型 | 说明 |
|
||
|---------|------|
|
||
| `group:create` | 创建群组 |
|
||
| `group:disband` | 解散群组 |
|
||
| `group:join` | 加入群组 |
|
||
| `group:leave` | 离开群组 |
|
||
| `group:invite` | 邀请加入 |
|
||
| `group:accept_invite` | 接受邀请 |
|
||
| `group:reject_invite` | 拒绝邀请 |
|
||
| `group:member_update` | 成员更新通知 |
|
||
| `group:role_change` | 角色变更 |
|
||
|
||
#### 群组通信
|
||
|
||
| 消息类型 | 说明 |
|
||
|---------|------|
|
||
| `group:broadcast` | 广播(所有成员) |
|
||
| `group:multicast` | 组播(指定成员) |
|
||
| `group:direct` | 群内单播 |
|
||
| `group:relay` | 消息中继 |
|
||
|
||
#### 任务协作
|
||
|
||
| 消息类型 | 说明 |
|
||
|---------|------|
|
||
| `group:task_split` | 任务拆分 |
|
||
| `group:task_assign` | 任务分配 |
|
||
| `group:task_merge` | 结果合并 |
|
||
| `group:task_progress` | 子任务进度 |
|
||
|
||
#### 共识与投票
|
||
|
||
| 消息类型 | 说明 |
|
||
|---------|------|
|
||
| `group:vote` | 发起投票 |
|
||
| `group:vote_submit` | 提交投票 |
|
||
| `group:consensus` | 达成共识 |
|
||
|
||
#### 人在回路(HiL)
|
||
|
||
| 消息类型 | 说明 |
|
||
|---------|------|
|
||
| `group:consensus_escalate` | 共识僵局升级给人类 |
|
||
| `group:subtask_escalate` | 子任务阻塞升级给人类 |
|
||
| `group:human_decision` | 人类决策结果 |
|
||
| `inter_group:escalate` | 跨群组升级 |
|
||
|
||
**完整定义:** [types/types.go](../types/types.go)
|
||
|
||
---
|
||
|
||
## 4. 群组生命周期
|
||
|
||
### 4.1 状态机
|
||
|
||
```
|
||
creating → active → frozen → disbanded
|
||
↑ ↓
|
||
└─────────┘
|
||
解冻
|
||
```
|
||
|
||
### 4.2 群组创建流程
|
||
|
||
```
|
||
创建者 被邀请成员
|
||
| |
|
||
|------ group:invite -------------->| 发送邀请
|
||
| |
|
||
|<----- group:accept_invite --------| 接受邀请
|
||
| |
|
||
|------ group:member_update ------->| 通知成员更新
|
||
| |
|
||
[群组创建完成,状态变为 active] |
|
||
```
|
||
|
||
### 4.3 群组解散流程
|
||
|
||
```
|
||
coordinator 所有成员
|
||
| |
|
||
|------ group:disband ------------->| 通知解散
|
||
| |
|
||
[群组状态变为 disbanded] |
|
||
```
|
||
|
||
---
|
||
|
||
## 5. 任务协作流程
|
||
|
||
### 5.1 MapReduce 模式(拆分-执行-合并)
|
||
|
||
```
|
||
┌──────────────┐
|
||
│ coordinator │
|
||
└──────┬───────┘
|
||
│
|
||
group:task_split(拆分任务)
|
||
│
|
||
┌────────────────┼────────────────┐
|
||
▼ ▼ ▼
|
||
┌─────────┐ ┌─────────┐ ┌─────────┐
|
||
│ worker1 │ │ worker2 │ │ worker3 │
|
||
└────┬────┘ └────┬────┘ └────┬────┘
|
||
│ │ │
|
||
│ 执行子任务 │ 执行子任务 │ 执行子任务
|
||
│ │ │
|
||
▼ ▼ ▼
|
||
子任务结果 子任务结果 子任务结果
|
||
└────────────────┼────────────────┘
|
||
│
|
||
group:task_merge(合并结果)
|
||
▼
|
||
┌──────────────┐
|
||
│ 最终结果 │
|
||
└──────────────┘
|
||
```
|
||
|
||
### 5.2 详细流程
|
||
|
||
1. **任务拆分阶段**
|
||
- coordinator 接收原始任务
|
||
- 将任务拆分为多个子任务(subtask)
|
||
- 为每个子任务指定执行的 worker
|
||
- 定义合并策略(merge strategy)
|
||
|
||
2. **并行执行阶段**
|
||
- 各 worker 并行执行子任务
|
||
- 定期上报进度(`group:task_progress`)
|
||
- 子任务完成后上报结果
|
||
|
||
3. **结果合并阶段**
|
||
- 所有子任务完成后,coordinator 合并结果
|
||
- 根据合并策略决定最终结果
|
||
- 输出最终结果
|
||
|
||
---
|
||
|
||
## 6. 合并策略(Merge Strategy)
|
||
|
||
| 策略 | 说明 |
|
||
|------|------|
|
||
| `all_success` | 全部成功才认为成功,否则失败 |
|
||
| `majority` | 多数子任务成功即可,取多数结果 |
|
||
| `any_complete` | 任意一个完成即返回结果 |
|
||
| `priority` | 按优先级,高优先级子任务结果优先 |
|
||
|
||
---
|
||
|
||
## 7. 投票与共识
|
||
|
||
### 7.1 投票流程
|
||
|
||
```
|
||
发起者 投票者
|
||
| |
|
||
|-------- group:vote -------------->| 发起投票
|
||
| |
|
||
|<------- group:vote_submit --------| 提交投票
|
||
| |
|
||
[计票,判断是否达到阈值] |
|
||
| |
|
||
|-------- group:consensus --------->| 公布结果
|
||
| |
|
||
```
|
||
|
||
### 7.2 投票规则
|
||
|
||
- `threshold`:通过阈值(0-1),如 0.5 表示过半
|
||
- `deadline`:投票截止时间
|
||
- `voters`:有投票权的成员列表
|
||
- 超时未投票视为弃权
|
||
|
||
### 7.3 共识僵局(Consensus Deadlock)
|
||
|
||
当投票无法达成共识(如平票、未达阈值且超时)时,可升级给人类决策。
|
||
|
||
---
|
||
|
||
## 8. 人在回路(HiL)
|
||
|
||
群组协作中有两种升级场景:
|
||
|
||
### 8.1 共识僵局升级
|
||
投票无法达成共识时,升级给人类裁决。
|
||
|
||
**消息:** `group:consensus_escalate`
|
||
|
||
### 8.2 子任务阻塞升级
|
||
某个子任务遇到无法自动解决的问题时,升级给人类。
|
||
|
||
**消息:** `group:subtask_escalate`
|
||
|
||
### 8.3 跨群组升级
|
||
问题超出当前群组能力时,可升级到上级群组或人类。
|
||
|
||
**消息:** `inter_group:escalate`
|
||
|
||
---
|
||
|
||
## 9. 接口规范
|
||
|
||
### 9.1 GroupProtocol 接口
|
||
|
||
```go
|
||
type GroupProtocol interface {
|
||
// 处理群组消息
|
||
HandleMessage(ctx context.Context, msg *UnifiedSynapseMessage) (*UnifiedSynapseMessage, error)
|
||
|
||
// 设置任务处理器
|
||
SetTaskHandler(h GroupTaskHandler)
|
||
|
||
// 查询群组列表
|
||
GetGroups() []*AgentGroup
|
||
|
||
// 查询特定群组
|
||
GetGroup(groupID string) (*AgentGroup, bool)
|
||
}
|
||
```
|
||
|
||
**参考实现:** [group/protocol.go](../group/protocol.go)
|
||
|
||
### 9.2 GroupTaskHandler 接口
|
||
|
||
```go
|
||
type GroupTaskHandler interface {
|
||
// 执行子任务
|
||
ExecuteSubtask(ctx context.Context, subtaskID string, payload map[string]interface{}) (any, error)
|
||
|
||
// 合并多个子任务结果
|
||
MergeResults(results []SubtaskResult, strategy MergeStrategy) (any, error)
|
||
|
||
// 验证任务是否可拆分,返回拆分方案
|
||
ValidateTaskSplit(taskType string, requirements map[string]interface{}) ([]Subtask, bool)
|
||
}
|
||
```
|
||
|
||
**说明:**
|
||
- `ExecuteSubtask`:执行单个子任务的业务逻辑
|
||
- `MergeResults`:根据策略合并多个子任务的结果
|
||
- `ValidateTaskSplit`:验证任务是否可拆分,并给出拆分方案
|
||
|
||
### 9.3 配置项
|
||
|
||
```go
|
||
type GroupConfig struct {
|
||
MaxGroupSize int // 最大群组人数(默认 20)
|
||
MaxSubtasks int // 最大子任务数(默认 50)
|
||
ConsensusTimeout time.Duration // 共识超时(默认 5 分钟)
|
||
TaskTimeout time.Duration // 任务超时(默认 10 分钟)
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 10. 载荷格式
|
||
|
||
### 10.1 GroupCreatePayload(创建群组)
|
||
|
||
```json
|
||
{
|
||
"group": {
|
||
"name": "视频制作组",
|
||
"topology": "star",
|
||
"config": {
|
||
"allow_self_leave": true,
|
||
"requires_approval": false,
|
||
"consensus_required": false,
|
||
"consensus_threshold": 0.5,
|
||
"broadcast_mode": "all"
|
||
},
|
||
"initial_members": [
|
||
{
|
||
"agent_id": "worker-1",
|
||
"system_id": "sys-a",
|
||
"endpoint": "http://worker1/synapse"
|
||
}
|
||
],
|
||
"roles": [
|
||
{
|
||
"id": "coordinator",
|
||
"name": "协调者",
|
||
"permissions": ["create", "disband", "split", "vote"],
|
||
"max_tasks": 10
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
### 10.2 GroupTaskSplitPayload(任务拆分)
|
||
|
||
```json
|
||
{
|
||
"original_task": {
|
||
"id": "task-xxx",
|
||
"type": "video_generation",
|
||
"requirements": {
|
||
"script": "xxx",
|
||
"duration": 60
|
||
},
|
||
"deadline": "2026-01-01T00:10:00Z"
|
||
},
|
||
"subtasks": [
|
||
{
|
||
"id": "sub-1",
|
||
"description": "生成脚本",
|
||
"assigned_to": "writer-agent",
|
||
"dependencies": [],
|
||
"estimated_duration": 120,
|
||
"priority": 1
|
||
},
|
||
{
|
||
"id": "sub-2",
|
||
"description": "生成配音",
|
||
"assigned_to": "voice-agent",
|
||
"dependencies": ["sub-1"],
|
||
"estimated_duration": 180,
|
||
"priority": 2
|
||
}
|
||
],
|
||
"merge_strategy": "all_success"
|
||
}
|
||
```
|
||
|
||
### 10.3 GroupTaskMergePayload(结果合并)
|
||
|
||
```json
|
||
{
|
||
"original_task_id": "task-xxx",
|
||
"subtask_results": [
|
||
{
|
||
"subtask_id": "sub-1",
|
||
"assigned_to": "writer-agent",
|
||
"status": "success",
|
||
"result": { "script": "..." },
|
||
"completed_at": "2026-01-01T00:02:00Z"
|
||
}
|
||
],
|
||
"merge_strategy_used": "all_success",
|
||
"merged_result": {
|
||
"video_url": "http://..."
|
||
},
|
||
"consensus_achieved": true
|
||
}
|
||
```
|
||
|
||
### 10.4 GroupVotePayload(投票)
|
||
|
||
```json
|
||
{
|
||
"vote_id": "vote-xxx",
|
||
"question": "是否采用方案A?",
|
||
"options": ["方案A", "方案B", "方案C"],
|
||
"voters": ["agent-1", "agent-2", "agent-3"],
|
||
"deadline": "2026-01-01T00:05:00Z",
|
||
"threshold": 0.66,
|
||
"status": "open",
|
||
"votes": []
|
||
}
|
||
```
|
||
|
||
### 10.5 GroupConsensusEscalatePayload(共识升级)
|
||
|
||
```json
|
||
{
|
||
"vote_id": "vote-xxx",
|
||
"escalation_id": "esc-xxx",
|
||
"question": "是否采用方案A?",
|
||
"votes": [
|
||
{
|
||
"voter_id": "agent-1",
|
||
"voter_role": "reviewer",
|
||
"option": "方案A",
|
||
"reason": "质量更好"
|
||
}
|
||
],
|
||
"consensus_status": {
|
||
"required_threshold": 0.66,
|
||
"actual_threshold": 0.33,
|
||
"leading_option": "方案A",
|
||
"options_tied": false
|
||
},
|
||
"escalate_reason": {
|
||
"code": "no_consensus",
|
||
"message": "无法达成共识"
|
||
},
|
||
"escalation_level": 2,
|
||
"deadline": "2026-01-01T00:10:00Z"
|
||
}
|
||
```
|
||
|
||
**完整载荷定义:** [types/types.go](../types/types.go)
|
||
|
||
---
|
||
|
||
## 11. 数据结构
|
||
|
||
### 11.1 AgentGroup(群组)
|
||
|
||
```go
|
||
type AgentGroup struct {
|
||
ID string
|
||
Name string
|
||
Topology GroupTopology
|
||
CreatedBy string
|
||
CreatedAt Timestamp
|
||
Config GroupConfig
|
||
Members []GroupMember
|
||
Roles []GroupRole
|
||
Status GroupStatus
|
||
}
|
||
```
|
||
|
||
### 11.2 GroupMember(群组成员)
|
||
|
||
```go
|
||
type GroupMember struct {
|
||
AgentID string
|
||
AgentName string
|
||
Role string
|
||
JoinedAt Timestamp
|
||
Status GroupMemberStatus
|
||
Capabilities []string
|
||
LoadFactor float64 // 负载因子 0-1,用于任务分配
|
||
}
|
||
```
|
||
|
||
### 11.3 Subtask(子任务)
|
||
|
||
```go
|
||
type Subtask struct {
|
||
ID string
|
||
Description string
|
||
AssignedTo string
|
||
Dependencies []string
|
||
EstimatedDuration int
|
||
Priority int
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 12. 错误码
|
||
|
||
群组协议特有错误码:
|
||
|
||
| 错误码 | 说明 |
|
||
|--------|------|
|
||
| `group_not_found` | 群组不存在 |
|
||
| `group_not_active` | 群组不活跃 |
|
||
| `group_full` | 群组已满 |
|
||
| `already_member` | 已是成员 |
|
||
| `not_group_member` | 不是群组成员 |
|
||
| `member_not_found` | 成员不存在 |
|
||
| `permission_denied` | 权限不足 |
|
||
| `invalid_params` | 参数无效 |
|
||
|
||
---
|
||
|
||
## 13. 参考实现
|
||
|
||
本协议的参考实现位于 `group/` 目录:
|
||
|
||
| 文件 | 说明 |
|
||
|------|------|
|
||
| [group/protocol.go](../group/protocol.go) | 群组协议核心实现 |
|
||
| [types/types.go](../types/types.go) | 群组相关数据类型 |
|
||
|
||
---
|
||
|
||
## 附录 A:与 A2A 协议的关系
|
||
|
||
- 群组内的点对点通信使用 A2A 协议
|
||
- 群组协议在 A2A 协议之上提供群组管理、任务拆分合并、共识投票等能力
|
||
- 群组消息同样使用统一消息信封(`UnifiedSynapseMessage`),通过 `group_id` 字段标识群组上下文
|