关键词:AI Agent 风险分级、Agent 高风险操作、Agent 人工审批、工具调用治理、业务系统安全
假设一套企业系统准备把下面三项能力开放给 Agent:
GET /orders/{id} 查询订单
POST /refunds 创建退款
POST /notifications/batch 批量发送客户通知
团队很快就会意识到,它们不能被同等对待。
查询订单通常不会改变业务状态;退款会影响资金;批量通知一旦对象或内容错误,可能在几分钟内影响大量客户。
于是大家增加一个字段:
risk:
level: high
接下来的问题却比增加字段更重要:
high到底是在描述这项操作可能造成的后果,还是在命令所有运行时必须启动同一种审批流程?
这两个问题看起来相近,实际上属于不同层次。
- 风险分级描述操作的后果属性;
- 审批、阻断、凭证升级和人工确认,是部署组织针对风险采取的治理动作;
- 最终能否执行,仍然取决于业务系统对主体、资源和实时状态的授权判断。
如果把三者压缩成一条固定规则,契约会显得“更强”,却很快失去跨组织、跨运行时和跨部署形态的可移植性。
1. 风险是“这个操作是什么”,审批是“我们准备怎么管”
先看两个组织面对同一项能力时可能做出的不同决定。
scope: refund.create
risk.level: high
甲公司可能规定:
任何退款都进入人工审批。
乙公司可能规定:
小额退款由已经获得短期授权的客服自动执行,超过阈值才进入审批。
丙公司的策略甚至可能是:
当前系统尚未具备足够的证据链,因此所有 Agent 发起的退款一律阻断。
三个组织对 refund.create 的后果认识可以完全一致:它涉及资金移动,属于高后果操作。
但它们采用的治理动作不同,因为它们拥有不同的:
- 组织制度与责任边界;
- 身份和委托机制;
- 审批系统与审计能力;
- 金额阈值和业务容忍度;
- 运行时形态;
- 法律、行业与地域约束。
因此,一份中立契约适合声明“这是高风险能力”,却不应据此强迫所有组织使用同一种审批 UI、同一个审批人模型或同一条工作流。
后果分类可以跨实现共享,治理响应必须由真正承担后果的组织决定。
2. 为什么不能直接定义 high = 必须审批
把高风险与人工审批一一绑定,最初看起来非常安全:
low -> 直接执行
medium -> 用户确认
high -> 人工审批
但这张表混合了至少四类不同概念:
| 概念 | 回答的问题 |
|---|---|
| 后果等级 | 如果 Agent 自动发起这项操作,最坏的合理后果是什么? |
| 运行时策略 | 当前部署准备放行、阻断、降级还是转交外部决策? |
| 审批机制 | 谁在什么系统中,以什么证据完成决定? |
| 最终授权 | 当前主体此刻能否对这个具体业务对象执行这次操作? |
一旦把 high 直接解释为“必须弹审批框”,就会出现一系列问题。
无 UI 的运行时无法兑现同一种动作
Agent 运行时不一定是一个带界面的应用。它可能是:
- API Gateway 插件;
- 消息队列消费者;
- 后台任务调度器;
- 本地执行器;
- 确定性工作流节点;
- 只负责策略判断的服务。
这些实现都能理解“高后果操作”,却不一定能弹出确认框。它们可能返回待决状态、创建外部审批任务、拒绝请求,或者把调用交给另一个控制面。
审批并不总是最安全的响应
审批不是风险治理的万能答案。
当系统无法确认可信主体、无法绑定审批参数、无法保证审计证据时,“创建一张审批单”并不会自动让调用变安全。更合理的策略可能是直接隐藏能力或拒绝执行。
反过来,一项高风险操作如果已经处于强身份、短期委托、确定参数、双人控制和完整审计的受控流程中,组织也可能采用不同于普通人工审批的治理方式。
同一风险在不同上下文中的响应可能不同
风险等级描述的是 operation 的稳定后果属性,而当前治理动作往往还取决于:
- 当前 Agent 场景;
- 主体身份和委托范围;
- 调用参数;
- 时间、环境与组织策略;
- 是否存在有效的外部决策;
- 业务系统返回的实时状态。
如果把全部变化都塞进风险等级,risk 最终会膨胀成一门私有策略语言。
3. ACC v1 如何定义风险
ACC v1 使用一个有意保持简洁的声明:
risk:
level: low
level 有三个取值:
| 等级 | 规范语义 |
|---|---|
low | 只读,或后果轻微且容易恢复 |
medium | 存在业务副作用,通常影响单个对象、可以恢复,或只是创建请求与草稿 |
high | 涉及资金、删除、权限变更、HR、合同、批量动作、跨租户影响、外部通知或难以回滚 |
它描述的是:
允许 Agent 自动发起该 operation 时,最坏的合理后果。
这里有三个关键词。
“后果”,而不是实现复杂度
一个接口代码只有十行,并不代表风险低;一个内部实现很复杂的查询接口,也不一定风险高。
风险应围绕业务后果判断,而不是围绕代码行数、服务数量或开发难度判断。
“合理”,而不是无限想象
任何系统都可以被设想出灾难性极端情况。如果每项查询都因为“理论上可能泄露全部数据”而标记为最高风险,分级就失去区分能力。
声明者应考虑在正常系统边界和可预见失败下,这项操作可能造成的最坏合理后果。
“自动发起”,因为 Agent 改变了行动链路
传统后台按钮通常位于受控页面、固定流程和人工操作上下文中。成为 Agent 工具后,operation 可能由模型根据自然语言目标选择,并由模型生成参数。
风险分类关注的正是这种新行动方式下,运行时需要提前知道的后果信号。
4. 用业务后果,而不是 HTTP 方法给风险贴标签
HTTP 方法可以提供默认线索,但不能代替业务判断。
下面这些操作都可能使用 POST:
POST /search 执行复杂查询
POST /drafts 创建草稿
POST /refunds 发起退款
POST /notifications/batch 批量发送外部通知
它们的后果完全不同。
同样,GET 通常是只读,但如果一个查询会返回大规模个人信息、商业机密或跨租户数据,仅凭方法名把它视为无条件低风险,也是不够的。数据敏感性和最终授权仍需由相邻治理层处理。
ACC v1 在 risk 省略时提供保守的基础默认:
- HTTP
GET或execution.readonly: true:运行时 SHOULD 默认为low; - 非只读写操作:运行时 SHOULD 默认为
medium。
默认值是最低限度的互操作行为,不是鼓励契约作者用 HTTP 方法代替业务评审。
对于资金、删除、权限、批量影响和难以回滚等操作,应显式声明 high。
5. 一个操作应该如何完成风险分级
可以从四个问题开始,而不必立即发明复杂评分模型。
这项操作是否改变业务状态
例如:
order.read 通常不改变状态
refund.request.create 创建新的业务请求
refund.execute 直接产生资金后果
“创建请求”和“完成最终动作”不应因为名称相近而被视为同一级别。
错误发生后是否容易恢复
修改商品描述和删除员工账号都是写操作,但恢复成本不同。
即使系统支持“撤销”,也要判断撤销是否真的能还原外部通知、资金流、合同效力和人员影响。
影响是单个对象还是批量扩散
调整一个 SKU 与覆盖整个仓库库存不是同一种后果。
给一个客户发送通知,与向十万客户批量发送消息,也不应只因为调用的是同一个发送服务就共享同一判断。
是否涉及资金、权限、人员或外部责任
这些领域通常具有更高的责任和追溯要求:
- 资金移动与结算;
- 权限授予、密钥和账号状态;
- 员工入离职和 HR 操作;
- 合同、承诺与法律后果;
- 向客户、合作方或公众发送外部信息。
ACC v1 没有把这些问题做成一套通用打分公式。它要求契约作者把评审结果收敛为跨实现可以一致读取的 low / medium / high 信号。
6. risk 与 approval 为什么必须同时存在
如果风险分级不直接决定审批,为什么契约中还需要审批声明?
因为两者表达不同事实。
x-agent-capability:
version: 1
enabled: true
scope: refund.request.create
risk:
level: high
subject:
required: true
approval:
when:
- param: amount
op: ">"
value: 1000
label: 退款金额超过 1000
这份声明表达:
- 这项能力具有高后果属性;
- 它需要可信行动主体;
- 当调用参数中的
amount大于 1000 时,应创建外部决策意图。
它没有表达:
- 必须由财务经理审批;
- 必须在某个 OA 页面完成;
- 审批有效期必然是 30 分钟;
- 通过审批就一定拥有退款权限;
- 业务系统可以跳过订单状态与余额校验。
风险帮助运行时理解后果,审批声明帮助运行时识别何时需要外部决策,业务系统继续持有最终裁决权。
这三层不应互相吞并。
7. 同一个 high 映射成不同流程,是不是标准不一致
不是。
如果两个运行时把同一份 risk.level: high 一个解释成“高后果”、另一个解释成“低后果”,那是规范一致性问题。
但如果两个组织都承认它是高后果操作,然后根据各自制度分别选择:
- 阻断;
- 人工审批;
- 更强凭证;
- 缩小参数范围;
- 仅允许特定受控工作流;
- 暂时不向 Agent 暴露;
这属于部署策略差异。
中立标准的目标不是让所有企业采用同一套管理制度,而是让不同实现对声明本身形成一致理解。
可移植性要求字段语义一致,不要求组织政策相同。
8. 为什么 ACC v1 没有直接定义更多风险维度
工程团队很容易继续提出:
risk:
impact: critical
reversibility: impossible
blast_radius: organization
data_sensitivity: high
这些维度可能有价值,也可能在某些组织的私有策略中十分必要。
但让它们进入通用契约,还需要回答更严格的问题:
- 每个枚举能否在不同业务领域中保持同一含义?
- 多个维度互相冲突时如何解释?
- 省略某一维度时使用什么保守默认?
- 旧运行时忽略新安全字段是否会静默降低安全性?
- 能否提供跨实现证据与可执行 Conformance 向量?
- 这些维度描述的是可移植事实,还是某个组织的策略输入?
因此,ACC v1 选择一个较粗、但稳定且可测试的后果等级作为公共基线。
这不代表风险永远只能有三个维度或三个等级,而是说明:
标准核心应先收纳已经收敛的公共语义,尚未收敛的复杂度可以在运行时策略、扩展或后续提案中验证。
字段多并不自动等于治理更强。没有一致默认、冲突和失败语义的“多维风险”,只会把歧义从代码搬进 YAML。
9. 风险分级不能替代最终业务授权
即使一项能力被标记为 low,业务系统仍然必须校验:
- 当前主体是谁;
- 是否有权访问这项资源;
- 资源属于哪个租户或组织;
- 业务状态是否允许当前操作;
- 请求参数是否满足实时规则。
同样,high 也不意味着“只要审批通过就一定执行”。审批发生后,业务系统仍可能因为订单已退款、余额变化、权限撤销或参数漂移而拒绝调用。
风险是治理输入,不是授权票据。
它不能证明主体身份,不能证明审批已经发生,也不能代替业务系统的实时事实。
10. 一条完整的风险治理链路
一个运行时可以按照下面的顺序处理 operation:
读取并校验 Agent-facing 能力声明
-> 应用 enabled 与 scope 暴露策略
-> 确认所需可信主体已经存在
-> 在模型调用前识别 operation 的风险等级
-> Agent 选择能力并提出业务参数
-> 按 OpenAPI 校验参数类型与结构
-> 评估 approval.required 与 approval.when
-> 由本地策略决定阻断、外部决策或继续执行
-> 携带可信主体与必要证据调用业务系统
-> 业务系统完成最终授权和业务校验
-> 记录风险判断、治理决定与最终结果
模型可以选择已暴露的工具并生成参数,但不能修改:
- 契约中的风险等级;
- 当前运行时的风险映射策略;
- 可信主体;
- 审批结果;
- 业务系统的最终授权决定。
11. 六个常见误区
误区一:high 就等于某个固定审批页面
风险是后果分类,审批 UI 是实现选择。无 UI 运行时也必须能够理解风险语义。
误区二:只按 GET、POST、DELETE 自动分级
HTTP 方法提供有限线索,业务后果才是风险判断的核心。
误区三:高风险已经审批,所以业务系统必须放行
审批表达外部决定,不是最终业务权限。实时状态和业务不变量仍可能导致拒绝。
误区四:低风险就不需要可信主体和审计
只读不等于公开。读取私有订单可能风险等级低,但仍需要主体、权限和适当审计。
误区五:风险越细越专业
没有稳定语义、保守默认和跨实现证据的细分,只会制造新的不一致。
误区六:让模型根据对话降低风险
模型输出属于不可信提议。风险元数据必须来自可信契约或运行时策略,不能因为模型声称“这很安全”而被覆盖。
12. 一份最小检查表
为 Agent-facing operation 标注风险时,可以逐项确认:
- 风险等级描述的是业务后果,而不是代码复杂度或 HTTP 方法吗?
- 是否考虑了资金、删除、权限、人员、批量影响、外部通知和恢复难度?
- 高风险是否与具体审批 UI、审批人和工作流保持解耦?
- 本地运行时是否记录了
low / medium / high分别如何映射到治理动作? - 没有 UI 的运行时是否也能一致消费这份声明?
- 模型输出是否无法修改风险等级或本地策略?
-
approval是否只表达外部决策意图,而不冒充最终授权? - 业务系统是否仍会校验主体、资源、参数和实时状态?
- 风险省略时,运行时是否应用了公开且保守的默认?
- 新增更细风险字段前,是否已经定义默认、冲突、失败与兼容语义?
如果这些问题没有答案,所谓“风险分级”很可能只是换了名字的审批开关。
13. 风险声明的价值,是让后果先于行动被看见
Agent 调用真实业务系统时,最危险的状态不是组织选择了不同的审批流程,而是运行时在行动发生之前根本不知道这项能力可能造成什么后果。
一份可移植的风险声明先建立共同事实:
这项操作是只读还是有业务副作用?
错误是否容易恢复?
是否涉及资金、删除、权限、人员或大范围外部影响?
随后,真正承担风险的组织再决定如何响应:放行、缩小范围、加强凭证、创建外部决策、暂时隐藏或直接阻断。
因此,风险分级最重要的设计纪律不是规定所有人采用同一套流程,而是坚持:
契约描述操作可能造成的后果,部署策略决定如何治理,业务系统保留最终裁决权。
这三层越清楚,Agent 越有可能从“只能查询”走向受控地执行真实业务操作。
也值得继续讨论一个问题:你的组织面对同一个高风险 operation,会选择审批、阻断、短期委托,还是另一种治理方式?答案可以不同,但对风险语义的理解不应不同。
延伸阅读
- ACC 规范:agentcapability.org/docs/spec/
- ACC 设计依据与边界:agentcapability.org/docs/design…
- ACC 实现者指南:agentcapability.org/docs/implem…
- ACC GitHub:github.com/agent-capab…
ACC 是 A2B 场景下的开放能力声明契约。它声明可移植的后果风险与治理意图,不替代部署组织的策略系统、审批产品或业务系统最终授权。