最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
为什么 ACC Core 不能和 OpenAPI、MCP 或 gRPC 绑死?
时间:2026-08-27 11:11:51 编辑:袖梨 来源:一聚教程网
假设一家企业已经有三种系统:

商城后台:通过 OpenAPI 描述 HTTP 接口内部微服务:通过 protobuf 定义 gRPC 方法Agent 工具网关:通过 MCP 暴露工具它们最终都可能触发相同的业务动作:
创建退款申请如果这项动作允许 Agent 使用,治理层仍然需要知道:
是否显式开放给 Agent; 用什么稳定 scope 引用; 后果风险是什么; 是否要求可信行动主体; 什么条件下产生审批意图; 是否含敏感数据; 是否只读、幂等,以及建议的执行边界。这些问题不会因为调用通过 HTTP、gRPC 还是 MCP 而消失。
但它们也不能被简单地复制成三套彼此独立的字段体系。否则同一项业务能力会随着传输方式变化而获得不同治理含义:
OpenAPI 中 high 表示高风险MCP 中 high 表示需要审批gRPC 中 high 又表示高优先级这样的“支持多个协议”只会制造新的碎片化。
更可靠的设计必须把两件事分开:
OpenAPI 是 ACC v1 的首个标准 Binding,但 ACC Core 的身份不等于 x-agent-capability,更不等于 HTTP。
1. Core 和 Binding 回答的是两组不同问题
ACC Core 回答:
一项 Agent-facing 业务能力需要声明哪些稳定治理事实?Binding 回答:
在某一种载体里,这份声明放在哪里、怎样提取、怎样和原生 Schema 对齐?可以把分工概括为:
| 层次 | 核心问题 |
|---|---|
| ACC Core | 字段是什么意思,默认值、失败语义和兼容规则是什么 |
| Binding | 声明放在哪里,如何映射参数、类型、描述和原生元数据 |
| Runtime | 如何消费已验证能力、暴露工具并执行确定性治理 |
| Business System | 当前主体能否对当前对象产生真实业务后果 |
这四层经常在同一条链路中协作,但任何一层都不能因为“实现方便”而吞掉其他层的责任。
2. x-agent-capability 是 OpenAPI 承载方式,不是 ACC Core 本身
在 OpenAPI 中,ACC v1 使用 operation 级扩展:
paths:/refunds:post:operationId: createRefundRequestx-agent-capability:version: 1enabled: truescope: refund.request.createrisk:level: high这里有两个不同对象:
OpenAPI operation-> 描述路径、方法、参数、请求体和响应x-agent-capability-> 承载 ACC Core 声明对象x-agent-capability 只是 OpenAPI Binding 选择的放置位置。
如果未来存在经过规范化和验证的 gRPC Binding,它不可能继续使用 OpenAPI extension field;如果存在 MCP Binding,它也必须遵守 MCP 自己的对象结构和扩展规则。
但不论载体怎样变化:
risk:level: high都不能在新 Binding 中被重新解释为“无条件审批”或“禁止调用”。
Core 的意义就在于:
3. 为什么不能把所有内容都放进 Core
既然 Core 要跨协议稳定,是否应该把路径、方法、参数和响应也全部纳入?
不应该。
这些内容已经由 Binding 原生机制表达:
| 信息 | OpenAPI | gRPC / protobuf | MCP |
|---|---|---|---|
| 操作标识 | path、method、operationId | service、method | tool name |
| 输入结构 | parameters、requestBody、JSON Schema | request message | input schema |
| 输出结构 | responses、JSON Schema | response message | tool result |
| 描述与示例 | summary、description、examples | comments、annotations | description 等原生机制 |
如果 ACC 再定义一套:
parameters:responses:transport:method:它会立即产生两个事实来源:
OpenAPI 说 amount 是 numberACC 又说 amount 是 string运行时只能猜哪一个正确。
因此,Core 只保留具有可移植治理意义的字段:
versionenabledscoperisksubjectapprovalauditexecutionguidanceBinding 继续复用自己的原生 Schema。
这不是 ACC 功能不够,而是避免重复协议事实的设计纪律。
4. 一个合格 Binding 必须定义什么
“把 ACC 字段塞进另一个协议”还不足以构成 Binding。
一个可互操作 Binding 至少需要回答六组问题。
4.1 声明放在哪里
OpenAPI Binding 已明确要求:
放在 operation object不放在 document root、path item、schema、parameter 或 response未来的 Binding 也必须选择一个稳定、无歧义的承载对象。
如果同一份声明可以同时出现在服务、方法和参数上,却没有明确优先级,不同解析器就会产生不同结果。
4.2 operation 的稳定引用是什么
运行时、审计系统和兼容性报告必须能够指出:
这份 ACC 声明绑定的是哪一项原生操作?OpenAPI 可以使用绑定限定的 path、method 或 operation reference。
其他协议需要定义自己的限定方式,而不能假设一个裸 scope 就能替代原生 operation 身份。
scope 是治理标识,Binding operation reference 是载体中的具体操作引用,两者用途不同。
4.3 原生输入怎样映射到 JSON 值模型
ACC 条件审批使用严格 JSON 类型:
objectarraystringfinite numberbooleannullOpenAPI 的 JSON Schema 与这个模型较接近。
但 protobuf 可能包含:
int64; bytes; enum; oneof; map; field presence; well-known timestamp; 默认值与未出现字段的差异。 Binding 必须说明这些原生值如何映射。
如果无法无损表达,就必须拒绝或跳过受影响声明并给出诊断,不能静默转换。
例如:
原生 int64 超过 JavaScript 安全整数-> 不能悄悄转成不精确 number-> 否则 amount > 100000 的审批判断可能改变4.4 approval.when.param 怎样解析
下面的条件:
approval:when:- param: amountop: ">"value: 1000只有在 amount 能确定解析到原生输入字段时才有意义。
Binding 必须定义:
路径从哪个输入根开始; 嵌套对象如何寻址; 多个参数位置怎样合并; 引用如何解析; 数组和可选字段怎样处理; 同名字段冲突时如何失败。两个兼容同一 Binding 的实现,必须把同一路径解析到同一输入。
否则,同一份审批声明会在不同运行时触发不同结果。
4.5 原生元数据与 ACC 怎样确定优先级
承载协议可能已经具有相关信号:
OpenAPIdeprecated; HTTP GET; MCP 只读或破坏性提示; protobuf 自定义 options; 原生 description 和 examples。 Binding 必须说明:
哪些原生信号可以映射; 哪些只是参考; 显式 ACC 字段与原生信号谁优先; 冲突时怎样诊断; 缺失时怎样保守回退。它不能看到一个相似字段名就自行赋予 ACC 语义。
4.6 失败时怎样保持保守
Binding 解析失败不能生成一个治理更弱的工具。
例如:
x-agent-capability 解析失败-> 跳过该 operation 并给出诊断不能变成:
x-agent-capability 解析失败-> 当作普通工具继续暴露后者会让“治理声明写错”自动退化成“没有治理”,这正是最危险的失败方式。
5. Validated Capability Artifact 为什么重要
Core 与 Binding 分开后,运行时不一定要亲自解析每一种协议。
Binding Parser 可以向运行时提供一个经过验证的能力产物,概念上包含:
ACC declarationbinding-qualified operation referencebound input schemabinding name and supported versiondiagnostics它可以表现为:
内存对象; 编译后的工具定义; 生成代码; 网关路由; 缓存记录; 其他等价结构。ACC 不强制规定一个新的线格式。
这个抽象带来两个价值。
价值一:运行时不必耦合所有协议解析器
OpenAPI ParsergRPC ParserMCP Adapter-> 统一产出经过验证的 capability artifact-> Runtime 消费稳定 Core 语义运行时可以专注于暴露、主体、审批、审计和执行,不必把每种协议的全部解析逻辑塞进核心。
价值二:Binding 可以独立测试
一个解析器是否正确,不必等到真实退款执行后才知道。
它可以用 conformance vectors 验证:
placement 是否正确; malformed declaration 是否被拒绝; 参数路径是否确定解析; 类型是否严格; unsupported version 是否诊断; schema 不足时是否保守跳过。这让“支持某个 Binding”从营销措辞变成可以核验的兼容性声明。
6. 为什么 MCP 不能自动等于 ACC Binding
MCP 解决工具、资源和提示的连接与调用生态。
ACC 解决 Agent-facing 业务 operation 的可移植治理声明。
两者可以组合:
ACC 标注的业务 operation-> 被网关编译成 MCP tool-> MCP 客户端发现并调用-> 运行时继续执行 ACC 治理但“通过 MCP 调用”本身不能证明:
Core 字段被完整保留; 风险默认值一致;approval.when 参数路径一致; subject trust 边界一致; 未知字段和失败行为保守; 原生 annotations 与 ACC 的优先级明确。 所以一个 MCP adapter 可以是有价值的实现,却不能仅凭字段复制就宣称形成了标准 ACC Binding。
正式 Binding 还需要:
公开的映射规范; 失败语义; 类型映射; 机器可读测试向量; 独立实现证据; 明确的兼容性声明语言。7. 为什么 gRPC 也不能只加几个 protobuf option
protobuf 的 option 扩展机制确实适合承载元数据。
一种实验性设计可能看起来像:
rpc CreateRefund(CreateRefundRequest) returns (RefundRequest) {option (...) = {enabled: truescope: "refund.request.create"};}但这只是开始。
一个真正的 gRPC Binding 还必须回答:
option 挂在 service 还是 method; proto2、proto3 和 editions 如何处理 presence; enum、oneof、map、bytes 和 int64 如何映射; well-known types 如何进入 JSON 值模型; request field path 如何解析; streaming RPC 是否适合作为一项 ACC operation; client streaming、server streaming 和 bidi streaming 的结果语义是什么; reflection 不可用时怎样获得 Schema; code generation 与运行时 reflection 的兼容证据是什么。所以“protobuf 天然支持扩展”不等于 Binding 已经完成。
它说明方向可能可行,不说明跨实现语义已经稳定。
8. 同一项能力跨协议时,什么必须保持不变
假设同一项退款能力分别通过 HTTP、gRPC 和 MCP 暴露。
Core 层至少应保持:
version: 1enabled: truescope: refund.request.createrisk:level: highsubject:required: trueapproval:when:- param: amountop: ">"value: 1000audit:sensitive: trueexecution:readonly: falseidempotent: trueBinding 层可以不同:
| Binding | operation 载体 | 输入 Schema |
|---|---|---|
| OpenAPI | HTTP operation object | parameters requestBody |
| gRPC(未来候选) | protobuf RPC method | request message |
| MCP(未来候选) | tool 或明确映射对象 | tool input schema |
但下面这些结果不能因 Binding 改变:
enabled: false 不得暴露; scope 缺失不得作为有效能力暴露; high 不能被重新解释; subject requirement 不能被原生 description 抵消; amount 条件必须使用相同类型和值语义; Schema 不足时不能降级成无治理工具; 最终业务授权仍由业务系统持有。 传输可以变化,治理语义不能漂移。
9. Binding 不能替代运行时
解析出声明不等于治理已经执行。
Binding Parser 可以证明:
这项 operation 带有合法 ACC 声明amount 条件能解析到 number 输入当前声明版本受支持它不能自动证明:
路由 allowlist 已经配置可信主体已经解析审批系统已经收到并绑定精确参数审计记录已经持久化幂等由业务系统兑现最终权限已经校验因此完整链路仍然是:
Binding-> 提取并验证声明与原生 SchemaRuntime-> 暴露能力并执行确定性治理Business System-> 校验实时权限和业务状态,产生最终结果把 Parser 宣称成控制面,和把 API 文档宣称成授权系统一样不准确。
10. Binding 也不能替代业务系统
即使所有协议都完美保留 ACC 语义,运行时仍然不知道:
当前订单属于哪个租户; 可退余额是否变化; 员工是否已经离职; 合同是否进入锁定状态; 当前主体是否仍有资源级权限; 业务对象是否刚被另一事务更新。这些事实只能由持有新鲜业务状态的一侧判断。
Core 与 Binding 分层并没有改变 Reach 与 Authority:
Core Binding Runtime-> 控制 Agent 最多能触达和怎样尝试调用Business System-> 决定当前主体此刻是否真的可以做跨协议一致不等于跨过最终授权。
11. 为什么“先支持一个 Binding”比同时支持所有协议更专业
标准早期很容易追求一张漂亮的兼容矩阵:
OpenAPI ✓MCP ✓gRPC ✓A2A ✓但每个勾如果没有类型映射、失败行为和测试证据,就只是“我们可以读取几个字段”。
先把一个 Binding 做完整,至少可以验证:
Core 是否真的独立; 参数路径是否可复现; 默认值和优先级是否明确; Parser 与 Runtime 的责任是否能分开; conformance 是否可以被第三方实现; 错误声明是否保守失败。这比同时发布多个无法互操作的草案更有价值。
OpenAPI 作为 ACC v1 首个标准 Binding,代表的是当前可验证范围,不是对其他协议的否定。
未来 Binding 应当通过新的证据扩展生态,而不是用文档里的一个“支持”标签提前制造兼容性承诺。
12. 十二个常见误区
误区一:ACC 就是 OpenAPI 扩展字段
OpenAPI extension 是首个 Binding 的承载方式,Core 是其中的声明语义。
误区二:只要字段名相同,两个 Binding 就兼容
类型映射、参数路径、优先级和失败行为也必须一致。
误区三:MCP 已经能传工具,所以不需要治理声明
传输和工具发现不自动回答风险、主体、审批和业务责任边界。
误区四:有 ACC 就不需要 MCP
ACC 不替代连接、会话、调用和工具传输协议。
误区五:protobuf 有 options,gRPC Binding 就很简单
承载字段容易,稳定定义输入映射和流式语义更难。
误区六:Binding 可以重新定义 Core 字段
Binding 只能映射和补充协议特定规则,不能改变 Core 含义。
误区七:原生 metadata 可以静默升级风险
任何映射都需要明确的信任、优先级、默认值和保守失败语义。
误区八:解析失败时继续暴露普通工具更友好
这会让治理错误变成安全降级,应当跳过或拒绝并给出诊断。
误区九:Validated artifact 必须成为新网络协议
它是概念接口,可以是内存模型、生成代码或网关路由。
误区十:支持 Parser 就等于支持完整 Runtime
解析兼容和执行治理是不同 conformance profile。
误区十一:跨 Binding 一致就等于拥有最终权限
最终授权仍由掌握实时业务状态的系统决定。
误区十二:未来可能适用,就可以现在宣称兼容
研究方向必须与当前规范范围分开;正式兼容需要 Binding、测试和独立实现证据。
13. 一份 Binding 设计检查表
为新的载体设计 ACC Binding 前,可以逐项检查:
[ ] 是否明确声明了 Binding 名称、版本和规范状态? [ ] 是否定义了声明的唯一合法放置位置? [ ] 是否给出 binding-qualified operation reference? [ ] 是否完整定义原生输入到 JSON 值模型的映射? [ ] 是否处理了大整数、bytes、enum、presence、union 和引用? [ ]approval.when.param 是否能确定性解析? [ ] 同名或歧义输入是否保守拒绝,而不是静默选择? [ ] 原生 description、examples、deprecated 和行为 annotations 的优先级是否明确? [ ] 原生限制是否永远不会被 ACC 元数据削弱? [ ] 解析失败是否跳过或拒绝能力,而不是降级为普通工具? [ ] 是否提供最小有效示例和异常示例? [ ] 是否提供机器可读 Parser vectors? [ ] 是否区分 Parser、Generator、Runtime 和 Policy Component 声明? [ ] 是否有至少一个可复现实现,最好还有独立实现证据? [ ] 是否明确最终业务授权仍不属于 Binding? 14. 结语:开放不是支持所有协议,而是允许语义脱离协议继续成立
一个真正开放的能力契约,不是把同一份 YAML 粘贴到尽可能多的平台。
它需要做到:
协议可以更换传输可以更换解析器可以更换运行时可以更换但同一治理字段的含义不能更换这正是 Core 与 Binding 分层的价值。
Core 保留不同实现必须共享的最小语义。
Binding 尊重每种协议自己的操作模型、Schema 和元数据,并承担确定映射和保守失败。
Runtime 将经过验证的能力变成可以执行的治理链路。
Business System 继续持有最终 Authority。
OpenAPI 是 ACC v1 的首个标准 Binding,因为它为现有业务 API 提供了一个可落地、可测试的起点。
MCP、gRPC 或其他载体未来是否形成正式 Binding,应当由公开规范、失败语义、测试向量和独立实现证据决定,而不是由字段看起来能否塞进去决定。
标准的扩展能力,不在于它承诺覆盖一切。
而在于它能够在扩展时,仍然守住同一份语义和责任边界。