news 2026/8/25 19:18:57

Agent 能力契约为什么不能包办一切?审批人、租户隔离和事务编排为什么不该进入 ACC 核心

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Agent 能力契约为什么不能包办一切?审批人、租户隔离和事务编排为什么不该进入 ACC 核心

一份面向 Agent 的能力契约,应该描述到什么程度?

当开发者第一次看到 ACC(Agent Capability Contract,Agent 能力契约)里的enabledscoperisksubjectapprovalexecution,很容易继续追问:

  • 既然已经有approval,为什么不直接声明谁能审批、要几级会签?
  • 既然已经有subject,为什么不把tenant_id、角色和数据权限一起标准化?
  • 既然已经有条件审批,为什么不支持累计金额、跨工具前置条件和事务回滚?
  • 既然要让 Agent 安全办事,为什么不把整套企业策略都写进同一份契约?

这些问题都很合理。

但答案不是“ACC 还没来得及加字段”,而是:其中很多能力有意没有进入 ACC Core。

一个开放契约的目标,不是用一份越来越大的 YAML 接管企业已有的身份系统、审批平台、租户模型和工作流引擎。它应该只标准化那些能够被不同运行时一致理解、确定执行并通过 Conformance 验证的最小治理语义。

这篇文章只讨论一个核心问题:

为什么审批人、租户隔离、业务规则和事务编排明明都很重要,却不应该被塞进 ACC 核心?

我们也会结合 BailingHub 的实现说明:标准没有定义某项能力,不等于产品不能实现;产品实现了某项能力,也不等于它自动成为开放标准的一部分。

一、先看一份“什么都想管”的巨型注解

假设我们准备给退款接口增加 Agent 能力声明,并试图一次性把所有规则写进去:

# 下面是刻意设计的反例,并不是 ACC 字段x-agent-capability:enabled:truescope:refund.executeapproval:approver_role:finance_managerlevels:2delegates_allowed:truetimeout:24hescalation_to:finance_directortenant:source:jwt.claims.tenant_idisolation:row_leveltable_field:merchant_idpolicy:expression:amount <= order.refundable_amountdata_source:mysql.orderstransaction:steps:-freeze_balance-create_refund-update_order-notify_customercompensate:create_refund:cancel_refundfreeze_balance:unfreeze_balance

它看起来很完整,甚至很“企业级”。

但换一个组织,问题马上出现:

  • 审批人可能不来自role,而来自部门、金额区间、项目归属、临时授权或 OA 流程;
  • 有的系统使用 JWT,有的使用 PHP Session、企微成员 ID、证书、服务账号或签名票据;
  • 有的租户按数据库隔离,有的按 Schema、行级字段、组织树、商户关系或资源归属隔离;
  • refundable_amount是实时业务状态,不是能力契约中的常量;
  • 退款的补偿不一定等于调用一个反向接口,还可能涉及资金渠道、对账、人工介入和不可逆外部通知;
  • 无 UI 的网关、队列消费者和命令行 Agent,根本没有同一种审批交互界面。

于是,这份看似统一的声明实际上只是把某个产品、某个组织和某套数据库的假设写成了公共字段。

其他实现即使能解析 YAML,也无法以相同语义兑现它。

这不是可移植标准,而是把私有业务系统藏进注解里。

二、一个字段进入 ACC Core,必须先通过六道门

ACC 的设计依据给出了一组核心字段准入测试。一个新字段至少需要同时满足:

  1. 它会改变可移植的 Agent 治理语义;
  2. 相互独立的 Parser 或 Runtime 能实现相同含义;
  3. 不依赖某个产品的私有数据库、UI、身份目录或工作流,就能测试行为;
  4. 目标 Binding 的原生 Schema 和标准机制尚不能清晰表达它;
  5. 它不要求 Agent Runtime 成为最终业务授权方;
  6. 旧运行时忽略它时不会静默降低安全性,否则必须进入新的 Major 兼容边界。

即使全部通过,也只代表这个字段有资格进入治理评审,还要继续回答:

  • 是否在多个独立实现中出现了同一种需求;
  • 默认值、优先级和失败语义是否完整;
  • 是否具备机器可读测试向量;
  • 是否存在更合适的 Binding、扩展或相邻协议;
  • 加入核心后,生态实现成本是否值得。

这组测试背后有一个朴素原则:

字段不是越多越安全。无法被不同实现一致执行的字段,只会制造“已经治理”的错觉。

三、为什么 ACC 声明“需要审批”,却不声明“谁来审批”

ACC 可以声明一项调用需要形成审批意图:

approval:required:true

也可以针对本次调用参数声明条件审批:

approval:when:-param:amountop:">"value:1000label:退款金额超过 1000 元

这两种语义都具有可移植性。

任何合规 Runtime 都可以观察到一次具体调用的amount,按严格 JSON 类型比较,并确定:

本次调用是否应该先产生审批意图

但下面的问题没有统一答案:

谁有资格批准? 在哪里批准? 需要几个人? 是否允许委托? 审批多久过期? 主管休假时如何升级? 法务和财务是串行还是并行? 批准记录由谁签名并长期保存?

这些答案依赖组织结构、权限目录、业务类型、审批系统、合规要求和实时状态。

如果 ACC 增加一个看似方便的字段:

approval:approver:finance_manager

它会立即引入一串无法由 Core 回答的问题:

  • finance_manager是角色名、用户组、岗位编码还是外部目录 Claim?
  • 谁证明当前审批人属于这个角色?
  • 角色刚刚被撤销怎么办?
  • 跨公司、跨租户时,这个角色属于哪个组织?
  • 代理审批、会签和条件升级怎样表达?
  • 一个无 UI Runtime 应该把审批送到哪里?

因此,ACC 只声明审批意图,不定义审批流程所有权。

BailingHub 怎样承接这条边界

BailingHub 会在高风险或条件命中的调用上冻结具体调用快照,形成ApprovalIntent,其中包含:

job_id request_id subject tool scope risk args args_hash

审批可以被投递到业务侧 Webhook、IM/OA 卡片,或由中枢控制台在轻量场景中兜底。业务侧返回ApprovalDecision时,中枢会复核任务身份和args_hash,只放行与批准快照完全一致的那次调用。

但 BailingHub 仍不维护企业的组织关系、审批人权限和多级审批规则。生产环境中,谁能审、在哪里审、是否会签、审批证据如何归档,仍由业务审批所有者决定。

这说明:

ACC:声明需要审批 BailingHub:冻结调用、投递意图、验证决策、精确放行 业务审批系统:决定谁能批准以及流程如何完成

三层缺一不可,但不能互相冒充。

四、为什么subject.required不等于标准化租户隔离

ACC 可以声明:这项能力必须存在可信行动主体。

subject:required:true

它的可观察结果很明确:当 Runtime 没有可信主体时,该工具不应该暴露给 Agent,也不应该在调用层被放行。

但 ACC 不规定主体必须长什么样。

真实系统可能使用:

  • tenant_1:user_1001这样的结构化主体;
  • JWT 中经过验证的租户和用户 Claim;
  • 后台 Session 对应的员工 ID;
  • 企微、飞书或钉钉成员标识;
  • mTLS 证书绑定的服务主体;
  • 业务系统签发的短期票据;
  • 服务账号加单独的委托证明。

这些机制的发行者、有效期、信任域和撤销方式完全不同,不能因为都包含一个字符串,就被视为同一种身份保证。

租户隔离为什么必须留在业务系统

假设工具入参中有:

{"tenant_id":"tenant_2","order_id":"SO-1001"}

如果tenant_id来自模型输出,用户只要要求模型换一个值,就可能尝试访问其他租户。

即使tenant_id由网关注入,也仍然不能代替业务系统自己的对象级检查。因为攻击者或内部服务可能绕开 Agent Runtime,直接访问原 API。

真正的租户隔离应该满足:

无论请求来自人类后台、Agent Runtime、内部任务还是直接 API 调用 -> 业务系统都从可信身份上下文恢复租户 -> 查询和写入都限定在授权数据边界内 -> 目标对象不属于该租户时 fail closed

ACC 的subject.required可以阻止匿名 Agent 获得这项工具,scope可以限制某条 Agent 路由最多触达哪些能力,但它们都不是最终租户权限。

BailingHub 的实现方式

BailingHub 把可信业务主体作为不透明值传给业务工具,并将其钉入请求签名。接入方可以使用tenant_1:user_1001之类的结构化主体,也可以映射成自己的身份形式。

中枢不解释这个主体究竟对应哪张用户表、哪个商户层级或哪种行级策略。业务 API 验证调用来源后,仍要:

  1. 解析可信主体;
  2. 恢复真实租户上下文;
  3. 查询原业务权限;
  4. 核对目标订单、员工或资源归属;
  5. 在不满足条件时拒绝。

这不是 BailingHub “少做了一层”,而是避免把每个 SaaS 完全不同的租户模型硬编码进通用中枢。

五、为什么单次条件审批不能变成通用策略引擎

ACCapproval.when有意只处理有限、类型安全的单次调用条件。

例如:

approval:when:-param:amountop:">"value:1000

Runtime 可以确定性地判断当前 JSON 参数是否命中。

但它不表达累计、滚动窗口、跨调用或序列约束。

例如,下面三次调用都没有单次超过 1000 元:

第 1 次退款:400 元 第 2 次退款:400 元 第 3 次退款:400 元

如果业务规则是“同一订单当日累计退款超过 1000 元必须财务复核”,只看每次调用的amount就会漏掉累计 1200 元的事实。

要正确计算它,系统必须知道:

  • 哪些历史调用已经成功;
  • 哪些仍在审批或结果不确定;
  • 统计窗口使用哪个时区;
  • 退款撤销后是否释放额度;
  • 多实例并发时如何原子更新;
  • 当前业务数据是否仍然新鲜。

这些已经不是一个参数条件,而是一套有状态策略系统。

同理,下面的规则也不适合直接塞进 ACC Core:

退款金额 <= 当前订单可退余额 员工只能导出自己管理部门的数据 过去 24 小时累计发券不超过 5000 张 先完成库存预占,才能创建订单 合同金额变更后必须重新执行法务检查

它们依赖权威业务数据、读取权限、时效、并发和失败处理。ACC 如果只提供一个通用expression字符串,却不定义数据来源和一致性,就会制造半成品策略语言。

一个真正的通用策略引擎需要:

  • 类型系统;
  • 表达式语法;
  • 权威数据源;
  • 数据读取授权;
  • 时效和缓存规则;
  • 确定性失败语义;
  • 执行沙箱;
  • 冲突与优先级规则;
  • 可解释和可审计的决策结果。

这已经是 OPA、Cedar 或企业策略服务所在的责任层,而不是一个能力声明字段应该假装解决的问题。

六、为什么工具顺序、事务和补偿不属于能力声明

考虑一条“创建订单”的业务流程:

校验客户状态 -> 锁定库存 -> 创建订单 -> 扣减余额 -> 发送通知

如果第三步成功、第四步超时,系统应该怎样处理?

  • 回滚订单还是等待余额结果确认?
  • 库存锁定是否可逆?
  • 通知已经发送还能撤回吗?
  • 重试会不会重复扣款?
  • 补偿动作本身需要什么权限和审批?
  • 外部支付渠道返回不确定结果时,是否应该自动重试?

这不是五个工具描述的简单相加,而是一个 Saga、事务或工作流问题。

ACC 声明的是单项业务能力面向 Agent 的治理边界。它可以告诉 Runtime:

  • 某个工具是否启用;
  • 属于哪个scope
  • 自动发起的最坏后果等级;
  • 是否需要可信主体;
  • 本次参数是否命中审批;
  • 是否只读、幂等、需要超时或限流。

但“工具 A 成功后才能调用工具 B”“工具 B 失败后必须补偿工具 A”属于跨操作的状态机。

把这类顺序塞进能力声明,会让一个描述“能力是什么”的契约变成描述“业务流程怎么跑”的工作流语言。不同组织的重试、补偿、人工介入和一致性要求不可能靠几个通用字段自动统一。

BailingHub、n8n 和业务工作流怎样分工

BailingHub 可以承载持久任务、审批暂停、结果续查、工具调用幂等和 Trace,也可以由 Agent 在一个任务中选择多个工具。

n8n、LangGraph、业务流程引擎或自研服务则可以负责确定性的步骤编排。

但无论由谁编排,真正的业务事务语义仍需要业务所有者明确设计:

哪些步骤可以重试 哪些结果属于不确定 哪些动作需要补偿 补偿是否还要授权 什么时候必须转人工 最终状态由哪个系统记录

产品可以提供这些能力,ACC Core 不需要因此变成另一个工作流引擎。

七、“不进入 Core”不等于“无法表达”

业务私有信息仍然可以放在正确的位置。

1. 优先复用 Binding 原生机制

业务参数继续使用 OpenAPI Schema,响应结构使用标准responses,认证方案使用协议已有机制。ACC 不复制一套请求和响应 Schema。

2. 使用带命名空间的扩展

OpenAPI Operation 可以保留业务扩展:

x-business-owner:trade-teamx-business-policy:approval_scene:order_over_limitworkflow_key:refund_v3

ACC 兼容 Runtime 可以把它们放进扩展袋,交给明确支持这些字段的产品或二开模块消费。

关键边界是:

未经标准化的扩展不能静默改变scope、风险、审批、限流、审计或签名等安全行为。

否则,同一份声明在支持和不支持该扩展的 Runtime 中可能得到相反安全结果。

3. 把权威规则放回业务 API

例如:

退款金额不得超过当前可退余额

应由退款预检或执行 API 使用最新订单状态判断。即使调用绕过 Agent Runtime,这条规则也必须成立。

4. 把组织流程交给审批和工作流所有者

接口只声明“这项动作需要审批”,部署配置决定审批意图发往哪里;业务审批系统决定谁能审以及流程怎样完成。

这样既保留开放契约的可移植性,也不会阻止企业使用复杂流程。

八、ACC、BailingHub 和业务系统的完整责任图

可以把整条链路画成:

OpenAPI / MCP / 其他 Binding 负责接口事实与原生 Schema | v ACC 声明 enabled / scope / risk / subject / approval / audit / execution / guidance 负责可移植的 Agent 触达与治理意图 | v BailingHub 等 Agent Runtime 工具装配、路由白名单、可信主体闸、审批意图、参数快照、限流、幂等、审计、Trace | +------> 企业身份与委托系统 +------> OA / IM / 审批平台 +------> n8n / Saga / 业务工作流 | v 业务系统 Authority 租户隔离、对象权限、实时状态、业务不变量、最终写入与结果

其中:

  • ACC 负责让不同 Runtime 对最小治理语义形成共同理解;
  • BailingHub 负责消费声明并执行具体控制面机制;
  • 企业现有身份、审批和工作流系统继续承担各自权威责任;
  • 业务系统在调用时做最终授权。

“薄标准”并不是缺少这些组件,而是拒绝对不属于自己的组件作虚假保证。

九、一条真实接入应该怎样落地

第一步:先把业务动作拆成原子能力

不要把“完成整套退款流程”暴露成一个含糊工具。优先拆成:

refund.preview refund.request.create refund.status.get refund.execute

查询、预检、创建申请和真实执行具有不同后果,也应有不同风险与审批策略。

第二步:用 ACC 声明可移植治理意图

x-agent-capability:version:1enabled:truescope:refund.request.createrisk:level:mediumsubject:required:trueapproval:when:-param:amountop:">"value:1000audit:sensitive:trueexecution:readonly:falseidempotent:false

这份声明让 Runtime 知道 Agent 是否可触达、是否需要主体、何时先形成审批意图,以及调用应怎样被审计和约束。

第三步:由业务侧建立可信主体

用户登录、租户归属和身份票据应来自可信业务代码,不经过模型生成。Runtime 只接受经过验证的主体上下文。

第四步:接入真实审批所有者

生产环境优先让审批意图进入现有 OA、IM 或业务审批页。审批回调需要绑定任务、工具和精确参数快照,不能只返回一个裸approved=true

第五步:业务 API 继续执行最终授权

验签成功只证明请求来自可信中枢,不证明该主体有权操作目标对象。业务系统仍要校验租户、角色、资源归属、订单状态和业务不变量。

第六步:多步骤流程交给确定性编排

需要顺序、等待、重试、补偿或人工介入时,使用业务工作流、Saga、n8n 或其他显式状态机。不要把跨步骤事务寄托在模型临场规划上。

第七步:用负向测试验收边界

至少验证:

  • 无可信主体时,受保护工具不可见且调用被拒;
  • 错误args_hash的审批决策无法放行;
  • 审批人权限被撤销后,审批系统拒绝决策;
  • 伪造其他租户资源时,业务 API fail closed;
  • 多次小额调用命中业务累计上限时仍被拦截;
  • 工作流中途失败时按已定义状态进入重试、补偿或人工对账;
  • 绕过 Agent Runtime 直接调用业务 API 时,租户和业务规则仍然成立。

十、怎样判断一个新字段应不应该进入 Core

以后再遇到“能不能给 ACC 加一个字段”的问题,可以先用下面的清单过滤。

可移植性

  • 两个没有共享私有代码的 Runtime,能否给出相同解释?
  • 字段是否依赖某个组织的角色名、数据库或 UI?

可测试性

  • 能否用有限输入和预期输出形成机器可读测试向量?
  • 失败时应该拒绝、降级还是产生更多审批,是否足够明确?

层级归属

  • Binding 的原生字段是否已经能表达?
  • 它是否实际上属于身份、授权、审批证据、策略或工作流协议?
  • 是否要求 Runtime 读取业务私有数据并成为最终授权方?

安全兼容

  • 旧 Runtime 忽略它时会不会更宽松?
  • 如果会,是否需要新的 Major 家族或能力协商,而不是悄悄增加一个可选字段?

实现证据

  • 是否已经在多个独立实现中出现同一问题?
  • 是否先通过带命名空间的扩展完成过真实验证?

如果这些问题还没有答案,先作为实现扩展存在,通常比急着进入 Core 更安全。

十一、标准与产品必须允许不同速度演进

ACC 是实现中立的能力契约。

BailingHub 是消费 ACC 的一个开源实现。它可以提供:

  • 审批意图账本和回调;
  • 主体传递与签名;
  • 持久任务和有界等待;
  • 幂等、限流、审计和 Trace;
  • 控制台、渠道适配与运行状态。

这些产品能力可以比标准更快演进,也可以保留部署特有的选择。

但不能反过来说:因为 BailingHub 实现了一个功能,所以 ACC Core 必须增加同名字段。真正进入标准的语义,需要证明它能够跨实现成立,并具备明确的 Conformance 行为。

同样,其他 Runtime 可以用完全不同的数据库、审批系统和身份桥实现 ACC,只要它对规范字段给出一致的可观察结果。

标准与产品分离,带来的不是割裂,而是两个重要自由:

标准可以保持中立、稳定和可移植 产品可以针对真实部署快速完善运行能力

十二、写在最后:边界清楚,才是真正的完整

企业 Agent 当然需要审批人、租户隔离、业务策略和事务编排。

但“需要”不等于“都应该由一个契约定义”。

一份可靠的能力契约,应该准确声明自己能够兑现的最小语义,并明确把其他责任交还给真正拥有权威数据和组织流程的系统。

所以 ACC 的完整性不体现在字段覆盖了多少企业名词,而体现在责任链有没有断裂:

ACC 声明 Agent 触达与治理意图 -> Runtime 确定性执行暴露、主体、审批和审计闸门 -> 身份、审批与工作流系统完成自己的权威职责 -> 业务系统在最新状态下做最终授权

如果把审批人、租户模型和事务编排全部塞进 Core,契约可能更厚,却会更依赖单一产品、更难一致实现,也更容易对外作出无法兑现的安全承诺。

真正成熟的标准,不是看到所有问题都增加字段。

而是知道哪些问题必须标准化,哪些问题必须留在标准之外,并让两边通过清晰接口协作。

项目、规范与真实 API 评估入口

  • ACCv1.0.5规范:https://github.com/agent-capability/agent-capability-contract/blob/v1.0.5/SPEC.md
  • ACC 中文设计依据与边界:https://github.com/agent-capability/agent-capability-contract/blob/v1.0.5/DESIGN_RATIONALE.zh-CN.md
  • ACC 治理与演进规则:https://github.com/agent-capability/agent-capability-contract/blob/v1.0.5/GOVERNANCE.md
  • ACC 官网:https://agentcapability.org/
  • BailingHubv0.3.4:https://github.com/bailinghub/bailinghub/releases/tag/v0.3.4
  • BailingHub 工具模型:https://github.com/bailinghub/bailinghub/blob/v0.3.4/docs/TOOLS_MODEL.md
  • BailingHub 架构说明:https://github.com/bailinghub/bailinghub/blob/v0.3.4/docs/ARCHITECTURE.md
  • BailingHub 开源仓库:https://github.com/bailinghub/bailinghub
  • 真实 API 接入评估:https://github.com/bailinghub/bailinghub/issues/new?template=integration_evaluation.yml

如果你正在评估现有商城、CRM、ERP、OA 或内部管理系统,可以只准备“一条脱敏业务 API + 当前身份与租户方式 + 审批由谁承接 + 一个允许的测试对象”,先验证第一条受治理动作,不需要公开生产凭据或整套后台。

提交公开 Issue 时,请勿附带 Token、模型密钥、个人信息或生产业务数据。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/25 19:17:24

DeepSeek Service Mesh面试题解析与核心概念

1. 项目概述"DeepSeek Service Mesh 面试题及答案&#xff08;100道&#xff09;"这个项目直指当前云计算和微服务架构领域最热门的技术方向之一——Service Mesh&#xff08;服务网格&#xff09;。作为连接、管理和监控微服务间通信的基础设施层&#xff0c;Servic…

作者头像 李华
网站建设 2026/8/25 19:10:27

软件测试面试全攻略:从理论到实战案例解析

1. 软件测试面试全景解析作为从业十二年的测试老兵&#xff0c;我经历过上百场技术面试的"拷问"&#xff0c;也主导过数十场招聘考核。这份全网最全的软件测试面试题合集&#xff0c;将系统梳理测试岗位的考核要点&#xff0c;覆盖功能测试、自动化测试、性能测试、安…

作者头像 李华
网站建设 2026/8/25 19:02:12

Linux命令-xz(高压缩比压缩工具)

Linux命令-xz&#xff08;高压缩比压缩工具&#xff09;&#x1f530; 命令简介&#x1f4d6; 语法格式⚙️ 常用选项&#x1f4a1; 实战示例1. 基本压缩与解压2. 不同压缩级别3. 配合 tar 使用&#xff08;.tar.xz 格式&#xff09;4. 标准输入输出&#xff08;管道操作&#…

作者头像 李华
网站建设 2026/8/25 18:59:23

企业如何实现创新能力综合分析与评价?

观点作者&#xff1a;科易网-国家科技成果转化&#xff08;厦门&#xff09;示范基地在全球新一轮科技革命与产业变革的浪潮中&#xff0c;科技创新已成为驱动经济高质量发展的核心引擎。然而&#xff0c;企业在推进科技创新过程中&#xff0c;常常面临一个关键性难题——如何系…

作者头像 李华
网站建设 2026/8/25 18:47:55

claude-mem:为AI编程助手打造长期记忆,解决上下文限制难题

1. 项目缘起&#xff1a;当Claude Code遇上“金鱼记忆”如果你和我一样&#xff0c;深度依赖Claude Code作为日常编程的“副驾驶”&#xff0c;那你一定经历过这种抓狂时刻&#xff1a;你正在开发一个复杂的微服务模块&#xff0c;花了十分钟向Claude Code解释清楚了业务逻辑、…

作者头像 李华