12 KiB
12 KiB
P2A 协议(Person/Program-to-Agent Protocol)
版本:1.0.0
状态:草案
类型:实现规范
基于:灵隙原始协议(Synapse Raw Protocol) v1.0.0
1. 概述
P2A(Person/Program-to-Agent)调用协议定义了非 Agent 调用方(如普通后端服务、前端应用、第三方系统、人类用户)如何调用 Agent 能力的规范。
本协议将 A2A 协议的复杂性封装起来,提供简洁的 RESTful API,使调用方无需了解 A2A 协议细节即可使用 Agent 能力。
1.1 适用场景
- 前端应用直接调用 Agent 能力
- 后端业务系统集成 Agent 服务
- 第三方开发者通过 API 接入
- 无需实现完整 A2A 协议的调用方
1.2 设计原则
- 简单易用:标准 RESTful API,JSON 格式
- 两种模式:回调模式 + 轮询模式,调用方按需选择
- 认证简单:API Key 认证,无需 HMAC 签名
- 文件支持:支持 multipart/form-data 上传文件
- 错误友好:清晰的错误码和错误信息
1.3 与 A2A 协议的关系
外部调用方 ──P2A 协议──▶ External API Layer ──A2A 协议──▶ Agent
P2A 协议是 A2A 协议的"简化入口",所有请求最终会转换为 灵隙消息发送给 Agent。
2. 认证方式
2.1 API Key 认证
- 在 HTTP Header 中传递:
X-API-Key: {api_key} - 或在 URL Query 中传递:
?api_key={api_key} - 如果服务端未配置 API Key,则跳过认证
2.2 回调验证(可选)
如果调用方提供了 callback_token,则服务端在回调时会在 Header 中带上 X-Callback-Token,用于调用方验证回调来源。
3. API 端点
所有端点默认前缀:/api/v1/synapse
3.1 端点清单
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /task |
提交任务(JSON) |
| POST | /task/multipart |
提交任务(带文件上传) |
| GET | /task/{task_id} |
获取任务详情 |
| GET | /task/{task_id}/status |
获取任务状态(简化版) |
| GET | /tasks |
获取任务列表 |
| POST | /task/{task_id}/cancel |
取消任务 |
| GET | /capabilities |
获取能力清单 |
| POST | /callback |
接收回调(调用方实现) |
4. 任务提交
4.1 提交任务(JSON)
请求:
POST /api/v1/synapse/task
Content-Type: application/json
X-API-Key: your-api-key
{
"task_type": "text_generation",
"payload": {
"prompt": "写一首诗",
"style": "古典"
},
"external_task_id": "my-task-001",
"priority": "normal",
"callback_url": "https://your-domain.com/callback",
"callback_token": "your-callback-token"
}
请求字段说明:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
task_type |
string | 是 | 任务类型,如 video_generation, image_generation |
payload |
object | 是 | 任务参数,具体结构取决于 task_type |
external_task_id |
string | 否 | 调用方的任务 ID,用于关联 |
priority |
string | 否 | 优先级:low, normal, high, urgent,默认 normal |
callback_url |
string | 否 | 回调 URL,不提供则需轮询 |
callback_token |
string | 否 | 回调验证 token |
响应:
{
"success": true,
"task_id": "task-abc123",
"status": "received",
"message": "任务已接收"
}
响应字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
success |
bool | 是否成功 |
task_id |
string | 服务端生成的任务 ID |
status |
string | 初始状态,通常为 received |
message |
string | 提示信息 |
error |
string | 错误信息(失败时) |
4.2 提交任务(Multipart 带文件)
请求:
POST /api/v1/synapse/task/multipart
Content-Type: multipart/form-data
X-API-Key: your-api-key
------WebKitFormBoundary
Content-Disposition: form-data; name="task_type"
image_generation
------WebKitFormBoundary
Content-Disposition: form-data; name="payload"
{"prompt":"一只猫","style":"写实"}
------WebKitFormBoundary
Content-Disposition: form-data; name="priority"
normal
------WebKitFormBoundary
Content-Disposition: form-data; name="file"; filename="reference.jpg"
Content-Type: image/jpeg
[二进制数据]
------WebKitFormBoundary--
表单字段:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
task_type |
string | 是 | 任务类型 |
payload |
string(JSON) | 是 | 任务参数(JSON 字符串) |
external_task_id |
string | 否 | 外部任务 ID |
priority |
string | 否 | 优先级 |
callback_url |
string | 否 | 回调 URL |
callback_token |
string | 否 | 回调 token |
file |
file | 否 | 上传的文件(可多个) |
响应: 同 JSON 提交方式
5. 任务查询
5.1 获取任务详情
请求:
GET /api/v1/synapse/task/{task_id}
X-API-Key: your-api-key
响应:
{
"success": true,
"task": {
"id": "task-abc123",
"type": "text_generation",
"status": "completed",
"progress": 100,
"message": "任务已完成",
"created_at": "2026-01-01T00:00:00Z",
"updated_at": "2026-01-01T00:01:00Z",
"completed_at": "2026-01-01T00:01:00Z",
"eta": "2026-01-01T00:01:00Z",
"result": {
"text": "生成的文本...",
"metadata": { "tokens": 1024 }
},
"error": null,
"external_task_id": "my-task-001"
}
}
任务状态:
| 状态 | 说明 |
|---|---|
received |
已接收 |
processing |
处理中 |
completed |
已完成 |
failed |
已失败 |
cancelled |
已取消 |
5.2 获取任务状态(简化版)
请求:
GET /api/v1/synapse/task/{task_id}/status
X-API-Key: your-api-key
响应:
{
"success": true,
"task_id": "task-abc123",
"status": "processing",
"progress": 50
}
5.3 获取任务列表
请求:
GET /api/v1/synapse/tasks?status=processing&limit=20&offset=0
X-API-Key: your-api-key
查询参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
status |
string | 否 | 按状态过滤 |
limit |
int | 否 | 每页数量,默认 20 |
offset |
int | 否 | 偏移量,默认 0 |
响应:
{
"success": true,
"tasks": [
{
"id": "task-abc123",
"type": "text_generation",
"status": "completed",
"progress": 100,
"created_at": "2026-01-01T00:00:00Z",
"updated_at": "2026-01-01T00:01:00Z"
}
],
"total": 1,
"limit": 20,
"offset": 0,
"has_more": false
}
6. 任务取消
请求:
POST /api/v1/synapse/task/{task_id}/cancel
X-API-Key: your-api-key
响应:
{
"success": true,
"task_id": "task-abc123",
"status": "cancelled",
"message": "任务已取消"
}
7. 能力查询
请求:
GET /api/v1/synapse/capabilities
X-API-Key: your-api-key
响应:
{
"success": true,
"capabilities": {
"agent_id": "my-agent",
"agent_name": "我的Agent",
"system_id": "my-system",
"protocol_version": "1.0.0",
"supported_task_types": [
{
"type": "text_generation",
"name": "文本生成",
"description": "生成各种类型的文本内容",
"estimated_time": "30s",
"input_schema": "...",
"output_schema": "..."
}
],
"supported_transport_modes": ["callback", "polling"],
"max_file_size": 104857600,
"max_concurrent_tasks": 10,
"support_progress_updates": true,
"support_streaming": false,
"support_hil": true,
"support_groups": true
}
}
8. 回调机制
如果调用方提供了 callback_url,服务端会在任务状态变化时主动回调。
8.1 回调请求
POST {callback_url}
Content-Type: application/json
X-Callback-Token: {callback_token}
{
"task_id": "task-abc123",
"status": "completed",
"progress": 100,
"message": "任务已完成",
"result": {
"text": "生成的文本..."
},
"error": null,
"timestamp": "2026-01-01T00:01:00Z"
}
8.2 回调类型
| 触发时机 | 说明 |
|---|---|
| 任务开始处理 | status=processing, progress=0 |
| 进度更新 | status=processing, progress=N |
| 任务完成 | status=completed, progress=100, 包含 result |
| 任务失败 | status=failed, 包含 error |
| 任务取消 | status=cancelled |
8.3 回调响应
调用方应返回 2xx 状态码表示成功接收。如果返回非 2xx,服务端会重试(指数退避,最多 5 次)。
9. 错误处理
9.1 错误响应格式
{
"success": false,
"error": "invalid_task_type",
"message": "不支持的任务类型"
}
9.2 错误码列表
| 错误码 | HTTP 状态码 | 说明 |
|---|---|---|
unauthorized |
401 | API Key 无效或缺失 |
invalid_request |
400 | 请求格式无效 |
invalid_task_type |
400 | 任务类型不支持 |
invalid_params |
400 | 参数无效 |
task_not_found |
404 | 任务不存在 |
task_already_completed |
409 | 任务已完成,无法取消 |
file_too_large |
413 | 文件过大 |
rate_limited |
429 | 请求过于频繁 |
internal_error |
500 | 服务内部错误 |
service_unavailable |
503 | 服务不可用 |
10. SDK 客户端接口
为方便调用方集成,提供 SDK 客户端。
10.1 SDK 初始化
client := sdk.NewClient(sdk.ClientConfig{
BaseURL: "https://agent-api.example.com",
APIKey: "your-api-key",
Timeout: 30 * time.Second,
})
10.2 SDK 方法清单
| 方法 | 说明 |
|---|---|
SubmitTask(ctx, req) |
提交任务(JSON) |
SubmitTaskWithFiles(ctx, req, files) |
提交任务(带文件) |
GetTask(ctx, taskID) |
获取任务详情 |
GetTaskStatus(ctx, taskID) |
获取任务状态 |
ListTasks(ctx, status, limit, offset) |
获取任务列表 |
CancelTask(ctx, taskID) |
取消任务 |
GetCapabilities(ctx) |
获取能力清单 |
WaitForTask(ctx, taskID, interval) |
等待任务完成(轮询) |
10.3 数据结构
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
Message string
CreatedAt string
UpdatedAt string
CompletedAt string
ETA string
Result map[string]any
Error *TaskError
ExternalTaskID string
}
完整 SDK 实现: sdk/client.go
11. 参考实现
本协议的参考实现:
| 模块 | 文件路径 | 说明 |
|---|---|---|
| 服务端 | externalapi/handler.go | External API Handler |
| 客户端 SDK | sdk/client.go | Go 语言 SDK |
附录 A:调用模式选择
回调模式 vs 轮询模式
| 对比项 | 回调模式 | 轮询模式 |
|---|---|---|
| 实时性 | 高,状态变化即时通知 | 低,取决于轮询间隔 |
| 实现复杂度 | 调用方需提供公网可访问的回调接口 | 简单,只需调用 GET 接口 |
| 网络要求 | 调用方需要公网可达 | 只需调用方能访问服务端 |
| 适用场景 | 生产环境、需要实时通知 | 开发测试、内网环境 |
选择建议
- 有公网服务器:使用回调模式
- 本地开发 / 内网环境:使用轮询模式
- 长时间任务:建议回调模式,避免频繁轮询
- 短任务(<10s):可直接同步等待或高频轮询
附录 B:从 A2A 协议到 P2A 协议的映射
| 灵隙概念 | P2A 对应 | 说明 |
|---|---|---|
p2p:task_request |
POST /task |
任务提交 |
p2p:task_status_update |
回调 / GET /task | 状态更新 |
p2p:task_complete |
回调(status=completed) | 任务完成 |
p2p:task_failed |
回调(status=failed) | 任务失败 |
p2p:task_cancel |
POST /task/{id}/cancel |
任务取消 |
p2p:capability_query |
GET /capabilities |
能力查询 |
| Agent 身份 | API Key | 简化认证 |
| HMAC 签名 | Callback Token | 简化验证 |