← 返回日报
🌐 机器翻译 · DeepSeek · HN

Migrating a production AI agent to GPT-5.6: 2.2x faster, 27% cheaper


以下是您要求的英文文章翻译为流畅中文的结果,已按照您的格式要求(保留标题层级、列表、段落、代码块、技术术语等)输出为 Markdown 格式。


将生产级 AI 智能体迁移至 GPT-5.6:速度提升 2.2 倍,成本降低 27%

截至目前,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 仍然暴露了整个技术栈中与提供商相关的假设。不同提供商在模型填充工具参数、缓存提示词以及在轮次之间重放推理的方式上存在差异。我们首先修复了评估框架,然后是工具模式、提示词缓存和推理重放。

步骤 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 | | 挂钟时间 | 8m 00s | 3m 42s | | 输入 tokens | 2.60M | 1.70M | | 输出 tokens | 33.0K | 17.1K | | 视觉评分 | 0.936 | 0.970 |

GPT-5.6 完成页面的速度是 2.2 倍,成本降低 27%,使用的输出 tokens 大约减少一半。它编写的代码也更少。在一组匹配案例中,Opus 生成了一个 17,957 字符的 globals.css,包含 174 个 CSS 变量,其中大部分是未使用的颜色渐变。GPT-5.6 使用了 2,508 个字符和 45 个变量,实现了可比甚至有时更好的渲染页面。

GPT-5.6 擅长干净、紧密网格化的布局,但如果没有强有力的引导,它倾向于收敛于这种风格。在我们为 Opus 4.8 设计的旧评估框架下,GPT-5.6 Sol 经常忽略现有的设计系统,产生干净但通用的输出。我们在此所做的更改值得单独写一篇文章。我们的设计和工程团队改进了引导方式,直到 GPT-5.6 达到我们在生产环境中要求的品牌一致性标准。

步骤 1:检查你的工具调用

我们智能体的代码工具有 25 个顶层参数。其中一个,action,是必需的;其余都是可选的。Claude 只发送它使用的两三个参数,并省略其余参数。GPT-5.6 在每次调用时都会发送全部 25 个参数,用看似合理的值填充未使用的参数,例如 offset: 0timeout: 120000siteId: "00000000-0000-0000-0000-000000000000"。我们在三天的生产代码(读取)轨迹中看到了这一模式。

模型调用携带全部 25 个属性的情况

| 模型 | 调用次数 | 携带全部 25 个属性的调用次数 | | :--- | :--- | :--- | | gpt-5.6 | 6,635 | 6,635 (100%) | | claude-opus-4.8 | 2,898 | 4 (0.1%) | | claude-sonnet-5 | 1,933 | 0 |

冗长并不是问题所在。文件读取实现无法区分一个编造的值和一个预期的值。它将 offset: 0 视为真实参数,导致 GPT-5.6 的 52% 到 64% 的文件读取返回空结果。该工具对有效读取和空读取都返回 success: true,因此模型无法判断它正在读取空白文件。它通过更多调用和更差的结果来补偿。提示词无法解决这个问题。一个工具描述指令要求“省略未使用的参数”,仍然产生了全部 25 个参数。每个属性的“可选,如果未使用则省略”提示也是如此。我们在 OpenAI 的严格模式下测量了相同的行为,采用该模式需要从每个模式中剥离 patternformat 和数组边界验证。

这种行为源于模型发出函数调用的方式,因此我们改为更改模式。有效的修复是在提供商边界处进行模式转换。对于 OpenAI 系列的模型,我们将每个可选属性重写为必需但可为空的属性,使用 anyOf: [T, null]。这为模型提供了一个表示未使用参数的显式值。然后,我们在共享的工具调用边界处进行验证之前剥离这些 null 值,因此工具实现无需更改。模型看到的是一个表示未使用值的模式,而工具接收到的输入与之前相同。

// 之前:25 个键,每个都携带一个编造的值
{
  "action": "read",
  "file_paths": ...
}

如果您需要我继续翻译剩余部分(代码块之后的内容),请提供完整的原文,我将为您完成。

📖 阅读原文 →