最近 Google Go 团队写了一篇文章,讨论了一个问题:当 Coding Agent 开始参与更多的代码编写工作,什么样的编程语言会更适合 AI 辅助开发?
他们给出的答案是 Go。
熟悉 Go 语言的人很好理解这点。虽然 Agent 可以快速生成代码,但代码写出来后,还要被阅读、编译、测试、检查和维护。这个过程,语言和工具链能不能给出清晰、稳定的反馈,会直接影响 Agent 后续修改代码的过程。
从这个角度来看,过去 Go 在软件工程上强调的一些设计,刚好适合 Agent 参与开发的场景。
从代码生成到代码验证
过去我们讨论编程语言的开发效率,会关注代码写起来是否方便:语法够不够简洁、表达能力够不够强、能不能用更少的代码实现目标。
但,自从 Coding Agent 加入工作流、协助编程之后,这个过程发生了一点变化。
Agent 快速生成的数百行代码,需要人类工程师去确认这些代码是否符合设计要求、能不能如期运行、有没有影响其他模块,以及当中是否存在安全和可靠性问题。
所以,Google 在文章中多次强调“Review 和 Verification”。
对于 Agent 来说也是一样的。每次完成修改之后,它需要知道代码能不能编译、测试有没有通过、依赖是否正常。如果缺少这些外部反馈,Agent 就只能继续结合当前上下文判断问题出在哪里。
Go 的一个优势就是从语言、编译器到开发工具,提供了一套相对完整的反馈机制。
统一的开发工具链
Go 从设计之初就不只关注语言语法,还把软件开发生命周期里的很多工具放进了自己的工具链。代码格式化有 gofmt,测试可以用 go test,依赖通过 Go Modules 管理,安全检查还有 govulncheck,再加上编译器、语言服务器和标准库,不少开发环节都配有固定的工具。
这个设计对 Coding Agent 很重要。
如果不同项目分别使用不同的格式化工具、测试框架、依赖管理方案和静态检查工具,Agent 接手一个项目之后,要先理解这些规则,才能判断修改代码后应该调用什么。
用 Go 开发的流程相对固定。
Agent 修改代码之后,可以进行格式化、编译和测试,再根据工具返回的结果继续修复:生成代码 → 编译或测试 → 获取反馈 → 修改代码 → 再次验证。
将这些原本给开发者使用的工具放进 Agent 工作流后,可以成为模型判断代码状态的一组外部反馈。
更统一的代码结构
Go 另外一个明显的特点是重视代码的可读性和一致性。典型例子就是 gofmt。
很多 Gopher 不用花太多精力在讨论缩进、换行和格式风格上,代码经过 gofmt 处理后,会按照统一规则完成格式化。
Go 语言设计本身还控制了复杂语法和抽象方式的数量,希望不同的开发者写出的 Go 代码保持相近的结构。
放到 AI Coding 中,这种一致性能带来收益。如果同一段逻辑存在多种风格差异很大的表达方式,不同 Agent、不同 Prompt 生成的代码就可能出现更多变化。人再去 Review 时,需要先理解这些表达方式,再判断逻辑有没有问题。
Go 对格式和代码结构做的许多约束,可以减少这部分表达差异。
这样一来,人检查 Agent 生成的代码时,可以把更多注意力放到 API 调用、业务逻辑、边界条件和安全问题上。Google 还提到,Go 开源生态较统一的代码风格,也让模型接触到的 Go 代码具有更强的一致性。
编译与测试反馈
Coding Agent 写代码时,一个亟待解决的现实问题是幻觉。
例如调用不存在的方法、传入错误的参数类型,或是理解错不同文件之间的数据结构。
Go 的静态类型系统和编译器能提前发现其中的部分问题。如果 Agent 调用了不存在的方法,或是无法匹配类型,在编译阶段代码就会报错。Agent 可以读取这些错误信息,再修改对应的代码。
对 Agent 来说,这类反馈很重要。因为结果足够明确:代码能不能编译、错误发生在哪个位置、涉及什么类型,都可以从工具得到。
测试也是类似的逻辑。Go 自带测试框架,也原生支持 Fuzz Testing。Agent 完成修改之后,可以运行测试,再根据失败用例继续定位问题。Fuzz Testing 还能通过不断改变输入,帮助发现一些边界条件下才会出现的问题。
这样,Agent 的代码修改就不用只依赖模型自身判断。编译器负责检查语法和类型,测试负责检查程序行为,Agent 再根据这些结果进行下一轮修改。
依赖管理与安全检查
让 Agent 实现功能时,还有一个问题是选择哪些依赖。
模型可能根据训练数据引入某个第三方库,但这个库可能版本较旧、停止维护,或者存在已知漏洞。
Go 的标准库覆盖了 HTTP、JSON、加密、文件处理、测试等不少开发需求,一些功能甚至可以在不额外增加第三方库的情况下实现。
需要使用外部模块时,Go 还有自己的模块管理和校验机制。
Google 在文章里提到了 Go Module Mirror 和 Checksum Database。它们会保存模块副本和校验信息,用来验证模块内容的完整性,也可以降低依赖被修改或消失带来的影响。
另一项相关工具是 govulncheck。它会结合程序实际调用的代码路径检查已知漏洞。如果某个依赖包含漏洞,但程序没有调用受影响的函数,检查结果就可以减少无关提示。
对于 Coding Agent 来说,这些工具同样可以进入开发流程:Agent 负责生成代码,模块校验和漏洞扫描继续提供安全层面的反馈。
代码维护与长期演进
Agent 的用途也不只是在项目里增加新功能。它还能用来升级 API、迁移旧代码、调整依赖、重构项目。
Go 从 Go 1 开始就强调向后兼容,希望旧代码在新的工具链中依然能够顺利编译和运行。对于长期维护的软件,这可以减少语言升级带来的迁移压力。
同时,Go 还提供了 gopls、go fix 等工具。一些规则明确的代码升级,可以交给确定性工具来完成。比如 Google 在文章中提到的 Modernizers。它可以识别一些旧的代码模式,再按照新的语言特性和 API 进行更新。
这种方式很适合和 Agent 配合。规则明确、可以机械完成的修改交给工具处理;需要理解业务逻辑、跨文件关系和设计意图的部分,再让 Agent参与。
相比让 Agent 自己重新生成整段代码,确定性的迁移工具可以减少修改范围,也更方便后续 Review。
部署与生产环境反馈
代码写完了,Agent 还会参与后续的构建、部署和运行维护。在这些部分,Go 有自己的自动化特性。
Go 程序可以编译成单一二进制文件,并支持针对不同操作系统和 CPU 架构进行交叉编译。对于需要创建 CLI、启动服务或者把程序部署到不同环境里的 Agent 来说,可以减少一部分运行环境和构建流程上的处理。
程序进入生产环境之后,Go runtime 还提供 profiling 和 execution tracing,来观察程序真实运行时的性能表现。
Go 编译器还支持 PGO,也就是 Profile-Guided Optimization。开发者可以把生产环境采集到的性能 Profile 提供给编译器,让后续构建根据真实运行情况进行优化。
Google 在文章中作出设想,可以把这些能力接入由 AI 编排的部署流程:生产数据进入性能分析,再反馈给构建和优化环节。
这一部分像是一种工程延伸,但它说明了另一个特点:Agent 能够利用的不只有写代码时的工具,生产环境同样可以继续向它提供反馈。
Go 为什么适合 AI 辅助开发
这些能力放在一起显示了 Go 对 Coding Agent 的优势。
从代码生成、编译测试,到依赖检查、代码维护和运行优化,Go 的工具链能持续地为 Agent 提供明确反馈,让它知道代码哪里出现问题、下一步该如何修复。