OpenAI 7/9 把 GPT-5.6 + ChatGPT Work 同日上线后 48 小时,生态在三条线同时重新选边:OpenAI 自己暂时取消了 Plus / Business / Pro 的 5 小时使用限制;Codex 周活冲到 600 万;生产代理侧一家叫 Ploy 的公司,把自己的核心代理(构建营销网站、跨 App 规划、读写代码库、自截图、自判 done)从 Claude Opus 4.8 切到 GPT-5.6 Sol,首次跑就比 Opus 4.8 快 2.17 倍、便宜 27%、视觉分 0.970 vs 0.936。
这三件事单独看都已经是新闻,凑在一起看更像信号:模型层的差距正在被工程层的差距代替。任何现在想迁生产代理到 GPT-5.6 的 builder,都会撞上同一堵墙——账面对了,堆栈没准备好。
真正抢眼的是这一步:把生产代理换模型的账
Ploy 那篇迁移笔记(作者 Lorenzo Gentile,7/9 当天发的 11 分钟长文)公开的逐项数据,是当下少见的「真生产代理换模型」的硬数:
- 单任务成本:Opus 4.8 $3.06 → GPT-5.6 $2.22(降 27%)
- 端到端构建时长:8m00s → 3m42s(2.17x)
- 输入 token:2.60M → 1.70M
- 输出 token:33.0K → 17.1K
- 视觉分(生成网站的截图评分):0.936 → 0.970
这组数字抢眼的点不是 27%,是「生产代理能公开这件事」。过去 18 个月,所有「模型 X 比模型 Y 强多少」的对比,几乎都跑在公开 benchmark 上;Ploy 这是把一个真在替客户构建完整营销网站的代理整体换模型,然后把账放出来。
但文章里真正该看的不是这张表,是表下面三个隐性坑。Ploy 自己写得很清楚:「我们以为在做 A/B 测试,结果前三天 50% 以上的 tool calls 拿不到正确的文件内容,迁完之后我们才知道,过去一年的工程栈是悄悄为 Opus 4.8 优化的。」
但 Ploy 自己说的三个隐性坑
把这三个坑拆开看,每一条都不是「GPT-5.6 不会」,是「GPT-5.6 会的东西跟你的 schema 长不一样」。
工具调用越权:25 个参数全填默认值
Ploy 的 code tool schema 有 25 个 top-level 参数,1 个 required + 24 个 optional。切到 GPT-5.6 之后三天生产 trace:
- GPT-5.6 共 6635 次
code(read)calls,6635 次都把 25 个属性带齐(100%) - Claude Opus 4.8 共 2898 次,只有 4 次带齐 25 个属性(0.1%)
- Claude Sonnet 5 共 1933 次,0 次带齐
GPT-5.6 看到一组 optional 字段,会主动按 schema 给每个字段填一个「看起来合理」的默认值:offset: 0、limit: 100、timeout: 120000、siteId: "00000000-0000-0000-0000-000000000000"……Ploy 用的是「真读取」语义,传了 siteId 占位 UUID 直接落到了「取全站列表」的 code path,结果 52%–64% 的 file read 返回空内容,agent 自己以为是文件不存在,不断重试,单任务 tool call 数被推高 30%。
Ploy 的修法是 schema 层直接重写:把每个 optional 改成 required-but-nullable,用 anyOf[T, null] 表达「这个字段可以是 null,模型不填的话就是 null」,然后在 provider boundary 把 null 都剥掉再交给后端。
// schema 转换前(GPT-5.6 会填默认值进去)
{
"type": "object",
"properties": {
"offset": { "type": "integer", "default": 0 },
"limit": { "type": "integer", "default": 100 },
"timeout": { "type": "integer", "default": 120000 },
"siteId": { "type": "string" }
},
"required": ["siteId"]
}
// schema 转换后(只有传了的字段才会进请求)
{
"type": "object",
"properties": {
"offset": { "anyOf": [{ "type": "integer" }, { "type": "null" }] },
"limit": { "anyOf": [{ "type": "integer" }, { "type": "null" }] },
"timeout": { "anyOf": [{ "type": "integer" }, { "type": "null" }] },
"siteId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }
},
"required": ["siteId", "offset", "limit", "timeout"]
}
这个修法做完的效果是:空读取率 52% → 0%,单任务 tool call 数 -30%。本质上,Opus 4.8 的行为是「不该填就空着」,GPT-5.6 的行为是「schema 有 default 就填默认」,你的堆栈得为后一种行为显式表态。
缓存断崖:取消 partial-prefix 隐式缓存
Opus 4.8 那边的 prompt cache 是「org-scoped partial-prefix」命中,1 个 29K tokens 的静态前缀(系统提示 + 工具描述 + 团队风格规范),命中率长期 92%–96%。切到 GPT-5.6 不做改造,命中直接掉到 0%。
GPT-5.6 砍掉了 partial-prefix 隐式缓存,改成显式 prompt_cache_key + prompt_cache_breakpoint 两段标记,不打标不打点就没有缓存,冷写一次 $0.18。Ploy 的修法是把静态前缀拆成「system prompt(不变)→ breakpoint → 任务模板(不变)→ breakpoint → 任务实例(变)」三层,每层显式加 prompt_cache_breakpoint,用 prompt_cache_key 按 workspace 区分(不是按 conversation,因为单个 workspace 内多个 conversation 共享同一段不变前缀),首调用命中从 0% 提到 83.7%,总 uncached input tokens 降 28%。
但这里有个隐形天花板:OpenAI 同一个 cache key 每分钟大约只能撑 15 次请求(15 rpm),超过就被 fan-out 到冷节点。所以 key 的拓扑也很关键:
- Global key:撞 rpm 配额,每个请求反而要走冷前缀,反而更贵
- Per-conversation key:永远 cold,每次新建会话第一个请求都是冷写
- Per-workspace key:是 sweet spot,工作空间内所有会话共享同一段不变前缀,命中率高又不撞配额
Ploy 的方案本质上是「把不变前缀跟会话生命周期解耦,跟工作空间生命周期绑定」。这件事听起来是配置项,实际是 prompt 设计哲学的差别:Opus 时代你写好 prompt 就行,GPT-5.6 时代你得想清楚「这段 prompt 会在哪个 key 下被读几次」。
Reasoning replay:server-side item reference 翻车
第三个坑最隐蔽。GPT-5.6 / Responses API 默认是 server-side item reference:调用 Responses 时 server 给你一个 rs_xxx 句柄,下一轮你传 previous_response_id: rs_xxx 把推理链条接回去。看起来很优雅,Ploy 迁完三天后的生产 trace 却出现一类新错误:Item 'rs_xxx' not found。
根因不是 server 删数据,是 server state 跟客户端 append-only input 之间发生分裂。Ploy 的代理是流式追加:worker 端会持续把新 tool 输出 push 进同一个 rs_xxx 的引用里,多 worker 并发的时候,server 那边收到 push 的顺序跟主会话的时间序有偏差,主会话下一次取这个 rs_xxx 的时候 server 内部索引对不上,直接 404。
Ploy 的修法是显式 store: false。这拿到的是另一种 Responses 行为:不存 server-side item reference,而是把整个 reasoning 内容用加密 blob 直接嵌在响应体里,下一轮你把这个 blob 当 input 原样回传,等于回到「append-only 本地推理」模型。代价是单次请求体积变大,但客户端 session 模型是确定的:append-only,server state 不参与,多 worker 并发安全。
说白了,Responses API 有两种模式,「引用」模式跟「回放」模式。Opus 时代你只有「回放」模式(claude 的 multi-turn 也是靠 client-side message array),GPT-5.6 默认给「引用」,多 worker 并发场景下「回放」是唯一不掉链子的选择。
7 天爆出来的其他信号
Ploy 之外,这周 GPT-5.6 + OpenAI 家庭另外几个信号值得一起看:
- Codex 周活 600 万:上一周 7/10 那篇 ChatGPT Work 文章里是 500 万,这一周又多了 100 万,仍然以「真实完成任务数」为口径。
- Plus / Business / Pro 5 小时限额暂时取消:OpenAI 内部显然在用分发层动作告诉市场「GPT-5.6 产能没问题」,这个动作跟 GPT-5.6 + ChatGPT Work 同发是配套的。
- Tibo 在 X 上放出「用 CLIProxyAPI 把 Claude Code 后端切到 GPT-5.6 Sol」的 5 分钟教程:这是 builder 侧的实测,意味着不只是 Ploy 一家在迁,至少有 KOL 觉得这件事值得出一个公开教程。
三件事的方向一致:GPT-5.6 的供应没问题,需求在快速从 Opus 往 GPT-5.6 上挪。
对 builder 的具体含义:迁生产代理必须走的三步
如果你正在考虑把生产代理从 Opus 4.8 迁到 GPT-5.6,Ploy 的三条经验合并成一份迁移清单:
- 重写 tool schema,做 null-strip boundary。所有 optional 字段改成
required-but-nullable(anyOf[T, null]),provider 层剥 null。这是 schema 层的「GPT-5.6 适配」必修课,单这一步就能拿下 30% 的 tool-call 减量。 - 为 prompt cache 重做 prompt 拓扑。把 prompt 拆成三层显式
breakpoint,key 用 per-workspace 而不是 per-conversation。然后重跑一遍 trace,看看冷写 $/月是不是真的降了,Ploy 拿到的数字是总 uncached input tokens -28%。 - 明确选 reasoning replay 模式。多 worker 并发场景,直接
store: false,回到 append-only 本地回放。单 worker、串行场景可以用 server-side item reference 省 token。
这三步的本质不是「迁模型」,是「迁你的堆栈以匹配新模型的默认行为」。Ploy 之前一周堆栈是悄悄为 Opus 4.8 优化的,他自己都没意识到;迁完之后才显式意识到「opportunism 的差异不是模型,是堆栈适配」。
跟 6/27、7/10 区别在哪
同一个 GPT-5.6 主题,我之前在 6/27 那篇 ID-check 文章讲的是普通用户层的变化(登录多一道身份验证、Washington Post 报道、「白名单分发」变成产品定义本身);在 7/10 那篇 ChatGPT Work 文章讲的是市场层的变化(OpenAI 同日双发模型 + Agent、Codex 周活 500 万、Musk 公开认 Anthropic 领先、agent 任务完成度成为新主战场)。这两篇都还没讲到具体 builder 的工程账。
这一篇专门讲 builder 这边:Ploy 把真生产代理从 Opus 4.8 切到 GPT-5.6,公开账之外藏着三个真工程坑(schema 越权、缓存断崖、reasoning replay 失配),共同点是「你以为是模型的差异,实际是你堆栈已经悄悄适配了 incumbent 模型」。这三件事的修法都不是改业务逻辑,都是改 schema / 改 prompt 拓扑 / 改 replay 模式,是堆栈层的事。
读 6/27 那篇你能回答「我作为用户登录会怎样」;读 7/10 那篇你能回答「OpenAI 现在押什么」;读这篇你能回答「我现在做 agent,想换模型,工程上要按什么顺序检查」。三篇拼起来,GPT-5.6 上线后这一周的全图就出来了。