第二十届D2大会,可能是掌声最多的一场:用了3年AI辅助编程,他说"出来混早晚要还"

1 阅读10分钟

LLM辅助编程的短期效率红利与长期技术债陷阱-茹炳晟

这是我在 D2 大会上听过掌声最多、笑声最多的分享,也是最长的一场。原定半小时,加上提问总时长快一个小时。听了前面其他场次大牛的分享,就感觉 AI 很快要淘汰开发了,很焦虑。这场听下来,有点像给技术人的"心理按摩"——AI 有很多缺陷,开发还是有非常大的存在价值,"开发不死"。

分享者三年多前就开始用 LLM 辅助编程了,开场就说"我绝对是 AI 的拥护者"——但正因为用得够早,踩得够深,讲的不是理论,是已经还过一轮债之后的冷静复盘。

image.png


问题:AI 辅助编程之后,短期数据好看,长期到底发生了什么?

需求交付变快了,代码提交数字也好看了,老板满意。但背后的代价是技术债在爆发式积累——架构守护没到位,代码风格一致性越来越差,扩展性、安全性、可测试性都在悄悄打折扣。

分享者的原话是:「出来混早晚要还。」他们团队已经亲自还过一轮了,现在在慢慢爬坑出来。


问题:用了 AI,效率反而下降了?

image.png

写代码的时间确实缩短了,但写代码从来不是开发时间的大头,大量时间在开会、沟通、协调。AI 加速了写代码这一步,其他时间一点没少。

更重要的是,AI 还凭空带来了一批新任务:打磨提示词、等 AI 回复、review AI 生成的代码、在几个方案里做选择。而且程序员天生对别人的代码不信任,AI 的代码也不例外——看起来在"指挥 AI 干活",其实自己也没轻松多少,有一种虚假的掌控感。


问题:LLM 对已有代码库的理解,根本上差在哪里?

image.png

三个层面:

暗知识:代码库里真正关键的技术决策,从来不在文档里。是在小黑屋里几个人聊出来的,是老板因为"下周必须上线"拍脑袋拍出来的。这些知识 LLM 根本拿不到——而且在敏捷开发的节奏下,工程师自己也没时间把这些上下文整理清楚。两头都缺,LLM 永远不知道这个系统为什么长成现在这样。

暗实现:LLM 除了做它该做的,有没有做它不该做的?分享者讲了一个真实案例。某公司出了安全事故,日志里泄露了敏感信息。顺着 git 记录查到了责任工程师——10 年老员工。所有人都不相信是他的问题。后来才搞清楚:他让 AI 生成了那段代码,功能验收通过了,回归测试也通过了,但他没注意到 AI 额外塞进了一条 log 语句,把一个复杂数据结构整个序列化打进去了,里面就包含了敏感字段。直接上线。

分享者说,这种暗实现还不是恶意的。可能有些训练语料是被人为投毒的,让模型在某些场景下生成特定代码。这个更防不住。

训练数据是静态切片:大模型训练用的代码,基本上取的是 release 分支或 master 分支——软件在某个时间点的静态画像。但软件本质上是演化出来的,不是设计出来的。你心情好的时候写,跟你心情不好的时候写,同一个团队写出来都会不一样。用静态切片训练出来的模型,只能依葫芦画瓢,不懂软件的生长过程。

分享者的观点是:正确的训练方式,应该把一个仓库的所有 commit history,加上每次提交对应的需求和设计,整个演化过程都作为训练素材。这样模型才能真正理解软件工程的思想。


问题:LLM 会不会把代码风格和逻辑一致性悄悄破坏掉?

会,而且无声无息。代码里已经封装了一个排序函数,LLM 遇到同样的排序需求,很可能直接重新写一个,不去复用原来的。这段新代码本身没什么问题,但随着时间推移,同一个实现会散落在多个地方,以后要改得把所有拷贝全找出来,而且每个入口调用方式还各不相同。

他说这个一致性是被谁摧毁的?是你自己。为什么?因为你要高效。为什么要高效?因为老板逼着。就是这个逻辑。


问题:直接"需求到代码",为什么行不通?

分享者说这种做法"简直就是胡扯"。真实场景下,没有人在重新做一个贪吃蛇游戏。大部分工作都是在一坨已有代码上缝缝补补,需求也不会平铺直叙,全是在存量系统上加功能。

真正难的是理解那坨东西,而那坨东西本身的可理解性就是个大问号。SDD/Spec 方式对从零开始的新应用可能有用,但放到祖传系统上,核心难点在于原来的 legacy 知识根本没有被提取出来。


问题:LLM 自动生成单元测试,有用吗?

分享者说这条路「有可能压根就是死路」。有个陷阱叫「将错就错」。

举个例子:有一个函数叫 fa,接收两个参数,内部做减法。把这段代码扔给任何模型,让它生成单测,问大家:fa(8, 3) 的断言结果会是几?

是 5。因为模型理解了这段代码是减法,就顺着生成了减法的测试。

但问题是:这个函数的本意是做加法,fa 其实是 function add,代码写错了。单测的目的不就是发现实现错误吗?但 LLM 是顺着错误的代码去理解的,生成的单测只是提高了覆盖率,根本发现不了问题。

有人会说,提示词里告诉它"基于设计意图,不要根据代码实现"不就行了吗?分享者的回答是:解决了一半。你还得告诉它设计意图从哪来。注释?很多注释本来就是 AI 读代码生成的,循环引用。接口契约?算是奢侈品,有就不错了。函数名?只有函数足够简单时才管用,create_user 这个函数名根本说不清楚要往哪几张表插哪几个字段。

所以目前业界比较公认的用法,是把这类能力用在接口测试上,而不是单元测试。


问题:Vibe Coding 到底适合用在哪?

image.png

Vibe Coding 适合影响小,质量要求低的项目,影响大的项目要慎重,因为最终是人负责。

核心业务上要非常谨慎。Vibe Coding 能生成大量代码,但那和 production ready 根本不是一回事——可能不合规,可能风格不对,可能有各种隐患,出了问题还是人来背锅。

他们团队的实际做法是把 Vibe Coding 交给产品经理用。产品经理在需求探索阶段,通过对话交互生成一个界面,哪里不满意继续提问题继续改,搞到自己满意为止——整个过程研发工程师不参与。确认了之后,才把他最终想要的东西交给研发团队正式实现。

ToB 场景也适合:跟客户现场沟通完,直接跑出来一个原型给他看,确认了再带回去做。

Vibe Coding 短期效率确实高,但长期债务也大。适合影响范围小、容错高的地方,影响大的系统用起来要慎重。


问题:AI 会替代哪种程序员?

image.png

分享者的判断是:纯 CRUD 的、永远在做"加一个字段"这种事的,会很快被替代。真正能和 AI 共生的,是懂需求理解、懂性能可扩展、懂业务长期维护的工程师。

大语言模型来了之后,真正尝到红利的,是那些本来对软件工程就理解得够深的人——能问对复杂问题,能做领域驱动设计,能把大任务拆成小块,把最后一个具体的功能函数交给模型去实现。即使模型写得不够好,影响范围也就在那个小块里,整体架构还是可控的。

用他的话说:用了大语言模型之后,你对这个系统能不能长期拥有掌控感,这才是最关键的。


问题:小团队的机会来了吗?

分享者说,每个人都可能成为超级个体,靠 agent 帮自己干活。以前保持小团队是做不到的,现在有机会了。但他也说:不建议单干。


问题:知识工程为什么会成为分水岭?

模型谁都能用,商业化的大模型大家都能买到。以后企业在大模型时代能不能真正发挥价值,不取决于模型,而取决于你的知识工程做没做到位——你对系统、业务、架构的理解,有没有被真正沉淀下来。从今天开始做,永远不晚。

还有一个稀缺能力:清晰表达。

他讲了个段子。有个老板用 AI 效果不好,让技术团队去看问题。技术去了,看老板的操作:上传了一堆文档,提示词就写了一句「你帮我搞一下」。技术解释说,需求得说清楚,AI 才能有效回答。老板不满意,反怼了一句:「我平时给你发任务,不也是一个文档给你,你帮我搞一下。你这叫什么,模型不行?」


什么变了,什么没变?

image.png

变的是:写代码的能力平权了,效率有提升,产品经理也能用工具跑出一个可用界面。

没变的是:软件工程的本质复杂度、不一致性、可维护性这些问题,人月神话里说的那些矛盾,大语言模型出来之后根本没有变。甚至因为 LLM 本身的不确定性被嵌入软件系统,复杂度和不一致性反而更高了。


问题:开发 + AI = 全栈吗?

提问环节有人问了这个,现在后端转全栈的风很大,搞得大家很焦虑。

分享者先讲了为什么全栈这个方向本身是合理的:分工协作带来的最大问题是知识传递的损耗,以及为了传递知识额外产生的文档工作量。他举了个例子——微信支付没有测试,整个团队全是开发自测。为什么?因为业务逻辑太复杂,测试根本接不住,能接住的测试基本就是架构师级别了。传递成本太高,干脆不分工。

但分享者的核心观点是:不是 AI 加你等于全栈,而是 AI 帮你成为全栈。差别在哪?你对代码有没有掌控感。

让 AI 写你不懂的前端代码,功能自测可能没问题,但换个浏览器、换个分辨率,犄角旮旯的场景一出,锅还是你背——你是全栈工程师,你发布的,你负责。团队里有工程师反馈:「与其让 AI 帮我生成兜不了底的前端代码,还不如让 AI 教会我前端,然后我再用 AI 辅助,这样我能兜底。」

真正的全栈,是你通过 AI 真正学会了另一端,对代码有充分的掌控感,不是 AI 帮你凑出来一个全栈的假象。