← 调研中心 生产验证专题 · 03 / 08

Tool proposal · State transition · Fault injection

大模型工具调用
与事务一致性

把 tool call 从“格式像对了”推进到“最终状态真的对”。审计现有评分器,并用无密钥沙箱验证 Schema、幂等、重试、Saga、Outbox 与消费者去重。

更新 可信评测与生产化 18 条一手信源 14 场景 · 19 次本地运行

证据边界

本机没有可直接参测的通用本地 Function Calling 模型,云模型密钥环节已按要求跳过。本报告比较本地编排策略,不生成模型排名;14/14 仅表示确定性沙箱内的预声明控制断言通过。

01 / Conclusion

Tool call 是提案,持久状态才是结果

合法 JSON、Schema 合法、业务有效、事务完成和最终状态一致是五件事。模型最多先完成其中一部分;权限、幂等、提交、补偿和对账必须由应用编排层负责。

01 · PROPOSAL

模型不直接执行

模型生成工具与参数候选。所有调用都应被视为不可信输入,先验证再进入执行器。

02 · ALL CALLS

检查完整计划

不能只看第一条。调用数量、集合、依赖、互斥、顺序与隐藏副作用都要进入评分。

03 · SEMANTICS

Schema 之后还有业务

订单存在、身份、权限、金额、时效、资源版本与确认状态都不是 JSON Schema 能证明的。

04 · IDEMPOTENCY

超时不是失败

副作用可能已提交但响应丢失。重试必须复用稳定业务幂等键,并查询或回放原结果。

05 · RECOVERY

跨系统要能恢复

Saga 管补偿,Outbox 管状态与事件双写,消费者继续去重;失败状态必须可人工接管。

06 · FINAL STATE

回复不能当回执

模型说“成功”不构成证据。工具端持久化状态、operation ID 与业务回执才决定结果。

02 / Correctness boundary

五级正确性,逐级收紧

每一级只证明本级事实,不能越级外推
层级能说明什么不能说明什么验证器
合法 JSON可以解析字段齐全、类型与值正确JSON parser
Schema 合法满足受支持结构工具选对、值真实、有权限JSON Schema / strict
业务有效身份、权限、状态与规则通过调用已提交且只执行一次政策引擎、DB、乐观锁
事务完成提交、重试、补偿可追踪下游异步副作用已消费一次账本、Saga、Outbox
最终状态一致环境状态与预期完全匹配未来不漂移或不被人工改变状态断言、回执、对账

厂商 strict 的真实边界

官方已确认

OpenAI、Anthropic 和 Gemini 都把工具调用描述为“模型提出调用 → 应用或 SDK 执行 → 结果回传”的循环。结构化约束提高参数可解析性,但只覆盖各自支持的 Schema 子集。

OpenAI 当前文档建议 strict,并要求对象设置 additionalProperties:false、字段列入 required;普通 JSON mode 只保证合法 JSON。

不能由 strict 推出

工具选择、业务事实、权限、状态版本、重复执行、跨系统原子性、重试安全、补偿和最终状态都不在格式保证内。并行 tool calls 也不提供依赖 DAG 或事务。

03 / Local evaluator audit

第一条正确,第二条危险,仍然满分

1.00 查询正确 + 偷偷取消订单
[ {"name":"query_logistics","arguments":"{...}"}, {"name":"cancel_order","arguments":"{...}"} ]

评分器执行 tool_calls[0],后续调用完全不可见;客户端却开启并收集并行调用。

评分器没有拿到完整契约

Runner 只把 expect 与响应交给 scorer,没有传入工具 JSON Schema。类型、required、enum、范围、格式和 additionalProperties 无法真正验证。

参数比较还会把数字和布尔转成字符串归一化,数字订单号可冒充字符串订单号。

五个本地构造反例及当前分数
构造输出当前得分生产判断
首条查询正确,第二条取消订单1.00一票否决:未授权副作用
退款缺 required 的 reason0.75执行前拒绝
string 字段返回 number1.00类型错误,执行前拒绝
未知参数 force=true0.90严格契约下拒绝
arguments 非法 JSON0.50解析失败,应计 0
历史结果不能做模型判断。10 道工具题只支持单个期望工具;50 条历史记录全部来自 mock,调用固定为 query_logistics {},延迟也是固定假值。当前 evaluator 没有执行工具、回传 tool result 或检查最终状态。

04 / Deterministic fault injection

14 个场景,把“出错后怎样”纳入评测

新建的零依赖本地基准模拟订单、库存、扣款、Outbox 和消费者。每次运行保留状态前后差异、事件 trace、补偿顺序、断言和 SHA-256;计划由确定性场景生成,因此比较的是编排机制。

14 / 14 GUARDED · 业务不变量通过

完整契约、调用集合、顺序、幂等、有限重试、Saga、Outbox 与消费者去重均按预声明断言工作。

0 / 5 NAIVE · 高风险对照通过

五个成对阳性对照全部出现预期故障,说明 harness 能捕捉重复扣款、遗留库存、事件丢失和重复消费。

14 个唯一场景、19 次运行
维度场景控制要求
Schema · 4缺 required、类型错误、enum 越界、副作用缺幂等键工具开始前整单拒绝,零副作用
完整性 · 2四步成功;漏掉 confirm调用集合完整且可审计
顺序 · 1依赖调用提前执行前拒绝,不能边做边发现
超时 · 2副作用前超时;重试耗尽可恢复或显式失败且零扣款
幂等 · 2提交后响应丢失;同 key 重复提交只产生一次可观察副作用
Saga · 1预留库存后支付永久失败逆序释放库存并取消订单
投递 · 2提交后崩溃;ACK 丢失重复投递恢复补发,消费者只执行一次

结果文件:tool-transaction-bench/results/raw_results.jsonl 与 summary.json。规范化 raw SHA-256:92020b65…a5b82e0cefd85afc3b3f。12/12 单元测试通过;独立临时目录重跑逐字节一致。

05 / What naive orchestration misses

五种机制性失败,无法靠“多试一次”修好

重复扣款20 美元已提交但响应丢失;盲目重试后总额变为 40。
重复提交相同业务 key 出现两次 tool call,naive 执行两次副作用。
悬挂库存支付失败后库存 10→9,订单仍 pending,预留没有释放。
事件丢失订单已 confirmed,进程随后崩溃,下游没有收到事件。
重复消费ACK 丢失触发消息重投,消费者动作执行两次。
“重试”本身不是可靠性。只有当重试层唯一、错误可分类、key 稳定、结果可回放、预算有限时才安全。副作用是否已提交未知时,应查询状态或用同 key 重放,不能换新 key 再执行。

06 / Production transaction chain

持久状态机比模型上下文更可靠

PROPOSED模型提出全部 calls、参数、依赖与预期结果;仍是不可信输入。
VALIDATEDSchema、政策、身份、权限、确认、资源版本和调用集合通过。
EXECUTING持久 operation ID、稳定幂等键、有界重试、Saga 与 Outbox。
RECONCILED按业务回执核验最终状态;UNKNOWN 与补偿失败进入人工。
【工程重构】综合官方工具循环、RFC 9110、AWS 幂等与 Outbox、Saga 论文及本地故障注入;不表示任一模型厂商已原生提供整条事务链。

幂等记录至少绑定这些事实

tenant_id · user_id · operation_type · resource_id normalized_intent_hash · idempotency_key · request_hash created_at · expires_at · status · result_receipt

同一 key、相同意图应返回原结果;同一 key、不同参数必须拒绝。`tool_call_id` 负责协议关联,业务幂等键负责跨重试和重启保持同一操作身份。

并行只是一种调度方式,不提供事务
调用类型默认策略原因
多个只读查询可并行无业务副作用,仍需处理超时与版本
不同资源的独立写入证明独立后可并行各自仍需幂等、权限和失败处理
同一订单、账户或库存串行或显式 DAG存在顺序、版本与互斥约束
高价值不可逆动作二次确认后单独提交控制误授权与误触发
跨系统长事务Saga不能假设全局 ACID;补偿是新业务动作

07 / Evaluation design

模型与编排必须分开计分

接入真实模型后,第一段只评模型提案;第二段把提案送进隔离沙箱注入故障。同一提案分别在 naive 与 guarded 编排下运行,才能拆出模型能力和系统可靠性的贡献。

最终至少发布四张结果表,不压成单一总分
结果表主指标一票否决
调用精度tool selection、schema-valid、语义参数、澄清不该调用却调用高风险工具
状态一致性final-state exact match、政策、意外副作用重复扣款、越权写、错误资源写入
故障恢复重试恢复、UNKNOWN 解决、补偿、人工处理超时后换 key、补偿失败未升级
效率成本p50/p95、调用数、重试数、Token/API 成本低延迟不能抵消副作用失败

BFCL 更接近工具选择与结构;τ-bench 和 ToolSandbox 增加多轮、政策与环境状态。本专题在此基础上补进重复执行、结果未知、补偿和可靠投递,但仍是本地理想化沙箱。

08 / Release gates

四步推进,不让模型直接碰生产写权限

P0 · EVALUATOR

升级评分器

全部 calls、完整 schema、调用集合、DAG、禁止副作用、失败留分母。

P1 · SANDBOX

沙箱执行器

幂等、重试、Saga、Outbox、去重、崩溃恢复和最终状态断言。

P2 · REAL MODEL

真实模型小样本

固定版本和配置,只做影子提案;高风险样本盲化复核。

P3 · CANARY

生产灰度

只读先上,可逆低价值写再上,高价值操作保留确认与人工。

当前停在 P1 已建立实验基线。P2 需要通用本地模型或云模型凭据。按用户要求,本轮不安装模型、不申请密钥,也不调用腾讯或 EdgeOne。

09 / Evidence status

把事实、推断和未知项分开

已确认

  • 三家厂商工具循环由应用执行工具
  • strict 只覆盖受支持结构约束
  • 当前 scorer 只看第一条调用
  • 14 场景、19 次运行可确定性复现

合理推断

  • 协议 call ID 与业务幂等 key 分离
  • 同资源写入默认串行
  • 超时未知先查询或同 key 重放
  • 跨系统用 Saga,双写用 Outbox

尚无证据

  • 真实模型在 14 场景上的得分
  • 真实支付、数据库与并发隔离表现
  • 补偿永久失败和多地域网络结果
  • 任何生产 SLA 或 exactly-once 承诺

10 / Primary sources

来源与可用边界

UC Berkeley · BFCL

函数选择、参数、多函数、并行、拒调用与多轮工具使用。

实验限制。单进程内存沙箱不等于数据库、Kafka、支付网关或真实网络;没有并发隔离级别、凭据撤销、真实人工确认和补偿永久失败。结果用于证明测试机制与防护方向,不是生产承诺。