上个月我接了个小活——用 AI 给一个 Go 项目写几个微服务。本来以为半天搞定的事,结果折腾了两天。
不是 AI 不行。是 AI 太行了——行到让我开始怀疑之前对"编程语言选型"的理解全是错的。
事情是这样的:同样的需求,我让 Claude 先生成了一遍 Go 版本,又生成了 Python 版本(FastAPI),还顺手试了下 Node.js。三个结果拿过来一对比,差距大到离谱。
Go 版本几乎可以直接 deploy——代码风格统一、依赖就一个标准库、错误处理规范。Python 版本嘛……能用,但 package 的选择五花八门,同一件事有四五种写法。Node 版本更惨,express、fastify、hono 三个框架混着用,我甚至不知道它到底想干嘛。
这就引出了一个有意思的问题:
AI 写代码的水平,跟你用的语言有直接关系。
一致性,就是模型的"舒适区"
Jacob Young 在四月份发了篇博客叫Use boring languages with LLMs,讲的其实就是这个事。核心论点一句话就能说清楚:
大语言模型放大不一致的技术栈,默默强化一致的那些。
翻译成人话就是——你用的语言/框架越"分裂",AI 写出来的代码就越拉胯。
为什么?你想啊,模型训练的时候看的是整个公开代码库。Python 有 pip、poetry、uv 三个主流包管理器,还有 Django、FastAPI、Flask、Starlite……你让模型猜你的项目结构,它猜中的概率有多大?
xz 漫画里有个经典梗——"How Python projects handle dependencies",一张图里画了十几条路,箭头乱飞。对 AI 来说这不是梗,是真实的训练数据分布。每条路在语料里都出现,模型根本不知道该走哪条。
Go 就不一样了。
Go:被低估的 AI 友好型语言
说实话,我早几年写 Go 的时候没少骂它。没有泛型(当时)、语法啰嗦、IDE 支持一般。当时我跟同事吐槽:"Go 就是 Google 造出来给写基础设施的苦力用的。"
但放到 AI 编程这个场景下,Go 的优势就全出来了。
1. 并发模型——goroutine 是真香
AI 写异步代码经常翻车,这是共识。回调地狱、async/await 颜色问题、事件循环阻塞——这些东西模型学得半生不熟。
Go 的 goroutine 就简单了:
results:=make(chanstring,len(urls))for_,u:=rangeurls{gofunc(ustring){resp,err:=http.Get(u)iferr!=nil{results<-err.Error()return}deferresp.Body.Close()results<-resp.Status}(u)}forrangeurls{fmt.Println(<-results)}goroutine 就是一个go关键字,channel 就是一个带类型的管道。没有 async 函数和普通函数的颜色区分,没有复杂的生命周期。模型学起来简单,写出来也稳定。
你敢信?Go 的并发代码在我用过的所有语言里,AI 生成的正确率是最高的。
2. 标准库——够用就行
net/http支撑了互联网上不知道多少微服务。crypto/tls是 Google 掏钱维护的,安全性没得说。你不需要装第三方包就能搭一个生产级的 HTTP 服务。
packagemainimport("fmt""net/http")funcmain(){http.HandleFunc("/healthz",func(whttp.ResponseWriter,r*http.Request){fmt.Fprintln(w,"ok")})http.ListenAndServe(":8080",nil)}这段代码任何一个版本的 Go 都能跑,语料里出现过无数次。模型闭着眼睛都能写对。
3. 工具链——没有选择就是最好的选择
Go 的工具链值得单独拿出来夸。gofmt强制统一格式,不需要讨论"大括号放哪行"这种问题。go vet静态检查。go fix自动迁移。
$govet./... ./user.go:22:2:resultoffmt.Errorfcallnotused ./user.go:38:9:declarationof"err"shadowsdeclarationatline34对 AI 来说,这种"只有一种正确写法"的生态简直是福音。模型不需要在 Go 的各种风格之间做选择,因为它根本就没有选择。
对比一下 Python:
# 你用的是哪个?pipinstallflask poetryaddflask uvaddflask三个命令都能让 AI 写出能跑的代码,但 AI 怎么知道你项目用的是哪个包管理器?模型只能猜,猜对了还好,猜错了你就得手动改。
那其他语言呢?
说到这儿可能有读者要问了:你只说了 Go 和 Python,那 Java、Rust、Ruby 呢?
我大概归纳了一下:
| 语言 | 生态一致性 | AI 代码质量 | 备注 |
|---|---|---|---|
| Go | 高 | 高 | 标准库+工具链无敌 |
| Rails/Ruby | 高 | 中高 | 约定优于配置,模型学得透 |
| Java/Spring | 中高 | 中 | 生态大但 Spring Boot 是事实标准 |
| Python | 低 | 中低 | 选择太多,模型无所适从 |
| JavaScript | 极低 | 低 | 框架泛滥,AI 写出来常是混搭 |
| Rust | 中 | 中 | 所有权/借用检查对 AI 是硬门槛 |
这个表是我的个人经验,不一定对。不过有一点可以确定——你用的技术栈越"无趣"、越标准化,AI 产出就越稳定。
Rails 是个好例子。虽然 Ruby 本身不如 Go 一致,但 Rails 框架在 Ruby 生态里是绝对的主导。Jacob 的文章里提到过,用 Rails 的 AI 代码质量明显高于用普通 JavaScript 后端的。原因很简单——模型训练时见过的 Rails 代码足够多,怎么写都有模板可循。
Rust 的情况比较特殊。它的所有权模型和借用检查器很强大,但 AI 经常在这上面栽跟头。一个常见的场景:AI 生成了一段 Rust 代码,编译报 borrow checker 错误,然后修了三次才通过。不是说 Rust 不好——它是一门优秀的语言——只是在 AI 编程的场景下,学习曲线对模型来说和对人一样陡。
这不是"最佳语言"的争论
话说回来,我写这篇文章不是想说"Go 是最好语言"——这种事情吵了十年也没吵出结果。我想说的是:
选技术栈的时候,把你未来可能用 AI 编程这件事考虑进去。
如果你在 2026 年还在写纯手撸代码,那你大概率不是效率最优的那批人。AI 编程助手(Claude Code、Cursor、GitHub Copilot)已经成了标配。那问题就变成了:哪些语言能让 AI 发挥出最大价值?
Go 的回答很明确:一致性。没有选择的自由,就没有选择困难。对模型来说,这是一个高度可预测的环境。
一个实操建议
如果看完这篇文章你想试试,建议从一个小项目入手:
- 装好 Go(版本 1.22+)
- 打开 Claude Code 或 Cursor
- 让它用 Go 写一个简单的 CLI 工具——比如从 API 拉数据并格式化成表格输出
- 观察它是不是一次就写出能编译的代码
然后换 Python 做同样的事。你大概率会发现:Python 版本可能需要你手动修一两处 import 或异步调用的问题,Go 版本基本一把过。
这里有个小技巧——gopls是 Go 语言服务器,装好后能实时给 AI 提供语义反馈。加上golangci-lint做静态检查,AI 生成的代码质量会上一个台阶。
所以……要不要换 Go?
不一定。
如果你的团队已经在用 Python 或 JavaScript,并且积累了大量基础设施和业务代码,为了"AI 友好"全盘重写显然不现实。但有几个方向可以考虑:
- 新项目选型时多一个维度:除了性能、生态、招人之外,加上"AI 生成代码质量"这个指标
- 核心微服务可以试试 Go:特别是 CLI 工具、API 网关、中间件这类场景,Go 本身就是强项
- Python 项目做好约束:用 ruff 做格式化、用 pyproject.toml 统一配置、选一个包管理器就别换了
说个坑——我之前有个项目用 Python 做数据处理,让 AI 帮忙写 ETL 脚本。结果它每次生成的 import 方式都不一样,有时候用pandas.read_csv,有时候用csv.DictReader,还有一次直接用了open() + split()手撸解析。代码都能跑,但风格完全不统一。后来我把它重写成了 Go,AI 每次输出都稳如老狗。
结尾
这个话题其实挺有意思的——当 AI 成为主力编码工具后,"好语言"的定义可能完全变了。以前我们追求表达能力、生态丰富度、开发效率。以后可能要看:模型在你这门语言上训练得有多深、写出来的代码有多稳定。
你平时用哪个语言配 AI 编程?有没有遇到过"AI 写 Go 一把过,写 Python 反复修"的情况?评论区说说,我整理到后续文章里。