关键词: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 GETexecution.readonly: true:运行时 SHOULD 默认为 low
  • 非只读写操作:运行时 SHOULD 默认为 medium

默认值是最低限度的互操作行为,不是鼓励契约作者用 HTTP 方法代替业务评审。

对于资金、删除、权限、批量影响和难以回滚等操作,应显式声明 high

5. 一个操作应该如何完成风险分级

可以从四个问题开始,而不必立即发明复杂评分模型。

这项操作是否改变业务状态

例如:

order.read             通常不改变状态
refund.request.create  创建新的业务请求
refund.execute         直接产生资金后果

“创建请求”和“完成最终动作”不应因为名称相近而被视为同一级别。

错误发生后是否容易恢复

修改商品描述和删除员工账号都是写操作,但恢复成本不同。

即使系统支持“撤销”,也要判断撤销是否真的能还原外部通知、资金流、合同效力和人员影响。

影响是单个对象还是批量扩散

调整一个 SKU 与覆盖整个仓库库存不是同一种后果。

给一个客户发送通知,与向十万客户批量发送消息,也不应只因为调用的是同一个发送服务就共享同一判断。

是否涉及资金、权限、人员或外部责任

这些领域通常具有更高的责任和追溯要求:

  • 资金移动与结算;
  • 权限授予、密钥和账号状态;
  • 员工入离职和 HR 操作;
  • 合同、承诺与法律后果;
  • 向客户、合作方或公众发送外部信息。

ACC v1 没有把这些问题做成一套通用打分公式。它要求契约作者把评审结果收敛为跨实现可以一致读取的 low / medium / high 信号。

6. riskapproval 为什么必须同时存在

如果风险分级不直接决定审批,为什么契约中还需要审批声明?

因为两者表达不同事实。

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

这份声明表达:

  1. 这项能力具有高后果属性;
  2. 它需要可信行动主体;
  3. 当调用参数中的 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 规范:https://agentcapability.org/docs/spec/
  • ACC 设计依据与边界:https://agentcapability.org/docs/design-rationale/
  • ACC 实现者指南:https://agentcapability.org/docs/implementer-guide/
  • ACC GitHub:https://github.com/agent-capability/agent-capability-contract

ACC 是 A2B 场景下的开放能力声明契约。它声明可移植的后果风险与治理意图,不替代部署组织的策略系统、审批产品或业务系统最终授权。

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐