# P2A 协议(Person/Program-to-Agent Protocol) > 版本:1.0.0 > 状态:草案 > 类型:实现规范 > 基于:[灵隙原始协议(Synapse Raw Protocol) v1.0.0](./01-a2a-raw-protocol.md) --- ## 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) **请求:** ```http 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 | **响应:** ```json { "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 带文件) **请求:** ```http 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 获取任务详情 **请求:** ```http GET /api/v1/synapse/task/{task_id} X-API-Key: your-api-key ``` **响应:** ```json { "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 获取任务状态(简化版) **请求:** ```http GET /api/v1/synapse/task/{task_id}/status X-API-Key: your-api-key ``` **响应:** ```json { "success": true, "task_id": "task-abc123", "status": "processing", "progress": 50 } ``` ### 5.3 获取任务列表 **请求:** ```http 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 | **响应:** ```json { "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. 任务取消 **请求:** ```http POST /api/v1/synapse/task/{task_id}/cancel X-API-Key: your-api-key ``` **响应:** ```json { "success": true, "task_id": "task-abc123", "status": "cancelled", "message": "任务已取消" } ``` --- ## 7. 能力查询 **请求:** ```http GET /api/v1/synapse/capabilities X-API-Key: your-api-key ``` **响应:** ```json { "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 回调请求 ```http 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 错误响应格式 ```json { "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 初始化 ```go 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 数据结构 ```go 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](../sdk/client.go) --- ## 11. 参考实现 本协议的参考实现: | 模块 | 文件路径 | 说明 | |------|---------|------| | 服务端 | [externalapi/handler.go](../externalapi/handler.go) | External API Handler | | 客户端 SDK | [sdk/client.go](../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 | 简化验证 |