Capability Manifest 规范 (v1)
本页是 A2H Capability Manifest v1 协议的权威规范。覆盖 Agent 如何声明 工具与权限、客户端如何发现与授权、tool call / tool response 的 wire 协议、breaking-change 检测、客户端安全契约。
1. 背景
1.1 问题
- A2H Protocol v0.3 缺少能力声明协议
- MsgSubtype 枚举已有
artifact_tool_call(Agent → User);User → Agent 走 现有artifact_response - 后端 DB / 验证器 / CRUD 路由当前缺
agents.capability_manifest和h2a_relations.granted_scopes列
1.2 E2EE 约束
- Tool call + tool response 是用户 ↔ Agent 流量,必须走 6 层 E2EE 管线
capability_manifest本身是公开 Agent 属性 — 后端可见故意如此: 用于发现与搜索
2. 设计
2.1 Manifest 提交
Agent 在 POST /agents 或 PATCH /agents/:id 时传 capability_manifest
JSON 字段。
DB schema:
| 列 | 类型 | 说明 |
|---|---|---|
agents.capability_manifest | jsonb | 完整 manifest JSON |
agents.capability_manifest_version | integer | 单调 +1(永不跳号) |
agents.capability_manifest_hash | text | SHA-256(canonical_json) hex |
h2a_relations.granted_scopes | jsonb (string[]) | 用户已授权的 scope IDs |
2.2 Manifest 完整格式
{ "schema_version": "1.0", "agent_version": "1.0.0", "tools": [ { "name": "read_file", "description_i18n_key": "agent.cap.read_file.description", "input_schema": { "type": "object", "properties": { "path": { "type": "string" } }, "required": ["path"], "additionalProperties": false }, "permission_scope": "filesystem:read", "required": false, "timeout_ms": 5000 } ], "permission_scopes": [ { "id": "filesystem:read", "label_i18n_key": "agent.scope.filesystem_read.label", "description_i18n_key": "agent.scope.filesystem_read.description", "sensitivity": "medium" } ], "capability_flags": { "supports_streaming": true, "supports_artifacts": true, "supports_voice": false, "supports_group_chat": false }}2.3 字段约束
| 字段 | 约束 |
|---|---|
schema_version | 固定字符串 "1.0" |
agent_version | SemVer |
tools[].name | 正则 ^[a-z][a-z0-9_]{1,31}$;Agent 内唯一 |
tools[].input_schema | 合法 JSON Schema (Draft 2020-12) |
tools[].permission_scope | 必须匹配 permission_scopes[].id 之一 |
tools[].description_i18n_key | i18n key 引用 |
permission_scopes[].sensitivity | "low" | "medium" | "high" |
| 整体大小 | hard cap 128 KB(CI 强制);≥ 64 KB 触发 telemetry warning |
| 保留 scope 前缀 | hashee:*, system:*(平台拥有) |
2.4 客户端发现 + 授权
建立 H2A 关系时
- 用户发现 Agent →
GET /agents/:id返回 manifest body - 客户端按
permission_scopes分组渲染权限同意 UI(敏感度图标 + i18n 翻译) - 用户同意 →
POST /h2a/relations,body ={ agent_id, granted_scopes: [...] } - 后端持久化 grant 到
h2a_relations.granted_scopes
Manifest 变更时
- Agent owner 调
PATCH /agents/:id传新 manifest(用户 JWT;仅 owner 可改) - 后端 diff 新 vs 旧 manifest
- 后端 recompute
capability_manifest_hash+capability_manifest_version += 1 - 如 breaking:后端广播
h2a.reauth_required给所有有活跃 H2A 关系的用户 - 如非 breaking(如已授权 scope 下新增 tool / scope 或 tool 删除):静默同步
- 客户端收到
h2a.reauth_required→ 渲染”Agent 能力变更,是否继续?“页面 → 用户同意 →PATCH /h2a/relations/:id更新 scope 授权
2.5 Breaking-change 检测(服务端单源 diff 引擎)
强制架构:Breaking 判定仅在服务端做。客户端不本地判定;信任服务端
广播的 h2a.reauth_required 事件。
Breaking 规则(canonical,服务端):
| 变更 | Breaking? |
|---|---|
给 tool input_schema 加 required 字段 | ✓ |
| 改 input_schema 内字段 type | ✓ |
additionalProperties 从 true → false | ✓ |
从 enum 去掉值 | ✓ |
Tool permission_scope 提升敏感度(如 medium → high) | ✓ |
加新 permission_scopes 条目 | ✓ |
| 删 scope 或 tool | ✗(静默同步) |
additionalProperties 从 false → true | ✗ |
| 加 enum 值 | ✗ |
事件 emission:breaking 时后端 emit h2a.reauth_required 含
{ agent_id, new_manifest_version, new_manifest_hash, scopes_requiring_reauth }
通过 WebSocket 给所有受影响用户(webhook 配置的 Agent observer 也送)。
3. Tool Call 消息格式(复用现有 MsgSubtype)
关键不变量:V1 不新增 tool_call / tool_response MsgSubtype 值。
Agent → User 复用 artifact_tool_call;User → Agent 复用 artifact_response。
仅 artifact.subtype 字段区分 tool 流量。
3.1 Agent → User: tool call
msg_subtype = "artifact_tool_call"content_type = "artifact"- payload:
{ "type": "artifact", "artifact": { "subtype": "tool_call", "call_id": "call_abc123", "tool_name": "read_file", "arguments": { "path": "/Users/alice/notes.md" }, "permission_scope": "filesystem:read", "timeout_ms": 5000 }}3.2 User → Agent: tool response
msg_subtype = "artifact_response"content_type = "artifact"- payload:
{ "type": "artifact", "artifact": { "subtype": "tool_response", "call_id": "call_abc123", "status": "ok", "result": { "content": "...file content..." } }}3.3 Status + reason 枚举
| status | reason / error_code | 语义 |
|---|---|---|
ok | — | 执行成功 |
error | TOOL_PLATFORM_ERROR | 运行时 / 平台错误 |
error | TOOL_INVALID_ARGUMENTS | 参数未通过 input_schema 验证 |
error | TOOL_UNAVAILABLE | 客户端不支持(如 mobile 无 filesystem) |
denied | user_refused | 用户通过提示拒绝 |
denied | scope_not_granted | 客户端检测 scope 不在 granted_scopes |
denied | tool_not_declared | 客户端检测 tool 不在 manifest |
denied | user_timeout | sensitivity:high 提示在超时内未确认 |
denied | tool_not_supported_in_group | V1 禁用群聊 tool call |
denied.reason 是稳定机器枚举(全小写 snake_case,无空格)—— 外部
开发者可分支判断。
3.4 参与者
Tool call + tool response 都走完整 6 层 E2EE 管线。参与者:
- H2A 一对一:发送方 + 接收方
- H2G 群聊:V1 禁用群内 tool_call。Group-level tool 语义(谁执行 /
谁可见结果 / scope 授权是 per-group 还是 per-member)未解决,deferred 到 V2。
capability_flags.supports_group_chat = true仅表示”Agent 参与群对话”, 不表示”Agent 可在群内 tool_call”。客户端在群对话内收到 tool_call → 回复denied + reason: tool_not_supported_in_group。
4. 客户端安全契约
收到 tool call 时,客户端必须:
- 验证
tool_name存在于缓存的manifest.tools[]。不存在 → 回denied: tool_not_declared - 验证
permission_scope存在于缓存的h2a_relation.granted_scopes。不存在 →denied: scope_not_granted - 验证
arguments符合声明的input_schema。不符 →error: TOOL_INVALID_ARGUMENTS - 应用敏感度策略:
| 敏感度 | UI 行为 | 超时 |
|---|---|---|
high | 每次调用都弹窗(即使 scope 已授权) | 30 秒未确认 → denied: user_timeout |
medium | 首次弹窗 + 同设备同会话 24 小时内静默(sliding window) | — |
low | 静默执行 | — |
- 执行 tool,返回带匹配
call_id的tool_response - 追加客户端本地审计日志条目(
{ call_id, agent_id, tool_name, scope, arguments_digest, status, timestamp };arguments_digest是 SHA-256 摘要,不存明文;保留 30 天)
5. 后端安全契约
后端不参与 tool 执行(盲管道)。
| 项 | 状态 |
|---|---|
| Manifest 签名 | V1 不签名(明文 JSON 存);V2 评估 Agent Ed25519 签名 + 客户端独立验证 |
| 速率限制 | agent.tool_call 发送:60 条/分钟/Agent |
| 超限 | HTTP 429(客户端不另行 rate-limit) |
6. V1 预置 scope(i18n bundle)
| Scope ID | Label | Sensitivity |
|---|---|---|
notification:send | 发送系统通知 | low |
filesystem:read | 读取本地文件 | medium |
clipboard:read | 读取剪贴板 | medium |
location:read | 读取位置 | high |
其它约定 scope(filesystem:write / shell:exec / camera:use 等)V1
不预置;用此类 scope 的 Agent 必须在 manifest 提供 *_fallback 文案。
跨规范关系
| 文档 | 连接 |
|---|---|
| E2EE 规范 | Tool 消息走完整 6 层 E2EE 管线 |
| Agent 开发者平台规范 | Manifest 在 POST /agents 提交 |
| Webhook 投递规范 | Tool 消息也通过 webhook 投递(message.new / artifact_response) |
| A2H Protocol v0.4 (内部 spec) | §4 Capability Manifest + §5 Tool Call Flow + §6 Permission Scopes |
| MsgSpec v6.1 (内部 spec) | artifact subtypes tool_call + tool_response |
验收清单 (Stage 3 closeout)
-
capability_manifestJSONB 列在agents表 + 128 KB hard cap -
capability_manifest_version(monotonic int) +capability_manifest_hash(SHA-256 hex) -
granted_scopesJSONB 列在h2a_relations表 + 默认[] - 服务端 manifest diff engine emit
h2a.reauth_required按 §2.5 规则 - 客户端
tool_callhandler 强制 §4 验证链 - 客户端 tool-call 审计日志保留 30 天 + 只存
arguments_digest - 后端速率限制
agent.tool_call = 60/min/agent - V1 launch 文案不声称群内 tool call 支持;群内调用回
tool_not_supported_in_group -
TOOL_*错误码注册在 errors.ts
相关页面
- Capability Manifest 声明 — Agent 视角操作
- SDK Tool Call — SDK 封装与代码示例
- Artifact 高级 — 双向交互 — artifact_update / revision
- Agent 开发者平台规范
- Webhook 投递规范