AI 编程带来的新变革
过去三个月,我和一群经验丰富、志同道合的工程师,一直在 Amazon Bedrock 内部鼓捣一个很酷的项目。虽然项目本身很让人兴奋,但我们团队还有个更独特的地方——我们大部分的代码,都是由 AI 智能体(AI Agent)写的,比如 Amazon Q 或 Kiro。
先别急着翻白眼:不,我们不是在搞“凭感觉编程”(vibe coding)。我不认为那是构建健壮软件的正确姿势。
相反,我们采用的是一种人与 AI 智能体协作的模式。在我们团队,每一次代码提交(commit)都有工程师署名,这位工程师必须审查并为这段代码负责。我们用“引导规则”(steering rules)来设定约束,告诉 AI 智能体在我们的代码库里该如何工作。事实证明,用 Rust 语言编程帮了大忙。Rust 编译器以其对正确性和安全性的极致追求而闻名,它能在编译时就揪出大量问题,并提供非常有用的错误信息,帮助 AI 智能体不断迭代。相比“凭感觉编程”,我更愿称之为“智能体编程”(agentic coding)。这个词听着是无聊多了,但在我们这行,“无聊”通常是件好事。
对我个人而言,近来我提交的代码中,大约 80% 都是 AI 智能体写的。我的工作流是这样的:先把任务拆解清楚,直到我自己脑子里完全明白(这个过程也经常用 AI 来探索不同方案);然后,给 AI 智能体下达指令(prompt);接着,审查它的输出;和它一起迭代,直到我满意为止;偶尔,我也会接管代码变更集,自己动手完成最后的部分。智能体生成的每一行代码我都会仔细看,直到我对其质量完全满意才会接受——这和我自己写每一行代码的标准毫无二致。
我自认一直是个高效的程序员,就算过去几年里能分给编程的时间很有限,我也总能挤出时间写代码。而过去的这几个月,是我职业生涯中编码产出率最高的几个月。我的团队也不例外——我们的代码产出速度,是普通高效团队的 10 倍。这不是吹牛(hyperbole)——我们实实在在地收集和分析了数据。

以 200 迈(约 320 公里/小时)的速度狂飙
有趣的地方来了。一个典型的软件团队,哪怕经验再丰富,也不可能永远不犯错。即使有良好的测试和工程实践,Bug(程序缺陷)偶尔还是会溜进正式版本。我们都听过“在生产环境中测试”(testing in production)这句无奈的玩笑话。这个现实让我一直坚信,光靠测试是远远不够的,同样重要的,是投资于控制“爆炸半径”(blast radius)和缩短“恢复时间”(time to recovery)。
AI 辅助编写的代码也没什么不同,它同样可能包含 Bug,就算有人类仔细审查过。我猜,出 Bug 的概率和人自己写差不了多少。然而,当团队以 10 倍的速度提交代码时,这笔账就全变了。过去一年才出一次的生产环境大 Bug,现在可能每周都会来一次。就算大部分 Bug 在集成或测试环境中被抓住了,它们还是会影响共享的代码库,拖慢整个团队的进度,迫使大家停下来调查。这同样不是危言耸听——我们的团队已经看到了这些挑战的苗头,这是产出率“阶跃”式增长(即突然的、非线性的剧增)带来的必然后果。
我越来越相信,要想让“智能体编程”真的带来 10 倍的工程效率提升,我们也必须把“问题提交”(problematic commits)的概率降低 10 倍。甚至可能要降得更多,因为在高速迭代下,各个独立的提交之间也可能以意想不到的方式相互作用。
换句话说,当你以 200 迈的速度飙车时,你需要巨大的下压力(downforce)才能让车子稳稳地贴在赛道上!
成本-收益的再平衡
减少 Bug 的最好方法之一是改进测试。我是个飞机迷,一直很佩服飞机制造商们用的那些测试方法。从早期模拟、到部件测试、到风洞(wind tunnel)测试、再到极限破坏测试,最后是整机试飞。就连飞行模拟器也在提升整个行业的安全性方面扮演着角色。软件行业也尝试过其中一些方法,但远未普及。
举个例子,我一直很喜欢“风洞”式的测试,它能在受控环境中测试完全组装好的系统。为了实现这一点,我用过的一种模式是为外部依赖(external dependencies)实现高保真(high fidelity)的“冒牌货”(fake versions),让它们能在本地运行。这样,你就可以在编译时(build-time)编写在本地运行的测试,验证整个系统的端到端(end-to-end)行为。你甚至可以往这些“冒牌”依赖里注入意外行为和故障,来测试系统的应对能力。这类测试写起来和跑起来都很容易(因为在本地),而且非常擅长捕捉那些藏在组件接缝处的隐蔽 Bug。
不幸的是,对于一个中等复杂度的服务来说,伪造所有的外部依赖并不容易。就算你做到了,你还得负责在真正的依赖演进时,同步维护这些“冒牌货”。因此,以我的经验,大多数团队并不会写这类测试。
我认为,我们正看到“智能体编程”改变这笔账(calculus)的早期迹象。AI 智能体非常擅长“喷出”(spitting out)大量代码,尤其是在需求明确、没什么歧义的情况下。那些在原则上合理,但实现和维护起来过于昂贵的想法,它们的成本“duang”一下降低了 10 倍。我真的太喜欢驾驭行业中这种巨变了,因为它为过去那些不切实际的方法打开了新大门。
我们的项目(在 AI 智能体的帮助下)就维护了一套用于测试的“冒牌”外部依赖,包括身份验证、存储、链式复制和推理引擎。然后我们写了一个测试框架(test harness),用这些“冒牌货”在开发者的机器上就能启动我们整个分布式系统,包括所有的微服务。编译时测试(Build-time tests)会针对这个完整组装起来的系统栈启动“金丝雀”(canaries)(一种小规模先行测试策略),从而验证整个系统的功能。
我非常看好这种方法,它能捕捉到一类在过去只有代码提交并部署到测试环境后才能发现的 Bug。几年前,这种想法会被认为是“挺好,但太贵了”而被抵制。而这一次,即便是面对一个相对复杂的系统,我们也只花了几天时间就实现了。
开快车需要更紧密的反馈闭环
归根结底,所有这些代码变更都需要被构建、测试和部署,才能为客户带来价值。对于软件团队来说,一个 CICD(持续集成/持续交付)管线(pipeline)花费几小时来构建、打包和测试软件变更是很常见的。然后,这个管线可能还需要几天时间,才能把一批变更逐步推过预生产(pre-prod)环境,并最终推到生产(production)环境。通常,拥有这种自动化水平的团队,就已经被认为是相当“健康”的了。
“智能体编程”改变了这种动态。在构建、打包和测试一批提交所需的时间里,可能已经有另外十几批提交在排队了。等到一个变更集准备好部署到生产环境时,它可能已经包含了 100 多个提交。如果其中一个提交有问题,整个部署就必须回滚(rolled back),导致管线“嘎吱”一声停摆。与此同时,更多的变更还在不断堆积,加剧了混乱和风险。
我是个 F1 赛车迷,这让我想起赛道上的事故会导致“黄旗”(Yellow Flag)亮起。正常情况下,赛车们以惊人的速度和加速度飞驰。但一旦发生事故,赛道调度员会亮起黄旗,所有赛车都必须减速,跟在安全车(pace car)后面。一场激动人心的比赛瞬间变成了悠闲的绕圈巡游,直到碎片被清理干净,赛道恢复安全。为了尽量减少这种“慢吞吞”的时段,赛事组织者会为各种类型的事故做足准备,确保他们能在几分钟内清理完赛道,重新开始比赛。

就像“全系统本地测试”有助于收紧捕捉某些 Bug 的反馈闭环一样,我们也需要用类似的思路来考虑如何实现我们的 CICD 管线。当团队以每小时几十个提交的速度前进时,有问题的内容必须在几分钟内被识别、隔离和恢复(reverted),而不是几小时或几天。这意味着,常规的构建和测试基础设施需要比现在快上一个数量级。就像玩在线游戏一样,如果玩家的输入和游戏的反应之间有高延迟(lag),游戏就会变得没法玩;同样,如果你的每次提交都需要漫长的等待才能看到反馈,那么想实现 10 倍速的开发真的太难了。
沟通的瓶颈
我喜欢观察那些运营良好的业务。如果你曾瞥一眼繁忙餐厅的后厨,第一眼可能觉得那里一片混乱。但如果你再多花点时间注意细节,你会发现所有成员都在不停地相互协调。主厨、厨师、服务员、杂工和经理们在持续不断地来回传递信息。通过保持这种持续同步,一个运营良好的餐厅即使在高峰时段也能服务好顾客,而不会牺牲质量或速度。

我相信,软件团队要想实现类似的速度提升,就需要对团队的沟通方式施加约束。当你的产出率提高 10 倍时,你不仅仅是在写更多的代码——你是在做更多的决策。我们应该用这个缓存策略还是那个?这个边界情况(edge case)该如何处理?这里用什么抽象(abstraction)是正确的?在正常速度下,一个团队可能每周做一两个这样的决定。而在 10 倍速下,他们每天都要做好几个。
挑战在于,许多这样的决策会影响到其他人正在做的工作。工程师 A 决定重构(refactor)身份验证流程,这会影响到工程师 B 正准备扩展的 API。这些不仅仅是实现细节——它们是会在整个代码库中产生连锁反应的架构选择。
我发现,传统的协调机制在这里引入了太多的延迟。等待一个 Slack 回复,或者安排一个“今天晚些时候”的快速同步会议,要么意味着制造了一个瓶颈——这个决策阻塞了进度——要么就得冒着在意识到冲突之前已经走上错路的风险。在高产出率下,协调的成本本身就可能成为最大的开销!
一种方法是消除协调——如果每个人都在搞相互独立的组件,他们就不太可能需要协调。但我发现这个理想在大多数真实世界的系统中是不切实际的。所以另一种选择是,大幅降低协调的成本。我们团队的工位都在同一层楼,我认为这对我们的速度至关重要。当有人需要做一个可能影响他人的决定时,他们可以直接走过去,在白板前花几分钟把事情讨论清楚。我们实时地统一方法、讨论权衡,然后两个工程师都能回去继续工作。决策被快速、正确地做出了,而且没有造成一堆工作被阻塞。
我承认,这并没有解决分布式团队(distributed teams)的问题——那仍然是一个有待解决的挑战。
前进的道路
我对“智能体编程”的潜力真的非常兴奋。我认为它不仅有能力提高软件开发的效率,还能让我们去解决那些过去因为过于小众(niche)或成本过高而无法解决的问题。这种收益是实实在在的——我们团队 10 倍的产出率提升不是理论上的,它是可衡量的。
但关键在于:如果我们只是简单地把 AI 智能体“拴”到我们现有的开发实践上,这些收益是不会自动实现的。这就像给一辆装着窄轮胎和旧刹车的汽车加装了一个涡轮增压器,结果不会是更快的圈速,而是撞车。在 10 倍的代码速度下,我们当前的测试、部署和团队协调方法会成为新的限制因素。瓶颈只是转移了。
这意味着我们需要从根本上重新思考我们构建软件的方式。为每天 10 个提交而设计的 CICD 管线,在每天 100 个提交的压力下会崩溃。在正常速度下“足够好”的测试策略,在高速下会漏掉太多 Bug。以前行之有效的沟通模式,现在会造成持续不断的工作阻塞。
好消息是,对于全面的测试、快速的部署和高效的协调,我们已经有了很多很棒的想法——这些想法已经显示出了潜力,但因为实现和维护的成本太高,而没有得到广泛采用。现在,情况变了,‘智能体编程’本身就可以极大地降低这些成本。那些帮我们提高代码产出率的 AI 智能体,同样可以帮助我们构建起能支撑这种产出率所需的基础设施。
这才是真正的机会所在:不仅仅是更快地编写更多代码,而是利用 AI 使那些以前不切实际的工程实践变得切实可行。那些最终能在“智能体编程”时代胜出的团队,将是那些认识到整个软件开发生命周期都需要协同进化的团队。
来源: https://blog.joemag.dev/2025/10/the-new-calculus-of-ai-based-coding.html