如果 Claude Opus 4.7 因为请求里还有 temperature 而返回 400,先不要找“更稳的 temperature 数值”。这不是调参题,而是请求字段已经和新模型契约不匹配。最安全的第一步,是把 temperature 从真实发出的请求里删掉。
同一条规则也覆盖 top_p 和 top_k。你真正要排查的是:字段来自你写的 SDK 调用,还是来自 Bedrock adapter、网关、代理、IDE 插件、评测脚本,或者某个旧的默认配置。删完字段以后,先在同一个模型、同一条路由、同一个任务上复验,不要马上换 provider。
简短顺序就是:删除旧采样字段,确认最终 outbound payload 真的干净,再用更清晰的 prompt、schema、测试或 effort 承接原先想做的控制。只有当前工具链今天确实停不掉这些字段,fallback 才算合理。
先选修复分支
把这个问题先当成请求路径排查,而不是“模型不好用”或“渠道坏了”。同一个报错可能由不同层负责,先定位负责层,才不会把能验证的问题改成一团不可复现的配置变更。
| 你看到的现象 | 最可能的责任层 | 第一动作 | 怎么复验 |
|---|---|---|---|
代码里显式传了 temperature、top_p、top_k | 直接 API 或 SDK 调用 | 删除这些字段,不要换成别的数字 | 打印最终 payload,再用同一路径重试 |
| 代码里看不到字段,但最终请求里还有 | SDK 默认值、公共 helper、网关、代理、评测脚本 | 找到最后一层 request builder 或 transformer | 确认离开该层的 payload 不含旧采样字段 |
| Bedrock 路由升级后报错 | Bedrock adapter 或 provider schema 翻译层 | 从 Bedrock payload 和 adapter 默认值里删字段 | 同一个 Bedrock model ID、同一任务复跑 |
| IDE 或 agent 工具切到 Opus 4.7 后失败 | 插件、preset、model wrapper 或旧模板 | 查 preset 是否还写入旧生成控制 | 删除 preset 默认值后复跑原任务 |
主要报错是 Claude Code 里的 top_p deprecated | Claude Code 专属分支 | 走 Claude Code 版本、路由、preset 检查 | 参考 Claude Code Opus 4.7 top_p Deprecated |
这张表最重要的是最后一列。你如果一边删 temperature,一边换模型、换渠道、改 prompt、换代理,最后跑通也不知道到底是哪一步起效。先保持同一路径,才有清晰信号。
Opus 4.7 变了什么
Anthropic 当前的 Opus 4.7 迁移说明把边界写得很明确:对 Claude Opus 4.7 设置非默认的 temperature、top_p 或 top_k 会返回 400。迁移建议不是“找一个还能用的数字”,而是省略这些字段,用 prompt 控制行为。
这也是为什么 temperature: 0 不是好补丁。旧模型里,低 temperature 也从来不是跨环境、跨路由、跨重试的严格确定性保证。到了 Opus 4.7,这个字段本身就不应该继续作为稳定性开关。你应该把严格性写进任务要求、输出格式、校验逻辑和测试用例。
可以把旧控制意图拆成下面几类:
| 旧想法 | 现在更合适的做法 | 边界 |
|---|---|---|
| 用低 temperature 让回答更稳 | 写清 schema、示例、禁止项和验收条件 | prompt 让行为更可控,但不等于绝对确定 |
| 用高 temperature 要更多变化 | 明确要求多方案、对比维度和选择标准 | 不要用被移除的采样旋钮模拟多样性 |
用 temperature: 0 做代码确定性 | 加测试、格式约束、回归 fixture | 稳定来自验证,不来自继续发旧字段 |
| 手动调推理预算 | 用路由支持的 effort | effort 管推理/成本,不管随机采样 |
所以正文里一直使用“旧采样字段”这个说法,而不是把它写成简单的“temperature 参数消失了”。这能提醒你同时检查 top_p 和 top_k。
先修直接 SDK 请求

如果字段在你自己的代码里,修复非常直接:删除,不要改数值。
pythonmessage = client.messages.create( model="claude-opus-4-7", max_tokens=1200, temperature=0.2, top_p=0.9, messages=[{"role": "user", "content": "Refactor this function."}], )
改成:
pythonmessage = client.messages.create( model="claude-opus-4-7", max_tokens=1200, messages=[{"role": "user", "content": "Refactor this function."}], )
TypeScript 也是同理:
tsconst response = await anthropic.messages.create({ model: "claude-opus-4-7", max_tokens: 1200, messages: [{ role: "user", content: "Summarize the incident." }], });
代码里删完以后,别只看调用处。要看最终 outbound body。很多团队以为已经删干净,其实公共 helper 又把默认 temperature 合并回来,或者 retry middleware 用旧模板重建了请求。
一个更有用的严格输出 prompt 是:
textReturn exactly one JSON object with keys "root_cause", "fix", and "verification". Do not include prose outside the JSON. If evidence is insufficient, set "root_cause" to "unknown".
这比继续发送 temperature: 0 更符合 Opus 4.7 的控制面。
如果团队里有多条调用路径,建议把修复写成一个很小的变更单,而不是让每个业务方自己猜。变更单至少包含三件事:哪些模型 ID 进入 Opus 4.7 分支,哪些字段必须在发送前被剥离,以及哪条日志能证明最终 payload 已经没有旧采样字段。这样前端、后端、平台组和评测脚本看到的是同一个契约,而不是五份“我这里已经删了”的口头确认。
上线时也不要只跑 happy path。选一个曾经失败的真实任务,把 prompt、模型、路由和 provider 都固定住,只改请求字段。第一次请求应该不再出现 400;第二次检查日志里也不应该出现 temperature、top_p、top_k。这两个信号同时成立,才说明你修的是当前路径,而不是靠旁路绕过了错误。
找到隐藏注入层

最麻烦的情况是:业务代码没有写 temperature,但 API 仍然拒绝请求。这时不要只盯着第一层函数调用,要看请求离开系统前的最后形状。
优先检查这些位置:
- SDK wrapper 是否给所有模型统一加默认生成参数;
- OpenAI-compatible 网关是否把
temperature原样翻译进 Anthropic 请求; - Bedrock 或其他 provider adapter 是否合并账号级默认值;
- IDE 插件、agent preset 是否还沿用旧模型模板;
- eval harness 是否为了可比性给每次运行都盖上
temperature; - 环境变量里是否有
MODEL_TEMPERATURE、DEFAULT_TOP_P; - retry 逻辑是否第一次请求清理了,第二次又从旧 body 重建。
排查时只需要记录字段名、模型 ID、路由和是否含旧字段,不要把密钥和完整 prompt 打到日志里。你要证明的是:最终发出的 JSON 已经没有 temperature、top_p、top_k。
Bedrock 和 provider 路由也要清
AWS Bedrock 的 Claude Opus 4.7 文档也写到 temperature、top_p、top_k 不再支持,并建议省略这些参数。这意味着不是只有直连 Anthropic API 才会遇到这个问题。
Bedrock 和网关用户最容易修错层。你的应用可能只发一个通用对象,adapter 再把它翻译成 provider payload。如果 adapter 仍然把 temperature 当成无害默认值,错误就属于 adapter,而不是业务代码。
| 路由层 | 要看什么 | 安全修法 |
|---|---|---|
| 应用请求 | 请求对象里是否还有旧采样字段 | 在进入 provider adapter 前删掉 |
| Adapter 映射 | 是否把 OpenAI 风格字段复制进 Bedrock Anthropic payload | 为 Opus 4.7 增加 drop 分支 |
| 项目默认值 | 控制台 preset 或配置文件是否全局注入 | 让默认值按模型分支,而不是全局套用 |
| 日志与重试 | retry 是否从旧模板重建 payload | 从清理后的 payload 重试 |
UI 上写着 Opus 4.7 不够。你要信最终 model ID、provider route 和 payload 字段。正确路由配旧 payload,照样会失败。
用什么替代 temperature

没有一个字段能一比一替代 temperature。你要先问:过去用 temperature 想完成什么控制任务?
| 控制任务 | 现在的做法 | 注意边界 |
|---|---|---|
| 输出格式更稳定 | schema、示例、禁止输出、验证反馈 | 不是绝对确定性 |
| 推理更充分 | 使用支持路由上的 effort | 影响推理和 token,不是采样随机性 |
| 减少啰嗦 | 收紧 max_tokens、回答结构和 stop 条件 | token 太紧会截断,要配优先级 |
| 要多个方案 | 明确要求候选方案和选择标准 | 不靠旧采样字段制造变化 |
| 生产稳定性 | 同 prompt、同路由、测试和回归 fixture | 稳定来自契约检查 |
effort 很有用,但它不是 temperature 的改名。把它当作推理预算控制,而不是随机性控制。旧的 manual thinking 字段也不要顺手保留,Opus 4.7 的 adaptive thinking 路径需要单独看官方当前说明。
复验,再决定 fallback
你的修复只有在同一路径成功后才算成立。复验流程很短:
- 模型、provider、prompt、任务都不变。
- 从真实发送路径里删
temperature、top_p、top_k。 - 确认最终 outbound body 没有这些字段名。
- 重试一次。
- 加回归检查,防止旧 wrapper 以后又把字段塞回来。
临时 fallback 不是禁区,但它只能放在最后。比如保留旧模型路径、在网关层剥掉被拒字段、或暂时 pin 某个工具版本。这些都是桥,不是长期契约。能修当前路径,就优先修当前路径。
错误示范是:换模型、换 provider、删字段、改 prompt 同时做,然后宣布问题解决。那只能说明另一路能跑,不说明原来的 Opus 4.7 路径已经干净。
常见问题
temperature 参数是完全移除,还是只有非默认值会失败?
官方边界说的是非默认 temperature、top_p、top_k 会返回 400。工程上仍建议省略字段,因为 SDK、网关和 adapter 对默认值的处理可能不同。
能不能设置 temperature: 0 来求确定性?
不要这样迁移。低 temperature 从来不是严格确定性保证,Opus 4.7 的修复也不是继续发送旧字段。用 prompt、schema、测试和同路径复验来提高稳定性。
effort 是 temperature 的替代品吗?
不是。它控制推理强度和 token 开销,不控制采样随机性。需要更严格格式时,先写清输出契约。
为什么 Bedrock 路由也会报?
因为 Bedrock 文档同样不支持这些旧采样参数。还要检查 adapter 是否把通用请求里的字段翻译进了 Bedrock payload。
这和 Claude Code 的 top_p deprecated 是一回事吗?
底层边界相同,但排查顺序不同。Claude Code 用户要先看版本、路由和 preset,可以转到 Claude Code Opus 4.7 top_p Deprecated。
工作规则
Claude Opus 4.7 因 temperature 报错时,先删字段,查注入层,同路径复验。不要先换渠道,也不要给旧采样参数找新数值。
