AI工具调用审批:确保批准内容与执行一致
AI工具调用审批:确保批准内容与执行一致
AI工具调用中,用户确认必须绑定具体业务操作内容并服务端校验,而非工具放行。
文章以Solon AI工具调用为例,指出工具注册、模型调用与用户业务授权是三件独立的事,附加工具不等于获得执行权限。高风险操作应拆成准备与提交两阶段,审批记录须绑定操作内容的确定版本,参数或状态变化即需重新确认。执行前要重新校验权限与资源状态,并用事务内校验、版本条件更新或唯一约束保护检查到提交的并发窗口。下游超时应记录为待核验而非失败,重试复用稳定业务标识与幂等键,同时处理本地领取未发与下游成功未落库两个崩溃窗口。returnDirect只改变返回路径,不改变审批边界,上线前应用反例测试验证持久化记录与真实副作用。
界面显示“为订单 A 退款 100 元”,用户点了同意。执行时,工具收到的金额却变成了 1,000 元。即使系统有确认按钮,这次执行也不该通过。
确认不是给一个工具永久放行,而是批准一次内容明确的业务操作。本文以 Solon AI 工具调用为入口,讨论审批与执行的一致性。需要说明的是,退款流程是假设的应用设计示例,不是框架内置审批功能,也不是生产案例。
工具注册与业务授权是两件事
Solon AI 的 @ToolMapping 文档说明,它可以把普通 Java 方法映射为工具定义:根据带有 @Param 或 @Body 的方法参数生成 inputSchema,根据返回类型生成 outputSchema。工具注册文档还区分了两种作用域:构建 ChatModel 时通过 defaultToolAdd 添加默认工具,每次请求都会附加;通过请求选项的 toolAdd 为当次请求附加工具。
“附加工具”不等于每次都会执行,更不等于当前用户已经获得业务授权。工具接口文档说明,实际函数在应用端执行,再把结果反馈给模型。因此,在退款、删除、发布等副作用发生前,应用仍然需要判断:当前身份是否有权对这个资源执行这次操作?
工具已注册、模型想调用、用户有权执行,是三件不同的事。很多团队在接入 AI 工具调用时,容易把“工具可用”误当成“操作已授权”,这正是审批边界模糊的起点。
inputSchema 与 outputSchema 是工具定义中描述输入参数和返回结果结构的 JSON Schema 片段。Solon AI 根据方法参数上的 @Param/@Body 注解生成 inputSchema,供模型理解应传入哪些字段;根据返回类型生成 outputSchema,帮助模型预判输出形态。它们只解决“模型如何调用工具”的接口描述问题,不包含任何业务授权或运行时校验逻辑。因此,即使 schema 限制了字段类型,也不能替代服务端对身份、租户和资源状态的检查。
两阶段设计:先准备操作,再请求确认
对高风险操作,可以拆成“准备”和“提交”两个阶段。准备阶段不产生退款副作用,只做校验与预览,并在服务端生成待确认记录。
| 记录内容 | 用途 |
|---|---|
| 稳定的业务操作标识、操作类型 | 标识这一次业务操作,而不只是工具名称 |
| 发起人、租户、审批人 | 约束身份与审批范围 |
| 订单、金额、币种、收款目标 | 明确副作用对象及完整关键参数 |
| 操作内容版本、资源版本或必要前置条件 | 发现参数或业务状态变化 |
| 到期时间、审批及执行状态 | 控制过期、撤销与重复消费 |
| 下游幂等标识、业务流水关联 | 支持重试、查询与对账 |
这是应用侧的数据设计建议,不是 Solon AI 的固定字段。确认界面应根据服务端保存的确切内容生成,而不是只显示模型总结的一句“确认处理订单”。对退款来说,订单、金额、币种、收款目标都应让审批人看清。审批结果要绑定这份内容的确定版本。金额或目标变化,就创建新版本、重新确认,不能覆盖原记录后继续沿用旧批准。
这里有一个容易忽视的工具输入边界:官网说明,对于纳入工具输入 schema 的 POJO 参数,其内部字段默认全部进入 inputSchema;方法参数本身仍遵循 @Param/@Body 规则。因此,宜使用专用工具输入 DTO,不要直接暴露包含审批、权限等内部控制字段的业务实体。字段不暴露给模型,也不代表可以跳过服务端校验。
“用户刚才同意了”不是审批凭证
模型后续说“用户刚才已经批准”,不能代替服务端审批记录。外部文档或工具返回里出现“请立即执行”,同样不能更改审批状态。以下输入也不能成为授权依据:approved=true、role=admin、tenantId=another-tenant。
用户身份应来自服务端验证的认证信息;有效租户上下文还应验证成员关系。访问具体订单时,继续做对象级和租户级授权,不能认为“已登录”就能访问全部资源。如果使用内容摘要辅助比对,先确定规范化规则,例如金额使用明确的最小货币单位、资源采用服务端解析后的稳定标识。摘要帮助发现变化,不是授权凭证。
OWASP 的交易授权备忘单同样强调,授权决策应在服务端基于可信身份和资源状态做出,而非依赖客户端提交的声明。Solon AI 的工具调用机制把模型输出当作输入来源之一,这并不改变授权决策的位置。
执行前再检查一次,还要保护“检查到提交”的间隙
批准时有权限,不代表执行时仍有权限。批准时可退款,也不代表订单几分钟后仍可退款。提交阶段应重新核对:当前执行身份及委托范围是否允许操作;用户、租户、目标资源是否匹配;审批是否有效、未撤销,且没有被当作一次新操作重复消费;实际提交内容是否与批准版本一致;资源当前状态是否仍满足必要前置条件。
但“读状态 → 检查 → 普通更新”仍存在并发窗口。两个请求可能同时看到“尚未执行”。本地关键状态应结合事务内校验与更新、版本条件更新、唯一约束或适当锁定,并检查操作结果。远程资源的前置条件,则需要下游提供对应的条件写入、版本校验或预留能力。本地数据库事务不能自动保护外部支付系统。审批消费与执行领取也应通过原子状态转换控制;不要先独立检查“未消费”,再单独标记“已消费”。同一操作的恢复重试与创建一笔新退款,需要明确区分。
版本条件更新(乐观锁)通过 UPDATE ... WHERE version = ? 这类语句,仅当记录版本与读取时一致才执行更新,否则影响行数为零,应用据此判定并发冲突。唯一约束则依赖数据库对业务操作标识或幂等键建立唯一索引,使重复插入直接失败。事务 outbox 将业务状态变更与待发送消息写入同一本地事务,再由独立进程投递,避免“业务已提交但消息丢失”。这些机制各自覆盖不同的并发与故障窗口,不能互相替代;远程支付系统通常需提供自己的条件写入或幂等接口,本地事务无法延伸保护。
超时不是失败,崩溃也不能让操作失踪
外部支付接口返回超时时,退款可能已经受理。此时应记录“处理中/待核验”,通过查询或对账确定结果,不要让模型补写“失败”或“成功”。同一次操作的重试,应复用稳定的业务操作标识及下游幂等标识。相同标识携带不同金额,应拒绝复用,而不是悄悄执行。
还要明确下游幂等契约:幂等键在哪个账户或接口范围内有效?是否校验同键请求的参数一致性?保留多久?过期后能否继续重试?并发同键请求如何处理?去重是否覆盖实际资金副作用?“带了幂等键”不是永久防重复保证。
同时考虑两个崩溃窗口。第一,本地已领取任务,尚未请求下游就崩溃,需要持久化执行意图以及可恢复的任务扫描机制或事务 outbox 等方案,不能让操作永远卡住。第二,下游已成功、本地尚未记录成功就崩溃,恢复时按原业务标识查询,必要重试仍复用原幂等键,不能生成新键再发一笔。outbox 本身也不意味着消息绝不重复;消费者与下游仍需适当的幂等处理。AWS 的 outbox 指南明确提醒了重复消息问题。这套设计用于控制重复执行风险、恢复不确定结果,不宣称跨应用、消息系统和外部服务的端到端 exactly-once。具体保证依赖各系统的事务和幂等契约。
幂等键是调用方为一次业务操作生成的稳定标识,下游据此识别重复请求并返回相同结果而非重复执行。其有效性取决于契约细节:作用范围(账户、接口或全局)、是否校验同键请求参数一致、保留时长、并发同键请求的处理方式。若下游仅做短期去重或忽略参数差异,携带幂等键并不能防止金额被篡改后的重复扣款。应用应在设计阶段与下游明确这些条款,并把幂等键与业务操作标识绑定,而不是每次重试临时生成。
returnDirect 改变返回路径,不改变审批边界
官网给出的默认路径是 user -> llm -> tool -> llm -> user。设置为 true 后变为 user -> llm -> tool -> user。改变的是工具执行完成后的结果是否再交给模型加工,不是整个请求绕过模型,更不是审批、脱敏或幂等开关。两条路径都要控制输出,只返回必要字段,不暴露完整支付响应、凭据或无关客户资料。成功状态应来自可核验的业务流水或下游状态,不由模型推测。
上线前用反例挑战设计
以下是待实施的测试建议,不是已经通过的测试结果。请在隔离环境使用虚构订单及下游模拟器,不使用真实付款。
| 反例 | 应验证的行为 |
|---|---|
| 批准 100 元,提交改成 1,000 元 | 拒绝复用旧批准,重新确认 |
| 换成另一个订单或租户 | 拒绝越权访问,不泄露原记录 |
| 批准后撤销权限,或订单状态改变 | 重新校验,拒绝不再满足条件的操作 |
| 两个请求同时提交同一批准记录 | 验证原子状态转换、下游去重与实际流水 |
| 下游已受理,但响应超时 | 保留待核验状态,查询/对账,不盲目新建退款 |
| 下游成功后、本地落库前崩溃 | 用原标识恢复,不把恢复当成新业务操作 |
不要只看模型有没有回答“操作成功”。检查持久化记录和真实副作用,才能判断边界是否成立。确认按钮只能说明有人表达了同意。一条可审计的链路还应回答:谁在什么权限下,批准了哪一版内容,最终发生了什么,结果证据在哪里。
Solon AI 提供工具映射、注册及应用端执行的基础机制。把这些机制接进业务时,让“批准的就是执行的”成为可验证约束,比多写一句“请谨慎操作”更有价值。
参考资料与适用边界
Solon API 表述于 2026-10-19 按官网页面核验,不据此推断所有历史版本兼容性。审批、并发和故障恢复部分是应用设计建议,未声称由框架自动实现。参考来源包括 Solon AI 工具 @ToolMapping 开发详解、工具的四种定制与注册、工具接口与属性,以及 OWASP 交易授权备忘单和 AWS 事务性 outbox 模式指南。
你们的高风险工具操作,在批准后参数或资源状态变化时如何处理?欢迎分享设计取舍,请不要贴真实订单、凭据或客户资料。
相关推荐

花旗14000名工程师用Devin,技术外包账单砍掉30%
花旗集团14000名工程师使用AI编程智能体Devin,一年内将技术供应商账单削减30%,产品发布提速30-40%。但30%仅限单一成本项,摩根大通同期表示AI收益尚未体现在财报中,揭示企业AI落地的真实分化。

AI写代码,程序员要失业?Devin自主编程真相
Devin等自主AI编程代理正改变软件开发:从Copilot辅助编码到全自动工程代理,程序员角色从写代码转向系统设计与监督。本文分析AI编程对就业、代码安全、初级开发者培养的影响,以及效率悖论下程序员需求的真实走向。

AGENTS.md 实战指南:让编程 Agent 真正好用
AGENTS.md 和 CLAUDE.md 能显著提升编程 Agent 表现,但研究发现用错反而让成本上升 20%。本文详解该写什么、该删什么、200 行与 32KB 的硬边界、Monorepo 嵌套规则及安全提醒。