opus 5.5 用 medium 还是 high,我拿自己的 repo 测了一下
起因
opus 5.5 今天出来了,我第一件事是想定一下默认用哪一档 reasoning effort。opus 5.5 有五档:low、medium、high、xhigh、max。我之前 claude code 全局开的是 xhigh,给 opus 5.5 单独设的是 medium,纠结的点其实就是 medium 和 high 选哪个。
网上能找到的大多是 benchmark 分数,但 benchmark 和我自己每天让 agent 干的活不太是一回事。我平时基本不自己写代码了,改动几乎全是 agent 写的,我也不逐行 review,所以我真正关心的是两件事:
- 在我自己的 repo、我自己会交给它的那种任务上,两档的完成度差多少。
- 差出来的那点东西,值不值得多花的时间和 token。
所以干脆直接测。
怎么测的
思路是 replay 历史提交,有点像 SWE-bench 那一套,只不过题目全部来自我自己的 repo。具体流程大概是这样的:
- 挑题。让 agent 去扫我 11 个 repo 最近几个月的提交历史,这些 repo 有 TS 的 side product、Rust 写的桌面工具和凭据管理工具、Python 的出版流水线、Node 的 agent runtime,挺杂的。挑的标准是:一个提交同时改了源码和测试,测试放在单独的文件里,改动量在几十到几百行,而且是 feature 或者 bug fix,不是 refactor。最后挑出 22 个。
- 验题。对每个候选题,另开一个 agent 独立复现一遍:在父提交上把原提交的测试叠上去,必须 fail;切到原提交,必须 pass;再跑两遍查 flaky。同时它还要检查任务描述公不公平,也就是隐藏测试依赖的每个函数名、签名、报错文案,任务描述里有没有写清楚,写没写清楚都不能泄露实现。有几道题被它改了措辞才放行。
- 跑题。每道题 medium 和 high 各跑 2 次,一共 88 次。每次都在一个新的 git worktree 里,停在父提交,依赖提前装好,给 agent 的任务描述两档一模一样。同一道题的 medium 和 high 是同时开跑的,这样机器负载对两边是一样的。
- 判分。agent 跑完以后,把原提交的测试叠到它的改动上跑,这是硬指标。再跑一遍整个 test suite 看有没有引入新失败。
- 盲评。同一道题同一轮的两份答案,打包成 A/B 交给一个 judge,它看得到任务、原提交的 diff、两份 diff、测试结果和 agent 自己的收尾报告,但不知道哪份是哪一档。每一对评两次,第二次 A/B 对调,抵消位置偏好。一共 88 次评审。
replay 测试流程:挑题、验题、配对跑、隐藏测试判分、盲评
时间和 token 从每个 agent 的 transcript 里直接算,不靠它自己报。另外我还扫了一遍所有 agent 跑过的命令,看有没有人偷看 HEAD 之后的历史或者主 checkout,没有。
中间出了个插曲:跑到一半,我本机的登录 token 被换了一次,旧 token 当场作废,12 秒之内 39 个 agent 全部 401 挂掉。workflow 里的子 agent 遇到 401 不会重试,直接判失败。当时正卡在 cargo build 这种长命令里的几个 agent 反而活了下来,因为那 12 秒里它们没发 API 请求。我的处理是只要一对里有一边挂了,就整对作废重跑,worktree 也删了重建,保证两边的负载条件还是一样的。最后的数据全部来自完整跑完的 44 对。
结果
先说最直接的,两档的完成度没有区别。88 次全部通过隐藏测试,也都没有引入新的测试失败。full suite 里有一些失败,我一个个对过,要么是原提交本来就挂的测试,要么是并发跑的时候机器太忙导致的超时,闲下来重跑就过了。
差别在时间、token 和质量上:
| 指标 | medium | high |
|---|---|---|
| 隐藏测试通过 | 44/44 | 44/44 |
| 耗时中位数 | 140s | 234s |
| 耗时(配对几何平均) | 1× | 1.33×,44 对里 39 对 high 更慢 |
| 输出 token(配对几何平均) | 1× | 1.35×,44 对里 43 对 high 更多 |
| 按 token 估的成本 | 1× | 约 1.29× |
| 盲评胜场 | 7 | 16(另有 21 对打平) |
盲评那一行要展开讲一下,因为 high 赢的地方挺有意思的。judge 给 high 投票的那些对,大部分是抓到了测试查不出来的真 bug:
- 一个 dashboard 的柱状图,medium 版把柱高按压缩前的数据算比例,但画的是压缩后的柱子,90 天和全部时间的图会画出超过 100% 的柱子。测试没覆盖渲染,所以两边都是绿的。
- 一个定时衰减的逻辑,medium 版改了数据库里的状态,但没同步内存里的那份,后面一次整体写回会把刚写进去的衰减标记冲掉。
- 一个迁移脚本加了「检查不通过就拒绝写入」,medium 版的检查放在已经改完两个文件之后,拒绝的时候磁盘已经半脏了。high 版两次都是先检查再动磁盘。
- 一个几何图元的两套光栅化实现,high 版两次都让浮点实现、整数实现和 SVG 描述的是同一块区域,任务里要求的面积误差在各种角度下都守得住,medium 版在小尺寸和 45 度的时候会破。
- 还有两个是 medium 没按任务写明的语义来:一个是条件判断的顺序写偏了,一个是破坏了 repo 里一条限制中文硬编码数量的检查。
反过来 medium 赢的 7 对里,只有一对是真 bug:high 在改一个登出请求的时候,顺手把平台要求的客户端 IP 头删掉了,真实环境下登出会直接失败。其他几对 medium 赢在 high 多改了没要求的东西,或者 high 忘了更新被改动弄过时的文档。
judge 的分项分数也是这个形状。high 在完成度(8.90 对 8.72)和验证充分度(8.89 对 8.62)上高一点,medium 在不越界(8.76 对 8.28)上高一点。high 更爱顺手多干一点,这个有好有坏:多干的部分大多是补测试、更新文档,但偶尔也会动到不该动的东西。
需要说清楚的是,16 比 7 这个差距还不够统计显著,符号检验 p 大概是 0.09,judge 偏好均值的置信区间也跨过了 0。所以结论只能说是一个倾向,真正让我倾向 high 的是上面那几个具体的 bug,它们都是那种测试全绿、我自己又不会逐行去看、上线以后才会炸的东西。
对一下 Artificial Analysis 的数据
Artificial Analysis 今天也放了 opus 5.5 的评测,五档 effort 全测了。我把 Intelligence Index 和跑完整套评测花的 token 摘出来:
| effort | Intelligence Index | 跑完评测的输出 token | 相对上一档的成本 |
|---|---|---|---|
| low | 42 | — | — |
| medium | 51 | 38M | — |
| high | 54 | 53M | 约 1.3× |
| xhigh | 56 | 100M | 约 1.9× |
| max | 58 | 260M | 约 2.6×(按 token 算) |
这组数据和我自己测出来的挺吻合的。他们那边 high 对 medium 的 token 是 1.39 倍,成本大概 1.33 倍,我这边是 1.35 倍和 1.29 倍,基本一个数。分数上 medium 到 high 涨了 3 分,花 1.3 倍的钱,这是整条曲线上最划算的一步。再往上,high 到 xhigh 涨 2 分要花将近 2 倍,xhigh 到 max 再涨 2 分,token 又翻了 2.6 倍。
effort 阶梯:medium 到 high 这一步最划算,再往上成本翻倍
他们的文章里还提到,opus 5.5 的 max、xhigh、high、medium 四档都在「分数对单题成本」的 Pareto frontier 上,这个价位上没有别的模型能同时更便宜又更强。价格也比 opus 5 降了一截,cache read 尤其便宜,这对 agent 这种大量重复读 context 的用法很友好。
所以两边的数据说的是同一件事:medium 已经很强,high 用三成多的额外成本换来一点实打实的提升,再往上就是边际收益快速变小的区间了。
最后怎么定的
默认改成了 opus 5.5 + high。理由其实就是上面那几个 bug。我的 workflow 里没有人工 review 这一环,能兜底的只有测试和 agent 自己的判断,测试查不出来的那类错误,就只能靠模型多想一步。多花三成的时间和 token 换这个,对我来说是值的。
改配置的时候踩了一个坑,顺便记一下。我把 settings.json 里的 effortLevel 改成了 high,新开 session 一看,实际跑的还是 xhigh。查了一圈发现是 ultracode:只要 "ultracode": true,每个 session 都会被强制成 xhigh,settings 里的 effort 设什么都不生效,交互模式和 claude -p 都一样。验证的办法是看 transcript 里每条消息记的 effort 字段,或者直接看启动画面那行「with high effort」。所以想要 high 当默认,ultracode 得关掉,需要的时候再单独开。另外 --effort 参数和 CLAUDE_CODE_EFFORT_LEVEL 环境变量都能直接覆盖,临时切档用这两个就行。
不同用法怎么选
这是我自己的场景得出的结论,换一种用法答案可能就不一样了。大概分这么几类:
- agent 自己跑到底、没人 review 的(跟我一样):用 high。完成度两档一样,但 high 能多抓一些测试兜不住的问题,这正好是没人 review 的时候最怕的那种错。
- 结对编程、自己会看 diff 的:medium 就够了。快三分之一,越界更少,它漏掉的那种问题你 review 的时候大概率能看出来。等它的时间省下来,体验上差别挺明显的。
- 额度比较紧的(Pro、订阅用量经常撞墙、或者按 API 大量调用):默认 medium,碰到难的任务手动
--effort high。三成多的 token 差距放到一个月的量上还是挺可观的。 - 难题(算法、几何、并发、数据一致性、跟钱有关的路径),或者一跑好几个小时的长任务:可以开到 xhigh。AA 的数据显示 xhigh 还能再涨 2 分,但成本差不多翻倍,只值得花在这种地方。max 我只会留给真的卡住了的问题。
- 批量的机械活(grep、改名、格式化、简单的 subagent 任务):low 或者 medium,这种活多想没什么用。
还有几个限制要说一下。第一,我挑的题任务描述写得都比较细,因为隐藏测试要求接口名对得上,所以完成度可能被题目本身撑满了,拉不开两档的差距,更模糊的需求下差距可能会更大。第二,judge 本身也是 opus 5.5 high,理论上可能有偏好,我用了盲评和 A/B 对调来压这个问题,但没法完全排除。第三,我测的是 workflow 里的子 agent,不是交互式 session,xhigh 也没有放进来一起测。样本是 44 对,够看出方向,不够下定论。
后面如果有新模型出来,这套流程可以直接复用,挑题、验题、配对跑、盲评都是现成的,换个模型名再跑一遍就行。