氛围编程者与软件工程师的差异

12
分类佳文共赏
作者Yusuf Aytas
来源跳转
发表时间

内容

十多年前,我写过一篇关于Java 开发者与软件工程师的文章。当时我并没有意识到,人们竟然如此深地把自己的职业身份与 Java 绑定在一起。我的目标是区分两类人:一类是被某种特定语言定义的人,另一类则是更宏观地思考如何解决问题的人。

整场讨论都始于一个前提:Java 已经成了那个“正道”。许多开发者开始从 Java 出发去思考问题。工具变成了看待一切问题的透镜。而当某个问题不符合这副透镜时,人们就会把问题硬拗到符合为止。

我不想把这个类比拉得太远,因为 AI 不只是另一种编程语言或框架。它改变的是软件开发的经济学。不过,旧有的模式依然存在:一种工具变得强大,人们把身份包裹在它周围,最后这门手艺被简化成了工具本身。

现在,问题不再是 AI 能不能写代码。它能,而且它每天都写得更好。真正的问题是,这个过程产出的是什么样的工作成果,以及当它进入真实代码库、面对真实用户、真实数据、真实合规要求、真实事故,以及需要长期维护它的真实的人时,会发生什么。

这就是我看到的vibe coder 与软件工程师之间的区别。vibe coder 是想用生成软件原型来验证想法的人。软件工程师则会思考整个软件开发生命周期。所以,区别不在工具,而在责任从哪里开始、到哪里结束。

拜托拜托,我能合并吗?

拜托拜托,我能合并吗?

错误的衡量指标

围绕 vibe coding 的很多讨论,衡量的仍然是错误的东西。人们展示的是自己从想法到应用用了多快。这当然有价值,尤其是在目标只是验证一个想法时。但在软件开发团队里,总得有人审查它。总得有人理解背后的意图。总得有人判断这个依赖是不是该放在这里。总得有人检查测试是否真的验证了行为。总得有人处理 schema 变更。总得有人在团队之间协调这次改动。总得有人回滚。总得有人写运行手册。总得有人回应告警。

这些都不属于任何人的玩具项目。所以我会用一个不同的指标来衡量 AI 生成的工作:安全合并所需时间。这包括可审查性、风险、测试质量、所有权、回滚,以及作者是否能解释这次变更中那些关键决策。如果 AI 让代码生成更便宜,却让安全合并更昂贵,那团队获得的收益就没有自己以为的那么多。

这就是第一个区别。vibe coder 衡量的是首次跑通版本所需时间;软件工程师衡量的是安全合并所需时间。当工作处于探索阶段时,首次跑通版本很有用;但当工作进入共享代码库时,安全合并所需时间就是必要指标。它包括审查成本、测试成本、发布成本、回滚成本、协调成本,以及未来的维护成本。这就是为什么演示不是正确的终点。它只能证明某样东西能被展示出来,却不能证明它能被团队接纳。

输出不等于进展

AI 辅助编写的代码应该更好,而不是更多。如果工具让你能生成更多内容,那么人就必须更多地约束它。否则,你并没有省下工作量,只是把工作顺延到了下游,让维护变成别人的麻烦。AI 辅助代码不能适用不同的标准。它必须达到和手写代码一样的门槛。所以它应该是收敛的。它应该只有一个存在理由。它不应该包含无关的清理。它不应该因为模型“顺手”就把半个文件重新格式化。它不应该在没有清晰解释的情况下新增一个包。

如果变更之所以很大,是因为模型生成得太多,那就拆分。我对此经历很多次了。它很乐意为一个十行就能写完的东西生成一大堆样板代码。所以,如果作者不能解释为什么每个有意义的文件都发生了变化,那就还没准备好。这就是基本的所有权意识。

第二个区别是工作的单位。vibe coder 把生成结果当作进展;软件工程师则把任何改动都视为责任单位。生成结果可以很大、很乱、也可以是临时的。但真正的变更管理不能这么随意。它必须足够聚焦,便于审查;足够可解释,值得信任;足够边界清晰,能够合并而不把半个系统一起拖下水。这就是速度要么变得有用、要么沦为审查债的地方。

AI 无法替你担责

审查生成代码和审查普通代码并不一样。当人写代码时,通常会有一条决策链。它可能有缺陷,但至少有一个人能解释这条路径。你可以问他为什么用了那个抽象,为什么把规则放在那里,为什么选这个包,为什么测试写成那样。

而对于 AI 生成的代码,其中一些所谓“决策”根本不是决策,只是补全。如果作者没有把生成结果转化为自己真正负责的成果,那么审查者实际上是在同时做两件事:审查与追溯作者意图。

所有权是第三个区别。vibe coder 可以说是模型生成的;软件工程师必须说,这是我负责的。这意味着,在请求审查之前,作者必须先把生成内容转化为一个工程决策。代码也许是从模型开始的,但责任不能停留在模型那里。

上下文不只是文件

现在,模型已经能读很多代码了。这并不意味着它理解系统。一部分上下文存在于代码里,但大量工程上下文存在于别处。它存在于事故中、旧迁移中、客户行为中、运维痛点中、团队惯例中、安全要求中、合规规则中,以及过去那些奇怪的决策里。

如果你不给它,这些上下文模型就没有。即便你给了,它携带这些上下文的方式也不像工程师那样。它是在自己的上下文窗口里运行。任务越大,模型越容易局部优化,却在全局上造成破坏。

所以,“直接让它把整个东西修好”既是个坏习惯,现阶段也确实不太管用。我自己也懒到不止一次这么做过。更好的方式是在让它写代码之前,先缩小决策空间。当我要求更具体时,它确实能给我做得更好。但更具体要求什么?要求我自己真正明白我到底在干什么。我认为,经验丰富的工程师会从 AI 中获得最大价值,不是给模型更多自由,而是给它更少自由。自由适合周末折腾;生产环境需要约束。

这就是第四个区别。vibe coder 给模型一个目标,而软件工程师给模型一个有边界的任务。真正的工程性恰恰发生在这个有边界的任务里:用这个接口,不要碰这一层,等等。一个好的提示词在这里并不是魔法。它通常只是说明工程师已经理解了边界。

Vibe Coding 适合交付流程中的某些阶段,但不适用于所有地方

▶ 最近的一次采访中——我非常推荐观看——Zig 的创建者 Andrew Kelley 说,该项目禁止 AI 贡献,并把它们一概称为垃圾。我能理解他的意思。维护者们看到的是大量 AI 生成的拉取请求,里面充满无关改动、损坏的遗留行为、奇怪的依赖新增,以及那些连自己提交的代码都解释不清的贡献者。

但他们描述的混乱,并不是对 AI 的判决;它只是 vibe coding 在越界时的产物。所以我不会禁止它,我会把它放到合适的位置。

这就是第五个区别:探索与交付。同样一份会让维护者花掉一整个下午的拉取请求,在你做原型验证时却无伤大雅。没人会对那段一次性代码负责。探索可以容忍混乱,因为目标是学习,或者围绕一个想法快速迭代。交付则不能容忍无法解释的混乱,因为目标是一个真实的业务结果。你不能说我们有 99.9% 的正确率。有时候,它就是必须正确。这就是现实中的分界线。

坦白说,这条线也在不断移动。随着工具在测试、回滚和审查方面变得更强,安全合并的部分成本会下降。但下降不等于消失。只要仍然需要有人对结果负责,就必须保有一定程度的纪律。把 vibe coding 用在出错代价低的地方,把工程纪律用在出错代价由客户、团队或业务承担的地方。

学徒问题

初级工程师一定会用 AI,而且他们也应该用。用得好时,它可以解释代码、比较方案、生成示例,并加速学习。但也有坏的一面。

如果初级工程师用 AI 来逃避理解系统,那么他们可能会交付更多,却学得更少。这是一笔糟糕的交易。工程生涯的头几年,正是人们建立心智模型的时候。他们需要在自己的大脑里建立这个模型,而不是从机器那里借来

你不会靠一直站在系统外面、让模型替你修复问题来建立判断力。这也是管理者最难处理的部分之一。AI 可能会在短期内让初级工程师看起来更高产,却削弱了把他们培养成强工程师的学习闭环。Kelley 对 Zig 禁止 AI 的更深层原因也与此相关。他把代码审查称为“贡献者扑克”,也就是项目寻找值得成长为核心团队成员的人的方式。而 AI 提交会破坏这一点,因为贡献者并没有真正学习代码库,也没有吸收反馈。

这就是最后一点。工程需要一定程度的学徒制。vibe coding 会诱使你单打独斗;而人是在团队中工作和学习的。软件工程师通过与他人协作来提升技艺。工作不只是写代码,工作是判断,而不是产出。软件工程师要判断什么有风险、什么没风险。这种判断力来自与系统和人之间的接触。

区别

当主要产出是创意验证时,vibe coder 是有用的。他们可以缩短想法到可点击原型之间的距离。很多想法都值得先这样处理,再决定是否值得投入真正的工程产能

当主要成本是责任归属时,就需要软件工程师。他们控制什么进入系统、如何审查、如何保护、如何测试、如何运维,以及今后如何修改。这个区别是运营层面的,它也不是固定身份。同一个人应该在探索阶段进行 vibe coding,在交付阶段切换到工程模式。关键技能在于知道自己当前处于哪种模式,并且不要让一种模式的习惯渗透到另一种模式里。vibe coding 可以帮助你更快学习;软件工程则能帮你避免为这份学习付出永远的代价。

评论

(0)
未配置登录方式
暂无评论