新人 免费注册,送 10 次调用,最高 $1,免绑卡。
Claude Fable 5 用于 Agent:工具调用中途拒绝、与 GLM 5.2 的成本对比

Claude Fable 5 用于 Agent:工具调用中途拒绝、与 GLM 5.2 的成本对比

目录
  1. 执行工具调用前先检查 stop_reason
  2. 五种 Agent 负载形态的成本
  3. 降低 Agent 成本
  4. 文档不会提醒你的两个成本意外
  5. 请求接口有哪些变化
  6. 结论
  7. 常见问题

在我们的评测中,Claude Fable 5 在 44 个编码 Agent 回合里有 11 次在工具调用中途拒绝,任务甚至只是修改配置默认值。模型生成工具参数到一半时会返回 stop_reason: "refusal"。截断后的参数仍能解析成合法 JSON。如果 Agent 循环只要收到工具调用就执行,却不检查停止原因,它会直接把只写了一半的文件保存到磁盘。将 Fable 5 接入 Agent 时,首先要处理的是这个行为,而不是价格。

TL;DR

  • Claude Fable 5 会在普通 Agent 任务中途返回 stop_reason: "refusal",包括修改配置默认值和预订会议室。截断后的 write_file 参数仍能正常解析,因此不检查停止原因的循环会执行调用,写入残缺文件。
  • Fable 5 采用自适应思考,无法关闭:enableddisabled 都会被拒绝,只能通过 output_config.effort 控制。
  • Fable 5 的成本溢价取决于负载形态:一个四回合编码任务的成本为 $0.045,而 glm-5.2 为 $0.003,相差 15 倍;在缓存已预热的批处理任务中,成本仅为 sonnet-5 的 5 倍。
  • Fable 5 要求保留数据 30 天。

以下数据均于 2026-07-05 通过 Synthorai gateway 测得。我们用一个小型场景测试工具覆盖五种 Agent 工作负载形态:使用工具的编码循环、RAG 问答、工具密集型编排、批量分类,以及 15 回合对话。测试模型包括 claude-fable-5claude-opus-4-8claude-sonnet-5glm-5.2。对波动有影响的任务各运行三次。这些任务有意设计得很简单,完成率只用于基本校验,并非能力基准。成本取自 gateway 计费结果中的 usage.cost

执行工具调用前先检查 stop_reason

文档没有提醒这种故障,但它会破坏状态。Agent 读取 app.py,决定写入修复内容,并开始生成 write_file 调用。文件内容生成到一半时,输出流突然停止:

{
  "stop_reason": "refusal",
  "content": [{
    "type": "tool_use",
    "name": "write_file",
    "input": {
      "path": "app.py",
      "content": "DEFAULTS = {\n    \"timeout_s\": 30,\n    "
    }
  }]
}

这里的 input 对象结构完整,可以解析为合法 JSON。对象本身没有任何信息表明“输出已提前停止”。如果循环的逻辑是“收到工具调用就执行”,app.py 就会被一段仅有 38 个字符、停在字典定义中间的内容覆盖,文件也无法再被 Python 解析。下一回合仍然会遭到拒绝,最终循环结束,工作区则已损坏。

从数据中可以确认三点:

  • 普通任务也会触发。 触发拒绝的任务包括修复配置查找中的 KeyError、实现 slugify 函数、预订会议室,以及创建发票草稿。这些任务既不涉及双重用途,也不包含敏感内容。
  • 问题可以稳定复现,并非随机波动。 其中一个编码任务连续三次都触发拒绝,streaming 和非 streaming 模式均是如此。其他任务则一次也没有触发。综合不同条件,Fable 5 在这些简单编码任务中的完成率为 58-75%,而 claude-opus-4-8、claude-sonnet-5 和 glm-5.2 均为 100%。所有失败都源于拒绝,而不是代码错误。
  • 对话中一旦出现拒绝,本轮任务就无法继续。 后续回合都会返回 stop_reason: "refusal",且输出为空。在同一个上下文中重试也无法恢复。

触发条件与任务内容无关,数据非常明确。每次运行都遭到拒绝的任务,只是修复一个九行配置字典中的 KeyError,不涉及凭据或漏洞利用。相比之下,批处理场景对涉及加密货币挖矿、泄露的 Stripe key 和钓鱼页面的支持工单进行分类,却一次都没有拒绝。RAG 场景读取包含 AES-256-GCM 密钥和数据泄露响应流程的文档后回答问题,也没有问题。所有拒绝都出现在两个多回合、会执行工具的场景中;另外三个单次请求场景即使内容更敏感,也从未触发拒绝。问题出在 Agent 循环的形态,而不是输入中的词语,因此清洗输入无法避免它。

只需在执行工具前加一段检查:

if response.stop_reason == "refusal":
    # do NOT execute tool calls from this turn: arguments may be truncated
    raise AgentInterrupted("model refused; restart episode or escalate")

Anthropic 的文档说明了具体机制:如果拒绝发生在任何输出之前,响应会包含空的 content 数组,且不计费;如果在输出流中途拒绝,已经输出的内容仍会计费,官方建议丢弃这些不完整内容。响应还会附带 stop_details 对象,其中包含类别,例如 cyberbio 或 null,可用于区分分类器拦截和普通拒绝。文档没有明确说明它与工具调用结合时会怎样:拒绝可能发生在参数生成过程中,而部分参数看起来与完整参数没有区别。

官方也提供了恢复方案。在 Claude API 中,可以使用 beta 版 fallbacks 参数(betas: ["server-side-fallback-2026-06-01"]fallbacks: [{"model": "claude-opus-4-8"}]),在同一次调用中用备用模型重新执行被拒绝的请求。如果拒绝发生在输出前,该次拒绝本身不计费。Amazon Bedrock、Vertex AI 和 Microsoft Foundry 不支持这个参数,其 SDK 提供的是客户端 fallback middleware。无论采用哪种方案,都必须先加上前面的保护逻辑:只要该回合的停止原因是拒绝,就绝不能执行其中的工具调用。

五种 Agent 负载形态的成本

以下是每个完成单元的成本中位数,单元可能是任务、查询、数据项或整段对话。所有模型使用相同 prompt,并在同一天测试:

场景fable-5opus-4-8sonnet-5glm-5.2
编码循环(每个任务,中位数 4 回合)$0.045$0.012$0.0059$0.0031
RAG 回答(每次查询)$0.024$0.0075$0.0036$0.0031
工具编排(每个任务)$0.048$0.011$0.0045$0.0027
批量分类(每项,缓存已预热)$0.0024$0.0012$0.00046$0.00057
15 回合对话(全程)$0.94$0.34$0.26$0.083

这张表有两点比任何一个单独数字都更重要:

  • 最便宜的模型会随负载形态变化。 glm-5.2 在循环和长对话中成本最低,但在这组模型里,claude-sonnet-5 才是最便宜的批量分类模型,甚至低于 glm-5.2。原因是缓存预热后,固定 prompt 的 cache-read 占比达到 97%,同时还能享受其首发价格
  • Fable 5 的成本溢价同样取决于负载形态:编码循环的成本是 glm-5.2 的 15 倍,对话为 11 倍;但在缓存已预热的批处理任务中,仅为 sonnet-5 的 5 倍,因为大部分 prompt 成本被缓存抵消。

接下来要讨论的是如何控制这些成本,以及两个会在不经意间再次推高成本的因素。

降低 Agent 成本

缓存是影响最大的手段,而且 Fable 5 的缓存规则没有变化。Agent 测试数据能直接体现它的价值:移除 cache_control 标记后,同一编码任务的成本变为 2.0 倍,缓存已预热的批处理任务则变为 6.8 倍。opus-4-8 在同样测试中的结果分别为 3.8 倍和 6.9 倍。对于循环任务,滑动标记模式不是锦上添花的优化,而是决定成本是否可接受的关键。

Prompt 顺序是第二个重要手段,所有测试模型的结果都一致。将固定规则放在每次查询的上下文之前,而不是之后,可让四个模型的 RAG 查询成本降低 26-37%。对于 Claude 系列,如果顺序错误,每次调用还要额外承担 1.25 倍的 cache-write 费用。具体机制见 LangChain 缓存文章;这里的数据只是确认同样的规则也适用于 Fable 5。

Fable 5 还增加了两个独有的控制手段。首先,满足缓存条件的最低长度已降至 2,048 个 token,只有 Opus 4.8 的 4,096 个 token 的一半。看起来只是个小变化,但 Agent 的缓存收益主要来自反复出现的固定部分,包括 system prompt、工具定义和滑动对话前缀,而且只有超过最低长度才能缓存。某个工具密集型 Agent 如果每回合的前缀长度在 2,048 到 4,096 个 token 之间,在 Opus 4.8 上完全无法缓存,但在 Fable 5 上可以。之后每个回合都能把原本按全价计费的前缀,变为价格约为原来 10% 的 cache read。反过来也一样:为达到旧的 4,096 token 下限而填充的前缀,现在可能包含多余内容。不要靠猜,直接读取线上响应中的 cache_read_input_tokens。Fable 5 的缓存折扣会更早生效。

第二个手段是 task budgets(beta,header 为 task-budgets-2026-03-13)。它正好解决了本次对比反复暴露的问题:Fable 5 循环很快就会累积高额费用,而 max_tokens 无法解决。max_tokens 是模型不可见的单次响应硬上限。模型会按输出空间无限来规划,最后在思考中途被截断。task budget 不同。你可以为整个循环设置一个模型可见的 token 上限,最低为 20,000。模型会看到持续递减的剩余额度,据此调整节奏,并在预算用完前正常收尾,而不是被强行截断。它统计模型生成的内容,以及当前回合读取的工具结果,不包括每次请求重新发送的完整历史。Fable 5 的编码循环单回合成本是 glm-5.2 的 15 倍,而让模型主动控制消耗的预算,是成本最低的防护措施。

文档不会提醒你的两个成本意外

即使上述控制措施都已设置,还有两个较小的因素会让费用朝文档未提及的方向变化。

low effort 并没有更便宜。 Fable 5 通过 output_config.effort 控制思考深度,直觉上 low 应该成本更低,但测试结果并非如此。设置 effort: "low" 后,编码循环每个任务的成本为 $0.0478,高于默认配置的 $0.0451,而且输出 token 更多。GLM 5.2 也出现了相同情况,它的 effort 名称同样不能反映 token 数量。不要想当然地认为 low 就代表“更少”,应先在实际工作负载上测试。数字难以预测的一个原因是,自适应思考在输出 token 中的占比会大幅波动:编码循环为 2%,RAG 回答为 30%,批量分类为 52%。这些结果来自同一模型和同一天。应按工作负载形态规划输出 token,而不是只按模型规划。

绝不要回传 reasoning_content 对于 OpenAI-compatible 模型,reasoning 字段不属于对话历史。DeepSeek API 要求移除它;在 GLM 5.2 中,回传虽然合法,但会计费。我们一度将它重新加入消息历史,导致 GLM 循环成本增加约 28%,移除后才恢复正常。Anthropic 自身的 thinking block 规则不同:使用同一模型时,必须原样回传;但如果将 Fable 5 的 thinking block 路由到另一个模型,例如 fallback 到 Opus,它会自动从 prompt 中移除,也不会计费,因此无需手动处理。

请求接口有哪些变化

Fable 5 的大部分请求接口与 Opus 4.7/4.8 和 Sonnet 5 相同。根据文档,以下功能已移除:

  • thinking: {type: "enabled", budget_tokens: N} 会返回 400。从 Claude 3.7 Sonnet 到 4.5 系列使用的按 token 预算控制机制 Extended thinking,已在 4.7 及后续系列中停用,改为自适应思考
  • thinking: {type: "disabled"} 会返回 400,而且这是 Fable 5 独有的变化。Opus 4.7/4.8 和 Sonnet 5 仍允许关闭思考,Fable 5 不允许。
  • temperaturetop_ptop_k 只要不是默认值,就会被拒绝。
  • Assistant-message prefill,也就是末尾追加一个 assistant 回合,会返回 400。

迁移旧请求时,最容易踩坑的是移除 temperaturetop_ptop_k 和 prefill。思考与数据保留方面的变化,前文及数据保留文章中已有说明。

结论

在 Agent 中使用 Fable 5,首先要解决的是工程问题,其次才是预算问题。执行工具调用前必须处理 stop_reason: "refusal",否则即使只是修改配置,截断的写入也可能破坏状态。成本则需要根据负载形态主动控制:缓存是最有效的手段;满足缓存条件的最低长度现在是 2,048 个 token,因此需要重新检查前缀;task budget 能避免循环持续累积本次对比中最高的单回合费用;effort: "low" 也不代表会有名称暗示的成本折扣。预算同样应按工作负载形态制定:同一个模型在编码循环中的成本是 glm-5.2 的 15 倍,而在缓存已预热的批处理任务中是 sonnet-5 的 5 倍。这并不是在建议使用或弃用它,而是说明默认配置并非中性选择。费用和故障模式都会随 Agent 形态变化。

常见问题

Fable 5 会频繁拒绝工具调用吗? 拒绝集中在特定任务上:一个配置修复任务每次运行都会被拒绝,其他任务则从未出现,而且同一任务在 streaming 和非 streaming 调用中都能复现。因此,这不是靠重试就能绕过的偶发问题。实际工作负载中的触发比例会不同,但工程上的处理方式不变:执行工具调用前检查 stop_reason

可以关闭 Fable 5 的思考吗? 不可以。thinking.type.disabledenabled 都会被拒绝。默认使用自适应思考,唯一的控制项是 output_config.effort;在我们的循环测试中,low effort 并未降低成本。

Fable 5 有可能是便宜的选择吗? 在这组测试中没有。它的最小成本溢价出现在缓存占比较高、且已预热的批处理任务中,约为 sonnet-5 的 5 倍,因为缓存抵消了大部分 prompt 成本。在循环和长对话场景中,它是我们测试过的模型里最贵的。


验证信息:所有数据均于 2026-07-05 通过 https://synthorai.io/ 测得。Claude 系列使用 Anthropic-native /v1/messages,glm-5.2 使用 /v1/chat/completions。五种场景形态共执行 505 个任务和 1,022 次调用;对波动有影响的任务各运行三次。成本取自 gateway 返回的 usage.cost,表中展示中位数。任务有意设计得较为简单,因此完成率只用于基本校验,并非能力基准;我们不会发布未经测量的能力结论。拒绝行为在 streaming 和非 streaming 模式下均可复现。实际结果会随 prompt、区域和负载变化。

← 返回博客