520 lines
17 KiB
Markdown
520 lines
17 KiB
Markdown
# SDK 实现说明
|
||
|
||
> 版本:1.0.0
|
||
> 更新日期:2026-06-27
|
||
> 协议版本:1.0.0
|
||
> 关联协议:
|
||
> - [A2A 协议](./02-a2a-protocol.md)
|
||
> - [A2N 协议](./03-a2n-protocol.md)
|
||
> - [P2A 协议](./04-p2a-protocol.md)
|
||
|
||
---
|
||
|
||
## 1. 概述
|
||
|
||
SDK 按照灵隙协议族(Synapse Protocol Suite)的三个子协议进行了模块化设计,分为三个子包,命名与协议名保持一致:
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ SDK (sdk/) │
|
||
├──────────────┬───────────────────┬───────────────────────────┤
|
||
│ sdk/p2a │ sdk/a2a │ sdk/a2n │
|
||
│ P2A 协议 │ A2A 协议 │ A2N 协议 │
|
||
│ (外部调用) │ (Agent间通信) │ (群组协作) │
|
||
│ ✅ 完整实现 │ ✅ 完整实现 │ ✅ 完整实现 │
|
||
└──────────────┴───────────────────┴───────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 2. SDK 目录结构
|
||
|
||
```
|
||
sdk/
|
||
├── doc.go # SDK 包文档(使用说明)
|
||
├── p2a/
|
||
│ └── client.go # P2A 协议 - 外部调用客户端
|
||
├── a2a/
|
||
│ └── client.go # A2A 协议 - Agent间通信客户端
|
||
└── a2n/
|
||
└── client.go # A2N 协议 - 群组协作客户端
|
||
```
|
||
|
||
---
|
||
|
||
## 3. 第一部分:sdk/p2a - P2A 协议
|
||
|
||
**协议对应**:[P2A 协议](./04-p2a-protocol.md)
|
||
**版本**:1.0.0
|
||
**用途**:非 Agent 调用方(前端、后端服务、第三方应用)通过 REST API 调用 Agent 能力
|
||
|
||
### 3.1 实现对应关系
|
||
|
||
| P2A 协议功能 | SDK 方法 | 位置 |
|
||
|-------------|---------|------|
|
||
| 认证方式 | `setHeaders()` | [sdk/p2a/client.go](../sdk/p2a/client.go) |
|
||
| 提交任务(JSON) | `SubmitTask()` | [sdk/p2a/client.go](../sdk/p2a/client.go) |
|
||
| 提交任务(Multipart) | `SubmitTaskWithFiles()` | [sdk/p2a/client.go](../sdk/p2a/client.go) |
|
||
| 获取任务详情 | `GetTask()` | [sdk/p2a/client.go](../sdk/p2a/client.go) |
|
||
| 获取任务状态(简化版) | `GetTaskStatus()` | [sdk/p2a/client.go](../sdk/p2a/client.go) |
|
||
| 获取任务列表 | `ListTasks()` | [sdk/p2a/client.go](../sdk/p2a/client.go) |
|
||
| 取消任务 | `CancelTask()` | [sdk/p2a/client.go](../sdk/p2a/client.go) |
|
||
| 能力查询 | `GetCapabilities()` | [sdk/p2a/client.go](../sdk/p2a/client.go) |
|
||
| 回调验证 | `VerifyCallback()` | [sdk/p2a/client.go](../sdk/p2a/client.go) |
|
||
| 轮询等待 | `WaitForTask()` | [sdk/p2a/client.go](../sdk/p2a/client.go) |
|
||
|
||
### 3.2 核心数据结构
|
||
|
||
```go
|
||
// Client 客户端
|
||
type Client struct {
|
||
baseURL string
|
||
apiKey string
|
||
httpClient *http.Client
|
||
}
|
||
|
||
// 配置
|
||
type ClientConfig struct {
|
||
BaseURL string
|
||
APIKey string
|
||
Timeout time.Duration
|
||
MaxRetries int
|
||
}
|
||
|
||
// 任务请求
|
||
type TaskRequest struct {
|
||
TaskType string
|
||
Payload map[string]any
|
||
ExternalTaskID string
|
||
Priority string
|
||
CallbackURL string
|
||
CallbackToken string
|
||
}
|
||
|
||
// 任务信息
|
||
type TaskInfo struct {
|
||
ID string
|
||
Type string
|
||
Status string
|
||
Progress int
|
||
Result map[string]any
|
||
Error *TaskError
|
||
}
|
||
|
||
// 文件上传参数
|
||
type FileParam struct {
|
||
FieldName string
|
||
Filename string
|
||
Data []byte
|
||
MimeType string
|
||
}
|
||
```
|
||
|
||
### 3.3 使用示例
|
||
|
||
```go
|
||
import "dp-headless/synapse/sdk/p2a"
|
||
|
||
client := p2a.NewClient(p2a.ClientConfig{
|
||
BaseURL: "https://agent-api.example.com",
|
||
APIKey: "your-api-key",
|
||
})
|
||
|
||
// 提交任务并等待完成
|
||
taskInfo, err := client.CreateAndWait(ctx, "text_generation", map[string]any{
|
||
"prompt": "写一首诗",
|
||
"style": "古典",
|
||
}, 5*time.Second)
|
||
|
||
// 使用回调模式
|
||
resp, err := client.CreateWithCallback(ctx, "image_generation", payload,
|
||
"https://your-domain.com/callback",
|
||
"callback-token",
|
||
)
|
||
```
|
||
|
||
---
|
||
|
||
## 4. 第二部分:sdk/a2a - A2A 协议
|
||
|
||
**协议对应**:[A2A 协议](./02-a2a-protocol.md)
|
||
**版本**:1.0.0
|
||
**用途**:Agent 之间的点对点通信,包含消息发送、签名验证、回调处理
|
||
|
||
### 4.1 实现对应关系
|
||
|
||
| A2A 协议功能 | SDK 方法 | 位置 |
|
||
|------------|---------|------|
|
||
| 发送任务请求 | `SendTaskRequest()` | [sdk/a2a/client.go](../sdk/a2a/client.go) |
|
||
| 发送任务取消 | `SendTaskCancel()` | [sdk/a2a/client.go](../sdk/a2a/client.go) |
|
||
| 发送人类决策 | `SendHumanDecision()` | [sdk/a2a/client.go](../sdk/a2a/client.go) |
|
||
| 查询能力 | `SendCapabilityQuery()` | [sdk/a2a/client.go](../sdk/a2a/client.go) |
|
||
| 消息签名 | `signMessage()` | [sdk/a2a/client.go](../sdk/a2a/client.go) |
|
||
| 签名验证 | `verifySignature()` | [sdk/a2a/client.go](../sdk/a2a/client.go) |
|
||
| 任务状态管理 | `GetTaskState()`, `ListTasks()` | [sdk/a2a/client.go](../sdk/a2a/client.go) |
|
||
| 等待任务完成 | `WaitForTask()` | [sdk/a2a/client.go](../sdk/a2a/client.go) |
|
||
| 回调服务 | `startCallbackServer()` | [sdk/a2a/client.go](../sdk/a2a/client.go) |
|
||
|
||
### 4.2 核心数据结构
|
||
|
||
```go
|
||
// Client A2A客户端
|
||
type Client struct {
|
||
agentEndpoint types.AgentEndpoint
|
||
authSecret string
|
||
callbackHandler MessageCallbackHandler
|
||
tasks map[string]*A2ATaskState
|
||
}
|
||
|
||
// 配置
|
||
type ClientConfig struct {
|
||
AgentEndpoint types.AgentEndpoint
|
||
AuthSecret string
|
||
CallbackPort int
|
||
Timeout time.Duration
|
||
MaxRetries int
|
||
}
|
||
|
||
// 消息回调处理器接口
|
||
type MessageCallbackHandler interface {
|
||
HandleTaskRequest(ctx context.Context, msg *types.UnifiedSynapseMessage) (*types.UnifiedSynapseMessage, error)
|
||
HandleTaskStatusUpdate(ctx context.Context, msg *types.UnifiedSynapseMessage) error
|
||
HandleTaskComplete(ctx context.Context, msg *types.UnifiedSynapseMessage) error
|
||
HandleTaskFailed(ctx context.Context, msg *types.UnifiedSynapseMessage) error
|
||
HandleNeedHuman(ctx context.Context, msg *types.UnifiedSynapseMessage) error
|
||
}
|
||
|
||
// 任务状态
|
||
type A2ATaskState struct {
|
||
TaskID string
|
||
Status types.P2PTaskStatus
|
||
Progress int
|
||
Message string
|
||
Result any
|
||
Error *types.SynapseError
|
||
}
|
||
```
|
||
|
||
### 4.3 使用示例
|
||
|
||
```go
|
||
import "dp-headless/synapse/sdk/a2a"
|
||
|
||
a2aClient, err := a2a.NewClient(&a2a.ClientConfig{
|
||
AgentEndpoint: types.AgentEndpoint{
|
||
AgentID: "my-agent",
|
||
AgentName: "我的Agent",
|
||
SystemID: "my-system",
|
||
Endpoint: "http://localhost:8080/synapse/callback",
|
||
},
|
||
AuthSecret: "my-hmac-secret",
|
||
CallbackPort: 8080,
|
||
})
|
||
|
||
// 设置消息处理器
|
||
a2aClient.SetMessageHandler(&myHandler{})
|
||
|
||
// 发送任务请求给其他Agent
|
||
taskID, err := a2aClient.SendTaskRequest(ctx, targetAgent, "video_generation", map[string]any{
|
||
"prompt": "生成一段视频",
|
||
})
|
||
```
|
||
|
||
---
|
||
|
||
## 5. 第三部分:sdk/a2n - A2N 协议
|
||
|
||
**协议对应**:[A2N 协议](./03-a2n-protocol.md)
|
||
**版本**:1.0.0
|
||
**用途**:多 Agent 群组协作,包含群组管理、任务拆分合并、投票、升级
|
||
|
||
### 5.1 实现对应关系
|
||
|
||
| A2N 协议功能 | SDK 方法 | 位置 |
|
||
|------------|---------|------|
|
||
| 创建群组 | `CreateGroup()` | [sdk/a2n/client.go](../sdk/a2n/client.go) |
|
||
| 加入群组 | `JoinGroup()` | [sdk/a2n/client.go](../sdk/a2n/client.go) |
|
||
| 离开群组 | `LeaveGroup()` | [sdk/a2n/client.go](../sdk/a2n/client.go) |
|
||
| 解散群组 | `DisbandGroup()` | [sdk/a2n/client.go](../sdk/a2n/client.go) |
|
||
| 提交群组任务 | `SubmitGroupTask()` | [sdk/a2n/client.go](../sdk/a2n/client.go) |
|
||
| 发送子任务结果 | `SendSubtaskResult()` | [sdk/a2n/client.go](../sdk/a2n/client.go) |
|
||
| 发起投票 | `InitiateVote()` | [sdk/a2n/client.go](../sdk/a2n/client.go) |
|
||
| 提交投票 | `SubmitVote()` | [sdk/a2n/client.go](../sdk/a2n/client.go) |
|
||
| 广播消息 | `Broadcast()` | [sdk/a2n/client.go](../sdk/a2n/client.go) |
|
||
| 升级到人类 | `EscalateToHuman()` | [sdk/a2n/client.go](../sdk/a2n/client.go) |
|
||
|
||
### 5.2 核心数据结构
|
||
|
||
```go
|
||
// Client A2N客户端
|
||
type Client struct {
|
||
a2aClient *a2a.Client
|
||
groups map[string]*GroupState
|
||
eventHandler GroupEventHandler
|
||
}
|
||
|
||
// 配置
|
||
type ClientConfig struct {
|
||
A2AClient *a2a.Client
|
||
EventHandler GroupEventHandler
|
||
}
|
||
|
||
// 群组状态
|
||
type GroupState struct {
|
||
GroupID string
|
||
Name string
|
||
Topology types.GroupTopology
|
||
Status types.GroupStatus
|
||
Members []types.GroupMember
|
||
Role string // "coordinator" | "worker"
|
||
}
|
||
|
||
// 群组事件处理器接口
|
||
type GroupEventHandler interface {
|
||
OnGroupCreated(ctx context.Context, groupID string) error
|
||
OnGroupDisbanded(ctx context.Context, groupID string) error
|
||
OnMemberJoined(ctx context.Context, groupID string, member types.GroupMember) error
|
||
OnMemberLeft(ctx context.Context, groupID string, agentID string) error
|
||
OnTaskSplit(ctx context.Context, groupID string, originalTaskID string, subtasks []types.Subtask) error
|
||
OnSubtaskProgress(ctx context.Context, groupID string, subtaskID string, progress int) error
|
||
OnTaskMerged(ctx context.Context, groupID string, originalTaskID string, result any) error
|
||
OnVoteInitiated(ctx context.Context, groupID string, vote types.GroupVotePayload) error
|
||
OnVoteResult(ctx context.Context, groupID string, voteID string, option string, passed bool) error
|
||
OnEscalation(ctx context.Context, groupID string, escalationID string, level int) error
|
||
OnBroadcast(ctx context.Context, groupID string, sender types.AgentEndpoint, message []byte) error
|
||
}
|
||
```
|
||
|
||
### 5.3 使用示例
|
||
|
||
```go
|
||
import (
|
||
"dp-headless/synapse/sdk/a2n"
|
||
"dp-headless/synapse/sdk/a2a"
|
||
)
|
||
|
||
// 创建A2A客户端
|
||
a2aClient, _ := a2a.NewClient(&a2a.ClientConfig{
|
||
AgentEndpoint: myEndpoint,
|
||
})
|
||
|
||
// 创建A2N客户端
|
||
a2nClient, err := a2n.NewClient(&a2n.ClientConfig{
|
||
A2AClient: a2aClient,
|
||
EventHandler: &myGroupHandler{},
|
||
})
|
||
|
||
// 创建群组
|
||
group, err := a2nClient.CreateGroup(ctx, "视频制作组", types.GroupTopologyStar, nil, members)
|
||
|
||
// 作为Coordinator,提交任务
|
||
subtasks, err := a2nClient.SubmitGroupTask(ctx, group.GroupID, "video_generation",
|
||
map[string]any{"script": "..."},
|
||
types.MergeAllSuccess,
|
||
)
|
||
|
||
// 发起投票
|
||
voteID, err := a2nClient.InitiateVote(ctx, group.GroupID,
|
||
"选择哪个方案?",
|
||
[]string{"方案A", "方案B"},
|
||
voterIDs,
|
||
0.5,
|
||
5*time.Minute,
|
||
)
|
||
```
|
||
|
||
---
|
||
|
||
## 6. SDK 架构总览
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ SDK (dp-headless/synapse/sdk) │
|
||
├─────────────────────────────────────────────────────────────┤
|
||
│ doc.go │
|
||
│ ├── 包文档和使用说明 │
|
||
│ └── 指向各子包的链接 │
|
||
├────────────────┬────────────────┬─────────────────────────┤
|
||
│ sdk/p2a │ sdk/a2a │ sdk/a2n │
|
||
│ │ │ │
|
||
│ P2A协议 │ 灵隙协议 │ A2N协议 │
|
||
│ │ │ │
|
||
│ ├── Client │ ├── Client │ ├── Client │
|
||
│ ├── 配置 │ ├── 配置 │ ├── 配置 │
|
||
│ ├── 任务操作 │ ├── 消息发送 │ ├── 群组管理 │
|
||
│ ├── 能力查询 │ ├── 任务状态 │ ├── 任务协作 │
|
||
│ └── 回调验证 │ ├── 回调服务 │ ├── 投票 │
|
||
│ │ └── 签名 │ └── 升级 │
|
||
└────────────────┴────────────────┴─────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 7. 快速开始
|
||
|
||
### 7.1 P2A 调用(外部调用者)
|
||
|
||
```go
|
||
package main
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
|
||
"dp-headless/synapse/sdk/p2a"
|
||
)
|
||
|
||
func main() {
|
||
client := p2a.NewClient(p2a.ClientConfig{
|
||
BaseURL: "https://agent.example.com",
|
||
APIKey: "your-api-key",
|
||
})
|
||
|
||
ctx := context.Background()
|
||
|
||
// 方式1: 轮询等待
|
||
result, err := client.CreateAndWait(ctx, "text_generation", map[string]any{
|
||
"prompt": "写一首诗",
|
||
}, 5*time.Second)
|
||
if err != nil {
|
||
fmt.Println("Error:", err)
|
||
}
|
||
fmt.Printf("Result: %v\n", result.Result)
|
||
|
||
// 方式2: 回调模式
|
||
resp, err := client.CreateWithCallback(ctx, "image_generation",
|
||
map[string]any{"prompt": "一只猫"},
|
||
"https://your-domain.com/callback",
|
||
"token",
|
||
)
|
||
fmt.Printf("Task ID: %s\n", resp.TaskID)
|
||
}
|
||
```
|
||
|
||
### 7.2 灵隙 通信(Agent 间)
|
||
|
||
```go
|
||
package main
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
|
||
"dp-headless/synapse/sdk/a2a"
|
||
"dp-headless/synapse/types"
|
||
)
|
||
|
||
func main() {
|
||
client, _ := a2a.NewClient(&a2a.ClientConfig{
|
||
AgentEndpoint: types.AgentEndpoint{
|
||
AgentID: "agent-001",
|
||
AgentName: "Agent 001",
|
||
SystemID: "my-system",
|
||
Endpoint: "http://localhost:8080/synapse/callback",
|
||
},
|
||
AuthSecret: "secret-key",
|
||
CallbackPort: 8080,
|
||
})
|
||
|
||
ctx := context.Background()
|
||
target := types.AgentEndpoint{
|
||
AgentID: "agent-002",
|
||
Endpoint: "http://agent-002:8080/synapse/callback",
|
||
}
|
||
|
||
// 发送任务请求
|
||
taskID, err := client.SendTaskRequest(ctx, target, "data_analysis", map[string]any{
|
||
"dataset": "sales.csv",
|
||
})
|
||
fmt.Printf("Task ID: %s\n", taskID)
|
||
|
||
// 等待完成
|
||
state, err := client.WaitForTask(ctx, taskID, 5*time.Minute)
|
||
fmt.Printf("Status: %s\n", state.Status)
|
||
}
|
||
```
|
||
|
||
### 7.3 A2N 群组协作
|
||
|
||
```go
|
||
package main
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
|
||
"dp-headless/synapse/sdk/a2n"
|
||
"dp-headless/synapse/sdk/a2a"
|
||
"dp-headless/synapse/types"
|
||
)
|
||
|
||
func main() {
|
||
a2aClient, _ := a2a.NewClient(&a2a.ClientConfig{
|
||
AgentEndpoint: myEndpoint,
|
||
})
|
||
|
||
a2nClient, _ := a2n.NewClient(&a2n.ClientConfig{
|
||
A2AClient: a2aClient,
|
||
})
|
||
|
||
ctx := context.Background()
|
||
|
||
// 创建群组
|
||
group, _ := a2nClient.CreateGroup(ctx, "协作组", types.GroupTopologyStar, nil, []types.AgentEndpoint{
|
||
{AgentID: "member-1", Endpoint: "http://member-1:8080"},
|
||
{AgentID: "member-2", Endpoint: "http://member-2:8080"},
|
||
})
|
||
|
||
fmt.Printf("Group ID: %s\n", group.GroupID)
|
||
|
||
// 提交任务
|
||
subtasks, _ := a2nClient.SubmitGroupTask(ctx, group.GroupID, "video_generation",
|
||
map[string]any{"script": "..."},
|
||
types.MergeAllSuccess,
|
||
)
|
||
|
||
fmt.Printf("Split into %d subtasks\n", len(subtasks))
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 8. 协议与包名对应关系
|
||
|
||
| 协议名称 | 协议文档 | SDK 包名 | 包路径 |
|
||
|---------|---------|---------|--------|
|
||
| 灵隙原始协议(Synapse Raw Protocol) | [01-synapse-raw-protocol.md](./01-synapse-raw-protocol.md) | - | 纲领性文档 |
|
||
| A2A 协议 | [02-a2a-protocol.md](./02-a2a-protocol.md) | `a2a` | `sdk/a2a/` |
|
||
| A2N 协议 | [03-a2n-protocol.md](./03-a2n-protocol.md) | `a2n` | `sdk/a2n/` |
|
||
| P2A 协议 | [04-p2a-protocol.md](./04-p2a-protocol.md) | `p2a` | `sdk/p2a/` |
|
||
|
||
**所有协议版本:1.0.0**
|
||
|
||
---
|
||
|
||
## 9. 扩展建议
|
||
|
||
| 优先级 | 扩展项 | 说明 |
|
||
|-------|-------|------|
|
||
| 高 | gRPC 传输 | 添加 gRPC 协议支持 |
|
||
| 高 | WebSocket | 添加 WebSocket 流式传输 |
|
||
| 中 | 批量操作 | 批量任务提交、批量查询 |
|
||
| 中 | 指标监控 | 内置指标收集 |
|
||
| 低 | 多语言 SDK | Python、JavaScript 等 |
|
||
|
||
---
|
||
|
||
## 附录:相关文件索引
|
||
|
||
| 文件路径 | 说明 |
|
||
|---------|------|
|
||
| [sdk/doc.go](../sdk/doc.go) | SDK 包文档 |
|
||
| [sdk/p2a/client.go](../sdk/p2a/client.go) | P2A 客户端实现 |
|
||
| [sdk/a2a/client.go](../sdk/a2a/client.go) | A2A 客户端实现 |
|
||
| [sdk/a2n/client.go](../sdk/a2n/client.go) | A2N 客户端实现 |
|
||
| [externalapi/handler.go](../externalapi/handler.go) | P2A 协议服务端实现 |
|
||
| [p2p/protocol.go](../p2p/protocol.go) | A2A 协议核心实现 |
|
||
| [group/protocol.go](../group/protocol.go) | A2N 协议核心实现 |
|
||
| [types/types.go](../types/types.go) | 公共类型定义 |
|
||
| [transport/transport.go](../transport/transport.go) | HTTP 传输层实现 |
|