# Ploy 将 AI 智能体默认模型从 Claude Opus 4.8 切换至 GPT-5.6 Sol

- 来源：Hacker News 热门（buzzing.cc 中文翻译）
- 作者：brryant
- 发布时间：2026-07-13 07:41
- AIHOT 分数：70
- AIHOT 标记：精选
- AIHOT 链接：https://aihot.news/items/cmrig9mkx0024bijp9pr04hss
- 原文链接：https://ploy.ai/blog/migrating-a-production-ai-agent-to-gpt-5-6

## 精选理由

这篇 Ploy 的迁移手记把 GPT-5.6 生产中踩的坑都摊开了，工具调用参数膨胀和缓存键设计两个问题，做 agent 的团队不看可能会付昂贵学费。

## AI 摘要

Ploy 将其 AI 智能体默认模型从 Claude Opus 4.8 切换至 OpenAI 今晨发布的 GPT-5.6 Sol。在真实营销网站构建测试中，GPT-5.6 Sol 完成页面平均耗时 3 分 42 秒，较 Opus 4.8 的 8 分钟快 2.2 倍；每次构建成本从 3.06 美元降至 2.22 美元，降低 27%；输出 token 从 33.0K 降至 17.1K，视觉评分从 0.936 提升至 0.970。迁移过程发现，GPT-5.6 会为所有 25 个工具参数填充默认值，导致 52%-64% 的文件读取返回空结果；提示词指令和 OpenAI strict 模式均无法修复此行为。此外，评估框架中约三分之一的原始失败源于针对旧模型的假设，而非模型本身问题。

## 正文

截至今天，Ploy 的智能体运行在 GPT-5.6 Sol 上，这是 OpenAI 今早发布的模型家族中的旗舰层级。数月以来，没有任何模型达到我们替换 Claude Opus 的标准。GPT-5.6 Sol 做到了。经过一轮正面对比评估，我们将其设为每个 Ploy 工作区的默认模型。

Ploy 的智能体负责构建和编辑生产环境的营销网站。它会规划页面、阅读代码库、编写组件、生成图像、对自己的作品截图，并判断何时完成。我们用这一工作负载测试每一个前沿版本。在 Opus 占据默认位置的这四个月里（先是 Opus 4.7，然后是 4.8），我们测试过的任何模型都未能超越它。GPT-5.6 是第一个做到的。

第一轮评估运行暴露出了若干失败模式，我们在下文会逐一说明。它也带来了强劲的结果。完成的构建耗时不到原来的一半，成本降低 27%，得分达到或超过我们现有的模型。这些结果证明了迁移工作的合理性。

我们使用 Vercel 的 AI SDK，但从 Claude Opus 4.8 切换到 GPT-5.6 Sol 仍然暴露出我们整个技术栈中针对特定提供商的假设。各家提供商在模型如何填充工具参数、缓存提示词以及在轮次之间重放推理过程方面存在差异。

我们先修复了评估框架，随后依次处理了工具 schema、提示词缓存和推理重放。

第 0 步：在信任任何一个数字之前，先修好你的评估框架

我们的评估套件让生产环境的智能体在固定工作区上运行。它覆盖了数百个用例，从“从零构建一个主页”到“这个克隆请求是否可以安全执行”。对于构建类用例，一个视觉评判器会针对参考设计运行十项二元检查，例如“主视觉是一幅全出血的摄影场景”以及“主要 CTA 是圆角矩形，而不是胶囊形。”我们还会运行内容检查、工具轨迹检查和文件断言。我们会对照完整轨迹对每一个失败进行分诊，包括工具调用和模型文本。

第一次跨模型运行暴露了评估框架中的一个问题。

我们的工具调用预算是按照 Opus 的串行风格来设定的。GPT-5.6 会进行并行调用，在它正确解决的用例上超出了这些预算。我们的评估执行器也不支持批量文件读取，而 Opus 很少使用这一功能，GPT-5.6 却经常使用。第一次运行中大约三分之一的原始失败来自框架假设，而非模型行为，而且这些失败分布不均。如果你要用一个挑战者模型去评估一个在位模型，在信任通过率之前先对轨迹进行分诊。否则，评估实际上是在奖励新模型表现得像旧模型。

一个省略了其minScore阈值的数据集继承了 1.0 的默认值，而没有任何东西标记出这一回退。因此 GPT-5.6 在一个得分为 0.98 的主视觉上“失败”了，而 Opus 尽管通过了每一项单独检查，却仍在一个用例上“失败”了。两种设计都站得住脚，但那个隐式阈值让它们都失败了。

基准测试结果

修复测试框架后，我们重新运行了重设计测试套件，在该套件中，智能体需要参照一份参考设计重建某个品牌的首页。

每次完成构建的平均值Claude Opus 4.8（n=11）GPT-5.6（n=10）

成本$3.06$2.22

实际耗时8分00秒3分42秒

输入 token2.60M1.70M

输出 token33.0K17.1K

视觉评分0.9360.970

GPT-5.6 完成页面的速度快 2.2 倍，成本低 27%，输出 token 用量约为一半。它写的代码也更少。在一组匹配对比中，Opus 生成了一个 17,957 字符的 globals.css，包含 174 个 CSS 变量，其中大部分是未使用的颜色梯度。GPT-5.6 只用了 2,508 个字符和 45 个变量，就渲染出了效果相当、有时甚至更好的页面。

Claude Opus 4.8

GPT-5.6 Sol

设计质量与一致性

GPT-5.6 擅长干净、网格严密的布局，但在缺乏强引导的情况下，它往往会收敛到这种风格。用我们为 Opus 4.8 设计的旧版 harness 时，GPT-5.6 Sol 经常忽略现有的设计系统，产出干净但千篇一律的结果。

我们在这里所做的改动值得单独写一篇文章。我们的设计和工程团队改进了引导，直到 GPT-5.6 达到我们在生产环境中所要求的品牌一致性标准。

第 1 步：检查你的工具调用

我们智能体的 code 工具有 25 个顶层参数。其中 action 是必填的，其余都是可选的。Claude 只发送它用到的两三个参数，省略其余部分。GPT-5.6 每次调用都发送全部 25 个参数，用看似合理的值填充未使用的参数，例如 offset: 0、timeout: 120000 和 siteId: "00000000-0000-0000-0000-000000000000"。

我们在三天的生产环境 code(read) 追踪记录中看到了这一模式。

模型调用次数携带全部 25 个属性

gpt-5.66,6356,635（100%）

claude-opus-4.82,8984（0.1%）

claude-sonnet-51,9330

问题并不在于冗长。文件读取的实现无法区分凭空捏造的值和预期的值。它把 offset: 0 当作真实参数处理，导致 GPT-5.6 的文件读取中有 52% 到 64% 返回空结果。该工具对有效读取和空读取都返回 success: true，因此模型无法判断自己读到的其实是空文件。它只能靠更多调用来弥补，结果反而更差。

提示词工程没能解决这个问题。在工具描述中加一条“省略未使用的参数”的指令，结果仍然生成了 25 个参数中的 25 个。逐属性的“可选，未使用则省略”提示也是同样的结果。我们用 OpenAI 的 strict 模式测得了完全相同的行为，而采用它就意味着要从每个 schema 中剥离 pattern、format 以及数组边界校验。这种行为源于模型发出 函数调用的方式，所以我们改为修改 schema。

有效的修复方案是在 provider 边界处做一次 schema 转换。对于 OpenAI 系列模型，我们用 anyOf: [T, null] 把每个可选属性改写为必填但可为 null。这样模型就为未使用的参数提供了一个显式值。随后我们在共享的工具调用边界处、校验之前剥离这些 null，因此工具实现无需改动。模型看到的 schema 能够表达未使用的值，而工具收到的输入与之前相同。

// Before: 25 keys, every one carrying an invented value { "action": "read", "file_paths": [...], "offset": 0, "timeout": 120000, ... }

// After: 25 keys, 4 real values, 21 explicit nulls (stripped before the tool runs) { "action": "read", "file_paths": [...], "offset": null, "timeout": null, ... }

改动之后，空文件读取从 52% 降至 0%。由于不再重复读取空白结果，智能体完成同样的工作所用的工具调用次数也减少了约 30%。

第 2 步：重建提示词缓存

两家 provider 都提供“提示词缓存”，但实现方式不同。在我们弄清这些差异之前，GPT-5.6 看起来比 Opus 贵约 50%。这个差距是我们的缓存配置造成的。模型定价本身没问题。

我们的智能体提示词以一个约 29K token 的静态前缀开头（工具 schema 加上核心系统提示词），该前缀在每次对话中都完全相同。在 Claude 上，我们用 cache_control 标记缓存断点，该前缀在整个组织范围内缓存。任何工作区中的任何对话都可以使用同一个共享条目，且不受按 key 的吞吐量预算限制。缓存命中率在 92% 到 96% 之间。

GPT-5.6 使用一种不同的 OpenAI 缓存模型。早期的 GPT 模型会缓存隐式的部分前缀匹配。GPT-5.6 取消了部分前缀匹配，因此隐式缓存现在会以最新消息为键创建整段提示词条目。一个共享我们 29K 静态前缀的新对话，其缓存命中率为 0%。每次对话都按未缓存费率重新计费整个前缀。GPT-5.6 还会对每个未缓存的提示词加收 1.25× 的缓存写入附加费，无论应用是否使用了缓存。

显式机制使用 prompt_cache_breakpoint 标记以及一个必填的 prompt_cache_key。该 key 是缓存标识的一部分，因此相同提示词搭配不同 key 不会产生缓存命中。每个 key 映射到一个缓存节点，该节点大约能承受每分钟 15 个请求，之后 OpenAI 会将流量分发到其他具有独立冷缓存的节点。

主要的设计决策是应由哪个实体来确定 key 的作用域。

按对话设置 key：新对话永远不会命中共享前缀。我们在此配置下测得首次调用命中率为 0%。

单一全局键： 每个请求都哈希到同一个缓存节点。生产流量超出了 15 rpm 的预算，请求溢出到冷节点。

按工作区划分的键： 客户工作区中的所有对话共享条目，而每个键的流量保持较低。

我们上线了按工作区划分的键，并将系统提示词拆分为带断点的分层，与我们此前用于 Anthropic 的结构保持一致：

request ──► hash(prompt head + prompt_cache_key) ──► cache node (~15 req/min per key) │ ┌──────────────────────────────────────────────────────┴───────────────┐ │ entries on the node, all namespaced by key ws:{workspaceId} │ │ │ │ [ tools + static prefix ]······················ A every session │ │ [ tools + static prefix + workspace context ]·· B same context │ │ [ ····················· + turn 1 + … + latest ] C this session │ └──────────────────────────────────────────────────────────────────────┘

条目 A 降低了会话首次调用的成本。当工作区记忆发生变化时，请求会未命中条目 B，但仍会命中条目 A，然后写入一个新的条目 B。这只需要一次上下文大小的写入，而无需为完整的 29K 前缀重新计费。条目 C 是 OpenAI 的隐式全提示词链，它在会话内有效，因为我们的提示词严格只追加。

OpenAI 的键分区阻止了静态前缀跨工作区共享。Anthropic 可以共享前缀，因为其缓存是组织范围的，没有键分区。在 GPT-5.6 上，每个工作区在每个空闲窗口都要为一次 29K 的冷写入付费，约 $0.18。成本是有界且可预测的。

改动之后，首次调用缓存命中率从大约 0% 上升到 83.7%，未缓存输入 token 总数下降了 28%，GPT-5.6 的每套件成本降至 Opus 以下。缓存配置错误正是我们此前测得的全部成本差距所在。当一个模型从冷缓存启动时，模型之间的成本比较是没有意义的。

第 3 步：让推理重放自包含

推理重放导致生产环境对话出现间歇性失败。GPT-5.6 的 Responses API 默认会将先前轮次的推理作为服务端条目引用进行重放，我们的对话有时会因 Item 'rs_...' not found 而失败。设置 store: false 会让 SDK 请求 加密的推理内容，并重放自包含的数据块，而不是指向服务端状态的指针。我们还了解到，即使应用程序发送的字节是仅追加的，服务端的推理状态也可能改变实际生效的提示词。

在生产环境中运行 GPT-5.6 Sol

GPT-5.6 今天发布，并且已经在 Ploy 上线。你可以 在 ploy.ai 免费开始使用，给它一个网站去构建，看看不到四分钟的构建是什么样子。

Ploy 是一个 AI 层，能够规划、构建、发布并优化网站和营销活动。如果你觉得凌晨两点调试缓存节点扇出很有趣，我们正在招聘.
