跳到主要内容

AI Agent 时代的技术选型

· 阅读需 22 分钟
马老师 Marvin
软件工程师 & 开源爱好者

2025 年 3 月 11 日,Anders Hejlsberg 发表了一篇题为 A 10x Faster TypeScript 的公告:微软要把 TypeScript 编译器移植到 Go。

对大多数读者来说,这只是一条关于性能的新闻。对我来说,这条新闻却把我五年前写的三篇旧文串到了一起。2021 年,我在短短几个月里先后写过三篇彼此不相干的文章:一篇问 大红大紫的 Golang 真的是后端开发中的万能药吗,一篇论证 为什么 TypeScript 是开发大型前端项目的必备语言,还有一篇夸 C# 的开发体验——那篇文章里我顺带提过一句当时看来只算趣闻的事实:TypeScript 和 C# 出自同一人之手。五年后,三篇文章的主角在同一个仓库里会师:我称为"必备"的那门语言的编译器,用我当年审视过的那门语言重写,主导者正是 TS 与 C# 共同的创造者。我知道这几篇文章之间有联系,但没想到它们会以这种方式交汇。

这场会师的价值不止于怀旧,它暴露了这场争论底下悄悄发生的变化。2021 年,咱们争的是哪种语言对"人"更友好:谁的语法更干净,谁的学习曲线更平缓,谁的类型系统更不烦人。这场争论至今没有结束,但裁判换了。从那之后,AI 编程智能体(coding agent)成了生产代码最高频的作者之一,也是代码的第一读者。agent 不在乎 Go 的错误处理有多啰嗦,也不嫌 TypeScript 的类型标注有多累赘。它只关心两件事:一是 多快拿到反馈,二是 反馈能不能被信任

这个观察就是本文的核心论点,我刻意用最保守的说法来陈述它:当 agent 加入你代码库的作者行列,技术选型会多出两个必须优先考虑的判据——agent 的反馈周期(一次"修改代码 → 获得可信反馈"要多久)和 验证信号密度(每一轮循环中,有多少对错能由机器直接裁决,不需要人)。这两个判据不会取代以人为本的旧判据,但会给它们重新排序。而在新的排序之下,2021 年那场语言之争的判决,有的被坐实,有的被推翻。

为了把话说周全,接下来我会先做一轮站内考古,看看 2021 年我们究竟在争什么;然后给两个新判据下精确定义;再检视 2025 到 2026 年的三组证据;随后让最强的反方论证单独占一节;最后给出一个小小的选型框架——你完全可以不同意它,但至少能清楚分歧出在哪里。

2021 年,我们在争什么

重读自己五年前的技术文章,就像做了一次考古。文章里提到的技术都还眼熟,真正让人吃惊的,是埋在文字底下的那些假设。

我的 TypeScript 篇(2021 年 2 月)翻来覆去只讲了一个论点:类型是协作契约。JavaScript 的自由度是全文批判的对象——"动态一时爽,重构火葬场",我当年引用的这句坊间流言说得够直白了。我最推崇的机制是 错误前置:违反契约的代码在编译时就以一条确定性的报错浮出水面,而不是等到生产环境里变成一句 undefined is not a function。不过当时我把这一切都当成人类团队的收益:接口就是文档,自动补全也让写代码舒服了不少。

我的 前端工程化篇(2021 年 3 月)事后看来,其实是一份课程表式的抱怨清单。它罗列了一个"真正的"前端工程师必须掌握的东西——Webpack、Babel、Node、NPM/Yarn、ESLint、TypeScript 配置——并且承认"稍微大一点的前端项目的依赖文件就会超过 500MB"。文章结尾半开玩笑地问:今天入坑前端的你,还学得动么?在那篇文章里,工具链的复杂度被当成理所当然的行业现状:我只琢磨怎么掌握它,从没想过它本身就是问题。

我的 Golang 篇(2021 年 3 月)没有吹捧任何一方。它的方法论是明确的辩证法:"Golang 的一些突出特性将成为它的双刃剑"——语法简单限制了表达复杂问题的能力;强制错误处理让 err 满天飞;而编译速度,我在优缺点对照表里开了个玩笑,是唯一一行没有缺点的特性("怎么可能是缺点?")。那篇文章甚至做了一个可证伪的预测:泛型大概要等 Go 2.0。结果这个预测还保守了:Go 1.18 在 2022 年 3 月就带来了泛型,连版本号都没进位。

我的 C# 篇(2021 年 11 月)引入了我如今看来最耐用的分析框架:满意度与市场份额的错位。引用 StackOverflow 2021 年对 82,914 名开发者的调查:市场巨人 Java 的用户满意度只有 47%,而它的"山寨版"C# 拿到了 62%。我当时的解读是:满意度是领先指标,市场份额是滞后指标。那篇文章的标题里写着"Part 1",Part 2 至今没有出现。这个梗先记下,文末有用。

四篇 2021 年文章并列:各自的判据、当年结论与 2026 年读来的成色——所有判据度量的都是人

把四篇文章这样排成一行,一个 2021 年谁都没想过要说出口的共同假设就浮出水面了:所有判据度量的都是 。人的学习曲线,人的阅读舒适度,人的满意度问卷。没有人问过机器会如何体验这套技术栈——因为当时没有机器在写代码。

裁判换了

观察一个 agent 改完代码之后做什么。它跑类型检查,跑测试,读报错,然后再改。取决于工作流的设计,这个循环在一个任务里会闭合几十次、上百次——而一个人类工程师,一天闭合几十次就到头了。于是你的技术栈有两个属性开始支配 agent 的吞吐量,而这两个属性在我 2021 年的判据清单里一个都没有。

反馈周期 是一轮循环的端到端耗时:安装、编译、类型检查、测试启动、拿到反馈。对人来说,70 秒的类型检查是个可以起身倒杯咖啡的烦恼;对一个要迭代几百次的 agent 来说,延迟就是吞吐量本身,每一轮循环都要再付一次。我 2021 年 Golang 对照表里那个玩笑行——编译速度"怎么可能是缺点?"——就这样悄悄升格成了一等选型判据。

验证信号密度 是每轮循环中机器无需人类判断就能裁决的正确性总量。一条 tsc 报错几乎零成本、结果确定、机器可读:同一个缺陷永远给出同一条消息,指向确切的文件与行号。生产环境里的一个运行时 TypeError 则处处相反:等它暴露出来代价已经很高,复现全凭运气,还需要人来解释。这个区别的分量今非昔比,因为 agent 是机械地消费这些信号的。一项 2025 年针对 LLM 生成代码的研究(GitHub 工程博客引用)发现:LLM 产出代码的编译错误中,94% 是类型检查失败——换句话说,从经验数据看,类型系统是 agent 所能遇到的密度最高的验证信号发生器。

agent 循环:修改代码 → 构建/类型检查/测试 → 信号分叉——确定性、机器可读的信号让 agent 自我纠正并循环成百上千轮;微弱的仅运行时信号则迫使人类介入。技术栈决定反馈周期与信号密度。

本文机制层面的核心,就压在这一句话上:训练数据决定 agent 首轮写得多好,验证信号决定它多快收敛到对。 agent 工作流天生是多轮的,所以主导经济账的是收敛变量,而不是首稿变量。全文的论证都建立在这句话上,反方证词一节里我会专门检验它到底站不站得住。

两个面板:同样一小时,慢循环 6 轮、快循环 60 轮;同一份首稿,密集信号让缺陷逐轮收敛归零,稀疏信号则停在半路、逃逸给人工评审与生产——交付速度与质量都随循环被复利放大

也该交代一下这个论点在既有讨论中的位置,因为它并不是凭空冒出来的。Daniel Demmel 的 反馈循环工程(feedback loop engineering) 把循环质量讲得很透,但刻意保持工具无关——避开了选型这个话题。Netlify 提出的 AX(agent experience) 点破了优化目标的迁移,但落点是"平台如何服务别人家的 agent"。我还没有见到有人把这两个思路接回我 2021 年那几篇文章真正讨论的那个决策——你到底选哪套技术栈——并且正视一个双方都没有碰的难题:代码库既要让人可审,又要让 agent 可循环。这两个诉求是会打架的:显式、冗长利于 agent,人类读者读起来却费劲。"人机联合 DX"不是一句口号,而是一个文末框架必须兜得住的取舍。

判决正在被改写

如果这两个判据是真的,世界上应该已经有人在为它们花钱,也有人在为它们投票。下面三组证据,就是这条钱和票的轨迹——而且每一组都不偏不倚,正好落在 2021 年某篇旧文的论点上。三组证据都取自 JS/web 生态:agent 在那里渗透最深,我的 2021 年考古也在那里——但这两个判据本身没有任何 web 专属的成分,文末的框架会把范围放宽。

证据一:微软为两个判据掏了真金白银。 这是全文最硬的一条证据,所以放在最前面。typescript-go 这次移植——2025 年 3 月宣布,2026 年 6 月进入 RCtypescript@rc;截至写作,npm 的 latest 还停在 6.0.3)——是业界资金最充足的编译器团队之一,花数年时间,用另一门语言重造一个本来就能用的编译器。值得问一句:这笔投入换来了什么?不是新的检查能力,移植的目标恰恰是输出"一模一样"的诊断,对齐了约两万个编译器测试。换来的是同样的验证信号、十分之一的延迟——微软自己 2025 年 12 月在真实代码库上的实测落在 7.5–10.2 倍,官方口径如今收敛为"通常约 10 倍"。拿 2021 年的旧文来对照,这笔投入的两头都是老熟人:TS 篇的"错误前置",从方便人类的特性,变成了机器每轮循环都要消费的信号;Golang 篇对照表里被我当玩笑写的编译速度那一行,成了这笔投入的全部理由。连人选都能说明问题——Hejlsberg 给出的选 Go 弃 C# 的理由,看重的是反馈循环的效率,而不是对某门语言的感情。

证据二:开发者在用满意度为信号密度投票。 证据一说明有厂商愿意掏钱,这一条说明有用户在用满意度投票。Hono 的 RPC 模式 把服务端类型直接共享给客户端——不用代码生成,不经容易漂移的 OpenAPI 中间层;再配上 Zod 校验(单是 @hono/zod-validator 在注册表官方口径下就有约 270 万次周下载),API 形状就变成一份机器检查的全栈契约:服务端改坏了,客户端连编译都过不去。

// 服务端:路由 + 校验器共同定义契约
const app = new Hono().post('/users', zValidator('json', userSchema), handler)
export type AppType = typeof app

// 客户端:请求/响应形状由 tsc 检查——传错 body 是编译错误,不是 500
const client = hc<AppType>('http://localhost:3000/')

这等于把"验证信号"这个论点直接做成了产品。而恰恰是这个框架,在 State of JS 2025 调查 里首年参评就以超过 90% 的满意度进入 S 级;同一份报告写道,Express 使用率仍是第一,"但满意度指标暴露了它的年纪"。这个结构就是我 C# 篇那张图换了名字:满意度领先,市场份额滞后,2021 年那套分析原封不动搬过来就能用。(按原始下载量,Hono 已是仅次于 Express 的第二名——但 2026 年注册表数字被自动化流量整体推高,所以我只为相对结论背书。)

证据三:Bun 只押了速度这一条轴。 Bun 是"反馈周期有市场"最响亮的证明:一个二进制吞下运行时、包管理器、打包器和测试运行器;安装速度是各路独立评测里最公认的优点;State of JS 2025 显示 21% 的受访者在使用它(同比 +4 个百分点)。2021 年的对照来自前端工程化篇:当年我默默忍受的 500MB 依赖目录,五年后成了别人的商机。但请注意这组证据缺了什么——Bun 的卖点里,没有任何一项在增加验证信号。它是押在单独一条轴上的赌注,而这个赌注赌得怎么样,是下一节的主题。

三组 2026 年证据与对应的 2021 年论点:typescript-go 坐实错误前置与编译速度论点;Hono 对 Express 复用满意度对市场份额框架;Hono RPC 让类型契约跨过网络边界;Bun 回应了工具链之怨——但双刃剑同样锋利

反方证词

这个论点可能错在哪里?下面三条反对意见的分量并不相同,我也不打算装作它们相同:第一条直接冲着论点的机制来,是真正的对手;第二条限定论点的适用范围;第三条则动摇了我们度量这一切所用的数据。

真正的对手:训练数据飞轮。 这条反对若成立,我的两个判据就沦为装饰。MultiPL-E 基准 确立了一个事实:LLM 各语言的代码生成正确率,与该语言训练语料的体量强相关;社区讨论里也反复引用悬殊的对比——一个流传很广的基准称模型写 Elixir 的正确率接近 97%,写 Rust 只有 61%。GitHub 自家的 Octoverse 2025 描述了由此形成的飞轮:越流行的语言生成质量越好,于是变得更流行。照这个说法,选型规则简化成一句"选最流行的"就够了。我的回应是前文那个核心判断——语料体量决定每轮循环的起点,验证密度决定的是收敛速度,而多轮工作流对后者是复利——但证据现状也必须交代清楚:截至写作,还没有任何一项控制变量的研究,能在隔离这两个变量的前提下度量 agent 跨技术栈的端到端任务成功率。这个论点立足于机制与行为证据,还谈不上盖棺定论。这正是全文采用保守说法的原因。

给论点划边界的一条:Bun,接着证据三说。 Bun 推翻不了这个论点,但它逼着论点把边界说清楚。用 2021 年 Golang 篇的方法——把每个优点都当双刃剑来审视——来看这个只押速度的选择:

用 2021 年 Golang 篇的方法审视 Bun——每个优点都是双刃剑:单二进制对兼容表面积与 5000+ 未关闭 issue;速度优先文化对内存泄漏与 OpenCode 迁出;AI 加速节奏对生产稳定性折价

社区早就形成了务实共识——开发用 bun install 提速,生产继续跑 Node——这句话本身就是结论:反馈周期再短,也替代不了运行时的可靠性。 所以命题必须带着边界来陈述:两个新判据是在"已经过了可靠性与生态及格线"的选项之间排序,而 Bun 目前还没有完全过线。最有意思的转折在于,连 Bun 的麻烦都在印证信号密度的重要性。2026 年 6 月,Prisma 把 Compute 产品迁到了 Bun 的 Rust 重写版 canary 上——因为他们实测发现稳定版内存泄漏、连接池死锁,而 canary 通过了他们的负载测试。他们的原话值得抄录:"The build which passed our tests made a better foundation than the build which failed them."(通过了我们测试的构建,比没通过的那个更适合当地基。)版本标签是弱信号,跑通的测试套件才是机器能直接裁决的硬信号。

最后交代一下数据口径的问题。 多年来,下载量一直是语言之争里最顺手的论据——2021 年我自己也这么用过——但它正在失效。2026 年上半年,npm 注册表的流量几乎全线翻倍(Express 的月下载量从约 2.2 亿涨到约 4.6 亿,这显然不是真人用户能带来的增长),普遍归因于 CI 与自动化 agent 流量。我们用来度量"流行"的指标,如今有一部分度量的其实是机器。这里头颇有讽刺意味:一个呼唤更硬验证信号的时代,恰好也是我们最软的那个信号悄悄失去含义的时代。

一个两轴选型框架

如果这两个判据是真的,它们就应该能用。下面是它们张开的平面;各点的位置是基于前文证据的 定性判断,不是打分。

两轴平面:反馈周期 × 验证信号密度,按增量内循环衡量,点的颜色随象限(紫色标注 Hono + Zod 与 Bun 两个生态层示例)、大小表示训练语料充足度。Rust 信号密度居首、检查循环处于中游;TS 7 原生版、Bun、Go、C#、Java、Hono + Zod 与小点的 Dart 分布在甜区一带;Kotlin、Swift 与 JS 版 tsc 的 TS 可信但更慢;Python 与 PHP 快而信号中等,Ruby 与纯 JavaScript 快而信号稀疏;C/C++ 落在 agent 困难模式区。

同一份判断,按维度摊开,并附上每个位置的一句依据:

逐栈列出反馈周期、信号密度与训练语料三项评分及一句依据——语料分档以榜单为定量基准并注明定性修正(Go 因基础设施语料深厚上调,Ruby 因基准坍塌下调);表末两行生态层示例说明框架可以抬升语言的位置

象限图只是摘要,真正有用的是用法。老老实实地用,一共三步。

第一步:先跑资格赛,再看图。 运行时可靠性、生态成熟度、安全性是及格线,不是坐标轴——过不了及格线的选项,根本不该出现在这张图上,它在图上的位置再漂亮也没用。Bun 的位置之所以要标注"现状",原因就在这里:社区那句"开发用 bun install,生产跑 Node",是资格赛阶段的结论,轮不到象限出场。

第二步:每条轴打两次分——一次替你的人打,一次替你的 agent 打——并且做好两份分数打架的准备。 同一个显式、注解密集的代码库,agent 拿到的是密集信号,资深工程师拿到的可能是不想评审的代码。两份分数冲突的地方,不是框架的缺陷,而恰恰是你真正需要权衡的地方。我 2021 年 Golang 篇结尾的三问——跟业务合不合、跟团队合不合、学习成本划不划算——就是"人"这一半的打分表,一个字不用改。

第三步:只在训练语料饱和的主流生态里比。 这两条轴默认各家的首稿质量大体拉平。把一门精致的冷门语言放上来,它在图上会比实际表现好看——因为它真正的短板是每一轮都拿到一份糟糕的首稿,而这一点两条轴都反映不出来。所以图中把语料充足度画成了点的大小,而不是第三条坐标轴——Dart 那颗小点就是警示:纯看两轴接近甜区,语料却很薄。这正是训练数据反方论证的合理内核,在这里落地成使用边界。

还有一条边界值得说破:这里比较的是语言,不是框架、库或工具链——而实践中,真正决定位置的往往是生态层。PHPStan 抬升 PHP 的信号密度,pyright 抬升 Python 的;Hono + Zod 和 Bun 出现在图上,正是这一层在起作用的示例。选型时要评估你真实的技术栈,而不是孤立的语言。

这个框架推不出"X 是 agent 时代最好的语言"这样的结论。2021 年我拒绝为 Go 写这句话——"如果一门编程语言能广为人知,那它绝对不会是一门糟糕语言"——五年过去,我只会拒绝得更坚决。判据可以沿用,结论却不能照搬。

当主体变成客体

这次研究里有一个进展,放在 2021 年会荒诞得像段子。Bun——我通篇作为 agent 的"选项"来掂量的那个工具——如今在很大程度上是由 agent"建造"的。Anthropic 于 2025 年 12 月收购该项目后,按 RedMonk 的统计,其提交中由 bot 完成的比例升到了 80% 以上;2026 年 5 月,一次由编程智能体在九天内生成的、超过百万行的 Rust 重写,以单个合并落入主干。我要谨慎地引用它:这是一场厂商有充分动机安排的展示,样本也只有一个代码库。但作为路标,它很难被替代。2021 年的问题——哪种语言最适合人来写——有了一个旧争论的框架根本装不下的新问题:哪套技术栈,最能让机器来写、让人来裁决、并让双方都信得过结果。

这个重新表述,正好补上考古一节留下的两个尾巴。前端工程化篇的结尾问:今天入坑前端的你,还学得动么?2026 年的答案比当年想象的宽松:你不必全学了——agent 替你消化了半张课程表。但有一件事你无法外包:由哪些判据来决定你的技术栈,你得自己想清楚,因为不管你给 agent 一个什么样的循环,它都会一头扎进去拼命优化。至于 C# 篇欠了五年的 Part 2——就当是这一篇吧。只是续集的主角,从一门语言,换成了给语言排座次的标准。

利益披露:本文讨论了 Anthropic 收购 Bun 与 Claude Code 的相关事件,而本文的写作过程本身使用了 Claude 辅助。文中所有数字均来自正文链接的第三方来源,并已标注口径与局限——欢迎核验。