Hotdry.

Article

用「无聊语言」提升 LLM 上下文效率:Go 与显式语法的 Token 经济学

探讨为何 Go 等「无聊语言」在 LLM 辅助编程中表现更优:从 token 密度实验数据到语言一致性的复利效应,提供可落地的语言选择框架。

2026-05-26ai-systems

在 LLM 辅助编程成为常态的今天,语言选择的考量维度正在发生微妙但深刻的变化。过去我们关注性能、生态、团队熟悉度;现在,一个新兴指标浮出水面 ——token 效率。Jacob Young 在其文章中提出的「无聊语言」(boring languages) 概念,恰好切中了这一时代的痛点:当代码的主要消费者从人类工程师转变为 AI 代理时,语言的「可读性」标准需要重新定义。

什么是「无聊语言」

「无聊语言」并非指技术陈旧或缺乏创新,而是指具备以下特质的编程语言:显式类型、简单语法、最小抽象、强一致性。这类语言的代码在视觉上可能显得「啰嗦」,但正是这种啰嗦,为 LLM 提供了清晰、可预测的推理路径。

Go 是这一概念的典型代表。它刻意回避了泛型(直到近年才引入)、宏、运算符重载等「便利」特性,坚持用显式的错误处理、统一的代码格式、简单的并发原语来表达逻辑。这种设计哲学在人工编码时代曾饱受诟病 —— 开发者抱怨它「过于保守」「缺乏表达力」—— 但在 AI 编码时代,这些「缺陷」反而成为优势。

Token 密度的量化证据

Context Engineer 团队的一项实验为这一直觉提供了数据支撑。他们使用 Rosetta Code 数据集(同一算法在多种语言中的实现),用 OpenAI 的 o200k_harmony 分词器对超过 600 个任务进行 token 计数分析。结果令人震惊:不同语言的 token 密度差异接近 2 倍

以 C# 为基准(1.0x),Python 的有效上下文窗口达到 1.90x—— 意味着同样的 token 预算可以容纳近两倍的有效逻辑。JavaScript 为 1.81x,F# 为 1.49x,就连添加了类型注解的 TypeScript 也能达到 1.16x。

更具说服力的对比来自 F# 与 C# 的 head-to-head:两者运行于同一 .NET 运行时,共享标准库,唯一的变量是语言范式。结果显示,F# 平均每个任务消耗 96 个 token,而 C# 需要 146 个 ——F# 以 34% 更少的 token 表达了相同逻辑

Token 开销的三大来源

实验进一步拆解了 token 开销的构成,可归为三类:

结构样板代码(structural boilerplate):命名空间声明、类定义、导入语句等。C# 的 using System; namespace Foo { class Bar { ... } } 结构在 Python 中完全不存在。

类型声明开销(type ceremony):显式类型注解、泛型约束、接口定义等。Rust 的生命周期标注、C# 的显式返回类型都属于此类。

语法冗余(syntax overhead):大括号、分号、冗余关键字等。虽然单条开销微小,但在大规模代码库中累积显著。

Python 在这三类开销上几乎为零,这解释了它的高密度表现。F# 虽然也是静态类型语言,但凭借类型推断和模式匹配,成功将第二、三类开销压缩到接近动态语言水平。

一致性的复利效应

Token 密度只是「无聊语言」优势的一个维度。Jacob Young 强调的另一点是训练语料的一致性—— 这一因素对 LLM 输出质量的影响甚至更为深远。

以 Python 为例,其生态系统的高度碎片化对模型构成挑战:pip/poetry/uv 的选择、async / 多线程 / 任务队列的决策、Django/FastAPI 的分野,每一种组合都在训练数据中占据一席之地。当模型面对一个 Python 问题时,它需要在高维向量空间中从众多可能性中「猜测」最可能的路径 —— 这种不确定性直接转化为输出质量的方差。

相比之下,Go 的「一种正确做法」哲学创造了惊人的一致性:

  • Goroutine:比线程、回调、async/await 更简单的并发原语,没有「函数着色」问题
  • 标准库net/http 运行着互联网相当比例的微服务,密码学包由 Google 直接维护
  • 工具链gofmt 强制执行单一代码风格,go vetgolangci-lint 提供实时静态反馈
  • GC 内存管理:相比 Rust 的借用检查器或 C/C++ 的手动管理,大幅降低代理出错的概率
  • 有限的坑集合nil 指针虽仍是问题,但相比 Python 的任意元类或 JavaScript 的类型强制,出错空间已被大幅压缩

这种一致性创造了正反馈循环:一致的训练语料 → 更可靠的模型输出 → 更一致的代码生成 → 更一致的未来训练数据。

权衡与边界

需要承认的是,token 密度并非唯一指标。Context Engineer 的实验也指出了几个重要的边界条件:

类型系统的推理价值:显式类型声明虽消耗 token,但为模型提供了结构化语义信息。一个带有完整类型签名的函数可能比纯动态代码产生更好的补全质量,因为模型能更准确地理解契约。

编译器反馈循环:F# 的强类型系统能在编译时捕获错误,为 AI 代理提供快速、确定性的反馈。相比之下,Python 的错误只能在运行时暴露,且可能深埋于调用栈中。对于自主迭代代码的 AI 代理,这种「密度换安全」的权衡可能值得。

实验数据的局限性:Rosetta Code 数据集由小型、自包含的算法任务组成,不代表生产代码的真实复杂度。实际代码库中,依赖注入、ORM 查询、中间件模式等都会改变 token 密度比。

可落地的决策框架

基于以上分析,以下是为 LLM 辅助开发选择语言时的实用清单:

新项目评估

  • 如果代码库将被 LLM 重度消费(AI 编码助手、自动代码审查、代理驱动开发),token 密度应成为语言选择的新维度
  • 优先考虑具备「一种正确做法」哲学的语言,降低模型的决策不确定性

现有代码库优化

  • 在 verbose 语言中工作时,投资更智能的 RAG 层:使用 AST 感知的分块策略、在嵌入前剥离导入块和样板代码、优先索引函数体而非结构脚手架
  • 考虑代码预处理流程:剥离注释、折叠导入块、规范化格式后再进行 token 化

语言特定建议

  • Go:CLI、后端服务、代理编排器的理想选择;利用 gopls 作为代理的实时护栏
  • Python:快速原型和 ML 相关任务的首选;但需在提示中明确指定包管理器和框架版本以减少歧义
  • F#:需要类型安全但关注 token 效率时的平衡选择;特别适合算法和数学领域
  • Rust:性能关键路径的首选;接受其较高的 token 开销,但利用宏系统在特定任务中压缩表达

结语

五十年来,编程语言 verbosity 的成本以「击键次数」和「屏幕空间」衡量。开发者基于性能、生态、个人偏好选择语言 —— 啰嗦是一种风格选择,而非成本驱动。

LLM 改变了这一经济学。每一个语法冗余的 token 现在都是字面成本—— 以美元计、以上下文窗口容量计、以模型推理质量计。大括号不再免费,显式类型声明有价格,命名空间声明占据了本可承载业务逻辑的空间。

一个五年前听起来荒谬的反转是:就处理量而言,AI 代理现在比人类工程师更频繁地消费你的代码。代码审查机器人、自主编码助手、分析差异的 CI/CD 代理、索引仓库的检索系统 —— 这些系统在每次提交、每次 PR、每个提示中读取你的每个文件。

如果代码最频繁的消费者已经改变,那么「可读性」的标准就值得重新审视。为 AI 代理理解而优化 —— 密集、高信号、低仪式感的代码 —— 可能比为人类视觉扫描大括号和显式类型注解而优化更重要。这并不意味着人类可读性不再重要,而是说平衡已经转移,而大多数团队尚未更新他们的先验判断。


参考来源

  • Jacob Young, "Use boring languages with LLMs", 2026-04-20
  • Context Engineer, "Your Programming Language Is an LLM Bottleneck", 2026-03-01

ai-systems

内容声明:本文无广告投放、无付费植入。

如有事实性问题,欢迎发送勘误至 i@hotdrydog.com