使用枯燥语言配合LLM
摘要
一篇观点文章指出,LLM在枯燥且一致的语言与生态系统(如Ruby on Rails)中表现更佳,因为训练语料库的方差较低,从而产生更可靠的智能体输出,而碎片化的生态系统(如JavaScript)则导致效果不佳。
暂无内容
查看缓存全文
缓存时间: 2026/05/26 09:53
# 使用“无聊”的语言与大型语言模型协同
来源:https://jry.io/writing/use-boring-languages-with-llms/
2026年4月20日
我是 Jacob——我经营着Sancho Studio (https://sancho.studio/),一家软件咨询集团,我们帮助公司处理技术领导力、战略和安全方面的事务。
我反复思考一个观点:一致性会产生复利效应。作为一名在过去两年里参与了多个不同项目的顾问,我对此感受尤为深刻。**大型语言模型会放大不一致的技术,并悄无声息地强化一致的技术**。那些碎片化最严重的语言和生态系统,产生的智能体(Agent)输出质量最差;而那些拥有最强约定的系统,则能产生最佳输出。我认为,在基于大规模语料库训练的大型模型时代,这种效应将日益决定哪些工具能够存活下来。
即使代码很廉价,运行推理也是一场赌博。你永远无法预知模型在某个时刻是否会决定安装一个包,或者生成一段来自2019年的古怪编码模式。如果我们承认这是在用“令牌(Tokens)”下注,那么就应该押注那些代表高度一致且经过强化的模型权重的嵌入(Embeddings),以产生中位水平的输出。对于软件开发来说,这实际上非常理想,因为中位水平的程序通常只是在做基础工作:处理信息、读写文件、响应网络请求等等。
在人工智能出现之前,工程师们抱怨那些仿佛每年都要自我革新一遍的语言。这些抱怨是真实的,但大多是审美层面的,并且折射出一种挫败感:人类需要维护或跟上那些毫无必要变化的生态系统。
回顾一下,2024年JavaScript状况调查 (https://2024.stateofjs.com/en-US/libraries/) 描述了一个相对碎片化的生态系统。对于人类来说,碎片化令人烦恼。对于一个在所有这些公共语料库上训练的模型来说,碎片化则更接近于一个需要通过在强化学习或智能体工具(例如Claude Code泄露的信息显示,Anthropic公司硬编码了一些针对JavaScript框架的偏见)中解决的问题。
Python也是同样的故事,只是换了个调子。问一个简单的问题,比如“你用的是哪个包管理器?”,就会得到一串语言版本、包管理器版本和操作系统兼容性的矩阵,作为一名技术负责人,我觉得这完全令人头晕目眩。
应该用 pip、poetry 还是 uv?你的工具链重要吗,还是你在做交叉编译?你怎么知道一个Python包是否静默地链接了一个C语言依赖?你用的是 async,还是转而用了任务队列?Django 还是 FastAPI?
[图片: xkcd 1987: Python环境混乱] xkcd 1987
从模型的角度来看,编写这些东西的方式实在太多了,而语料库以大致相等的权重反映了每一种方式,除非在训练时引入了新近度偏见。对我来说,这意味着很直接的一点,对你也应该如此:**训练语料库中方差低的语言和生态系统,能被编码智能体(Coding Agents)更好地表征和更可靠地执行。** 在更高维度的向量空间中,训练数据中的余弦相似度是模型注意力层和MLP层学习预测下一个令牌的基础。一致的语料库产生一致的推理令牌。
这种模式在其他语言中也有体现。在智能体工作中,对Rails项目的推理比通用JavaScript后端产生更一致的输出,这并非因为Ruby在某种柏拉图意义上是一种更好的语言,而是因为实质上只有一个Rails。而至少有十几种生产级JavaScript框架提供了相同默认功能的不同维恩图。"约定优于配置" (https://rubyonrails.org/doctrine) 对人类程序员来说是一个胜利,因为"灵活性被高估,约束带来解放" (https://www.windley.com/archives/2005/08/flexibility_is.shtml)。二十年后,对机器来说同样如此,甚至可以说更是如此。模型只是在求解哪个结果最有可能……
Go语言几乎是无意中最好地体现了这一原则。多年来,Go语言一直抵制程序员不断要求带来的便利性和更高级别的表达(尤其是泛型),这种抵制在工作的开发者中非常不得人心。我过去就是那些开发者之一;我写过几十万行Go代码,作为程序员,我经常觉得这门语言令人恼火。
我认识Go团队的一些成员,并且钦佩他们对于“程序未来”那种固执的承诺 (https://go.dev/doc/go1compat)。我开始认为谷歌无意中创造了当今世界上最好的语言。开箱即用,Go给智能体(Agent)提供了一套其他主流语言无法同时提供的优势。
并发模型是第一个优势。Goroutines 对于编码智能体来说,是一种比线程、回调、async/await 或其他地方占主导地位的“着色函数” (https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/) 体制更容易处理的基元。它们简单、类型安全,并且在模型训练的语料库中被普遍使用。不存在“你的函数是什么颜色”的问题,因为这个问题就不存在。
```
results := make(chan string, len(urls))
for _, u := range urls {
go func(u string) {
resp, err := http.Get(u)
if err != nil {
results <- err.Error()
return
}
defer resp.Body.Close()
results <- resp.Status
}(u)
}
for range urls {
fmt.Println(<-results)
}
```
标准库是第二个优势。仅`net/http`这一项就支撑了互联网上相当大一部分微服务,而其密码学包 (https://pkg.go.dev/crypto)(由谷歌资助和维护)世界一流。我在Zoom和Keybase上交付的生产系统都依赖于这些默认实现,并且从未需要引入外部库。
```
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "ok")
})
http.ListenAndServe(":8080", nil)
}
```
工具链是第三个优势,可能也是最被低估的。Go语言在设计上,为大多数事情提供了一种正确的做法:`gofmt`、`go vet`,以及现在的`go fix`,强制执行单一规范风格,无需协商。对语言模型来说,最好的组合是拥有一致的训练语料库,加上用于测试和运行时反馈的“唯一正确方式”工具。`gopls`为智能体提供了极好的护栏,因为它能提供实时的语义反馈,而`golangci-lint`允许你静态地强制编码风格和基元,而无需提示智能体顺从。
```
$ go vet ./...
./user.go:22:2: result of fmt.Errorf call not used
./user.go:38:9: declaration of "err" shadows declaration at line 34
$ golangci-lint run
user.go:51:6: exported func LoadUser should have comment (revive)
user.go:63:3: if block ends with return, drop this else (golint)
```
第四个优势是具有垃圾回收的性能。语言模型在内存管理上是不一致的;这是一个已充分记录的局限性,并且短期内不会消失。Rust在类型和借用检查层面上强制执行内存安全,这对人类来说很棒,但对智能体来说则是一场持续的战斗。用编码智能体编写C或C++更加困难,因为训练数据充满了内存漏洞、释放后使用错误,以及数十年积累的艰难教训,模型既可能重现这些错误,也可能避免它们。Go提供了接近原生的性能,而无需要求智能体直接管理内存。
```
func parseLines(r io.Reader) []string {
var out []string
s := bufio.NewScanner(r)
for s.Scan() {
out = append(out, s.Text())
}
return out
}
```
第五个优势是已知的、有限的一组“坑”。对于人类工程师来说,`nil` 指针在生产堆栈跟踪中可能难以追踪,但有了合适的工具,智能体出人意料地擅长于此。在惯用Go中可能出错的事情集合是有限的,而在例如带任意元类的Python中,可能出错的事情集合则不是这样。
```
data, err := os.ReadFile(path)
if err != nil {
return fmt.Errorf("read config %q: %w", path, err)
}
```
读到这篇文章,正确的反应不应该是“Go是最好的语言”,而是更具体的东西:**这种语言和工具链能够编写在职工程师想要的大部分非可视化软件。** 考虑将Go与智能体结合使用,来构建下一个CLI工具、后端服务或智能体编排器。
如果以上任何内容引起了你的共鸣,请与我联系 (https://sancho.studio/contact)。如果你正在寻找一位技术负责人来帮助你的团队持续交付。
相似文章
LLMs 不擅长编写“氛围式”规范
Hillel Wayne 基于对社区项目的分析,讨论了尽管 LLM 在编写 TLA+ 和 Alloy 等形式化规范方面很受欢迎,但它们经常生成浅显、同义反复的属性,无法捕捉微妙的缺陷。
迈向超越英语中心化开发的大语言模型
本文证明了大语言模型严重偏向英语,并表明持续预训练在将模型适配到其他语言(尤其是文化理解方面)时,并不比从头训练更具成本优势。
@haider1: Yann LeCun 表示,LLMs 在语言本身就是推理基础的领域(如数学和代码)中最强…
Yann LeCun 指出,LLMs 在语言作为推理基础的领域(如数学和代码)中最强,但它们并非有创造力的数学家、软件架构师或计算机科学家。
为什么不能训练LLMs用一种优化的AI语言而非英语来思考?
一个推测性的讨论,质疑为什么LLMs没有被训练使用优化的内部语言而非自然语言来思考,以及这是否能提高效率。
软件工程师:说正经的,你们真的从LLMs中有所收获吗?
一位软件工程师对使用本地LLM进行智能编码感到沮丧,指出诸如技术债务、忽略指令和过度生成代码等问题,质疑其有用性。