XIAODAO AI JOURNAL2026 / 08 / 11Agent 选语言 · 先验评测
Python 还是 Rust,排名可能测错了
一条写错的相对路径,把 Go 变成了所有语言的标准答案。
一项讨论 AI 编程语言的评测,本来想比较 Rust、Haskell、Go 等语言谁更适合 coding agent。测试脚本该运行候选目录里的 ../minigit,却写成了不存在的 ../../minigit。前面的 Rust 条件因此失败,后来的一个 Go agent 为了让测试跑通,顺手建了软链接。
然后,后面每一种语言的测试,都开始运行那一个 Go 可执行文件。
好家伙,一张语言排行榜,最后测成了 Go 和 Go 和 Go 的横向对比。
Dan Luu 刚发的这篇长文把这段翻了出来。原评测作者曾据此猜测,Rust 的所有权模型和 Haskell 的纯函数增加了 AI 的开发负担。Dan Luu 把 Rust 对准自己的可执行文件重新评分,满分。先前那个很顺眼的解释,啪一下没了。
这事儿最值得聊的,不是该给 Rust 平反,也不是 Go 躺赢有多好笑。
而是我们今天看到的很多 Agent 排行榜,可能还没开始测模型和语言,就已经被评测脚手架写好了结局。
一条路径,足够毁掉一张榜
WRONG PATH, WRONG WINNER
「动态语言更适合 AI 编程」这两年挺流行。逻辑听着也顺,Python、Ruby、Clojure 不用写那么多类型声明,代码短,token 少,模型生成起来当然更便宜。
一项常被引用的 token 实验测出了 2.6 倍差距,C 最费,Clojure 更省。后来 J 语言只用平均 70 token,比 Clojure 的 109 token 还少一截。另一个 ai-coding-lang-bench 也给出了相近方向。
70 token 能写完的任务,复杂度跟真实项目差得有点远。你让 agent 打印一个答案,语言的语法密度当然很显眼。可工程里真正烧 token 的地方,往往不是多写了几个类型,而是读规范、找错、跑测试、理解旧代码、被一个失败方案锚住,再来回修十几轮。
Dan Luu 没继续拿小题互殴。他给 GPT-5.6 Sol 一份 zstd RFC 和勘误,让 agent 在无网络容器里实现完整解码器,隐藏测试,不给现成答案。又改造 Pandoc 的 ProgramBench 任务,用可见测试开发,再用 holdout 测试验收。
Zstd 的交互图里,medium 推理强度下,动态语言整体确实更靠近「正确率高、成本低」那一侧。要是文章写到这里,标题已经可以起成「Python 再次赢麻」。可把推理强度切到 ultra,最好的几组里静态语言变多,动态与静态的边界开始混在一起。到了 Pandoc 的 holdout 对比,排名又换了一遍,Clojure 比它在 Zstd 里的表现好得多。
Zstd 在 medium 推理强度下的语言成本与正确率,动态语言集中在左上区域同一个模型,同一批语言,只换任务和推理预算,赢家就动了。
切到 ultra 后,静态与动态语言混在一起,原来的分组优势明显减弱所以问题不是 Python 和 Rust 到底谁赢。更准确的问题应该是,在某个模型版本、某种推理强度、某类任务、某套测试和某个成本口径下,哪种语言暂时占优。
推理预算一换,赢家也跟着换
BUDGET SHIFTS RANKING
很多团队做模型评测时,会把推理强度当成一个不太重要的开关。模型固定了,温度固定了,任务固定了,medium 和 ultra 无非是多想一会儿。
这篇实验提醒了一件很工程的事,推理预算不是脚注,它会改变 agent 与编译器、测试器、代码产物之间的反馈次数,也会改变失败路径。
原文还顺手比较了三种跑法,一次 ultra、保留上下文反复 medium、每轮清空上下文再重放原始提示词的 Ralph loop。
在 Zstd 这一个任务上,一次 ultra 按单位成本更有效,按耗时优势更明显。保留上下文继续做,也胜过每轮清空上下文。清掉上下文能扔掉坏思路,却扔不掉磁盘上的坏代码。下一轮 agent 看见那坨半成品,照样可能继续打补丁。
这个结果不能证明 Ralph loop 永远不行。它只能说明,推理强度、上下文策略和产物状态会互相作用。如果一张语言榜没有固定这三样,语言排名里混进去的很可能是 harness 策略,而不是语言特性。
Pandoc 任务如果只有可见测试,agent 会围着测试写代码。最粗暴的是识别输入后硬编码答案,更隐蔽的是按测试结构写一组脆弱分支,看起来像实现了功能,换个输入就碎。原文说,从「完全没作弊」到「明着背答案」的整条光谱,agent 都试过。
告诉 agent 还有隐藏测试后,可见测试成绩下降,holdout 成绩反而提高。它没那么执着于把眼前这几个绿灯点亮了,开始写更能泛化的实现。
厉害了,一句「后面还有考试」,直接改了模型的代码风格。
Pandoc 的 holdout 测试再次重排语言表现,汇编与冷门语言的成本尤其高这也是为什么我看到任何 100% 通过率,都会先找测试可见性。没有 holdout、fuzz、属性测试或真实回放,100% 很可能只代表 agent 学会了 verifier 的脾气。
评测脚手架才是隐藏自变量
HARNESS IS THE VARIABLE
Dan Luu 对自己的实验没有装得很稳。他明确说,这是一个 quick and dirty 的实验,代码仓库也没公开,因为环境还很乱。
光是搭 Zstd 的跨语言环境,他按语言条件算,已经修了 100 多个问题。
有的语言拿到旧工具链,有的缺 rustfmt 和 Clippy,有的 prompt 说环境里有 GDB,实际根本不能用。有些条件带额外脚手架,有些被加了莫名其妙的限制。智能体生成的测试里还混进了性能压力项,明明要求忽略性能,却让实现解压 4 GiB 数据。
最荒诞的一次,初始结果显示动态语言明显弱于静态语言。这个结论很新鲜,还刚好符合作者的预期,传播标题都像自己长出来了。检查后才发现,静态语言只是更不容易被那套模糊的构建约定坑到。
还有一次,汇编表现得跟高级语言差不多。听着有点子牛逼。再往下看,agent 先用 C 写完,再编译成汇编交卷。
这里藏着评测工程最难的一刀。发现异常后,到底该改哪一层。
是 prompt 没说清楚,是容器缺工具,是 harness 路径错了,是 verifier 太薄,还是被测 agent 真不会。把环境问题写进 prompt,等于让选手替考场修电路。把答案塞进上下文,绿灯是亮了,评测也泄题了。只补一个失败样例,agent 又可能学会针对样例打补丁。
高质量 eval 的活儿,大半不是跑分,是读 trajectory,定位问题属于哪一层,再改对那一层。Dan Luu 引述 Max Bittker 的经验,复用现成仓库、游戏、工具和关卡,在外面搭 harness 与 verifier,通常比让 agent 从零生成整套评测更靠谱。
我是真的觉得,这句话该贴在每个 Agent 团队的评测目录里。
别急着让 agent 生成 20 套环境。先做一套,人工读轨迹,修干净,再复制。
真选语言时,先把评测合同写死
CONTRACT BEFORE LANGUAGE
那团队真要给 Agent 项目选语言,怎么办?总不能看完 1 万字,得到一句「谁知道」。
任务合同
同一份真实需求,不用几十 token 的玩具题
运行合同
固定模型版本、推理强度、最大轮数、上下文策略
环境合同
固定编译器、依赖、工具权限、网络、CPU 与内存
验收合同
可见测试与 holdout 分离,补 fuzz、属性测试和安全检查
成本合同
同时记录 token、现金成本、墙钟时间、人工介入和失败重跑
复核合同
抽样读轨迹,确认跑的是正确二进制,也没有改测试和奖励投机
然后再放进 Python、TypeScript、Go、Rust,跑与你业务接近的任务。
如果你做的是数据清洗脚本,启动快、库多、胶水代码短可能更重要。若是常驻服务,编译器反馈、类型边界、并发模型和部署体积会进入成本。处理不可信输入时,单元测试没测出的内存安全也得算钱。
原文短暂检查了 Pandoc 条件下的 C 与 C++ 代码,所有 C 程序和除一个以外的 C++ 程序都找到了越界访问。把 ASan、UBSan、fuzz 和修复 token 加回成本,原来的便宜未必还便宜。Rust 可能在生成阶段多付一点类型和编译成本,却提前买了一部分安全约束。
不是说 Rust 一定赢,而是成本不能只数生成 token。
维护时 agent 要读多少旧代码,编译器能多早指出错,测试能否拦住投机,出了问题要不要人盯,这些才是账单的大头。语言只是这套系统里的一个参数。
Dan Luu 早先整理 agentic coding 评测的文章反复出现同一个影子,小题上的优势到了大任务会缩水,相近任务也能排出不同名次。今天这篇跨语言实验没有给任何语言加冕,倒是把一件更值钱的事照亮了。
Agent 时代,选技术栈前先选 verifier,选语言前先写验收合同。
CLOSING
否则你以为自己在比较 Python 和 Rust,跑到最后,屏幕上可能还是那一个 Go。
如果你觉得今天这篇有收获,欢迎点赞、在看、转发三连,我们下篇见
SAIL WITH XIAODAO AI