编程代理的最佳编程语言是什么?

Hacker News Top 新闻

摘要

Dan Luu 对现有基准测试提出批评,这些测试声称动态语言对编程代理的 token 效率更高。他认为,琐碎的问题和有缺陷的评估使这些结论不可靠。

相关:<i>哪些编程语言的 token 效率最高?</i> - <a href="https://news.ycombinator.com/item?id=46582728">https://news.ycombinator.com/item?id=46582728</a> - 2026年1月(91条评论)
查看原文
查看缓存全文

缓存时间: 2026/08/10 23:38

# 对于编码智能体来说,最好的编程语言是什么? 来源:http://danluu.com/pl-tokens/ 这篇被相当广泛引用的文章(https://martinalderson.com/posts/which-programming-languages-are-most-token-efficient/)\(反正我总是看到有人引用它\) 提出,动态语言和/或更简洁地表示事物的语言具有更高的 token 效率。似乎它的引用次数已经多到让 LLM 搜索结果也认同的程度。例如,当我搜索“dynamic vs static language token cost”(不带引号)时,Google 的 AI 摘要开头是这样说的: > 动态类型语言通常比传统静态类型语言具有更低的 LLM token 成本,因为省略显式类型声明会使代码更紧凑。 Google 的 AI 引用了同一篇文章,这表明一些简洁的动态语言相比 Rust、Go、C++ 等静态语言,token 成本可能只有其 1/2 到 1/3。作者说: > 在 C(我比较的语言中 token 效率最低的语言)和 Clojure(效率最高的语言)之间存在 2.6 倍的显著差距。 然后他们后来尝试了 J,并说: > 它以平均仅 70 个 token 的优势胜出,几乎是 Clojure(109 个 token)的一半。数组语言如果避免使用特殊的符号集,可以做到极高的 token 效率。如果 token 效率被证明是关键驱动因素,那么这可能是语言演进的一个非常有趣的方向。 我找到的另一个动态语言 vs. 静态语言的 token 比较是这一个(https://github.com/mame/ai-coding-lang-bench),它支持同样的结论。如果你想把这当作[关于基准测试、评估和实验设计的系列练习](http://danluu.com/exercise-7/)的第 8 部分,可以先点击链接,在继续阅读之前思考一下评估问题。 在不运行我们自己的评估的情况下,第一个实验的一个问题是题目过于简单,这可以从上面的引文中看出来;一个在 J 中只需 70 个 token、在 Clojure 中只需 109 个 token 就能解决的问题根本算不上什么问题(作者使用了 Rosetta Code)。正如我们在之前考察[其他“原始模式”的评估与我们的评估对比](http://danluu.com/ai-coding/)时看到的,对于大部分工作在于打印答案的琐碎题目,与需要一定“实际工作”的不那么琐碎的题目,会得到截然不同的结果;“原始模式”声称的巨大优势及其复制实验中的表现,在开始处理需要远不止几个 token 的问题时就会消失。总的来说,在琐碎任务上的表现不具备推广性。 第二个链接中的问题更加微妙,所以我们把大部分问题留到附录中,但其中包含诸如一个测试执行了错误的路径(该路径不存在),导致测试失败。之后某个智能体将不存在的路径符号链接到自己的可执行文件,这在该案例中有效,但也导致后续所有测试都运行那个智能体的可执行文件,而不是正确的可执行文件。作者试图从中得出关于 Rust 为什么有一些失败的结论,但实际上这只是意味着 Rust 的评分是在 Go 智能体将该损坏测试上的评分符号链接到 Go 可执行文件之前运行的。 与其依赖这些评估,我们可以尝试运行一些我们自己的评估。正如我们从这些评估以及我们上一轮关于评估的练习中讨论的评估(http://danluu.com/exercise-7/)中所见,很容易做出一个评估,其结果并不是评估创建者似乎以为它说明的东西。毫无疑问,这些评估也不会是例外,也会有缺陷(详见下面的附录)。 作为一种建立直觉的方式,我喜欢在查看结果之前预先注册猜测[1](#fn:P)。我向朋友们预先注册的一些想法包括: - 高置信度(95%):动态 vs. 静态语言的总体说法不成立 - 基于上述原因:这感觉类似于“原始模式”评估,结果最好也只能随着问题变大而被稀释 - 低置信度(60%):在超强度(ultra effort)下,静态语言会比动态语言稍好一些 - 非常低的置信度:在超强度下,测试框架能更快速地将反馈传递给模型,并由此在正确性或效率上带来某种好处;不过如果由于各种原因并非如此,也说得过去,例如,我注意到 codex 在调用 Rust 编译器时,经常会犯完全相同的错误,然后不得不修复它;也许这类问题会比假设中的更快反馈周期这类事情更重要 - 高置信度(98%):像 J 这样的“怪异”语言的优越性不成立 - 理由与上述静态 vs. 动态总体说法相同,另外还考虑到 AI 实验室不太可能把合成数据 RL 环境的精力投入到晦涩语言上(甚至可能为零) ### Zstd 对于第一个评估,我尝试给智能体 zstd RFC(外加勘误),并告诉它们实现一个完整的 zstd 解码器(智能体被困在没有互联网访问权限的容器中)。测试没有提供给智能体。对于像 zstd 这样规模的软件,期望测试覆盖每一种可能的情况并不现实。例如,尽管 zstd 是一个经过相当充分测试的软件,[我曾经在 zstd 中发现过一个数据损坏 bug](https://github.com/facebook/zstd/issues/1672)。测试套件并不是为了发现可能潜伏多年的极端边界情况,而是为了检查各种可以“容易”地从 RFC 推导出来且应该能工作的情形。 下图中,x 轴是成本,y 轴是正确性分数(越靠左上越好 / 越靠右下越差);这是使用 GPT-5.6 Sol 在中等强度(medium)和超强度(ultra)下的平均结果。如果我们只看中等强度(并忽略结果在不同任务上经常差异巨大的事实),我们可能会得出类似于 Alderson 评估的结论:动态语言在使用 LLM 时更高效、更好,因为(忽略相对晦涩的语言)动态语言簇落在静态语言簇的左上方(我们使用了 Alderson 的静态/动态颜色编码,以便一眼比较)。但如果看超强度,结果相当混杂,有几门静态语言表现最好,并且在较好的结果中静态语言多于动态语言。 下面的图表还有一个切换按钮,可以把 x 轴从成本切换为时间。`mame/ai-coding-lang-bench` 指出更快获得结果是有价值的(我个人不这么认为,因为结果耗时太长,我会同时做多件事而不是等待),所以我们也可以看看这个。类似地,我们观察到两种语言类型都没有压倒对方;尽管在这个特定任务的中等强度下,最好的动态语言结果再次优于最好的静态语言结果(尽管同样地,它们相当接近)。 我们可以观察到,就像我们将完全琐碎的“原始模式”评估与不那么琐碎的“原始模式”评估进行比较时一样,在琐碎评估中成立的非常强的关系并不会推广到这个更大的情形中。和那里一样,在这些更大的评估中,极端的性能比消失了,除非是在我们本就可以预期表现不佳的情形,例如使用汇编(对人类来说会显著更耗时且困难),以及使用相对晦涩的语言——我们本来就不太会指望 AI 实验室在这些语言上投入精力生成合成 RL 环境数据。 请注意,这与第一个评估的结论相反,那个评估认为像 J 这样非常密集的语言出于效率原因是有意义的。也许在预算非常大、且你可以训练或微调模型使其对你的专属语言有效的情况下,使用一门晦涩(且“怪异”)的语言是有意义的;但如果你是一个普通 LLM 用户,坚持使用主流语言似乎比使用晦涩的密集语言更稳妥。 事实还证明,如果我们绘制语言流行度与这个评估中表现的关系图(未显示),我们会观察到弱到中等的正相关:更流行的语言最终得到的解决方案既更正确,也更便宜。 正如我们之前指出的,非常相近的评估也可能给出截然不同的结果。例如,在[这里](http://danluu.com/ai-coding/)的“优化 1”和“优化 2”评估中,我们看到了显著不同的结果;这两个评估是在 wasm 中优化 bzip2 压缩和解压缩,作为评估而言是相当接近的任务。要提出一个强有力的普遍性论断,比如“动态语言比静态语言更高效”,我们必须在许多任务上运行评估。然而,要表明像这样的说法 > 动态类型语言通常比传统静态类型语言具有更低的 LLM token 成本,因为省略显式类型声明会使代码更紧凑。 最多只是在方向性上大致正确,且与任何特定情况都不太相关,也许还弱到不足以在一般情况下具有相关性,我们只需要尝试几个案例,看看这个说法并非普遍成立。在上面我们看到,在一个强度水平上,这个说法似乎勉强有些道理,但有例外;而在更高的强度水平上,这个说法似乎不太成立。这就足以说明该说法可能不是普遍正确的,前提是我们的评估没有完全使其失效的混杂因素。 ### Pandoc 但是,为了从一个非常不同的任务视角来观察,这个任务也以不同的方式呈现(更像 TDD 式,而不是“阅读规格”式),下一个评估采用 Pandoc ProgramBench 评估,并针对我们的用例进行了修改。与 ProgramBench 提出的逆向工程任务不同,我们向智能体提供 ProgramBench 材料以及 ProgramBench 测试,然后根据一组留出测试对智能体进行评分,以衡量每种条件下的表现[2](#fn:H)。 在下面的结果中,x 轴同样是成本,y 轴是留出测试中的分数。 和之前一样,我们没有看到成功或成本与语言是静态、动态还是非常密集之间有很强的关系。我们再次看到相对晦涩的语言往往表现不佳(尽管 Clojure 在这里比在 Zstd 上表现出色得多)。另外,汇编的表现要差得多,这似乎是意料之中的,因为我们会预期一个编写汇编的人类在实现 Pandoc 时会比实现 Zstd 时处于更大的劣势,而且似乎没有强有力的理由认为 LLM 在这方面会有所不同。 ### 这一切意味着什么? 谁知道呢? 关于使用 LLM 时什么方法效果好,我有很多疑问(例如,什么测试技术效果好,什么语言效果好,什么软件架构效果好,修复 bug 的成本是否因语言而异,一般程序维护成本是否因语言而异,等等)。这些问题大多数在公开数据中都没有答案,即使在 AI 实验室中已经得到了回答,这些信息大多也尚未公开。 大多数关于某种特定语言适合 LLM 使用的说法似乎都是错误的(例如,Ruby、Clojure 和 J 特别适合 LLM 的说法,这些出现在上面链接的评估中;还有 Elixir 特别适合 LLM 这种不太罕见的说法),但什么才是正确的并不清楚。 在 2014 年,我们考察了关于静态 vs. 动态类型的文献(http://danluu.com/empirical-pl/),发现除了少数案例研究外,浏览文献并没有太大信息量。举一个典型学术研究的例子,我们看到了论文《静态类型系统能提高软件系统的可维护性吗?一项实证研究》,我当时的评论是: > 实验对象会拿到一些类,他们需要修复现有代码中的错误或填写存根方法。Java 对应静态类,Groovy 对应动态类。在类型错误(以及相应的无方法错误)的情况下,开发者在 Java 中解决问题更快。对于语义错误,没有差异。该研究采用被试内设计,33 名被试随机化任务顺序。一个显著的局限是,研究避免使用“复杂的控制结构”,如循环和递归,因为这些会增加解决时间的方差。结果,所有 bug 都是琐碎的 bug。这可以从解决任务的中位时间看出来,在几百秒的量级。任务可能包含多个 bug,所以每个 bug 的时间相当低。 选择避免“复杂控制结构”(如循环和递归)、任务只需几百秒的研究,使得结果对于真正消耗专业程序员时间的任务毫无意义,就像我们看到的第一个评估一样,其任务只需要几十到一百多个 token。然而,借助 LLM,我们可以真正给它们提供非琐碎的任务,并比较它们做得如何。这里存在结果能否推广到不同任务的问题,但我们在人类研究中也恰恰会遇到同样的问题,而且更严重(LLM 的方差很大,但人类方差更大,因为你不可能让同一个人用不同的随机种子去做一堆任务)。而且,虽然花 20 美元让 LLM 实现一个 Zstd 解码器,一旦乘以语言数量以及每种语言每种条件下的迭代次数,并不便宜;但如果你想想雇用一名能阅读 zstd RFC 并将其实现出来的专业程序员要花多少钱,那么等效的研究是绝不可能完成的,因为成本会使其完全不可行。Pandoc 任务更是如此。 有了 LLM,很多问题从事实上无法回答,变成了只需一点努力和一些 token 就能回答。由于当前的相关激励[3](#fn:I),我们不清楚这类问题是否很快就会得到答案,但现在至少有可能尝试一下。 我见过很多流传的说法,这些评估既不能证明也不能反驳(原因如上所述:由于不同问题之间的方差,必须尝试更多任务才能下结论),但它们确实能对某些说法有所启发,例如: - 存在大量烂代码的语言(如 PHP)会表现更差 - 在这些任务上似乎不成立 - 因为现在重写太容易了,你应该使用一门强大的语言(如 Haskell) - 在这些任务上似乎不成立 - 你应该使用一门流行的语言 - 这一说法存在较弱的支持 对于我们预先注册的猜测,我们有: - 高置信度(95%):动态 vs. 静态语言的总体说法不成立 - 这看起来是正确的 - 低置信度(60%):在超强度下,静态语言会比动态语言稍好一些 - 没有足够的信息能确凿地判断这一点,但如果必须在正确/错误中二选一,我会说这是错误的 - 高置信度(98%):像 J 这样的“怪异”语言的优越性不成立 - 这看起来是正确的 - [来自一位草稿读者]:“动态语言在小规模上更好,但随着项目规模增长会被静态语言超越” - 这些任务并不支持这一点(在更大的 Pandoc 任务上,静态语言似乎并没有明显优于动态语言,而更小的 Zstd 任务上两者差异也不大),但任务和任务呈现方式差异如此之大,以至于不清楚这是由任务规模缩放引起,还是由其他差异引起。 顺便说一下,Clojure 在 Pandoc 评估中相比 Zstd 评估提升如此之大的主要原因,是 t

相似文章

前沿编程智能体利用元编程适应陌生编程语言

arXiv cs.AI

本文在深奥编程语言上评估了六个前沿编程智能体,发现更强的智能体使用元编程——编写Python程序在陌生的目标语言中生成和调试代码。禁止此策略导致性能大幅下降,而提供Python辅助代码则能提升较弱的智能体。

编程代理的胜负不在于提示词,而在于运行时基础设施

Reddit r/AI_Agents

随着编程代理能力增强,瓶颈从模型质量转向支持长时间运行的基础设施,包括持久状态、权限、检查点、可观测性和成本控制。作者认为,最好的代理产品更像是运行时和工作流系统,而非仅仅改进提示界面。