当前阅读总时间是:20,324小时
| AI工具使用时长 | 2,599小时 |
|---|---|
| 你已经读了多少本书 | 3625本 |
最近OpenAI发了一篇叫《Harness Engineering》的文章,讲他们怎么用Codex搭了一个几乎全自动生成的仓库。我看完第一反应是:终于有人把这件事说透了。
说透的是什么?是大多数团队现在用AI写代码的姿势,根本就是错的。
你观察一下身边,大部分团队用Cursor、用Codex、用Claude Code,忙的事情是什么?是研究“怎么把Prompt写得更漂亮”,是收集“最佳Prompt模板”,是在群里转发“一句话让Claude写出满分代码”。我不是说这些没用,但你要明白一件事:这是在折腾工具的表面,不是在造系统。
OpenAI那篇文章里有句话说得很实在:他们最早踩坑,不是因为Codex不够强,而是因为环境定义得不够清楚。后来每次失败,他们问的不是“怎么再试一次”,而是“到底缺了什么能力,怎么把它做成agent能理解、能被强制执行的东西”。
差距就在这里。一个把AI当打字员的团队,和一个把AI当工人的团队,用的根本不是同一套心智模型。
我见过一个特别典型的失败案例。某个中等规模的团队,上了Cursor半年,产出的代码量翻了三倍。老板很开心,工程师也很开心。然后线上事故开始密集爆发,每周一次、每周两次、每周三次。复盘的时候发现,大部分事故的根因都不是agent生成了错的代码——代码本身单独看都挺工整的——而是agent把某个旧的、本来就有问题的模式复制扩散到了整个代码库。以前这个模式只在两三处出现,老司机知道绕着走;现在agent“学”会了这个模式,把它复制到了几十个地方,连带几十个地方一起出问题。
这个团队的问题不在于agent不够强,也不在于工程师不够资深,而在于他们没有把“这种模式不能再用了”这件事,固化成agent能感知、能被强制纠偏的机制。换句话说,他们没有harness。
我看很多人聊AI编程,聊的都是下游的细节:哪个模型强、哪个IDE好用、哪个上下文工程技巧最新。这些都是战术问题。战术问题解决不了战略问题。
战略问题是什么?是当agent成为主要执行者之后,工程师的工作性质已经变了。
以前你的主产出是代码。一天能敲多少行有效代码,大致决定了你的价值。现在不是了。现在的主产出是约束、是反馈、是让下一次执行更正确的那套环境。OpenAI干脆把这个叫做“Harness Engineering”——驾驭工程。
Harness这个词翻译得有点拗口,但意思不复杂。你可以把它理解成马的缰绳、理解成货运的轨道、理解成流水线的夹具。它强调的不是那匹马有多快,而是那匹马必须跑在你设定的方向上、不能把你摔下来、跑完之后还能让下一匹马继续跑。
说白了,harness engineering就这一件事:把原本只存在于你脑子里的经验、边界、品味和验收标准,变成agent能看见、能执行、能被验证、能被沉淀的系统能力。
你品品这句话。过去我们说“老司机带新人”,靠的是口口相传、靠的是review里被骂几次就记住了、靠的是在Slack里翻一翻。这些套路在agent面前全部失效。为什么?因为agent没有记忆,没有面子,没有“上次被你骂过所以这次小心点”。它每一次都是新人。你想让它稳定产出,就必须把所有隐性规矩显性化。
这事儿以前也该做,只是过去你偷懒也能蒙混过关,因为人脑会帮你兜底。现在兜不住了。
再打个比方。你以前是老师傅,带三五个徒弟。徒弟犯错你骂一顿,骂完徒弟记住了,下次少犯。这种模式下,你的经验是靠“骂”在传递的,慢,但有效,因为徒弟会学。现在不是这样了,现在你面对的是无限多个刚上班的新人,每一个都不认识你、每一个都没被你骂过、每一个都得从头来。靠骂是传递不了经验的。你只能把经验做成“这里有道墙,撞上来自动弹回去”的东西。撞一百次还是弹回去,不需要你在场。这就是harness engineering和“写代码”的根本区别。
我按OpenAI的实践,加上我自己的理解,把harness engineering拆成四件脏活。之所以叫脏活,是因为它们都不光鲜,不性感,不能发朋友圈秀,但没有这四样,你那些Prompt再漂亮都白搭。
第一件脏活:把约束做成可执行的东西,而不是一份文档。
OpenAI一开始也犯了个很常见的错误——写一份巨长的AGENTS.md,把所有规则都塞进去。结果呢?上下文被挤爆、内容迅速腐化、也没人能校验这份文档是不是还有效。后来他们改了路子:AGENTS.md只做目录,规则拆到docs/的结构化文档里,真正生效的是linter、CI和结构性测试。
这个转变非常重要。你要搞明白:文档不是约束,能阻止违反的才是约束。
一条“不要直接调数据库”的注释,和一个“调数据库就CI挂掉”的规则,不是一回事。前者是建议,后者才是约束。前者是给人看的,后者是agent一碰就知道痛的。
我见过太多团队搞AI编程搞不起来,根子就是这里。他们写了一堆“规范”,贴在Confluence上,agent当然视而不见——因为那根本不是系统能读懂的东西。
你要问自己一个问题:这条规则,如果违反了,谁会最先发现? 如果答案是“靠review的人去看”,那它就不是约束;如果答案是“CI会挂、测试会红、linter会报”,那它才是约束。这两者的差别在于,前者依赖于注意力,后者依赖于系统。注意力会分心、会疲劳、会离职,系统不会。
更进一步说,一条活的约束至少要满足三件事:agent在生成代码之前能读到它、agent在生成代码之后能被它拦住、人看到失败信号之后能知道这条规则是什么意思。缺任何一条,这条约束都不算数。
第二件脏活:把验证路径设计得让agent自己能走完。
OpenAI这篇文章里另一个关键点是:他们把原本主要给人看的UI、日志、指标、trace,全都接到了agent能直接消费的地方。Codex能自己复现bug、自己验证修复、自己检查性能目标。
这其实就是反工业化的反面。过去工业化的反面是什么?是所有验证都要人来做。agent生成一段代码,扔给你,你跑一下、看一下、点几个链接、打开几个面板,然后判断行不行。这个流程的瓶颈永远是你。
真正的工业化,是把“行不行”这件事也交给系统去答。测试能跑、指标能读、日志能解析、性能能自动对比——所有这些,都是让agent在没有人盯着的时候也能自我验证。
你要学的一件事是:凡是只能靠人眼判断的环节,都是瓶颈;凡是瓶颈,都会被agent的吞吐反向压垮。
这条经验我个人踩过两次。一次是性能回归——以前性能好坏都是凭我跑一跑感觉一下,agent大规模上线之后,改动频率从一天几次变成一小时几十次,我再也跑不过来了。第二次是接口契约——以前我review时候能看出来“这里return的字段名不对”,现在根本看不过来,必须把接口schema做成CI强制校验。每一次瓶颈被暴露,都逼着我把一段判断力从脑子里搬进系统里。搬完之后才发现,原来这些判断力一直都值得被显性化,只是过去人肉凑合就过去了而已。
第三件脏活:把反馈回路建在重复问题爆发之前。
很多人对“反馈”的理解太浅了,以为就是给agent看错误日志。不对。反馈的本质是:偏差能被尽早发现,发现之后能被压回正确的轨道。
这里面分两层。第一层是实时反馈——测试挂了、静态分析挂了、structural check挂了,agent立刻知道。第二层是趋势反馈——某类问题是不是在反复出现?某个模块的技术债是不是在积累?某种写法是不是正在被错误地复制?
OpenAI的做法是搞“后台Codex任务”,定期扫描偏差、更新质量评分、直接发起针对性的重构PR。这就是典型的趋势反馈。它承认了一件事:全agent代码库一定会复制模式——好模式会被复制,坏模式也会被复制,熵一定会增加。
你如果指望靠每周五“大扫除”清理AI slop,那是靠资深工程师的英雄主义。这个办法一定不可持续。团队一扩大、项目一增多、资深工程师一休假,你就完蛋。
收垃圾必须是系统能力,不是人肉能力。记住这句话。
第四件脏活:把每一次经验沉淀成下次不用再交学费的资产。
这是最容易被忽视的一层,但可能是杠杆最高的一层。
你想想看,一个成熟工程师值钱在哪里?值钱在他踩过的坑。这些坑在他脑子里,离职了就带走了,招个新人要重新再踩一遍。agent时代放大了这个问题——因为agent比新人更“新”,它每次都是零经验上岗。
所以沉淀是个必答题。具体怎么做?一次问题解决之后,别只修这一次的bug,你要追问一句:这属于约束没做好、验证没做好、反馈没做好,还是沉淀没做好?然后强迫自己至少补一项资产——一份模板、一条CI规则、一个脚本、一个structural test、一个golden principle。
哪怕很小,只要它能让同一个坑下次不用再踩,就值得做。
沉淀还有一个被严重低估的价值——它能决定你的知识是属于个人还是属于组织。个人的知识,你一走就没了;组织的知识,存进系统里,下一个人来了立马能用。以前我们说“把自己做成不可替代的人”,其实是一种反组织效率的策略;在agent时代,更稀缺的是“能把知识沉淀成可复用资产的人”。这种人走到哪里,团队的整体能力都会涨一截。这种人,才是真正值钱的。
OpenAI那篇文章里有句话特别扎眼:他们的仓库首先是为Codex的可理解性而优化的。
注意这个表述。不是“可读”,不是“可维护”,是“Codex可理解”。
这背后的逻辑非常狠:以前我们写代码是给人看的,顺便机器也能跑;以后我们写代码是给agent读的,顺便人也能看懂。
你要反应过来这件事的含义。今天大部分团队的知识,都散落在Google Docs里、Slack对话里、会议纪要里、某个资深工程师的脑子里。这些地方agent看不见。
结果是什么?结果是agent的表现上限,直接被你“知识外泄”的程度卡住了。你有多少隐性知识没进到repo里,agent就差多少理解力。
我给你一个判断标准:知识是否是repo-local的、versioned的、discoverable的,决定了agent的表现天花板。
以后招工程师,你该问的问题不只是“你会写什么”,还要问“你会把什么固化进系统里”。前者是个人能力,后者是组织能力——后者才是AI时代真正稀缺的。
顺着这个逻辑往下想,你会发现连技术设计文档都得重写。以前的设计文档写得再华丽都没关系,反正是写给人看的,看不懂还可以找作者问。现在不行了,设计文档是agent读的,它不会找你问,它只会根据文档生成代码。所以那种纯解释性的长段落、那种“这里为了保持灵活性我们做了一些权衡”的模糊话术,agent消化不了。
agent需要的是什么?是目标和非目标、是模块边界、是依赖方向、是不变量、是数据边界、是验证路径、是观测点、是回滚策略,以及那句最关键的——哪些写法虽然能跑但不希望以后被复制。这是operational document,不是essay。文档的形态也必须跟着工程范式一起改。
我再展开说一件事,OpenAI那篇文章里有个观察非常尖锐:他们发现瓶颈已经不是“有没有人能把代码写出来”,而是“有没有足够的人类注意力做QA、裁决和判断”。
这句话值得反复咀嚼。
过去的工程瓶颈在什么地方?在代码产能。一个团队能养活多大的系统,大致取决于这个团队一天能产出多少有效代码。所以我们做架构、做分工、做流程,核心目标都是“让更多的代码能被更快地写出来并且还不出事”。
现在代码产能这个瓶颈被agent打破了。你想要多少代码就有多少代码。新的瓶颈变成了什么?变成了判断力。谁来判断这段代码要不要合、这个设计对不对、这个改动会不会踩线、这个权衡在当前业务环境下是不是合理?
判断力是稀缺资源。稀缺资源必须被精细配置。
这就解释了为什么harness engineering会成为核心——因为它本质上是在做“判断力的预置和规模化”。你把一次判断做好了、固化成约束、固化成验证、固化成反馈,那下次一万次类似的场景都不需要你再判断一次。你的判断力被复用了一万倍。这就是杠杆。
反过来,如果你不做这件事,你的判断力就是一次性的。agent吞吐翻十倍,你的判断力就会被稀释十倍。稀释的结果就是你要么熬死自己,要么放弃把关——哪种结果都不好看。
所以我经常跟团队说一句话:在AI时代,“做了什么事”越来越不值钱,“把这件事变成系统以后就不用再做了”才值钱。 一次性劳动是耗品,可复用判断力是资产。你得想清楚自己在积累哪一种。
这件事还有一个衍生结论——而且这个结论可能会让一些老派的人不舒服——吞吐量变化会反过来改写工程流程。
OpenAI那篇文章提到:他们的仓库采用更少的阻塞式merge gate、更短命的PR、用后续agent run修复flaky test。这些做法放在十年前,任何一个资深架构师都会拍桌子——这不是乱来吗?
但你仔细想想就明白了。过去流程之所以严格,是因为“修正很贵”——回滚成本高、重构成本高、找人复盘成本高。所以你要在PR阶段把一切堵住。
现在呢?修正变得很便宜。agent可以连夜跑、可以自动重构、可以批量改。贵的变成了“等待”——你堵在那里等review的每一分钟,都是在浪费agent的带宽。
流程不是神圣不可变的,流程应该服务于新的成本结构。
我不是说所有团队都该照搬这一套。OpenAI自己也强调,这依赖于他们特定的仓库结构、投入和纪律。但这个原则值得刻在脑子里:当下游的成本结构变了,上游的流程必须跟着变。
那些死守“每个PR都必须两人review、必须跑完所有测试才能合”的团队,不是在守质量,是在守习惯。守习惯的成本,未来会变成看不见的竞争差距。
说两句掏心窝子的话。
第一句:harness engineering不是coding的边角料,是在重新定义什么叫工程能力。
未来更稀缺的工程师,未必是手写代码最多的那个,而是最会设计“约束、验证、反馈、沉淀”这套系统的那个。他知道什么必须前置写清,他知道怎样让正确性可证明,他知道怎样让偏差尽早被发现,他知道怎样把一次经验固化成长期资产。
这种能力不是写Prompt能练出来的,是你一个项目一个项目踩过来、一次闭环一次闭环补出来的。
第二句:别再指望靠人肉兜底了。
agent吞吐上升以后,任何“靠资深工程师最后把关”的流程都会崩。你必须承认:纪律这件事,未来体现在scaffolding、tooling、abstractions和feedback loops里,而不是体现在某个具体的人有多靠谱。
你能不能活下来,取决于你能不能把自己从系统的关键路径上挪开,变成系统的设计者而不是瓶颈。
这事儿没有捷径。想明白了就开始做,做出一个闭环是一个闭环。别再在Prompt花招上浪费时间了,那条路走不通。
临了再啰嗦一句给那些团队负责人听。你们现在最该关心的不是“我们团队的AI编程渗透率是多少”,也不是“我们引入了哪些大模型”,而是“我们把多少判断力沉淀到了系统里”。前两个指标可以一夜暴涨,也可以一夜归零;最后那个指标是慢变量,是长期护城河,是未来决定组织效率的关键。
盯住慢变量,别被快变量骗了。这是我混了这么多年工程圈最大的体会。
你肯定听说过一句话——“AI来了,程序员要失业了”。这句话火了三年,讲的人不少,信的人也不少。但真正在工程一线的人都知道,这件事比这句话复杂得多。
今天我想跟你讲一个非常有意思的故事,以及一个你听完之后可能会重新理解“工程能力”这四个字的概念。这个概念叫Harness Engineering——姑且翻译成“驾驭工程”。它来自OpenAI今年二月发的一篇技术博客,但这件事的意义远不止一家公司的内部实践。我认为,它揭示了AI时代软件工程整个学科的重心迁移。
先说故事本身。OpenAI有一个团队,用了大约五个月的时间,搭建了一个几乎完全由Codex——就是他们内部的代码生成agent——写出来的仓库。从应用代码到测试,从CI配置到文档,从可观测性到部署脚本,整套东西基本上都是agent产出的。人呢?人不直接写代码,人负责“指挥”。
这个团队估计,他们的整体速度,大约是“人手写代码”时代的十分之一的工作量。换句话说,同样的功能量,他们用了一成的人力就搞定了。
他们在文章里甚至写了一句特别提气的话——“Humans steer. Agents execute.”——人来掌舵,agent来执行。
你第一反应可能是:哇,这是不是说AI真的可以取代程序员了?别急,故事的关键不在这里。
故事的关键在于:他们一开始搞得很烂。 真的很烂。早期agent的产出乱七八糟,Bug频出,代码风格各异,到处都是“模式复制”——agent把一段看起来还行但其实有问题的代码疯狂复制到几十个地方。团队每周五要花20%的时间专门清理agent生成的“AI slop”——就是那种看着不错、细看有问题的垃圾代码。
然后他们开始反思:为什么agent表现这么不稳定?
这里有一个非常关键的转折。他们没有把锅甩给“模型不够强”,也没有说“这活儿agent干不了”。他们问的问题是——我们到底缺了什么能力,才让agent干不好?
这个问法一换,一切都不一样了。
这里有一个非常有意思的认知切换。以前人看到AI代码写不好,第一反应是“模型不行”,觉得要换模型、要等下一代模型更强。这种思路把所有希望寄托在模型身上,工程师只是“等待升级”的旁观者。OpenAI这群人换了个问法——不是问模型行不行,是问我们给模型的环境行不行。这一问,主动权就回到了自己手上。
这是我在这篇文章里看到的最聪明的地方。它不是技术细节的聪明,是思考方式的聪明。
OpenAI通过这个项目得出一个非常有洞察力的结论。我再给你提炼一层——
过去我们做软件工程,瓶颈主要在“写代码”。团队能多快交付、能做多大系统,基本取决于工程师能写多少行有效代码。所以我们发明了各种加速写代码的工具:更好的IDE、更好的语言、更好的框架、更好的库。一切都围绕“让代码被更快地写出来”。
现在agent把“写代码”这件事的成本降到了接近零。那瓶颈跑到哪里去了?
跑到判断力那里去了。
想一想传统软件工程里,人的“判断力”承担了多少工作。一个资深工程师review代码的时候,他真正在判断的不是语法错误——那种事linter就能做——他在判断的是:这段代码有没有违反团队的隐性约定?会不会把某种坏模式扩散出去?踩没踩到那种“平时看不出问题但特定场景会炸”的坑?从长期看会不会变成技术债?
这些判断过去是够用的,因为代码产能本身就是瓶颈,判断力虽然稀缺但供给勉强跟得上。agent把代码产能翻了十倍之后,判断力立刻变成了最紧的那根线。
OpenAI在文章里用了一个词:他们最想最大化的稀缺资源,是人的时间和注意力。
这个表述特别精准。不是“人的能力”,是“人的注意力”。能力已经被agent放大了,放大之后剩下需要小心分配的,是那一点点珍贵的注意力。
这就引出了Harness Engineering这个新概念。
顺着这个逻辑你会想到一个有意思的问题——如果判断力变成了新的瓶颈,那一个工程师、一个团队最该优化的,就不是“我们今天写了多少代码”,而是“我们把多少判断力固化下来、不再依赖于某个人的脑子”。前者是工作量,后者是资产。这两者的差别就像“打工”和“建厂”的差别。打工赚的是当天的钱,建厂赚的是之后每一天的钱。
Harness这个词来自“马具”——就是缰绳、挽具、轭、车辕这些东西。单独一匹马是有力量的,但那股力量是发散的、甚至危险的。给它装上harness,马才变成了可用的生产力——力量被约束、方向被确定、状态被监控。
软件工程里的harness是同样的逻辑。agent本身是一股很大的力量,但这股力量天生缺方向、缺记忆、缺自纠偏。你需要一套系统来把它的力量转化成可用、可复用、可持续的产出。这套系统就是harness,设计这套系统的工程叫Harness Engineering。
那Harness Engineering具体在设计什么?我来给你提炼最关键的四件事:
第一件事:约束。 告诉agent什么不能做。但是——这里是最容易搞错的地方——文档不是约束,能阻止违反的才是约束。 你写一份“不要直接调数据库”的规范贴在Confluence上,那叫建议。你配一条“调数据库就CI挂掉”的规则,那才叫约束。前者依赖注意力,后者依赖系统。注意力会分心会疲劳,系统不会。
OpenAI自己就吃过这个亏。他们一开始写了一份巨长的AGENTS.md,想把所有规则塞进一份说明书。结果呢?上下文被挤爆、内容迅速腐化、校验不了谁还有效。后来他们改成AGENTS.md只做目录,规则拆到结构化文档里,真正起作用的是linter、CI和structural test。这才跑通了。
第二件事:验证。 告诉agent它做得对不对。关键是要让agent自己能走完验证路径。怎么做?把原本给人看的UI、日志、指标、trace接到agent能直接消费的地方。让Codex自己能复现bug、自己验证修复、自己对比性能目标。你只要有一个只能靠人眼判断的环节,那就是瓶颈;而瓶颈一定会被agent的吞吐反向压垮。
第三件事:反馈。 让偏差尽早暴露。这不只是“跑测试”这么简单。OpenAI搞了一个特别聪明的动作——他们设置了后台Codex任务,定期扫描代码库偏差,更新质量评分,自动发起针对性的重构PR。收垃圾从“资深工程师英雄主义”变成了“系统能力”。
这件事为什么重要?因为全agent代码库一定会复制模式,好的模式会被复制,坏的模式也会被复制。熵一定增加。如果你不把“降熵”做成系统,就只能靠人拼命救火,迟早累死。
第四件事:沉淀。 把一次经验变成资产。这是四件事里杠杆最大的一件。你想想看,一个bug修完之后,你做了什么?大部分人就修完了事。但一个会做Harness Engineering的人会问一句——这件事属于约束没做好、验证没做好、反馈没做好,还是沉淀没做好? 然后他会强迫自己至少补一项资产:一个CI规则、一条linter rule、一个structural test、一份golden principle。
哪怕很小。只要它能让同一个坑下次不用再踩,就值得做。
我要特别说一句——这四件事的顺序不是随机的,是有递进关系的。约束告诉系统“不该做什么”,是第一层护栏;验证告诉系统“做对了没有”,是第二层护栏;反馈让偏差能被自动捕捉并修正,是第三层护栏;沉淀把这次的经验变成下次的先验,是第四层护栏。前三层在“这一次”工作,第四层在“下一次”工作。只有四层都做到位,你的系统才算真正“会自我成长”。大多数团队只做了第一层甚至半层——写个规范贴在wiki上,然后就没有然后了。这是典型的“半截Harness”,上去就翻车。
到这里你可能还觉得这些东西有点抽象。我给你打个类比——
你可以把过去的程序员想成一个工匠。工匠的价值在于他的手艺——他能雕多好、多细、多快。一个工匠一生能做多少东西,取决于他自己的双手。
现在agent相当于给这个工匠配了无限多的学徒。学徒手艺惊人,但没经验、没规矩、不认识这家作坊的老规矩。工匠面前有两个选择——
选择A:工匠继续当工匠。自己做得飞快,一个人顶过去五个人,但因为学徒帮不上忙,瓶颈还是他自己的双手。
选择B:工匠升级成总工程师。他不再亲自雕,而是设计一套“学徒使用手册+质检流水线+错题本”,让无限多个学徒都能按这套系统干活。他自己动手的时间少了,但系统输出的东西多了十倍、百倍。
Harness Engineering就是选择B。它要求工程师从“做代码”升级到“做系统的系统”——做一个让agent能持续产出正确代码的系统。
这个升级不是一朝一夕的事,它要求工程师改变自己的工作重心,改变自己的能力结构,甚至改变自己的成就感来源。你不能再靠“我今天写了多少行代码”获得满足感,你得靠“我今天沉淀了多少可复用资产、堵住了多少潜在偏差”获得满足感。
这一点对资深工程师尤其不容易。他们过去的竞争力很大一部分就来自于那些“只在脑子里”的隐性判断——显性化了之后,等于把自己的护城河主动填平。心理上是很难过这道坎的。
但是——时代会逼着所有人过这道坎,早过比晚过好。
讲到这里我想插一段,因为Harness Engineering这件事有一个非常反直觉的地方,很多人卡在这里就过不去了。
反直觉在哪里?在于——做Harness Engineering,短期看上去是在“浪费时间”。
你想啊,工程师A天天在敲代码、交功能,老板看得见、同事看得见、产品经理看得见,朋友圈也方便发。工程师B呢?他每天在写CI规则、调整项目结构、重构agent的工作流、沉淀质量检查清单。他这一周可能一行业务代码都没写,但他把团队下一个月的返工量降了一半。
短期看,A的工作可见性高、显性产出多;B的工作可见性低、当下好像没干啥。如果团队的评价体系还停留在“看谁交付了多少feature”,B就会被严重低估。
但长期看,时间一拉长,B创造的价值是指数级的。因为A做的是“一次性劳动”——他这周写的代码,下周可能还得让别人review、改、维护;而B做的是“结构性劳动”——他沉淀下来的规则、流程、自动化,会在之后每一次类似场景里都发挥作用。
这个事情的难点不在技术,在组织认知。很多团队讲起来都支持Harness Engineering,但评价体系还是按旧的逻辑在运转——周报里看交付量、OKR里看feature数。这种组织就算有人想做Harness Engineering,也会被逼回去做一次性劳动。
所以我给团队负责人的建议是——如果你想让Harness Engineering在你的团队里真的发生,你必须亲自把“沉淀资产”写进评价指标。 不然没人愿意去做那些“当下看不见回报”的事。这是组织层面的闭环,不能只靠工程师的自觉。
有意思的是,一旦这个闭环建立起来,你会发现团队里最擅长Harness Engineering的那批人,往往不是代码敲得最快的人。他们是那些思考深、有耐心、愿意把一件事琢磨透然后系统化的人——而这种人过去在“交付KPI”的压榨下,反而一直是被边缘化的。
Harness Engineering的兴起,可能会让这类人重新成为团队里最有价值的人。
讲到这里,你可能会想:“这个道理我懂了,那我具体该怎么做?”
我提炼三条可直接上手的建议——
第一条:每次出问题之后,问自己那个四选一的问题。 约束、验证、反馈、沉淀,这次出问题到底是哪一层没做好?然后哪怕只补最小的一片——一条规则、一个测试、一份checklist——也去补。积少成多。三个月下来,你会发现你的系统变成了一个会自己变强的东西。
第二条:开始前先写非目标,而不是只写目标。 大部分人做需求、做设计,只写“我们要做什么”;更有经验的做法是同时写“我们明确不做什么,以及哪些写法虽然能跑但不希望以后被复制”。前者指方向,后者划边界。边界对agent时代格外重要,因为agent不会自动识别边界——它只知道哪里有例子就去那里学。你不划,它就自由发挥。
第三条:把repo当成你们团队的知识的唯一来源。 那些只在Slack、Google Docs、会议口头共识里的知识——对人勉强够用,对agent全是空白。agent看不见的知识,就等于不存在。所以你有多少隐性知识没进到repo里,你的agent表现上限就被卡在哪里。把知识repo-local化、versioned化、discoverable化,这是AI时代的组织基本功。
我再追加一条更进阶的建议——
第四条:审视自己的技术设计文档是给人看的还是给agent看的。 大部分工程师写的设计文档都还是“essay风格”:长段落、叙事、讲权衡、讲故事。这种风格给人读还行,给agent读就是灾难——agent不会抓中心思想,它只会按你写下来的内容去执行。agent时代的技术设计文档应该更像“操作手册”:目标和非目标要分清,模块边界要明确,依赖方向要画出来,不变量要列清单,数据边界要划出来,验证路径要指明,观测点要标注,回滚策略要写出来,最后还要加上那句最关键的——哪些写法虽然能跑但不希望以后被复制。
这种文档写起来比散文累得多,但每一条都是能被agent直接消费的“指令”,不是“建议”。文档的形态也必须跟着工程范式一起变。
我想在最后留一个思考给你。
如果Harness Engineering真的成为未来工程能力的核心,那会发生什么?
会发生一件事——工程师群体会出现一次快速的能力分化。
一部分人还会停留在“我用Cursor写代码很快”这个层面。他们的生产力确实会比不用AI的时候高,可能高到三倍五倍。但他们还是在做“一次性劳动”——写代码、修bug、review PR。这些劳动的单位价值会随着agent能力提升而持续下降。
另一部分人会转向“设计让agent工作得好的系统”。他们的产出单位价值会越来越高,因为他们做的每一件事——每一条CI规则、每一个structural test、每一份约束文档——都能被复用无数次。一件事写一次,帮你拦一万次偏差,这叫资产。一次性做完的事叫耗品。
这两种人的长期杠杆率差异会是指数级的。不是2倍、5倍,是10倍、100倍。
这就是AI时代工程能力的真正分水岭。它不是“用不用AI”的分水岭——那个问题已经过时了——它是“有没有能力设计agent的工作系统”的分水岭。
如果让我用一句话总结这整篇文章,我会这么说——在AI时代,“做了什么事”越来越不值钱,“把这件事变成系统以后就不用再做了”才值钱。
一次性劳动是耗品。可复用判断力是资产。过去这两种东西的价值差没那么大,因为人的时间是主要瓶颈,大家不得不做大量一次性劳动。agent打破了这个限制之后,这两种东西的价值差一下就拉开了。
Harness Engineering最深的含义,就是教会一个工程师如何把自己的判断力从“一次性”变成“可复用”。懂这件事的人,未来十年会越走越轻;不懂这件事的人,会发现自己越做越累、却越做越不值钱。
这不是一篇吓唬人的文章,这是一篇提醒你“时间窗口还开着”的文章。这个窗口不会永远开着。但你现在开始想清楚、开始动手,还来得及。
当你愿意花一点时间把那些“原本只能靠自己盯着”的判断搬出脑子、搬到系统里,你就已经站在了正确的那一侧。
我最近注意到一件有意思的事。过去三十年,软件工程这个学科一直有一个隐含的假设:工程能力的上限,大致等于工程师写代码的速度和质量。我们讨论编程语言、讨论设计模式、讨论架构、讨论review制度,几乎所有的讨论都围绕着同一个核心:如何让人写出更多、更好、更可靠的代码。
这个假设正在松动。
过去一年,我身边最好的团队开始花越来越多的时间做一件看起来不像“工程”的事:他们不再主要写代码,而是在搭建一种让agent能稳定产出代码的环境。他们写测试、写linter、写CI规则、写结构化文档、写可观测性管道。他们做的每一件事,都不是在直接产出功能,而是在定义一个系统——在这个系统里,agent能够被引导、被约束、被验证、被纠偏。
这件事一开始看起来很奇怪。如果agent已经能写代码,为什么还要花这么多时间去准备它的工作环境?为什么不直接让它写?
但如果你观察得久一点,你会发现这些团队的产出比那些只是“让agent写得更多”的团队高得多。它们不是更快,而是可持续地更快。
这个观察很重要。它指向一个我花了很长时间才想明白的结论:软件工程的重心,正在从“写代码”迁移到“设计让代码被正确地写出来的系统”。
我知道这句话听上去像一句话术,像某种被反复说过的“范式转移”口号。但它不是。它是一个有具体后果的判断,一个会改变你接下来每天做什么、关心什么、积累什么的判断。真正被迁移的不是某种技术栈,也不是某套工作流,而是“工程能力”本身在什么样的活动里被培养、被体现、被兑现。
这种迁移在历史上发生过几次。一次是从汇编到高级语言——那次迁移让工程能力的重心从“熟悉机器指令”变成了“熟悉抽象结构”。一次是从本地部署到云和分布式系统——那次迁移让工程能力的重心从“一台机器的优化”变成了“一整套服务的编排”。每一次迁移都让上一代最擅长的那批人突然发现,自己的竞争力不再完全适用,必须重新学一次。
我有理由相信,我们现在正处在类似的节点。
过去我们对生产力的直觉大致是这样的:一个工程师一天能写多少行代码,就决定了他一天能创造多少价值。这个直觉不完全对,但它大致成立——因为代码产能确实是大多数软件项目的主要瓶颈。
然后agent来了,这个直觉突然失效了。
一个使用agent的工程师,代码产能可以是原来的十倍、二十倍。但很少有团队真的跑出了十倍的产出。大部分团队跑出的是三倍、两倍,甚至更糟——一开始快,过几个月反而慢了下来。有些团队的bug率、技术债、重复工作量反而在上升。
为什么?
因为产能从来不是真正的瓶颈,我们只是以为它是。真正的瓶颈,是判断力。
想一想传统软件工程里“判断力”承担了多少工作。一个资深工程师在review一段代码的时候,他不是在“检查有没有语法错误”——那种事linter就能做。他真正在做的,是判断这段代码有没有违反团队的隐性约定、会不会把某种坏模式传播下去、有没有踩到某个只有在某种特定场景才会出问题的坑、长期看会不会变成技术债。
这种判断力是极其稀缺的,而且它只存在于少数人的脑子里。过去之所以没成为瓶颈,是因为代码产能更稀缺——判断力虽然也稀缺,但供给勉强够用。agent把代码产能拉高了一个数量级,判断力立刻变成了最紧的那根线。
这是一个非常经典的瓶颈迁移。它提醒了一件很重要的事:你一旦解除了某个瓶颈,系统的真正瓶颈就会显形,而那个新的瓶颈通常藏在一个你原本没怎么认真对待的地方。
这也是为什么“AI时代是不是要失业”这个问题问得不太对。它问的方向不对。真正该问的问题是:当代码产出变得便宜,什么东西变贵了?答案是判断力。判断力变贵之后,怎么分配和规模化这种稀缺资源?这才是更有意义的问题。
顺着这条线想下去,你就会意识到软件工程学科接下来很多年的真正议题,大概率会围绕“判断力的规模化”展开。怎么把一个人的判断力固化成代码?怎么把一个团队的共识固化成自动化的检查?怎么让agent在做决策时能访问到组织积累下来的那些“这种情况下应该这样做”的先例?这些问题从2020年的角度看会显得奇怪——那时代码产能还是瓶颈,没人会专门花精力“规模化判断力”——但从2026年的角度看,它们就是这个学科最中心的问题。
OpenAI最近写了一篇文章,给这种新的工程实践起了个名字,叫harness engineering。我觉得这个词起得很好。
harness这个词的本义是马具——那些把一匹马的力量转化成有方向、可控、可持续劳动的装置。缰绳、挽具、车辕、轭。如果只有一匹马,没有这些东西,马的力量是发散的,甚至是危险的。加上harness,马才变成了一个可用的生产力单位。
agent在某种程度上很像一匹马。它有力量,有速度,但没有方向,没有自控,也没有记忆。你要让它真正为你干活,就必须给它一套harness——那套能把它的原始能力转换成可用产出的系统。
harness engineering就是在设计这套系统。它包括什么?OpenAI自己把它拆成了几层:约束、工具、反馈、记忆。我觉得可以用更抽象一点的语言概括:你要告诉agent“不该做什么”,要给它“能做什么”的手段,要让它“做了之后能知道做对没有”的信号,还要让它“这次做错了下次能改进”的机制。
这听起来像常识。但有趣的地方在于,这件事过去根本不需要做。过去的工程师自带harness——他们的经验、他们的品味、他们上次被骂过的记忆,构成了一套隐性harness。这套harness装在他们脑子里,你看不见,但它一直在工作。
agent没有这套harness。你想让它工作,必须把harness外化成系统——变成代码、变成规则、变成测试、变成文档、变成流水线。
这就是harness engineering最本质的那件事:把原本存在于人脑中的隐性harness,外化成系统可执行的显性harness。
这个动作听起来平淡,但它触及了一个非常深的问题:大多数工程师的竞争力是从哪里来的?仔细想一下,你会发现它不是来自他们“知道”什么——知识在互联网时代早已免费了——而是来自他们“会判断”什么。他们知道什么时候该规范化、什么时候该hack、什么时候应该重构、什么时候不要动。这种判断往往讲不清楚,也没法完整地写下来。它存在于一种只有经验能锻炼出来的直觉里。
harness engineering要求你做一件过去几乎没人认真做过的事:把直觉写下来。 不是写成“设计原则”这种不会被执行的纸面规则,而是写成能拦住错误、能推动纠偏、能被系统反复执行的形态。这件事的难度,远大于大多数工程师的预期。也正因为它难,它才成为新的能力分水岭。
这种迁移一旦发生,会连带改变很多东西。我挑几个最重要的讲。
首先,它改变了“好代码库”的定义。
过去我们说一个代码库好,通常是说它“对人友好”——结构清晰、命名合理、注释得当、新人看得懂。现在开始有一种新的标准在出现:一个好的代码库首先是agent能独立理解并推理的代码库。
这个标准听起来和“对人友好”差不多,但实际上要求更严格。人可以靠口头沟通、靠私下问、靠经验脑补来弥补文档缺失;agent不行,它只能看见仓库里写着的东西。所以那些“只存在于某个资深工程师脑子里”的知识、“只在Slack里讨论过”的约定、“只在某次设计评审上口头说过”的边界——这些对人来说勉强够用的知识,对agent都是空白。
推论是很明确的:知识是否是repo-local的、versioned的、discoverable的,决定了agent的表现天花板。
其次,它改变了工程的主产物。
过去工程师的主产物是代码。现在agent可以写代码了,你的主产物开始往另一个方向迁移——往上游迁移,迁到约束上。
这个变化不是说代码不重要了。代码当然还重要。但代码变成了某种“下游产物”,是系统的输出,而不是系统本身。真正的系统是你搭起来的那个harness——它决定了下游产出什么样的代码。
一个工程师的杠杆率,越来越取决于他能不能让自己的工作“被写一次就能被使用无数次”。一条好的CI规则能拦住一万次错误。一个好的structural test能阻止某种坏模式的扩散。一份好的架构文档能让agent在下一次需要做类似决策时不用重新推理。这些都是可复用资产。
相反,亲自修一个bug、亲自review一个PR,这些是一次性劳动。它们在agent时代的性价比正在快速下降。
第三,它改变了思考的单位。
如果你还在思考“怎么把这个prompt写得更好”,你就还在“一次性生成”的心智模型里。agent的本质不是一次性生成器,它是一个循环——它推理、调用工具、观察结果、再推理。真正产生效果的单位不是一条prompt,是一个loop。
这个区别很大。一条prompt是静态的,一个loop是动态的。你在设计loop的时候,你不是在告诉agent“做这件事”,你是在设计“它做错了会怎么被发现、怎么被纠正、怎么被提醒下次别再这样”。这种思维方式接近于control theory,而不是prompt engineering。
第四,它改变了流程的逻辑。
以前的工程流程是为“修正很贵”的世界设计的。因为一旦一段代码合进了主干、出了问题,回滚成本、影响面、排查成本都很高,所以我们有了两人review、阻塞式merge gate、完整的回归测试门禁。这些流程的存在是合理的——它们对应着一个特定的成本结构。
agent时代的成本结构变了。修正变得很便宜——agent可以连夜跑,可以批量重构,可以自动修复flaky test。相比之下,“等待”变贵了——每一次阻塞式review都在消耗agent的带宽,消耗整个系统的吞吐。
所以你会看到一些先行的团队开始做看起来“违反直觉”的事:更短命的PR,更少的阻塞式门禁,更多的“先合再修”。如果你还停留在前一个成本结构里,你会觉得这是在放弃质量。但如果你理解了新的成本结构,你会意识到这不是放弃质量,而是把质量的维持工作从“入口处的一次检查”转移到了“持续的后台纠偏”。这是两种不同的质量观,它们服务于不同的世界。
这里有一个推论,我觉得非常重要,虽然OpenAI那篇文章没有直接说:未来最稀缺的工程师,可能不是那个手写代码最快的人,而是那个最会设计harness的人。
这两种人在过去的评价体系里看起来差不多,因为过去大部分工程师都不得不自己写代码。但在未来,当agent承担了主要的代码产出之后,这两种能力会分化得非常厉害。一个能把判断力固化成系统的工程师,和一个只会把判断力用在一次性劳动上的工程师,长期的杠杆率差距会是指数级的。
举个类比。古代的商人,最值钱的能力是会不会讨价还价、会不会砍价、会不会挑货;工业时代的商人,最值钱的能力是会不会设计供应链、会不会管库存、会不会做分销体系。同样是“商人”,但这两种人面对的问题完全不一样。
软件工程正在经历类似的分化。我们这个时代的“会讨价还价”是“会写代码”;我们这个时代的“会设计供应链”是“会设计harness”。这两种能力不是互斥的——你还是要会写代码,就像商人还是要懂货——但真正决定你长期价值的,是后者。
我想诚实地说一句:harness engineering是很难的,比大多数人以为的难。
它难,不是因为技术复杂,而是因为它要求你把那些你自己都没意识到的隐性判断,一条一条翻出来写成规则。这件事情对资深工程师来说尤其反直觉——他们的竞争力之一恰恰是这些隐性判断,现在你要他们把竞争力显性化、组织化、变成组织能力。心理上很难接受。
它还难在另一个地方:它不是一次性的工作。agent和业务都在演化,你的harness必须跟着一起演化。一条今天写下来的CI规则,三个月后可能就过期了。所以harness engineering不是“搭完就完事”,而是“持续搭建并持续维护”。
但正是因为它难,才值得做。简单的事情护城河浅,难的事情护城河深。一个团队如果能认真做harness engineering,它会获得一种几乎不可被快速复制的能力——不是因为别的团队学不会,而是因为别的团队意识不到这件事的重要性。等他们意识到的时候,你已经领先了太多。
如果让我用一句话总结我对这件事的理解,我会说:我们正在见证软件工程的重心,从“把代码写出来”迁移到“把让代码被正确写出来的系统搭起来”。
这不是一个温和的升级,而是一次心智模型的换轨。过去我们关心的是“你能不能写代码”;未来我们关心的会是“你能不能设计一个让别人(和agent)写出正确代码的环境”。前者是工匠的能力,后者是建筑师的能力。
一个工匠一生能盖多少房子,取决于他的手艺。一个建筑师一生能盖多少房子,取决于他能把多少人的手艺组织起来。这两种人的规模上限,差了不止一个数量级。
软件工程未来最有价值的人,会是那些想清楚了这件事、并且愿意把时间投到看起来“不像写代码”的地方的人。他们不会在朋友圈秀每天敲了多少行代码,他们会在安静地搭建那些让整个团队、整个仓库、整个agent舰队都能跑得更稳的轨道。
这些轨道不性感,但它们决定了所有跑在上面的东西能跑多远。
最后我想加一个提醒,因为这类文章太容易被误读。
我说“工程重心正在迁移”,不是在说“写代码不重要了”。恰恰相反——要设计好harness,你必须对代码有非常深的理解。你必须知道什么模式会演变成什么问题、知道什么抽象是真抽象什么是假抽象、知道什么边界值得守什么边界其实无关紧要。一个从未认真写过代码的人设计不出好的harness,就像一个从未真正懂马的人设计不出好的马具。
我说的“迁移”,是指时间和注意力的重新分配。未来一个好工程师花在“自己写代码”上的时间会变少,花在“设计让agent写出好代码的系统”上的时间会变多。这种变化是缓慢的、不均匀的,而且会先在前沿团队里发生,再逐步扩散。如果你在一个传统团队,你可能会在很长一段时间里还是主要写代码。但越早开始把一部分注意力转向harness,你的长期杠杆率就越高。
这件事不需要你辞职创业,不需要你推翻整个流程,不需要你背叛过去的经验。它需要的只是一个轻微但持续的倾斜:每当你做完一件事,花一点时间问自己一个问题——这件事,有没有可能被写成一条规则、一个测试、一份文档、一个脚本,让下次不需要我再做一遍?
如果有,就动手把它写下来。一次一次地写,写的东西越多,你就越接近那个未来最稀缺的工程师形象。
很多重要的变化看上去都像这样:不是哪一天突然翻天覆地,而是从某一个角度看,一切都已经不一样了。
副标题:Joel Spolsky 风格——老司机聊天,幽默比喻,可读性优先
我有个朋友——咱们叫他老王吧——上个月兴冲冲地跟我说:“哥们儿,我用 Claude 三天写了三万行代码,整个后端全出来了!”
我说:“恭喜你,你现在有三万行你不理解的代码了。”
老王愣了一下,然后说:“不是,我看了的,大部分都挺合理的。”
“大部分,”我重复了一下这个词,“你知道软件工程里最恐怖的词是什么吗?不是’deadline’,不是’legacy code’,甚至不是’我们重写吧’——是大部分能跑。大部分能跑意味着你不知道哪部分不能跑,而且你永远会在周五下午五点半、你老婆等你吃火锅的时候发现那部分。”
老王后来怎么样了呢?两周之后他跟我说,他花了整整十天时间 debug 一个“AI 觉得挺合理但其实完全错误”的权限校验逻辑。那个逻辑看起来无懈可击——变量命名规范,注释写得比他自己写的都好,甚至还加了单元测试。唯一的问题是:它默认所有管理员都能删除其他管理员的账号。
这就是 2026 年软件工程的真实写照:AI 能写出看起来完美的代码,但“看起来完美”和“真的完美”之间的距离,恰好就是一个资深工程师存在的意义。
让我先说一个可能会让你不舒服的事实:写代码这件事,正在变得越来越不重要。
别急着关掉这篇文章。我没说工程师不重要了。我说的是,“写代码”这个动作——就是那个你坐在那里、手指噼里啪啦敲键盘、把脑子里的逻辑变成 Python 或者 TypeScript 的过程——它在整个软件工程价值链里的占比正在急剧缩小。
这就像汽车出现之后,“驾驭马匹”这项技能变得不那么重要了,但“知道去哪里”变得更重要了。GPS 出现之后,“知道去哪里”也不那么重要了,但“决定要不要去”依然只有你自己能定。
过去二十年,我们软件工程师的日常是这样的:产品经理给你一个需求,你在脑子里把它翻译成数据结构和算法,然后花几天写代码实现它。中间你会查 Stack Overflow(或者现在查 AI),遇到几个 bug,骂几句脏话,最后提交 PR。
现在呢?你完全可以把“写代码”这一步交给 AI。但问题来了:交给 AI 之前和之后的那些事,突然变得比以往任何时候都重要。
交给 AI 之前,你需要:
交给 AI 之后,你需要:
你发现了吗?真正的变化不是“AI 取代了工程师”,而是工程师的工作重心从“中间”移到了“两头”——从“执行”移到了“定义”和“验证”。
这就是我今天想聊的核心话题:Harness Engineering。
每次有人发明一个新术语,我的第一反应都是翻白眼。这个行业最不缺的就是 buzzword。但 Harness Engineering 这个概念确实抓住了一些真实的东西,所以我忍住了。
Harness 这个词在英文里有“马具”的意思——就是套在马身上的那套东西,让马知道往哪儿走、什么时候停、拉多重的东西。马本身力大无穷(这就是 AI),但没有 harness,它要么在原地吃草,要么一路狂奔把你的马车拉到悬崖底下去。
Harness Engineering,简单来说,就是为 AI 设计工作环境的工程学。
它的核心思想是:把隐性知识显性化,把经验变成环境。
让我举个具体例子。假设你是一个有五年经验的后端工程师,你在某电商公司工作。当你写一个新的 API endpoint 的时候,你脑子里同时在想这些事:
这些知识在哪里?在你脑子里。 它们分散在你过去五年踩过的坑、参加过的 code review、读过的 postmortem、和同事吵过的架里。
现在你让 AI 写这个 endpoint。AI 不知道这些。它写出来的代码可能在语法上完美,在 GPT-5 的 benchmark 上得分 99.9%,但是用 float 存了金额,没加分页,错误格式和其他接口不一致。
Harness Engineering 就是把这些“脑子里的知识”变成“系统里的约束”。 不是写一份文档扔在 Confluence 上吃灰,不是在 Slack 里 @all 说“大家注意啊”——而是变成代码模板、lint 规则、CI/CD 检查、架构约束、测试断言、Prompt 上下文。让 AI 工作的时候,这些约束自动生效,就像马具一样。
这就是 Harness Engineering 的精髓:你不再是写代码的人,你是设计“AI在其中写代码的那个系统”的人。
软件工程的历史就是一部不断“往上走”的历史。
最早期,程序员要用机器码直接跟硬件对话。后来有了汇编语言,你不用记 10110000 01100001 了,写 MOV AL, 61h 就行。再后来有了 C 语言,你不用管寄存器了。再后来有了 Python,你连内存都不用管了。每一次抽象层的提升,都有人喊“程序员要失业了”,结果每一次,程序员不但没失业,反而变得更值钱了——因为他们在更高的层次上创造价值。
AI 辅助编程,本质上就是这个过程的最新一步。它把“把逻辑翻译成代码”这个动作自动化了,就像编译器把高级语言翻译成机器码一样。
但这一次有个重要的不同。
过去的每一次抽象提升,新工具都是确定性的:编译器不会“发挥”,它不会觉得你的代码太简单然后自作主张给你加个设计模式。但 AI 是概率性的——它会“创造”,它会“发挥”,它会在你没要求的时候给你来一个策略模式套工厂模式再套观察者模式的三层嵌套。
这就引出了一个全新的问题:如何约束一个有“创造力”的工具?
答案就是 Harness Engineering。你要做的不再是告诉机器“怎么做”(How),而是定义“做什么”和“不做什么”(What & What Not)。你从工匠变成了工厂设计师。
工匠亲手打造每一件作品;工厂设计师设计流水线、质检标准、原材料规格。作品的质量不再取决于工匠今天手抖没抖,而是取决于流水线设计得好不好。
这不是“人被降级了”,恰恰相反——这是人被升级了。你从一个一天能写 500 行代码的人,变成了一个一天能让 AI 正确地写 50000 行代码的人。前提是你的 harness 设计得足够好。
好了,现在让我聊聊 AI 最让人头疼的毛病。不是幻觉(hallucination),不是上下文长度限制,而是一个更隐蔽、更危险的问题:过度设计。
我管这个叫“AI 架构师综合征”。
你让 AI 写一个简单的用户注册功能。你期望的是什么?一个表单,一个接口,做个参数校验,存数据库,发个验证邮件,完事。
AI 给你的是什么?一个完整的事件驱动架构,包含用户注册事件发布、消息队列消费、通知服务解耦、策略模式处理不同注册渠道、工厂模式创建不同类型用户、外加一个你永远用不到的插件系统。
它还会跟你解释:“这样做的好处是扩展性强,未来如果你需要支持多种注册方式,只需要添加一个新的策略类就行了。”
听起来很有道理对吧?但问题是:你是个五人团队的创业公司,你的注册方式就一种——手机号注册,而且你连下个月能不能发出工资都不确定。
这就是 AI 在设计阶段最常犯的错误:它默认你需要的是“最佳实践”,而不是“最适合你现在情况的实践”。 它读过太多架构书、太多设计模式教程、太多“如何构建可扩展系统”的博客文章。它就像一个刚毕业的计算机硕士,满脑子都是理论上的“正确做法”,但不知道在现实世界里,“正确做法”往往意味着“过度做法”。
我在 Fog Creek 的时候就见过太多这种事了——不过那时候干这事的是人类。每个新来的工程师都恨不得把 Gang of Four 的 23 个设计模式全用上,好证明自己不是白学的。AI 现在做的,本质上就是这件事的超大规模版本。
过度设计的真正代价是什么?不是多写了几行代码——代码是 AI 写的,它不在乎。真正的代价是:
YAGNI——You Ain’t Gonna Need It。这个原则在 AI 时代不但没有过时,反而变得比以往任何时候都重要。因为 AI 不会帮你判断 YAGNI,它默认 YAGNI(You Are Gonna Need It)。
好,这就引出了一个至关重要的观点:在 AI 时代,人类 review 的核心价值不是添加东西,而是删除东西。
让我说得更直白一点:你最重要的工作,是对 AI 说“不”。
传统的 code review 是什么样的?看代码,找 bug,提建议,可能加个优化。reviewer 的价值主要体现在“发现代码里缺了什么”——缺了边界检查、缺了错误处理、缺了测试用例。
但当你 review AI 写的代码时,画风完全不一样了。AI 不会忘记写错误处理(它读过所有关于错误处理的文章),它不会忘记写测试(它知道测试的重要性),它甚至不会忘记写注释(虽然注释可能废话连篇)。AI 写的代码的问题不是“缺了什么”,而是“多了什么”。
所以,review AI 代码的时候,你要训练自己问这些问题:
我管这个叫“减法 Review”(Subtractive Review)。
传统 review 是加法——你在代码上添加你的智慧。
AI 时代的 review 是减法——你从代码里删除 AI 的过度热情。
最好的代码不是你能想到的最多的代码,而是你能去掉的最少代码之后还能工作的那版。 这句话来自圣-埃克苏佩里——对,就是写《小王子》的那哥们。他原话说的是设计,但放在代码上一样成立。
一个优秀的 Harness Engineer,最重要的能力就是知道什么时候说“这太多了,删掉”。
好了,到了本文最硬核的部分了。咱们聊聊系统原语(System Primitives)。
什么是系统原语?它是你系统里最基础、最底层、最频繁被复用的构建块。就像乐高积木里那些基本形状——2x4 的方块、1x1 的圆钮、那个带轮子的底座。你用这些基本形状可以搭出恐龙、城堡、飞机。搭出来的东西千变万化,但基本形状就那么几种。
在软件系统里,系统原语可能是:
这些原语之所以重要,是因为它们有一个可怕的属性:它们会被 AI 放大。
好的原语被放大了?恭喜你,AI 会基于这些好的原语写出大量一致的、高质量的代码。
差的原语被放大了?恭喜你,AI 会基于这些差的原语写出大量一致的、高质量的垃圾。
让我举个血淋淋的例子。
假设你的系统里有两种错误处理模式。一半代码用 throw new Error(message) 然后在外层 catch;另一半代码用 Result<T, E> 模式,返回一个包含成功或失败信息的对象。两种都能用,但不一致。
现在你让 AI 在这个系统里写新代码。AI 看到了两种模式,它怎么选?看心情——或者更准确地说,看它在上下文窗口里最近看到的是哪种。于是你的系统里就有了第三种模式:AI 在一个函数里混用了两种(在某些路径抛异常,在另些路径返回 Result),创造了一种全新的、前所未有的混乱。
原语的质量决定了 AI 输出的质量上限。 这就像印刷术——如果你的活字模板是歪的,你印出来的每一页都是歪的,而且你印得越快,浪费的纸就越多。
所以在 AI 时代,设计好你的系统原语,是回报率最高的工程投资。 没有之一。
说到这里,有人可能会说:“那我把所有东西都抽象一下不就好了?”
不。这就是一个巨大的陷阱。我管它叫“假抽象”(Fake Abstraction),它是好的原语的邪恶双胞胎。
好的原语和假抽象表面上看起来一模一样——它们都是“把某个模式提取出来,让大家复用”。但它们有一个根本的区别:
好的原语简化了决策。 你用了它之后,需要想的事情变少了。
假抽象转移了复杂性。 你用了它之后,需要想的事情没变少,只是换了个地方想。
来,我给你举几个例子你就明白了。
好的原语:统一的 HTTP 响应格式
1 | interface ApiResponse<T> { |
为什么这是好的原语?因为用了它之后,你(和 AI)在写任何接口的时候,不需要思考“返回值长什么样”这个问题。决策被消除了。前端同事也不需要猜每个接口的返回格式。所有人都知道,success 为 true 就看 data,为 false 就看 error。完事。
假抽象:通用事件总线
1 | class EventBus { |
为什么这是假抽象?因为它没有消除任何决策。你现在需要决定:事件叫什么名字?payload 的格式是什么?谁负责监听?监听的顺序重要吗?如果 handler 抛异常了怎么办?事件是同步还是异步?这个组件应该直接调用那个组件还是通过事件总线?
你“解决了”组件之间的耦合问题,但创造了十个新问题。而且这些新问题更难调试,因为你在代码里 grep 不到谁在调用谁——一切都隐藏在字符串类型的事件名后面。
判断一个抽象是“好的原语”还是“假抽象”的简单方法:问自己“用了它之后,我做决策的次数是变多了还是变少了?”
如果变少了——好原语,留着。
如果变多了或者没变——假抽象,删掉。
如果你需要写一篇文档来解释怎么正确使用它——那一定是假抽象。好的原语不需要说明书。
回到 AI 的话题:好的原语让 AI 更容易做对。 当系统里的错误处理只有一种方式,AI 不需要“选择”,它只会用那一种,而那一种是对的。
假抽象让 AI 更容易做错。 当系统里有一个万能事件总线,AI 会把所有它拿不准的通信都扔到事件总线上——因为那看起来像是“这个系统里推荐的做法”。
这可能是我今天说的最反直觉的一句话了:提升你工程效率的最好方式,不是用更强的 AI 模型,而是建立更好的验证循环。
我知道,这听起来不够性感。“我们升级到了 GPT-6!”听起来比“我们改进了 CI pipeline!”激动人心多了。但数据不会骗人。
让我用一个思想实验来说明。
场景 A:超强模型,弱验证
你用宇宙最强的 AI 模型,它生成代码的正确率是 95%。但你没有好的测试、没有严格的 lint 规则、没有类型检查。那 5% 的错误代码会怎么样?它悄悄混入代码库,直到某天在生产环境里爆炸。
场景 B:普通模型,强验证
你用一个普通的 AI 模型,正确率只有 80%。但你有完善的类型系统、全面的集成测试、严格的 lint 规则、自动化的安全扫描。那 20% 的错误代码会怎么样?它在 CI 阶段就被拦住了,AI 根据错误信息自动修正,最后合入代码库的正确率可能是 99%。
场景 B 的结果更好。 而且好很多。
这就是验证循环的魔力。验证循环不是“一次性检查”,而是一个反馈环:AI 生成 → 自动验证 → 发现问题 → AI 修正 → 再次验证 → 通过。这个循环每多转一圈,最终输出的质量就提升一大截。
更关键的是:验证循环是可累积的。 你今天加的一条 lint 规则,从今以后每一次 AI 生成的代码都会受到这条规则的约束。你今天写的一个集成测试,从今以后每一次代码变更都会被这个测试验证。这是复利效应。
而更强的模型呢?它是一次性收益。GPT-5 比 GPT-4 强,好,所有人都能用 GPT-5,你没有竞争优势。但你花两个月构建的那套定制化验证循环?那是你独有的。
我见过太多团队把预算花在“买更贵的 AI 订阅”上,却不愿意花时间建立基本的自动化验证。这就像买了一辆法拉利,但是不愿意花钱修路——你的法拉利在坑坑洼洼的土路上跑得还不如一辆在高速公路上的丰田卡罗拉。
实用建议: 在你考虑升级 AI 模型之前,先检查这个清单:
如果上面有任何一项的答案是“否”,那你的下一步不是升级模型,而是补上这个缺口。
在 Harness Engineering 的世界观里,bug 有了一个全新的含义。
传统观念里,bug 是错误、是失败、是需要修复的东西。修完了事,最多写个 postmortem 走个形式。
但在 AI 时代,每一个 bug 都在告诉你:你的系统里有一条规则没有被显性化。
让我解释一下这句话。
还记得老王的那个权限校验 bug 吗?管理员可以删除其他管理员。这个 bug 为什么会出现?因为“管理员不能删除其他管理员”这条规则,只存在于老王的脑子里。它没有被写在任何文档里,没有被编码成任何测试,没有被表达为任何约束。
对于 AI 来说,一条没有被显性化的规则,就等于不存在。
所以,当你发现一个 AI 产生的 bug 时,正确的反应不是:
正确的反应是:
“这个 bug 暴露了哪条隐性规则?我怎么把这条规则变成系统约束,让这类 bug 永远不再出现?”
具体来说:
这就是 Harness Engineering 的核心循环:Bug → 发现隐性规则 → 显性化 → 变成约束 → AI 下次自动遵守。
每走一遍这个循环,你的系统就强化一点。假以时日,你的系统会变得越来越健壮——不是因为 AI 变聪明了,而是因为你的 harness 变完善了。
我把这个叫做“Spec 挖矿”(Spec Mining)。每个 bug 都是一座小金矿,里面藏着一条你以前不知道自己知道的规则。你的工作就是把它挖出来,提炼成约束,铸造成原语。
最优秀的团队不是 bug 最少的团队,而是从每个 bug 里提取出最多 spec 的团队。
好了,聊了这么多,让我们总结一下工程师角色的变化。
过去,你是一个代码作者(Code Writer)。你的核心技能是:理解需求 → 设计方案 → 编写代码 → 调试测试。你的产出是代码行。你的效率用 LOC/day(虽然大家都说这不是好指标但暗地里都在数)来衡量。
现在,你正在变成一个边界定义者(Boundary Definer)。你的核心技能是:
注意,这些技能没有一项是全新的。它们一直都是优秀工程师的核心技能。不同的是,在 AI 时代,这些技能从“锦上添花”变成了“核心竞争力”。
过去,一个工程师可以靠“写代码速度快”吃饭。现在,写代码速度快的人是 AI。你需要靠的是“定义什么代码该写”。
这就像照相机发明之后,画家不是失业了——他们进化了。他们不再需要追求“画得像照片一样真实”,因为照相机做这事更快更准。他们转向了抽象、表达、概念——那些照相机做不到的事。印象派、立体派、超现实主义,全是照相机发明之后出现的。
同理,AI 写代码之后,工程师不是失业了——我们进化了。我们不再需要追求“写代码写得又快又好”,因为 AI 做这事更快(虽然“好”还有待讨论)。我们转向了架构设计、约束定义、质量保证——那些 AI 做不到(或者做不好)的事。
每隔几个月,科技媒体就会放出一个吓人的标题。
“AI 将在两年内取代所有程序员!”
“某 CEO 宣布公司将完全由 AI 写代码!”
“大模型已经能够独立完成复杂的软件项目!”
我在这个行业待了二十多年,这种标题看过无数了。只是把“AI”换成了以前的关键词而已:
结果呢?2026 年了,程序员比以往任何时候都多,工资比以往任何时候都高(好吧,这取决于你在哪个市场),软件行业比以往任何时候都大。
为什么?因为这些预言犯了一个经典错误:它们高估了技术的替代效应,低估了技术的创造效应。
AI 确实让写代码变简单了。但写代码变简单之后发生了什么?更多的人开始构建软件,更多的需求被提出来,更多的系统需要被设计、集成、维护、升级。需求的增长速度远远超过了效率提升的速度。
这就像洗衣机的发明。洗衣机让洗衣服变简单了,但人们没有因此少洗衣服——他们开始洗更多的衣服,换衣服的频率更高了,对干净的标准更高了。洗衣机创造的需求比它消灭的劳动力多得多。
所以,当你看到“AI 取代程序员”的标题时,深呼吸,然后问自己:
你不需要恐慌,但你需要进化。恐慌让你做出愚蠢的决定(比如花三个月全职学 prompt engineering),进化让你做出聪明的决定(比如花三个月构建你团队的 Harness Engineering 体系)。
理论讲够了,让我们来点实际的。假设你是一个 5-15 人的普通开发团队,没有 Google 的资源,也没有硅谷的光环。你怎么在日常工作中实践 Harness Engineering?
下面是我推荐的“AI 协作操作系统”,一共六个层次,从下到上:
第一层:原语层(花一周搞定)
把你系统里最基础的模式统一了。不需要一步到位,先挑最高频的三五个:
把这些写成代码模板或者基础库。AI 在生成新代码时,可以参考这些模板。
第二层:约束层(花一到两周持续完善)
把团队规范变成自动化检查:
strict: true,别偷懒)第三层:验证层(持续投入)
建立多层次的自动化验证:
第四层:上下文层(花几天搭建,持续维护)
让 AI 在工作时能获取到足够的上下文:
.cursorrules、.github/copilot-instructions.md),描述项目的技术栈、架构决策、核心规范第五层:反馈层(日常实践)
建立从 bug 到 spec 的转化机制:
第六层:度量层(每月回顾)
跟踪你的 Harness Engineering 效果:
你不需要一开始就追求完美。从第一层开始,每周改进一点,三个月后你的团队就会和大部分团队拉开显著差距。
让我以一个在这个行业干了多年的老家伙的身份,给你一个最终的判断:
在 AI 时代,真正的竞争优势不再是“谁有最好的工程师”,而是“谁能最快地把组织经验变成 AI 可执行的系统”。
为什么?因为 AI 模型是公开的——你能用 Claude,你的竞争对手也能用。AI 的基础能力是一个公共资源,它不构成差异化优势。
真正的差异在于:你的组织有什么独特的知识?你的团队踩过什么独特的坑?你的业务有什么独特的约束?这些东西,是 AI 在公开数据里学不到的。
而 Harness Engineering 就是把这些独特的东西系统化的方法。
想象两个竞争对手,A 公司和 B 公司。
A 公司有一群顶级工程师,每个人脑子里都有丰富的经验。但这些经验只存在于个人的大脑中。当 AI 来了,这些工程师各自指导 AI 干活,效果参差不齐——取决于每个人的 prompt 写得好不好、当天心情怎么样、有没有忘记提到某个重要约束。
B 公司的工程师水平参差不齐,但他们花了六个月时间做了一件事:把组织里积累的所有经验、规范、约束,系统化地编码成了原语、lint 规则、测试、CI 检查、AI 上下文。现在,即使是团队里最新来的工程师,配合 AI,也能产出接近最高水准的代码——因为那些“老司机的智慧”已经被嵌入到了系统里。
B 公司赢了。 不是因为他们的 AI 更强,不是因为他们的工程师更厉害,而是因为他们的 harness 更完善。
这就是 Harness Engineering 的终极价值:它把组织的集体智慧从“人脑里的隐性知识”变成了“系统里的显性约束”,让每一个人(和每一个 AI agent)都能站在整个组织的经验之上工作。
我想用一个比喻结束这篇文章。
你有没有观察过高速公路?高速公路上的车速很快——比普通公路快得多。但高速公路的事故率反而更低。为什么?
因为高速公路有极其完善的约束系统:
这些约束不是在“限制”驾驶员——它们是在“解放”驾驶员。正因为有这些约束,驾驶员才能放心地开到 120 码。如果是一条没有标线、没有护栏、没有限速的土路,你连 40 码都不敢开。
Harness Engineering 就是为 AI 修高速公路。
AI 是一辆动力无限的车。但如果你让它在一条没有标线的土路上跑,它要么翻车,要么走错方向。
你的工作,不是去教 AI 怎么开车——它已经会了,可能比你还溜。你的工作是修路。画标线。立护栏。设计合理的出入口。确保路面质量过关。
路修好了,AI 自然跑得又快又稳。路修得烂,再好的 AI 也只能在泥地里打转。
所以,别再纠结“AI 会不会取代我”了。问自己一个更有价值的问题:
“我修的这条路,够不够好?”
写到最后我想起了我那个朋友老王。上周他又给我发消息了,说他花了一个月时间重构了项目,统一了错误处理和 API 格式,加了 200 多条 lint 规则和一套集成测试。然后让 AI 在这个新框架里重写了之前那个权限模块。
“这次怎么样?”我问。
“AI 写了 800 行代码,CI 全过了,一个 bug 都没有。”
“恭喜你,”我说,“你终于不是在让 AI 写代码了。你是在为 AI 设计系统。”
老王在消息那头沉默了几秒,然后回了我一个字:
“懂。”
大多数人在问:“AI什么时候能替代程序员?”
这是一个错误的问题。
真正的变化不是AI取代了谁,而是工程的重心从“写代码”转移到了“设计AI工作的系统”。
你不会问一匹马:“汽车什么时候能替代你?”你会问:“道路该怎么修?”
过去二十年,软件工程师的核心能力是把想法变成代码。
现在,AI可以写代码了。而且写得越来越快,越来越便宜。
但这不意味着工程师消失了。恰恰相反——工程师的价值正在从“生产代码”跃迁到“定义代码生产的边界”。
想想看:工厂出现后,铁匠没有消失,他们变成了工程师。他们不再亲手锤打每一块金属,而是设计模具、定义工艺流程、把控质量标准。
软件行业正在经历同样的跃迁。
你不再是铁匠。你是设计锻造系统的人。
这个过程有一个名字:Harness Engineering。
它不是一个新框架,不是一个工具,不是一个可以npm install的东西。它是一种根本性的思维方式转变——从“我如何写好这段代码”到“我如何让AI在正确的约束下持续产出好代码”。
大多数团队还没意识到这个转变已经发生了。他们还在用旧的思维框架理解新的现实。
每个资深工程师脑子里都有一套没写下来的规则。
“这个模块不能直接调那个服务。”“日志要这样打,不能那样打。”“这里用事件驱动,不要用轮询。”“这段遗留代码别碰,碰了会塌。”
这些规则从来没有文档化。它们活在老员工的大脑里,通过code review口口相传,在午餐时间偶然提起,在新人踩坑后才被发现。
AI不吃午饭,也不做code review。它只认识被写下来的东西。
所以,Harness Engineering的第一个动作是:把隐性知识变成显性规则。
这听起来很简单,但它是整个范式转变的核心。因为——
你的经验如果不能被编码为约束条件,它在AI时代就等于不存在。
想想这有多深刻。你十年积累的技术直觉,你对系统架构的精微理解,你知道哪些“看起来优雅但实际上是坑”的设计模式——如果这些东西没有被转化为AI可以理解和遵守的规则,它们的价值就是零。
不是接近零。是零。
因为AI会绕过你所有的隐性知识,直接按照它训练数据里的“最佳实践”来干。而训练数据里的最佳实践,往往是脱离上下文的通用方案。
Harness Engineering就是把经验变成环境。不是教AI你知道什么,而是构建一个系统,让AI只能在你定义的边界内行动。
就像河流不需要“知道”应该流向哪里。河床决定了一切。
你不是在训练AI。你是在塑造河床。
软件工程一直被视为一种“手艺”。
每个程序员都是工匠,代码是他们的作品。我们甚至用“craft”这个词——software craftsmanship。我们谈论“优雅的代码”“漂亮的架构”,好像在谈论一件艺术品。
这个时代结束了。
软件正在从“手艺模式”进入“工厂模式”。这不是降级,这是升维。
手艺模式里,价值在于你能亲手做出什么。工厂模式里,价值在于你能设计什么样的生产系统。
一个木匠可以做出精美的椅子。但设计宜家平板包装系统的人,改变了全世界的人坐什么椅子。
哪个创造了更大的杠杆?
人在上移,不是在出局。 从执行层上移到设计层,从操作层上移到架构层,从写代码上移到定义代码的生成规则。
这里有一个关键区别:上移不是变得更“抽象”。不是画更多的架构图,开更多的会议,写更多的PRD。
上移意味着你的工作变成了:
你不是在管理AI。你是在工程化AI的工作环境。
这就是Harness这个词的含义——驾驭,束缚,利用。不是控制每一步,而是设计让正确行为自然涌现的结构。
给AI一个简单的任务,它会给你一个复杂的方案。
这不是bug,这是特性。或者说,这是它的本性。
AI被训练来展示能力,不是来展示克制。
你让它写一个用户登录功能,它会给你加上OAuth2.0、JWT刷新机制、多因素认证、设备指纹、风控引擎的接口预留、国际化支持、无障碍访问优化。
你只需要一个简单的邮箱密码登录。
这就是AI在设计阶段的核心问题:过度设计。
为什么?因为在AI的训练数据里,“更完善”的方案得到了更多的正面反馈。Stack Overflow上获赞最多的回答,往往是最全面的那个,不是最简洁的。技术博客里被转发最多的架构设计,往往是最精巧的那个,不是最朴素的。
AI学会了一个错误的等式:复杂 = 专业。
但真正的工程智慧恰恰相反。
最好的架构不是你再也无法添加什么的架构,而是你再也无法删除什么的架构。
AI不懂得删除。它只懂得添加。
它不会说“这里不需要”。它会说“这里可以加上”。每一次“可以加上”,都是技术债务的种子。
一百个种子长成一片杂草丛,你的系统就窒息了。
这就是为什么在设计阶段,AI的输出必须被视为“初始提案”而非“最终方案”。它是原材料,不是成品。
需要有人做减法。
大多数人以为code review的价值是找bug。
错了。
在AI时代,code review的核心价值是做减法。
Bug可以通过测试找到。逻辑错误可以通过形式化验证发现。安全漏洞可以通过扫描工具检测。
但“这个东西根本不应该存在”——这个判断,只有人能做。
AI擅长回答“怎么做”。人擅长回答“该不该做”。
当你review一个AI生成的PR时,你最重要的工作不是检查代码是否正确。而是检查——
这段代码是否多余?
这个抽象是否必要?
这层封装解决了真实问题还是想象中的问题?
这个配置项真的会被改变吗?
这个接口预留是基于真实需求还是基于“万一以后要用呢”?
每一行你删掉的代码,都比你写的代码更有价值。
因为删除的代码永远不会有bug,永远不需要维护,永远不会成为技术债务。
这就是为什么在Harness Engineering的框架下,人类审查不是瓶颈。它是系统中最关键的过滤器。
不是AI写得不够好。是AI不知道什么时候该停下来。
一个好的工程师,不是写了什么惊天动地的代码。而是挡住了一百个不应该存在的功能,删掉了一千行不需要的代码,说了一万次“不”。
这种能力——知道什么不该做的能力——是AI最难学会的东西。
因为“不做”在训练数据里没有正面样本。没有人会因为“什么都没做”而获得GitHub star。
但最好的系统,恰恰是被无数个“不做”雕刻出来的。
现在我们来谈一个核心概念:系统原语(System Primitives)。
系统原语是你架构中不可再分的基本构件。它们是AI构建一切的地基。
日志系统是原语。错误处理模式是原语。数据访问层的接口契约是原语。消息队列的使用规范是原语。配置管理的层级结构是原语。
原语不是你“选择”的。它们是你“定义”的。区别很大。
选择意味着从现有选项中挑一个。定义意味着你决定了这个东西在你的系统里是什么样子,有什么行为,有什么边界。
AI是一个放大器。它放大你的原语。好的原语被放大成好的系统。坏的原语被放大成灾难。
这就像复利。
如果你的利率是正的,时间是你的朋友。如果你的利率是负的,时间是你的敌人。
原语就是你的利率。
一个设计良好的错误处理原语,会让AI在每个模块里都产出一致的、可追踪的、容易调试的错误处理代码。一千个模块,一千次正确。
一个设计糟糕的错误处理原语——比如“catch所有异常然后打个日志”——会让AI在每个模块里都吞掉异常。一千个模块,一千个定时炸弹。
你不需要审查AI写的每一行代码。你需要确保你的原语是对的。
因为原语对了,AI的输出大概率是对的。原语错了,无论AI多强大,输出都会系统性地偏离。
这就像物理学。如果牛顿定律是对的,你可以推导出整个经典力学。如果牛顿定律是错的,你推导得越多,错得越远。
原语是你的定律。
投资时间在原语上。这是整个Harness Engineering中杠杆最大的一个动作。
但这里有一个陷阱。
不是所有看起来像原语的东西都是原语。很多时候,我们创造的是伪抽象——看起来像基础设施,实际上是不必要的复杂性。
真原语简化系统。伪抽象复杂化系统。
怎么区分?
真原语有三个特征:
第一,它解决了一个你真实遇到过的问题,不是一个你想象中可能遇到的问题。
第二,它减少了使用者(包括AI)需要做的决策数量。好的原语让你不用想。坏的抽象让你想得更多。
第三,它在不同上下文中的行为是可预测的。你不需要查文档就知道它在这个场景下会怎么表现。
伪抽象恰恰相反:
它解决的是假设性问题。“万一以后我们需要换数据库呢?”于是你建了一个数据库抽象层。三年后你没换数据库,但每个新功能都要跟这个抽象层搏斗。
它增加了决策数量。“我应该用AbstractBaseRepository还是ConcreteRepositoryAdapter?它们有什么区别?为什么有两个?”
它的行为因上下文而异。“在这个场景下用configV2,在那个场景下用legacyConfig,但如果是测试环境要用mockConfig,除非是集成测试。”
AI特别擅长制造伪抽象。因为伪抽象在代码层面看起来很“专业”。
它有清晰的接口定义,有完整的类型标注,有详细的文档注释。一切看起来都很好。除了一个事实——这些东西根本不需要存在。
所以当你为AI定义系统原语时,坚守一个原则:
如果你不能用一句话解释为什么这个原语必须存在,它就不应该存在。
不是“它很有用”。不是“它很优雅”。是“如果没有它,系统会在某个具体场景下出问题,而这个场景我们真实遇到过”。
从真实的痛苦中提炼原语,而非从想象中的完美中推导原语。
这是第一性原理思维的核心。
行业里有一种迷信:模型越强,问题越少。
这就像说“司机技术越好,就越不需要交通规则”。
不是这样的。
GPT-7不会让你不需要验证。Claude 5不会让你不需要测试。未来的模型不管多强,在你的特定业务上下文中,它仍然会犯错。
因为它不了解你的业务上下文。它不可能了解。你的上下文是独特的、动态的、充满历史遗留决策的。
真正决定AI工程质量的,不是模型的能力上限,而是验证循环的严密程度。
什么是验证循环?
AI生成代码 → 自动化测试 → 静态分析 → 规则校验 → 人工审查 → 反馈修正 → AI再次生成。
这个循环的每一个环节都在做同一件事:缩小AI的可能输出空间,直到它只能产出正确的答案。
想象一个漏斗。
AI的原始输出是漏斗的顶端——巨大,充满可能性,也充满错误。每一层验证都收窄一点。最终流出来的,是经过多层过滤的、高度可靠的代码。
漏斗设计得越精密,你对模型本身的依赖就越小。
这意味着:一个普通模型配上精密的验证循环,胜过一个顶级模型配上松散的流程。
这是一个违反直觉但极其重要的洞察。
大多数团队把80%的时间花在选择和调优模型上,把20%的时间花在设计验证流程上。
应该反过来。
验证循环是可以被你完全控制和持续改进的。模型是别人的产品,你无法控制。
把精力花在你能控制的事情上。这是Harness Engineering的基本纪律。
一个好的验证循环应该具备什么特征?
快。快到AI每次生成后都能在秒级得到反馈。如果验证需要半小时,AI就会在错误的方向上走半小时。
全面。覆盖功能正确性、代码规范、架构约束、安全规则、性能边界。每一层都是一道防线。
可解释。当验证失败时,失败信息必须清晰到AI可以理解并自我修正。“测试失败”是没用的。“在处理空列表时,期望返回空数组但实际返回了null”——这才有用。
可演进。每发现一个新的问题模式,就新增一条验证规则。系统像免疫系统一样,遇到的病原体越多,就越强壮。
验证循环是活的。它不是你搭建一次就忘记的基础设施。它是你最重要的工程资产,需要持续投入和迭代。
当AI产出了一个bug,大多数人的反应是修复bug。
这是正确的。但不够。
每个bug都是一条未被书写的规范。
这句话值得反复读。
AI为什么会在这里犯错?不是因为它“笨”。是因为在你的系统规范中,有一个空白地带——一条你以为是“常识”但从未明确写出来的规则。
用户ID不能为负数——你觉得这是常识。但你写在规范里了吗?
金额计算不能用浮点数——你觉得这是常识。但你的原语里有这条约束吗?
删除操作必须软删除——你觉得这是常识。但AI不知道。
在AI的世界里,没有“常识”这个概念。只有“已定义”和“未定义”。
未定义的空间,就是bug的温床。
所以,当你修复一个AI产出的bug时,不要只修复代码。要回溯:
这个bug对应的规则是什么?
这条规则为什么没有被写下来?
把这条规则写下来之后,它应该在验证循环的哪一层被检查?
如果这条规则更早被写下来,AI一开始就不会犯这个错误吗?
每修复一个bug,就多一条规范。规范越完善,AI犯错的空间就越小。这是一个正向飞轮。
最好的团队不是bug最少的团队。是规范增长最快的团队。
因为规范的增长速度决定了AI可靠性的提升速度。
这也回到了前面说的——经验的显性化。每个bug都是一次显性化的机会。不抓住这个机会,同样的bug就会以不同的面貌反复出现。
你消灭的不是bug本身,而是产生这类bug的条件。
这才是真正的根因分析。不是“为什么这段代码有bug”,而是“为什么我的系统允许这种bug存在”。
前者修复一个点,后者封堵一个面。
让我们把这一切串起来。
工程师的角色正在经历一次根本性的重新定义。
过去,你的工作是写代码。你的价值由你写的代码的质量和数量决定。
现在,代码由AI写。你的工作变成了——
定义AI工作的边界。
什么是边界?
边界是规则。“在这个系统中,所有API响应必须遵循这个格式。”
边界是约束。“任何数据库操作必须通过这个原语层,不允许直接SQL。”
边界是验证。“每次提交必须通过这组检查,不通过不允许合并。”
边界是接口。“这个模块对外暴露这三个方法,其余全部私有。”
边界是“不”。“不,我们不在这一层做缓存。”“不,这个功能不需要配置化。”“不,这个抽象不必要。”
你的价值不再是“我能写什么”,而是“我能定义什么样的边界,让AI在其中产出正确的东西”。
这是一种完全不同的能力。
写代码需要的是技巧——语言特性、算法知识、框架用法。
定义边界需要的是判断力——什么是必要的,什么是多余的,系统的真正约束在哪里,灵活性应该开放在哪里。
技巧可以被训练。判断力只能通过经验和反思获得。
这就是为什么资深工程师在AI时代不会贬值。恰恰相反——他们的判断力,是整个系统中最稀缺的资源。
一个初级工程师可以学会使用AI写代码。任何人都可以。
但只有经历过系统崩溃的人,才知道哪些边界是不可逾越的。
只有维护过遗留系统的人,才知道哪些“优雅的设计”最终会变成噩梦。
只有上线过大规模服务的人,才知道哪些假设在真实流量下会崩塌。
这种经验无法通过训练获得。这就是Naval所说的“specific knowledge”——独属于你的、无法被标准化传授的知识。
AI时代,specific knowledge的载体从“手指上的代码能力”变成了“脑子里的系统判断力”。
载体变了,本质没变。
“程序员将在两年内被取代!”
“AI已经可以独立完成项目了!”
“不学AI你就完了!”
深呼吸。
口号的目的是制造情绪,不是传递信息。
每一次技术变革都伴随着同样的叙事结构:新技术出现 → “旧技能将消亡” → 恐慌 → 卖课 → 现实逐渐展开 → 变化确实发生了但远没有口号说的那么极端。
还记得“no-code will replace developers”吗?
还记得“blockchain will replace databases”吗?
还记得“agile will eliminate project failure”吗?
变化是真实的。口号描述的方式是失真的。
判断一个变化是否真实,看它是否改变了底层的激励结构。判断一个口号是否失真,看它是否过度简化了这个改变。
AI确实改变了底层激励结构。写代码的边际成本趋近于零——这是真实的。这意味着能写代码不再是竞争优势——这也是真实的。
但“程序员消失”?这就是过度简化了。
代码生产的自动化不等于软件工程的自动化。代码只是软件的一部分——甚至不是最难的部分。
最难的部分是什么?
理解业务需求中的矛盾和模糊。
在不确定性中做出不可逆的技术决策。
管理一个系统在多年演进中的复杂性。
协调多个团队对“什么是正确的”的不同理解。
在紧急故障中快速判断根因。
这些能力,AI在可预见的未来都无法替代。不是因为AI不够强。是因为这些问题本身没有确定的答案,需要在特定上下文中做出权衡。
AI能解决有确定答案的问题。人解决需要权衡的问题。
所以,面对口号,保持两种能力:
第一,区分信号和噪音。AI改变工程方式——这是信号。“程序员两年消失”——这是噪音。
第二,把焦虑转化为行动。与其恐惧被取代,不如问自己:我的哪些能力是AI放大器的一部分?我的哪些能力只是在做AI已经可以做的事情?
聪明的人不恐惧变化,也不无视变化。他们重新定位自己在变化中的位置。
理论说够了。谈谈一个普通团队,明天早上该怎么做。
好的系统不需要英雄。它需要流程。
以下是一个Harness Engineering的实操工作系统,你可以从明天开始使用。
花一天时间,和团队一起列出你们系统中的所有原语。
不要想象。去看代码。
你们的错误处理是怎么做的?有统一模式吗?还是每个模块各自为政?
你们的日志是怎么打的?有规范吗?还是每个人凭感觉?
你们的API设计遵循什么约定?URL命名?参数校验?响应格式?错误码?
数据库访问有统一的抽象吗?事务怎么管理?连接池怎么配置?
列出来,分成三类:已有且好的、已有但差的、缺失的。
先修正“已有但差的”。这些是你系统中正在被AI放大的负面模式。
再补齐“缺失的”。每个缺失的原语都是一个AI可能犯错的灰色地带。
每个原语都应该有三样东西:一个清晰的接口定义,一组使用示例,一组反面示例(“不要这样用”)。
反面示例特别重要。AI很容易从正面示例中“过度泛化”。告诉它“不要”比告诉它“要”更有效。
从最简单的开始:
一套覆盖核心路径的自动化测试。不需要100%覆盖率。先覆盖最重要的20%路径。
一组架构规则检查。“不允许直接导入内部模块。”“不允许在Controller层调用数据库。”“不允许在工具函数中使用全局状态。”这些可以用简单的lint规则实现。
一个PR review检查清单。不是代码层面的,而是架构层面的:“这个PR是否引入了新的依赖?”“是否修改了公共接口?”“是否新增了抽象层?”如果答案是“是”,就需要更严格的人工审查。
每次修复AI产出的bug时,多做一步:
这个bug对应什么规范?规范是否已经存在?如果不存在,创建它。创建后,添加到验证循环中。
这个流程不需要复杂的工具。一个共享文档加上纪律就够了。
关键不是工具,是纪律。
不要一开始就让AI做所有事情。
从低风险的任务开始:写测试、写文档、做简单的CRUD。验证AI在你的原语系统中是否表现良好。
逐步扩大范围:更复杂的业务逻辑、跨模块的功能、性能敏感的代码。每扩大一步,都确认验证循环能捕获问题。
信任是earned,不是granted。对AI也是一样。
每周回顾:
本周AI产出了多少需要大幅修改的代码?
哪些修改是因为原语不清晰导致的?
哪些修改是因为验证循环有漏洞导致的?
哪些修改是因为模型本身的局限导致的?
前两类是你能控制的。第三类不是。
把精力花在前两类上,持续缩小AI犯错的空间。
这不需要专门的“AI工程师”。这是每个工程师的日常工作的一部分。就像测试不需要专门的QA团队(虽然有也好),原语维护和验证循环也是每个工程师的责任。
最后,让我们谈谈竞争。
AI模型是公共资源。GPT、Claude、Gemini——所有人都能用同样的模型。
模型不是竞争优势。从来不是。
真正的竞争优势是:谁能最快地把组织经验转化为AI可执行的系统。
想想这意味着什么。
公司A有十年的行业经验,但这些经验全在老员工的脑子里。AI对公司A来说就是一个通用工具——能写代码,但写出来的代码跟任何其他公司的AI写出来的没有本质区别。
公司B同样有十年的行业经验,但他们把这些经验编码成了系统原语、验证规则、架构约束、反面模式库。AI在公司B的系统中工作,就像一个浸泡了十年的资深员工——它自动遵循公司B独有的实践,产出的代码体现了公司B独有的工程哲学。
公司A的AI是通用AI。公司B的AI是定制AI。两者之间的差距,就是Harness Engineering的差距。
这不是关于谁用了更贵的模型。这是关于谁把自己的独特知识变成了系统。
再说直白一点:
模型是发动机。你的Harness是底盘、悬挂、轮胎、导航系统。同一台发动机装在不同的车身上,表现天差地别。
大多数公司在拼发动机。聪明的公司在造车身。
而造车身的能力——把组织经验系统化的能力——是不可复制的。因为每个组织的经验是独特的。这就是你的护城河。
不是AI的能力。是你驾驭AI的能力。
不是模型有多聪明。是你的系统有多聪明。
把所有的噪音去掉,AI对软件工程的影响可以用一句话概括:
代码生产的边际成本趋近于零。
从这一个事实出发,所有的推论都是必然的:
既然代码便宜了,那么决定代码质量的因素——原语、约束、验证——就变得更重要了。
既然AI能写代码了,那么人的价值就从“写代码”转移到“定义什么样的代码应该被写”。
既然产出变多了,那么过滤和审查——做减法——就成了最稀缺的能力。
既然模型是公共资源,那么竞争优势就在于你的Harness——你的系统、原语、验证循环、组织知识的编码化。
这就是Harness Engineering。不是一套工具。是一种思维方式。
它的核心信念是:
AI不需要被“管理”。它需要被“约束”在正确的结构中。
人的价值不在于做AI做不了的事。而在于定义AI应该做什么。
系统的质量不取决于最强的那个组件。取决于组件之间的边界定义得有多清晰。
不要追逐更强的模型。构建更好的系统。
模型会过时。系统会积累。
这是属于你的复利。
写代码的时代正在结束。设计系统的时代正在开始。你准备好了吗?
——Paul Graham 风格:小切口,大纵深
去年我看到一件很有意思的事。一个朋友的团队刚接入了最新的代码生成模型,生产力据说提升了三倍。但三个月后,他们的代码库变成了一团不可维护的意大利面。Bug数量翻了五倍,每次修一个地方就冒出两个新问题。他们困惑极了——AI明明写得又快又好,怎么整个系统反而更烂了?
我听完想了很久。后来意识到,这可能是我们这个行业正在经历的最重要的转型信号之一。
问题不在AI写的代码质量——事实上那些代码单独看都挺漂亮的。问题在于没有人为AI设计一个它能正确工作的环境。就好比你雇了一个打字速度极快的实习生,但你没告诉他公司的代码规范、架构约定、以及哪些地方绝对不能碰。他打得越快,灾难来得越快。
这就是我想聊的:软件工程正在发生的真正变化,不是“AI取代程序员”,而是工程师的核心工作从“写代码”变成了“设计让AI能正确工作的系统”。
让我先说说我观察到的一个规律。
每当一种新的生产力工具出现,人们总会经历同样的三个阶段。第一阶段是兴奋:哇,太快了!第二阶段是混乱:怎么到处都是问题?第三阶段是觉醒:哦,原来我需要换一种方式来使用这个工具。
打印机刚普及的时候,人们以为任何人都能做出漂亮的排版。结果满大街都是用Comic Sans写的通知单和用十种字体堆成的传单。后来人们才意识到,打印机放大的不是设计能力,而是设计决策——好的设计决策被放大成好的输出,坏的设计决策被放大成灾难。
AI写代码这件事,一模一样。
当你让AI在一个设计良好的系统里写代码,它会产出惊人的成果。当你让它在一个没有约束的真空里写代码,它会以极高的效率制造混乱。AI放大的不是代码能力,而是系统设计决策。
这就引出了一个有点反直觉的结论:AI越强大,系统设计就越重要。不是“不那么重要了”,而是“比以前任何时候都重要”。
我最近开始用一个词来描述这种新的工程实践:Harness Engineering——“驾驭工程”。
Harness这个词用得很准确。你不是在“使用”AI,你是在“驾驭”它。就像驾驭一匹马——马有自己的力量和速度,但如果没有缰绳和方向,那股力量可能会把你摔下悬崖。
Harness Engineering的核心,说白了就一件事:把隐性知识变成显性知识,把个人经验变成环境约束。
这话听起来很抽象,让我举个具体的例子。
假设你的团队有一条不成文的规矩:所有API的错误处理都要遵循一个特定的模式——先记日志,再包装错误信息,最后返回统一格式的响应。这条规矩存在于每个资深工程师的脑子里。新人来了,靠code review慢慢学会。大家都觉得这是“常识”。
但AI不知道这条“常识”。
你让它写一个新的API endpoint,它可能写出完全不同的错误处理方式——也许技术上完全正确,甚至在某些方面更“优雅”——但它和你系统里其他几百个endpoint的风格完全不一致。积累几十个这样的不一致,你的代码库就开始分裂了。
Harness Engineering要求你把这种隐性知识写出来。不是写在wiki里让人去读(人都不一定会读,何况AI),而是编码进系统本身——变成模板、变成linter规则、变成测试用例、变成AI的system prompt。让AI不可能不遵循它。
你可能会说:这不就是写文档和定规范吗?我们一直在做啊。
是的,但有个关键区别。以前你定规范,目的是让人理解和遵守。人是有判断力的,即使规范写得不够清晰,一个有经验的工程师也能“猜到”你的意思。但AI是字面意义上的“照章办事”。你说“保持简单”,它理解的“简单”和你理解的可能完全不同。
所以Harness Engineering的第一步,往往是一个痛苦但必要的过程:你必须把所有那些“大家都知道”的东西,用机器能理解的精确语言表达出来。 这个过程会迫使你重新审视很多从未被质疑过的假设,经常会发现那些“大家都知道”的东西,其实大家理解得都不一样。
说来讽刺——AI写代码这件事,反而帮助人类工程师更深刻地理解了自己的系统。
有些人听到这里会紧张:这是不是说程序员要失业了?
完全不是。实际上发生的事情更有意思:软件工程正在从“手艺”模式走向“工厂”模式,而人类在这个过程中是向上走,不是向外走。
让我解释一下这个比喻。
手艺模式是什么?就是一个熟练的工匠,从头到尾把一件东西做出来。他选材料、定尺寸、做切割、组装、打磨。每个步骤都需要他的判断和技能。这就是传统的软件工程——一个程序员拿到需求,设计方案,写代码,调试,部署。
工厂模式呢?不是说取消了工匠。而是把工匠的知识“编码”进了生产流程。流水线上的每个环节都内嵌了工匠的经验——这个模具的角度、那个焊接的温度、这个检测的标准。有了这些,普通工人(在我们的语境里就是AI)也能产出高质量的东西。
但谁在设计这些流程?谁在决定模具的角度?谁在制定检测的标准?
是工匠。他们从“做东西的人”变成了“设计做东西的方式的人”。他们不是被取代了,他们是升级了。
软件工程也一样。以前你一天写200行代码。现在AI一天写2000行。但那2000行代码的质量,完全取决于你设计的系统原语、约束边界、和验证流程。你的杠杆率提高了十倍——你的每一个设计决策,影响的代码量是以前的十倍。
这其实比以前的工作更难,也更有价值。
说实话,如果你仔细观察,最顶尖的工程师一直都在做这件事。他们最大的贡献从来不是自己写的那些代码,而是他们设计的那些架构、接口、约定——那些让其他所有人(现在包括AI)都能写出好代码的东西。Harness Engineering只是让这个趋势更加显性化了。
好了,现在让我聊聊一个很实际的问题:AI在“设计”这个环节上的一个严重缺陷。
我观察到一个反复出现的模式。你给AI一个任务,比如“设计一个用户通知系统”。它会给你一个非常完整、非常“工程化”的方案:抽象工厂模式、策略模式、观察者模式、一个消息队列、一个配置中心、一个可插拔的模板引擎……
看起来很专业,对吧?问题是:你的实际需求可能只是给用户发个邮件。
AI有一种系统性的“过度设计”倾向。 它在训练数据里见过太多复杂系统,对复杂性有一种本能的偏好。它不会“偷懒”——但在软件工程里,“偷懒”其实是一种美德。能用三行代码解决的问题,就不应该用一个框架。
这不是说AI不聪明。恰恰相反,这是因为AI太聪明了——它能想到所有可能的扩展场景、所有潜在的需求变化、所有“如果未来需要XXX”的情况。然后它会预防性地为所有这些可能性做设计。
但正如我们在YC反复告诉创业者的:不要解决你还没有的问题。 软件工程也是一样。那些“未来可能需要”的灵活性,在当下就是纯粹的复杂性负担。每一层不必要的抽象都是一笔技术债务,而且是那种最隐蔽的技术债务——因为它看起来很“干净”、很“架构化”。
这就是为什么人类审查在AI时代不是变得不重要了,而是变得至关重要了。
但这里有个微妙的地方。人类审查AI代码,最重要的工作不是“添加”——不是去补充AI遗漏的功能,不是去添加更多的边界情况处理。最重要的工作是做减法。
你知道米开朗基罗怎么说雕塑的吗?他说雕塑就是把多余的石头去掉,大卫一直就在那块大理石里面。对AI生成的代码做审查,本质上就是雕塑——你要把所有不该存在的东西去掉。
我见过一个很有经验的tech lead审查AI代码。他的修改记录几乎全是删除。删掉不必要的抽象层。删掉“以防万一”的配置选项。删掉只被使用一次的接口定义。删掉那些看起来很优雅但增加了理解成本的设计模式。
他说了一句很精辟的话:“AI写代码像一个刚毕业的名校优等生——技术上什么都会,但还没学会不做什么。”
“不做什么”这件事,可能是软件工程中最难学也最有价值的技能。它需要经验,需要对业务的深刻理解,需要判断力——哪些复杂性是值得承担的,哪些只是看起来很专业但实际上在添乱。
说实话,这个能力连很多人类工程师都不具备。但至少人类可以通过犯错来学习。AI不会——它没有“维护自己三年前写的烂代码”的痛苦记忆。所以它不会自然地发展出对不必要复杂性的厌恶感。
这就是人类审查的核心价值:做减法,而不是做加法。 你的工作不是让AI的输出“更完整”,而是让它“更精简”。不是问“还缺什么”,而是问“哪些可以去掉”。
这是一种全新的code review心态。以前review是在找bug、找遗漏。现在review更多是在找“过度”——过度设计、过度抽象、过度防御。
现在让我谈谈一个我认为被严重低估的概念:系统原语(System Primitives)。
什么是系统原语?就是你系统里最基础的构建块——你的数据模型定义方式、你的API设计规范、你的错误处理模式、你的日志格式、你的鉴权流程。这些东西就像建筑的地基和承重结构。
为什么它们在AI时代变得特别重要?因为AI会放大一切——好的和坏的。
想象一下。你定义了一个设计良好的数据库模型模式。AI每次生成新的数据模型时,都会遵循这个模式。一百个模型,全部一致,全部清晰。数据迁移和查询都变得可预测和可维护。好的原语被放大了一百倍。
反过来。你的数据库模型没有清晰的规范,AI第一次写了一个风格,第二次写了另一个,第三次又来一个。一百个模型,一百种风格。你的数据层变成了一个考古遗址,每一层代表一个不同的“文明”。坏的原语——或者说缺失的原语——也被放大了一百倍。
你的系统原语就是AI编程的倍增器。 好的原语,AI会生成海量一致的高质量代码。坏的原语,AI会高效地把混乱铺满整个代码库。
让我再展开说说这个逻辑。以前,一个工程师一天写200行代码。即使他的风格有点飘忽不定,影响也是有限的——200行的不一致性,人还能兜得住。但现在AI一天写2000行。如果这2000行代码风格不一致、模式不统一,你很快就会失去对代码库的控制。
所以在AI时代,系统原语是你最重要的杠杆点。你投入一小时来打磨一个好的原语,可能意味着AI在接下来的几个月里生成的代码都是高质量的。反过来,你偷懒跳过了这一步,可能意味着几个月后你面对的是一个无法维护的代码库。
这就是为什么我说,在Harness Engineering的世界里,设计一个好的错误处理模式,可能比写一百个API更有价值。
但什么是“好的”原语?这个问题比看起来要难。
让我先说说什么是假原语——或者说“假抽象”。
假抽象是那些看起来很像原语,但实际上并没有简化任何东西的东西。最常见的假抽象就是“为了抽象而抽象”——把一个只用一次的操作包装成一个通用接口,然后那个接口永远只有一个实现。
比如,你可能定义了一个INotificationService接口,然后只有一个EmailNotificationService实现。你跟自己说“未来可能会有短信通知、推送通知”。但如果“未来”在三年后都没有来,你这三年来一直在维护一个毫无价值的抽象层。
好的原语和假抽象的区别在于一个简单的测试:它是否真的减少了你需要思考的东西?
一个好的数据库查询模式,让你不用每次都思考连接池、超时、重试。它确实减少了认知负担。一个好的API响应格式,让前端不用每次都猜返回值的结构。它确实减少了沟通成本。
但一个“通用消息处理框架”如果只处理一种消息,它没有减少任何东西——反而增加了一层你需要理解的东西。
在AI时代,区分真假原语变得更加关键。因为AI会忠实地使用你给它的任何原语——不管是真的还是假的。假原语不会被AI“识破”。它会认真地、勤勉地使用你那个毫无必要的抽象层,在整个代码库里铺满间接引用和多余的接口。
所以在设计系统原语时,有一个我觉得非常实用的原则:如果你不能在一句话里解释清楚这个原语解决了什么问题,它可能就不是一个好的原语。
好的原语应该是显而易见的。当你看到它的时候,你的反应应该是“这当然应该是这样”,而不是“哦,这很巧妙”。巧妙的设计通常意味着有人在炫技,而炫技和好的工程是对立的。
让我列几个我见过的好原语的例子:
一个统一的API响应结构:成功就是{data: ...},失败就是{error: {code: ..., message: ...}}。简单到几乎无聊。但这个“无聊”的约定意味着整个系统的错误处理都是一致的,AI每次生成新API时都自然遵循这个模式。
一个标准化的数据库迁移流程:每次修改数据库结构,都生成一个带时间戳的迁移文件,包含up和down两个方法。这个模式存在了几十年,“无聊”到了极点。但它让数据库变更变得可追溯、可回滚、可自动化——对AI来说尤其友好,因为每次迁移都遵循完全相同的模板。
一个明确的目录结构约定:/routes放路由,/services放业务逻辑,/models放数据模型。不需要任何文档解释——结构本身就是文档。AI看到这个结构,就知道新代码应该放在哪里。
注意到共同点了吗?好的原语都很无聊。 它们不展示任何人的聪明才智。它们只是让事情变得可预测。而可预测性,在AI时代,就是最大的价值。
因为AI最擅长的就是在给定规则下执行。规则越清晰、越一致,AI的输出就越好。好的原语就是最好的规则。
让我接着说一个我觉得很多人还没充分意识到的真相:验证循环比更强的模型重要得多。
这句话值得反复咀嚼。
现在业界有一种迷思:AI生成的代码不够好?等下一代模型就好了。GPT-6、Claude-5、Gemini-4——总有一个足够强大的模型能解决所有问题。
这是一种非常危险的想法。
原因很简单:再强大的模型也无法保证每次输出都是正确的。这不是当前技术的局限,这是这类系统的本质特征。语言模型是概率性的——它给你的是“最可能正确”的答案,而不是“保证正确”的答案。在某些领域,“最可能正确”就够了。但在软件工程里,一个“几乎正确”的程序就是一个错误的程序。代码要么能跑,要么不能。
所以,与其等待一个“足够完美”的模型(它永远不会来),不如投资建设验证循环——让AI的每一次输出都经过自动化的检查。
什么是验证循环?就是AI生成代码后,自动触发的一系列检查:
类型检查通过了吗?Lint规则通过了吗?单元测试通过了吗?集成测试通过了吗?和现有代码的接口兼容吗?符合我们的架构规范吗?
如果任何一个检查失败,AI会得到反馈,然后重新生成。这个循环可以跑很多轮——直到所有检查都通过。
这里的关键洞察是:一个中等能力的模型加上一个好的验证循环,几乎总是比一个超强模型裸奔要好。
为什么?因为验证循环能捕获的错误类型远远超过模型能力的提升。一个GPT-6裸奔可能95%的时候给你正确答案。但那5%的错误分散在代码库的各个角落,你没有任何系统性的方式来发现它们。而一个GPT-4加上完善的验证循环,可能能捕获99%的错误——因为检查是确定性的、全面的、不会遗漏的。
这就像自动驾驶。你可以投入所有资源来训练一个“完美”的驾驶模型。但更有效的策略是:一个不错的驾驶模型,加上车道保持系统、碰撞预警、自动刹车——多层验证和保护。没有哪个单独的组件是完美的,但它们组合在一起,比任何单独的“完美模型”都安全。
我见过的最高效的AI编程团队,都不是在用最先进的模型。他们用的是最成熟的验证体系。他们的CI/CD管道里有几十个自动化检查,AI生成的每一行代码都要通过所有检查才能合并。模型的选择反而是次要的——因为验证循环会兜住大部分错误。
所以如果你问我,团队应该把时间花在哪里——是研究最新的模型,还是完善验证循环——我的回答毫不犹豫:投资验证循环。 模型会不断升级,但好的验证体系是永恒的基础设施。每一个你今天写的测试,明天还会继续保护你的代码。
说到验证循环,让我分享一个我特别喜欢的观察:每一个bug都在揭示一条未被写下的规格说明。
这句话不是我说的,但我觉得它非常深刻。尤其在AI编程的语境下。
想想看。AI写了一段代码,出了一个bug。这个bug是怎么来的?不是因为AI“不小心”——AI没有“不小心”这回事。它是在忠实地执行它理解到的规则。bug的出现,说明AI理解的规则和你期望的规则之间有差距。
而那个差距,就是一条你以为是“显而易见”但从未明确表达的规格说明。
举个例子。AI生成了一个用户注册的函数。一切都好,除了一件事:它没有检查邮箱格式。你可能觉得“检查邮箱格式”是常识。但你从未在任何地方明确规定“所有用户输入都必须经过格式验证”。AI不会假设没有被明确要求的事情。
当你修复这个bug时,你不应该只是加一个邮箱验证。你应该退后一步,问自己:这个bug揭示了什么未被写下的规则? 在这个例子里,答案可能是“所有用户输入都必须经过格式验证”。把这条规则写进你的系统规范。然后AI在未来处理所有用户输入时,都会自动包含格式验证。
一个bug修复了一个bug。一条规则修复了一类bug。
这是一种完全不同的debug心态。传统的debug是“找到问题,修复问题”。Harness Engineering的debug是“找到问题,发现它揭示的隐性规则,把规则显性化”。每一个bug都是一次学习机会——不是学习“这段代码怎么修”,而是学习“我的系统规范里还缺什么”。
我见过一些团队维护一个“规则日志”——每次AI的bug被修复时,都记录下这个bug揭示的规则。几个月后,这个日志变成了一份非常有价值的文档:它是团队隐性知识的明确化,是系统边界条件的完整目录。而且这份文档是“活”的——它在持续增长,每个bug都让它更完整。
这就是Harness Engineering最优雅的地方:它把失败转化为系统改进。不是“AI又犯错了”,而是“我们又发现了一条需要明确的规则”。失败不是挫折,而是进步的信号。
聊了这么多概念,让我说说更宏观的视角:人类工程师的角色到底在怎样变化。
传统的比喻是:程序员是“码农”——写代码的人。更好的比喻可能是“工匠”——设计并制作软件的人。但在AI时代,我觉得最准确的比喻是:“边界定义者”。
什么意思?
软件系统归根结底就是一系列的边界。数据的边界:什么样的数据是合法的,什么不是。行为的边界:系统在这种情况下应该怎么做,在那种情况下应该怎么做。安全的边界:谁能访问什么,不能访问什么。性能的边界:响应时间不能超过多少,内存不能用超过多少。
以前,工程师既定义这些边界,又在边界内填充实现。现在,AI越来越能处理“填充”的部分。但“定义边界”这件事——决定什么应该存在,什么不应该存在,什么是正确的行为,什么是不可接受的——这依然是、而且越来越是人类的工作。
因为定义边界需要理解业务。需要知道用户真正想要什么(而不是他们说他们想要什么)。需要在矛盾的需求之间做权衡。需要判断什么复杂性值得承担,什么可以省略。这些都是AI目前做不到的事情——不是因为技术限制,而是因为这些判断需要对“什么是重要的”有一种深层的、基于经验的直觉。
所以,如果你是一个工程师,想知道自己在AI时代的价值在哪里,答案就是:你定义边界的能力。
你能多准确地定义出“正确”的含义?你能多清晰地划定系统的责任范围?你能多精确地表达出“这个可以简化,那个不能”的判断?
这些能力不是通过刷LeetCode培养的。它们是通过多年的工程实践、通过维护大型系统、通过在生产环境里经历各种灾难培养出来的。AI可能会让“写代码”这个技能的价值下降,但“定义边界”这个技能的价值只会上升。
这也解释了为什么经验丰富的工程师在AI时代反而更值钱了。他们脑子里的那些“隐性知识”——那些“说不清但就是知道”的东西——正是AI最需要被告知的东西。一个有二十年经验的工程师,他的价值不在于他能写多快的代码,而在于他知道哪些代码不该写。
好了,让我换个话题聊聊情绪管理。因为我觉得很多程序员现在过得很焦虑,这种焦虑是没有必要的。
每隔几个月就有一个新的爆炸性标题:“AI将在X年内取代所有程序员!”“这个新模型可以独立完成整个项目!”“编程已死!”
我理解这种标题为什么会让人焦虑。但让我告诉你一些经验:任何说“X已死”的人,通常对X没有深入的理解。
编程没有死。就像电子表格没有杀死会计师,ATM机没有杀死银行柜员(实际上柜员数量在ATM普及后反而增加了),AI也不会杀死程序员。
但工作的内容确实在变。这是关键——你需要适应变化,但不需要恐惧变化。
让我给你一个简单的思维框架来处理每一个炒作口号。
第一,问自己:“这个demo是在理想条件下跑的,还是在真实生产环境里跑的?” 绝大多数令人震惊的demo都是精心挑选的最佳案例。在真实环境里——有遗留代码、有奇怪的业务逻辑、有不合理的性能要求、有十七个微服务互相调用——情况完全不同。
第二,问自己:“这个能力是AI独立完成的,还是有人在背后做了大量设计和引导工作?” 我见过很多“AI独立完成整个项目”的案例,仔细一看,有个资深工程师花了三天设计系统架构、定义接口、编写测试用例、设置验证流程。AI完成了编码部分——但那只是整个工程工作的一部分。
第三,问自己:“这个变化是淘汰了人,还是改变了人的工作内容?” 通常是后者。Excel没有让人失业,它让人从手动计算转向了数据分析。AI也不会让程序员失业,它让程序员从写代码转向设计系统。
所以当你看到下一个“编程已死”的标题时,深呼吸。然后去完善你的系统原语。
说了很多理念,现在让我聊聊实操。一个普通团队,明天就可以开始做的事情是什么?
我见过很多团队被Harness Engineering这类概念搞得很困惑——觉得要做的事情太多了,不知道从哪里开始。所以让我给一个非常务实的“工作流操作系统”。
第一步:审计你的隐性知识。
花一周时间,让团队里每个人写下他们在code review时经常给出的反馈。“不要这样处理错误”、“这个地方应该加日志”、“这种命名不符合我们的规范”——把所有这些收集起来。你会发现很多重复的主题。这些重复出现的主题,就是你最重要的未被文档化的规则。
第二步:把最高频的规则变成机器可执行的约束。
不是写成文档——文档没人读,AI也不一定会遵循。而是变成lint规则、变成测试用例、变成代码模板、变成AI的system prompt。你要确保这些规则是不可能被忽略的。
比如,如果你的团队规定所有API都必须返回统一格式的响应,那就写一个中间件来强制执行,写一个测试来验证,写一个模板让AI生成新API时自动使用。三重保障。
第三步:建立验证循环。
从最简单的开始:类型检查和lint。然后逐步添加:单元测试、集成测试、架构合规检查。不需要一次到位——任何一个验证检查都比没有好。
关键是要让验证循环自动触发。不要依赖人记得去跑测试。AI每次生成代码,验证循环就应该自动启动。如果检查失败,AI自动收到反馈并重试。人类只需要在验证循环无法自动解决的问题上介入。
第四步:维护“规则日志”。
每次你发现AI犯了一个你认为“不应该犯”的错误,问自己:是哪条规则没被明确?把这条规则记录下来,然后决定如何将它编码进系统。这个日志会越来越长,你的系统也会越来越健壮。
第五步:定期回顾和精简。
每个月回头看看你的规则和原语。有没有过度设计的?有没有互相矛盾的?有没有已经不再需要的?规则系统也需要“做减法”——不然它本身也会变成不可维护的技术债务。
这五步不需要一次全部实施。你可以先做第一步和第二步,运行两周,看看效果,然后再添加后面的步骤。关键是开始做——不完美的开始永远好过完美的计划。
最后让我说说我觉得这一切意味着什么——从更长远的视角。
在接下来的几年里,AI模型会继续快速进步。更大的上下文窗口、更强的推理能力、更好的代码生成质量。这些进步是不可避免的,而且速度可能超出大多数人的预期。
但有一件事不会因此改变:AI的输出质量永远受限于输入它的系统设计质量。 再强的模型,在一个混乱的系统里也只会产出更多的混乱。再弱的模型,在一个设计精良的系统里也能产出可用的代码。
这意味着什么?
这意味着真正的竞争优势不是谁用了最新的模型,而是谁最快地把组织经验转化为AI可执行的系统。
想想看。两个公司,用同样的AI模型。公司A有二十年的行业经验,但这些经验全在老员工的脑子里,从来没有被系统化。公司B只有五年经验,但他们花了大量时间把每一条学到的教训都编码进了他们的系统原语、验证循环、和AI工作流。
哪个公司的AI编程效率更高?
毫无疑问是公司B。因为AI不能读你员工的脑子。它只能使用被明确表达出来的知识。二十年的隐性经验,如果不被显性化,对AI来说就是零。五年的经验,如果被完整地编码进系统,对AI来说就是一座金矿。
这就是Harness Engineering的终极意义:它是把组织智慧从人的脑子里解放出来,编码进系统本身的过程。
这个过程并不容易。它需要你坦诚地面对很多从未被质疑过的假设。它需要你承认很多“常识”其实并不是常识。它需要你投入时间去做那些看起来“不是在写代码”的工作——定义规范、设计模板、建设验证流程。
但这些工作的杠杆率是惊人的。一个好的系统原语可以影响AI生成的上万行代码。一个好的验证循环可以在每天的每一分钟捕获错误。一条被明确表达的规则可以永远防止一类bug。
我们正处在软件工程历史上一个独特的转折点。AI不会取代工程师——它会让工程师的工作变得更加有趣、更加有价值、也更加困难。因为设计系统比写代码难得多。
但说实话?设计系统也比写代码有趣得多。
如果你只记住这篇文章的一件事,我希望是这个:
别再问“AI能不能写代码”了。 当然能,而且只会越来越好。真正值得问的问题是:“我给AI搭建的系统,值不值得它在里面高效运转?”
因为到最后,决定输出质量的不是AI的能力上限,而是你为它定义的系统边界。你的原语越好,AI越强大。你的验证越严密,你就越能信任AI的输出。你把越多的隐性知识变成显性规则,AI就越像你团队里一个真正可靠的成员。
工程师的价值不会消失。它只是从“我能写什么代码”变成了“我能设计什么系统”。
而这,才是我们这个行业真正令人兴奋的地方。
今天我想跟你聊一个正在发生的、但大多数人还没看清的变化。
这个变化不是“AI能不能写代码”——这个问题已经没有悬念了。真正的变化是:当AI已经能写代码的时候,人类工程师到底应该干什么?
过去两年,关于AI编程的讨论几乎都集中在一个维度上:AI的代码写得好不好?能不能通过测试?能不能替代初级程序员?这些问题当然重要,但它们都指向同一个隐含假设——编程的核心是“写代码”,谁写得更快更好,谁就赢了。
但如果你真正在一线用AI做过工程,你会发现一个完全不同的真相:AI写代码的能力已经不是瓶颈,瓶颈是你给AI搭建的工作环境。 同样一个Claude或GPT,在一个设计良好的系统里能输出惊人的生产力,在一个混乱的代码库里则会制造灾难。
这就引出了一个全新的工程学科,有人把它叫做 Harness Engineering——驾驭工程。今天这篇文章,我就来给你拆解这个概念,以及它背后一整套关于“人机协作”的新思维框架。
让我先给你讲一个真实的场景。
一个资深工程师,用AI助手在一个老项目里加一个新功能。他给AI写了一段很清晰的需求描述,AI也很快生成了代码。但生成出来的代码用了项目里早已废弃的旧API,引入了三个不必要的依赖,还创建了一个跟现有架构风格完全不搭的新模块。
代码能跑吗?能跑。测试能过吗?能过。但任何一个了解这个项目的人看一眼就知道:这不对。
问题出在哪?不是AI的能力不行,而是AI根本不知道这个项目的“潜规则”——哪些API已经废弃了、团队偏好什么样的架构风格、哪些依赖是被明确禁止的、模块之间的边界应该画在哪里。
这些东西,在传统软件工程里,存在于资深工程师的脑子里。新人入职靠口口相传,靠code review时被老人敲打,靠在项目里摸爬滚打三个月慢慢“悟”出来。
大多数人以为AI编程的挑战是“让AI写出更好的代码”,其实真正的挑战是让AI获得那些从来没被写下来的知识。
这就是 Harness Engineering 的核心命题:把隐性知识变成显性规则,把个人经验变成系统环境。
你不是在训练AI,你是在建设一个让AI能正确工作的“工厂”。AI是工厂里的机器,而你是设计工厂流水线的工程师。机器的能力固然重要,但流水线的设计决定了最终产出的质量。
这个类比非常关键,让我展开说说。
软件工程的历史上有一个长期的张力:它到底是一门手艺(craft),还是一种工业生产(manufacturing)?
敏捷开发运动(Agile)强调“个体与互动高于流程与工具”,整个文化崇尚工匠精神——好的程序员就是好的手艺人,写出优雅的代码就是最高追求。这种文化有它的道理,在过去几十年里也确实催生了伟大的软件。
但AI的到来正在改变这个等式。
想象一下:如果你有一个极其高效但完全没有“品味”的助手,能以你十倍的速度写代码,但完全依赖你给它的指令和环境来决定写什么样的代码——这时候,你的工作重心自然会从“亲手写代码”转移到“设计这个助手的工作环境”。
这正是软件工程正在经历的转变:从手艺模式(craft mode)转向工厂模式(factory mode)。
但这里有一个极其重要的澄清:工厂模式不意味着人类被降级了,恰恰相反,人类在升级。
在手艺模式里,一个高级工程师的时间分配可能是这样的:60%写代码,20%做设计,10%做review,10%做沟通。在工厂模式里,这个分配会变成:10%写代码(甚至更少),30%做系统设计,30%做review和质量把控,30%做规则制定和环境建设。
人类从“生产线上的操作工”变成了“生产线的设计师”。这是向上移动,不是被挤出去。
Kent Beck——极限编程(XP)的创始人,软件工程界的教父级人物——最近说了一句话,我觉得非常到位。他说:“我现在90%的代码都是AI写的,但我花在思考架构和设计上的时间比以前多了三倍。”
这不矛盾。当执行层面被自动化之后,设计层面的重要性反而被放大了。一个好的架构设计,在AI的放大效应下,能产生十倍的生产力提升;一个糟糕的架构设计,在AI的放大效应下,会产生十倍的混乱。
划重点:AI不是取代人类工程师,而是把工程师的杠杆率大幅提高了。杠杆率越高,支点的位置就越重要。而支点,就是你设计的系统。
现在让我们进入一个更具体的问题:当你让AI参与系统设计时,会发生什么?
答案可能出乎你意料:AI有一种强烈的过度设计倾向。
这不是bug,这是AI生成模型的本质特征。大语言模型的训练目标是“生成合理的、全面的回答”。当你问它“设计一个用户认证系统”时,它会把它见过的所有“好的实践”都堆上去——OAuth2.0、JWT、多因素认证、角色权限系统、会话管理、令牌刷新、安全审计日志……
每一项单独拿出来都是合理的。但对于一个只有三个开发者、服务五百个用户的内部工具来说,这就是灾难性的过度设计。
我把这个现象叫做 “AI的加法本能”。AI天然倾向于往系统里加东西,因为在它的训练数据里,“全面”通常是被奖励的,“简单”则往往不够引人注目。没有哪篇技术博客会因为“我们什么都没加”而获得点赞。
但任何有经验的工程师都知道:好的设计,核心能力是做减法。
Dieter Rams说“好的设计是尽可能少的设计”(Good design is as little design as possible)。这句话在软件工程里同样成立,甚至更加成立——因为软件系统的复杂度增长不是线性的,而是指数级的。每多加一个组件,系统的交互路径就多出好几条,未来的维护成本就多出好几倍。
所以,在人机协作的新范式里,人类review的核心价值不是“检查AI写的代码对不对”,而是“把AI想加的东西砍掉”。
这是一个认知上的重大转变。传统的code review是“找到遗漏的东西,补上去”——你漏了错误处理,你忘了边界条件,你没考虑并发。但AI时代的review恰恰相反:AI什么都考虑到了,你的工作是判断哪些不需要考虑。
一个优秀的 Harness Engineer 做review时,最常说的话不是“你漏了什么”,而是“这个不需要”、“删掉这层抽象”、“这里不用这么复杂”。
让我给你一个具体的例子。假设你让AI设计一个配置文件的读取模块。AI可能会给你生成这样一套东西:一个抽象的ConfigProvider接口、一个FileConfigProvider实现、一个RemoteConfigProvider实现、一个ConfigCache缓存层、一个ConfigValidator验证层、一个ConfigMerger合并层……
而一个有经验的工程师看了会说:我们现在只需要从一个JSON文件里读配置。 一个函数,二十行代码,搞定。等哪天真的需要远程配置了,再加不迟。
这就是 YAGNI 原则——You Aren’t Gonna Need It。在AI时代,这个原则比任何时候都更重要,因为AI让“加东西”的成本变得极低,但过度设计的代价并没有降低。
划重点:AI让你能更快地搭建复杂系统,但“能搭建”不等于“应该搭建”。人类的核心判断力在于知道什么时候说“够了”。
现在我要引入今天最重要的一个概念:系统原语(System Primitives)。
什么是系统原语?简单说,就是你系统里最基础的构建模块——你的数据模型是怎么定义的、模块之间是怎么通信的、错误是怎么处理的、状态是怎么流转的。这些底层的设计决策,就是你系统的“原语”。
为什么这个概念在AI时代特别重要?因为AI有一个特性:它会忠实地放大你的原语——不管是好的还是坏的。
让我用一个类比来解释。假设你在盖一栋大楼。原语就相当于你选择的建筑材料和基本结构方式——是用钢结构还是砖混结构,是框架体系还是剪力墙体系。AI相当于一个超级施工队,能极快地按照你的图纸把楼盖起来。
如果你的基本结构设计是合理的,AI会飞速地把一栋好楼盖起来。但如果你的基本结构有问题——比如承重设计不合理——AI也会飞速地把一栋危楼盖起来。而且因为AI盖得太快了,等你发现问题的时候,可能已经盖了二十层了。
在没有AI的时代,糟糕的原语造成的伤害是线性的——因为人写代码的速度有限,问题暴露得也快。但在AI时代,糟糕的原语造成的伤害是指数级的——因为AI会以极高的速度在错误的基础上不断堆砌。
所以,选择正确的系统原语,在AI时代变成了一项关键的战略能力。
让我给你举几个好原语和坏原语的对比:
好的原语:明确的错误类型体系。 比如你定义了一套清晰的错误分类——NetworkError、ValidationError、AuthenticationError——每种错误都有明确的处理方式和传播规则。AI在这套体系下生成的代码会自动遵循你的错误处理模式,每个新模块都会正确地抛出和捕获对应类型的错误。错误处理的一致性在整个系统里自动传播。
坏的原语:万能的BaseService基类。 你定义了一个巨大的BaseService,里面塞了日志、缓存、权限检查、事务管理、事件发布……所有service都继承它。AI会忠实地让每个新service都继承这个BaseService,哪怕某个service只需要其中5%的功能。结果就是整个系统里每个模块都背着一个巨大的、不必要的依赖包袱,而且任何对BaseService的修改都会波及所有模块。
这引出了一个重要的区分:好的原语 vs. 假的抽象。
好的原语有几个特征:
而假的抽象恰恰相反:
划重点:在AI时代,选择系统原语就像选择基因——AI会忠实地复制和表达你的基因,不管是好基因还是坏基因。投入时间在原语设计上,是杠杆率最高的工程投资。
现在让我给你说一个很多人忽略的真相:在实际工程中,改善验证循环的收益,几乎总是大于升级到更强模型的收益。
这是一个反直觉的结论。我们的直觉是:如果AI写的代码有bug,那应该用一个更聪明的AI。就像考试考差了,应该请一个更好的家教。
但现实中的数据告诉我们一个不同的故事。
假设你有一个AI编程助手,生成代码的首次正确率是70%。也就是说,每生成10段代码,有7段是对的,3段有问题。
方案A:升级到一个更强的模型,首次正确率提升到85%。
方案B:保持当前模型,但加入一个自动化的验证循环——类型检查、单元测试、集成测试、静态分析——让AI在提交前自己跑一遍,发现问题自己修。
在真实的工程环境中,方案B几乎总是更优的选择。为什么?
第一,验证循环的收益是可叠加的。 一层验证(类型检查)可能把错误率从30%降到15%。再加一层(单元测试)降到5%。再加一层(集成测试)降到1%。每一层都是独立的安全网,效果是乘法叠加的。而模型能力的提升,从70%到85%,你花了巨大的算力成本,但错误率只从30%降到了15%——跟加一层验证的效果一样。
第二,验证循环提供确定性保障。 模型的能力提升是概率性的——它“通常”写得更好,但你永远不知道哪次会翻车。而验证循环提供的是确定性的——类型检查通过了就是通过了,测试跑过了就是跑过了。在工程中,确定性的保障远比概率性的提升更有价值。
第三,验证循环产生有用的反馈信号。 当验证失败时,错误信息本身就是一条宝贵的线索,告诉AI“哪里不对、怎么不对”。AI可以利用这个信号来修正自己的输出。而“用更强的模型”则没有这种反馈机制——它只是“希望”一步就做对。
这就像教育领域的一个经典研究发现:频繁的小测验比偶尔的大考更能提高学习效果。 原因类似——小测验提供了即时反馈,让学习者能及时纠正错误,而大考只是一个最终评估。
所以,Harness Engineering 的一个核心原则是:与其追求完美的AI,不如构建完善的验证循环。
一个实用的验证循环通常包括这些层次:
注意这个层次结构:越往下,成本越高,越不应该频繁使用。越往上,成本越低,应该尽可能自动化。 好的Harness Engineering是让AI在提交到人类review之前,先自己跑完前四层验证。这样到达人类手里的代码,至少在技术层面已经是基本正确的了,人类只需要关注设计层面的判断。
划重点:不要迷信“更强的模型”,要投资“更好的验证循环”。在工程中,多层薄保障的叠加效果远优于单层厚保障。
这是 Harness Engineering 里我最喜欢的一个观点,也是最具洞察力的一个框架。
当AI写出一段有问题的代码时,大多数人的第一反应是:“AI搞错了。”然后修掉bug,继续前进。
但一个真正理解Harness Engineering的工程师会问一个不同的问题:“为什么AI会搞错?它缺少了什么信息?”
答案几乎总是:因为有一条规则、一个约束、一个偏好,从来没有被明确地写下来。
AI用了一个废弃的API?——因为“这个API已废弃”这条信息只存在于某个工程师的脑子里,从来没有被标记在代码里或者写进文档里。
AI创建了一个不符合项目风格的模块结构?——因为“我们项目的模块应该这样组织”这条规则从来没有被明确制定过,只是一种团队的默契。
AI引入了一个不该用的依赖?——因为“我们不用这个库,因为它有已知的安全漏洞”这条信息只在去年的某次会议上口头提过。
看到了吗?每一个AI的“错误”,本质上都是一条未被写下的规范。 AI只是把你系统中的信息缺口暴露了出来。
这就像一面镜子。在没有AI的时代,这些缺口被人类的“默契”和“经验”所弥补,所以你感觉不到它们的存在。但AI没有“默契”,它只看你明确告诉它的东西。所以它会毫不留情地踩中每一个信息缺口。
理解了这一点,你对AI犯错的态度就会发生根本性的转变:AI的每个错误,都是一次完善系统规范的机会。
具体来说,当你发现AI犯了一个错误时,正确的做法不只是修掉这个bug,而是要走完一个完整的闭环:
我把这个叫做 “Bug驱动的规范完善”(Bug-Driven Specification)。
这个过程有一个惊人的副作用:你的系统文档和规范会变得越来越完善。 不是因为有人刻意去写文档(我们都知道没人爱写文档),而是因为每次AI犯错,你都不得不把一条隐性知识显性化。
三个月后,你会发现你的项目拥有了前所未有的完善规范——所有的API约定、架构原则、编码规范、禁止事项,都被明确地记录了下来。而这些规范不只是对AI有用,对新加入团队的人类工程师同样有巨大价值。
划重点:不要把AI的错误看成AI的问题,把它看成你的系统信息缺口的暴露。每修复一个AI的bug,就完善一条系统规范。长期来看,这是在建设一个越来越完善的“知识库”。
到这里,我想你已经能看出来一个更大的图景了:人类工程师的角色定义正在发生根本性的变化。
传统上,我们用“写代码”来定义工程师。一个好工程师就是一个能写出好代码的人。面试考算法,评绩效看代码产出,晋升看技术方案的深度。
但在AI时代,这个定义正在松动。如果AI能写出90%质量可接受的代码,那“写代码的能力”就不再是核心竞争力。这不是说写代码不重要了——就像你仍然需要识字才能做编辑,你仍然需要懂代码才能做好工程师——但它不再是定义你价值的核心要素。
那什么是?
我认为,未来工程师的核心能力是定义边界。
这里的“边界”包含多个层次:
系统的边界:哪些模块应该存在,它们之间的职责如何划分,数据如何流动。这就是架构设计。在AI时代,这项能力的重要性被急剧放大,因为AI会忠实地在你画好的边界内工作——边界画对了,AI的产出就是对的。
规则的边界:什么能做,什么不能做。哪些模式是被鼓励的,哪些是被禁止的。这些规则越明确,AI的行为就越可预测。在传统开发中,这些规则大多是隐性的;在AI时代,它们必须被显性化。
质量的边界:什么程度的代码质量是可以接受的,什么是不可以的。这不是一个二元判断,而是一个需要根据场景灵活调整的标准——对一个核心支付模块和一个内部管理后台,你的质量标准不应该相同。人类需要做的是为不同的场景设定合适的质量阈值。
复杂度的边界:系统可以有多复杂。这是前面说的“做减法”能力的延伸。你需要不断地判断:这个复杂度是必要的还是多余的?这个抽象层是解决了问题还是制造了问题?这个功能是现在需要的还是“将来可能需要”的?
决策的边界:哪些决策AI可以自主做,哪些需要人类参与。这是一个元层面的边界设定。比如,AI可以自主决定一个函数的内部实现,但不可以自主决定是否引入一个新的外部依赖。AI可以自主修复一个单元测试的失败,但不可以自主修改公共API的签名。
定义这些边界,需要的不是“写代码快”的能力,而是对系统全局的理解、对业务需求的判断、对技术取舍的经验、以及对复杂度的直觉。
这些,恰恰是AI最不擅长的,也是资深工程师最擅长的。
划重点:未来的工程师不是“写代码的人”,而是“定义边界的人”。你的工作是画框,AI的工作是在框内填色。框画得好,整幅画就好。
好,让我们暂时从技术层面退一步,聊聊心态。
过去两年,你一定听过无数让人焦虑的口号:
“不会用AI的程序员将被淘汰!”
“AI编程将取代80%的开发者!”
“未来只需要10%的工程师!”
“不学AI,就会失业!”
每一条都引人注目,每一条都制造焦虑,但坦率地说——每一条都是过度简化的、不负责任的判断。
让我给你一个看待这些口号的框架。
首先,区分“任务自动化”和“岗位消失”。 AI确实在自动化编程中的很多具体任务——写样板代码、写测试、做代码转换、修简单bug。但“自动化某些任务”和“消灭整个岗位”之间有巨大的差距。ATM机自动化了柜台取款,但银行柜员并没有消失——他们的工作内容变了,从点钞变成了理财咨询。同样的逻辑适用于工程师。
其次,理解“生产力悖论”。 历史上,每一次自动化工具的出现,最终都增加了而不是减少了对相关技能人才的需求。Excel没有消灭会计,反而让更多人需要处理数据。网页编辑器没有消灭网页设计师,反而创造了整个Web行业。同样的,AI编程工具大概率会扩大对软件工程能力的整体需求——因为当写代码变得更容易,更多的问题就会被用软件来解决,从而需要更多的人来设计、审核和维护这些系统。
第三,关注“哪些能力变得更重要”,而不是“哪些岗位会消失”。 这是一个更有建设性的思考方向。我前面已经分析过了:系统设计能力、边界定义能力、做减法的能力、规范制定能力——这些都在变得更重要。如果你在这些方面持续提升自己,你就不需要为那些口号焦虑。
第四,记住 Amara 定律。 Roy Amara说过:我们往往高估技术的短期影响,低估技术的长期影响。AI编程的短期影响可能没有口号说的那么剧烈——大多数公司的AI采用速度远比你想象的慢。但长期来看,它对工程师角色的重塑可能比任何人想象的都更深远。所以既不需要恐慌性地转型,也不要掉以轻心。
我的建议是:把焦虑转化为好奇心。 不要问“AI会不会取代我”,问“AI能帮我做什么我以前做不了的事”。不要问“我该不该学AI工具”,问“哪个AI工具能让我在当前的工作中产生最大的杠杆效应”。
焦虑是消耗性的,好奇心是建设性的。
划重点:面对AI焦虑口号,最好的心态不是恐慌,也不是否认,而是保持清醒的分析能力。看穿过度简化的判断,关注真正重要的能力转移。
理论说够了,让我给你一套可以落地的实操框架。
不是每个团队都是Google或OpenAI,不是每个工程师都需要从零构建AI基础设施。对于大多数“普通团队”来说,Harness Engineering的落地可以分为这样几个阶段:
这是起点,也是杠杆率最高的一步。
把你们团队脑子里的隐性知识写下来。具体包括:
写这些东西的目标不是给人看的文档(虽然它对人也有用),而是给AI看的上下文。你需要把这些规范放到AI能读到的地方——项目的README、架构文档、AI工具的配置文件(比如Cursor的.cursorrules、GitHub Copilot的指令文件)。
有了规范,下一步是让验证自动化。
前面说了“Bug驱动的规范完善”,这里是落地方法:
随着验证循环的完善,你会越来越清楚地看到:哪些任务AI可以自主完成,哪些需要人类参与。
这个分类不是固定的——随着你的验证循环越来越完善、规范越来越清晰,很多黄色区域的任务会逐渐变绿。
划重点:不要想一步到位,分阶段推进。规范显性化是起点,验证循环是核心,反馈闭环是持续改善的引擎。最终目标是建立一个越来越高效的人机协作系统。
让我用一个更大的视角来收束今天的讨论。
很多人问:在AI时代,工程团队的竞争优势是什么?
最直觉的回答是“使用最好的AI模型”或者“雇最聪明的工程师”。但如果你理解了今天的讨论,你会意识到这两个答案都不够好。
AI模型是公共资源——GPT、Claude、Gemini,任何人都能用,你能用的模型你的竞争对手也能用。模型的能力差异在快速收敛,今天模型A比模型B强10%,下个月可能就反过来了。所以,模型不构成持续的竞争优势。
聪明的工程师固然重要,但个人的聪明是不可规模化的。一个天才工程师的知识和经验存在于他的脑子里,他离职了就带走了。而且在AI时代,原始的编码能力带来的优势正在缩小。
真正的竞争优势在于:谁能最快地把组织的经验转化为AI可以执行的系统。
让我解释这句话。
每一个组织都有独特的经验积累——对业务领域的理解、对用户需求的洞察、对技术选型的经验、对踩过的坑的记忆。这些经验目前主要存在于人的脑子里、会议记录里、零散的文档里、Slack的聊天记录里。
如果你能把这些经验系统化地提取出来,转化为:
那么AI就能利用这些经验来产生高质量的输出。这相当于你把整个组织的智慧“编码”到了你的工作环境中。
而这正是 Harness Engineering 的终极目标。
想象两个竞争的公司,同样用GPT-5来做开发。A公司的工程团队花了三个月把他们的架构经验、编码规范、领域知识全部系统化了,AI在他们的环境里能自主完成70%的开发任务,而且质量一致。B公司还是老模式,AI只是工程师个人的“代码辅助工具”,每次使用都需要工程师手动提供大量上下文。
半年后,A公司的开发效率是B公司的五倍。不是因为A公司用了更好的AI,而是因为A公司建设了更好的Harness。
这就像工业革命时期:最终赢得竞争的不是拥有最好蒸汽机的工厂,而是建设了最好生产线的工厂。蒸汽机是通用技术,生产线是独特的竞争优势。
同理,AI模型是通用技术,你的Harness是独特的竞争优势。
让我总结一下今天的核心框架。
如果只能记住三句话,请记住这三句:
第一,AI改变的不是“谁写代码”,而是“工程师的核心价值在哪里”。 价值不再在于写代码本身,而在于设计让AI正确工作的系统——包括原语、规范、边界和验证循环。
第二,好的系统原语 + 完善的验证循环 > 更强的AI模型。 不要追逐最新最强的模型,要投资构建最好的工作环境。模型会不断变化,但好的工程体系会持续累积价值。
第三,最大的竞争优势不是AI本身,而是谁能最快地把组织经验转化为AI可执行的系统。 这是Harness Engineering的终极命题,也是未来工程团队的核心能力。
软件工程正在经历一次深刻的范式转移。这次转移不是让工程师失业,而是让工程师的角色升级——从“写代码的人”变成“设计系统的人”,从“执行者”变成“架构师”,从“手艺人”变成“工厂设计师”。
在这个转变中,保持冷静的分析能力、持续学习的好奇心、以及对复杂系统的深刻理解,比任何具体的AI工具都更重要。
工具会变,原则不变。
这就是Harness Engineering想告诉你的事。
1811年的英格兰诺丁汉,一群愤怒的纺织工人在夜色中砸毁了工厂里的织布机。他们自称“卢德分子”,以一个据说名叫内德·卢德的人物为精神领袖。历史课本通常把这个故事讲成一则关于“反对技术进步”的寓言——愚蠢的工人试图阻挡不可阻挡的工业革命。
但如果你仔细阅读那段历史,会发现一个被忽略的细节:那些砸机器的工人,并不是最差的纺织工。恰恰相反,他们是最好的。
他们是手工织布的大师,花了十年甚至二十年时间掌握了一门精湛的手艺。他们愤怒的真正原因不是“机器比我快”,而是“我花了一辈子积累的判断力、手感和经验,突然之间似乎不再被需要了”。
两百年后,我在一间科技公司的会议室里听到了几乎一模一样的话。一位有着十五年经验的高级工程师,看着屏幕上AI生成的代码,说了一句让我至今难忘的话:“它写的代码能跑,但它不知道为什么要这样写。”
这句话里藏着一个关于我们这个时代最重要的洞察——关于AI、关于工程、关于人类经验的价值。
2024年到2026年之间,软件工程领域发生了一件微妙但深刻的事情。表面上看,大家都在讨论AI能不能替代程序员。但真正发生的变化,比这个问题本身有趣得多。
让我用一个类比来说明。
假设你经营一家餐厅。以前,你最重要的资产是一位天才厨师——他知道每道菜的火候、调料的比例、食材的搭配。现在,你拥有了一台无比强大的烹饪机器人。它可以同时处理一百道菜,速度是人类的十倍,而且永远不会累。
问题来了:你还需要那位天才厨师吗?
答案是:你比以前更需要他。但不是让他继续炒菜,而是让他设计菜谱、制定标准、定义什么叫“好吃”。
如果没有厨师的经验和判断,机器人会严格按照某个菜谱执行——哪怕那个菜谱有问题。它会在所有一百道菜里同时犯同一个错误。更可怕的是,它犯错的速度和规模,远超任何人类厨师。
这就是软件工程领域正在发生的事情。工程师的核心工作,正在从“写代码”转向“为AI设计系统”。不是被AI取代,而是角色发生了根本性的转变——从手艺人变成了系统设计师。
有人给这种新的工程范式起了一个名字:Harness Engineering——驾驭工程。
这个词本身就很有意味。Harness,既是名词“缰绳”,也是动词“驾驭”。它暗示着一种关系:AI是一匹力量惊人的马,但方向、边界和目的地,需要人来定义。
我有一位朋友是急诊室的医生。有一次我问他:“你觉得你工作中最重要的技能是什么?”
他想了很久,然后说:“知道什么时候不需要担心。”
他解释说,急诊室每天会涌进各种各样的病人,表现出各种各样的症状。一个年轻的住院医生可能会对每一个异常指标都紧张万分,开出一堆检查和治疗。但一个经验丰富的急诊医生,会在几秒钟内判断出哪些情况是真正危险的,哪些只是虚惊一场。
这种判断力没有写在任何教科书里。它是上万个病例在脑海中留下的模式识别能力——一种隐性知识。
软件工程中充满了这样的隐性知识。为什么这个模块要用这种设计模式而不是另一种?为什么这个接口要暴露这三个参数而不是五个?为什么那段看起来可以优化的代码偏偏不能动?
答案往往不在代码注释里,不在设计文档里,甚至不在任何人的脑子里以清晰的语言存在。它存在于整个团队的集体记忆中,存在于无数次代码审查的讨论中,存在于上线后被三个凌晨的故障电话教训出来的本能反应中。
Harness Engineering的核心,就是把这种隐性知识变成显性知识。把经验变成环境。
这听起来简单,做起来极难。因为隐性知识之所以是隐性的,恰恰是因为拥有它的人往往不知道自己拥有它。就像你很难向别人解释你是怎么骑自行车的——不是因为你不会骑,而是因为你会骑得太好了,以至于那些关键的平衡调整已经变成了无意识的本能。
但这正是工程师新角色的关键所在。你需要把“我就是知道这里不能这样做”翻译成AI能理解和遵守的明确规则、约束和边界。
每一次你对AI说“不,不要这样做”,每一次你在代码审查中否决了AI的建议,本质上你都在执行一次从隐性到显性的翻译。而真正的Harness Engineering,是把这些零散的翻译系统化、结构化,变成一个AI可以在其中正确工作的“环境”。
1908年,亨利·福特推出了T型车的流水线生产模式。在此之前,每一辆汽车都是由一组技艺精湛的工匠从头到尾手工打造的。一个优秀的汽车工匠需要掌握金属加工、发动机调试、底盘组装等十几种技能,培养一个这样的工匠需要五到十年。
流水线改变了一切。把复杂的整车制造分解成简单、标准化、可重复的步骤,每个工人只需要掌握其中一个环节。生产效率提高了几十倍,汽车价格从富人的奢侈品变成了中产阶级的日常交通工具。
但这里有一个被忽略的重要事实:流水线并没有让工匠消失。它让工匠升级了。
那些最优秀的汽车工匠没有去流水线上拧螺丝。他们变成了流水线的设计者——定义每个工位的标准、设计质量检测流程、优化整体生产节拍。他们的手艺经验没有消失,而是被编码进了整个生产系统中。
软件工程正在经历一模一样的转变。
过去二十年,写代码被视为一种“手艺”。我们推崇“代码工匠精神”,赞美优雅的算法、精妙的设计模式、简洁的代码风格。一个优秀的程序员,就像一个优秀的手工匠人,以作品的品质为荣。
AI正在把这种“手艺模式”推向“工厂模式”。代码的生成——就像福特时代的零部件制造——正在被自动化。但代码生成只是软件工程的一部分,就像拧螺丝只是造汽车的一部分。
真正的工程师正在“上移”,而不是“出局”。
他们从“写代码的人”变成了“定义代码应该怎么写的人”。从“在流水线上操作的工人”变成了“设计流水线的工程师”。这不是降级,而是升级。但它确实要求一种完全不同的技能组合——更多的系统思维,更多的抽象能力,更多的将隐性知识显性化的能力。
这种转变让很多人感到不安,这是完全可以理解的。就像诺丁汉的那些织布大师一样,当你花了十年磨练一种技艺,突然被告知这种技艺的执行部分可以被机器完成时,你很难不感到一种存在层面的威胁。
但历史一次又一次地告诉我们:真正有价值的不是某种具体的手艺动作,而是那些驱动手艺动作的判断力、经验和品味。这些东西不会因为执行方式的改变而贬值——恰恰相反,当执行变得越来越廉价、越来越快速时,判断力和品味的相对价值反而会飙升。
查理·芒格讲过一个关于建筑的故事。
有人问一位著名的建筑师:“设计一座伟大建筑的秘诀是什么?”建筑师回答:“知道什么东西不该放进去。”
这个回答揭示了一个深刻的道理,而这个道理在AI时代变得前所未有的重要。
AI在生成代码时有一个系统性的偏差:它倾向于过度设计。 给它一个简单的需求,它会返回一个带有三层抽象、两个设计模式和一个框架的解决方案。这不是因为AI“想”炫技,而是因为它的训练数据中充满了复杂的代码——那些被写进教科书、发布到开源社区、在技术博客上被讨论的代码,往往都是复杂度较高的代码。
简单的代码很少被人写文章讨论,就像没有人会为“今天又是平静的一天”写新闻报道一样。
结果是,AI有一种内在的“加法倾向”。遇到问题,它的本能反应是添加——添加一个新的抽象层、添加一个新的中间件、添加一个新的配置选项。它很少说“不,这里什么都不需要加”。
我见过一个真实的案例:一个团队让AI重构一个只有两百行的工具函数。AI返回了一个完整的“框架”——带有插件系统、配置文件解析器、中间件管道和一个命令行界面。从技术角度看,每一个组件都写得很好。但整体来看,它把一个简单的问题变成了一个复杂的问题。
原来两百行就能解决的事情,现在需要一千五百行和一个使用手册。
这就是为什么人类审查在AI时代的核心价值不是“加法”而是“减法”。
你的工作不是在AI的输出上继续添加东西,而是删掉不需要的东西。不是问“还缺什么?”,而是问“什么是多余的?”不是把代码变得更复杂,而是确保它保持简单。
这需要巨大的勇气和判断力。因为删除总是比添加更难——删除意味着你需要真正理解什么是本质的、什么是装饰性的。添加只需要“看起来有用”就行,删除则需要“确定不需要”。
安托万·德·圣-埃克苏佩里说过:“完美不是没有东西可以添加,而是没有东西可以删除。”在AI时代,这句话应该挂在每个工程师的显示器上方。
1986年1月28日,“挑战者号”航天飞机在发射后73秒爆炸,七名宇航员全部遇难。后来的调查发现,事故的原因是一个小小的橡胶O型圈——在低温下失去了弹性,导致固体燃料助推器的密封失效。
一个价值几美分的零件,摧毁了一个价值十二亿美元的航天器。
这个悲剧揭示了一个关于复杂系统的基本真理:系统的可靠性取决于它最基础的组件。 再先进的航天技术、再精密的飞行控制系统,都无法弥补一个基础密封件的失败。
在软件工程中,这些最基础的组件被称为“系统原语”(System Primitives)——你在其上构建一切的基石。它们可能是你的错误处理模式、你的数据验证逻辑、你的认证框架、你的API设计规范。
这里有一个关键洞察:AI会放大你的系统原语——无论好坏。
如果你的基础原语是干净的、一致的、经过深思熟虑的,AI会在这个坚实的地基上高效地构建。它会复用你的模式,遵循你的规范,生成与现有代码和谐一致的新代码。
但如果你的基础原语是混乱的、不一致的、充满历史遗留问题的,AI同样会忠实地放大这些问题。它会在一个摇摇欲坠的地基上快速堆砌更多的砖块,让整个建筑更快地走向崩溃。
而且——这是最可怕的部分——AI放大问题的速度,远远快于人类工程师发现和修复问题的速度。
想象一下:一个有问题的基础模块被AI在一天之内复用到了五十个新功能中。等你发现那个基础模块有问题时,你面对的不是一个bug,而是五十个bug——而且它们散布在整个代码库的各个角落。
这就是为什么在AI时代,系统原语的质量变得如此关键。在过去,一个有点问题的基础组件可能只会导致缓慢的技术债务积累。在AI时代,同样的问题会导致指数级的债务爆发。
好的原语就像好的地基:你不会注意到它们,直到地基出了问题,你才会意识到上面的一切都建在它之上。
在数学中,有一个概念叫“抽象泄漏”——一个抽象层本应隐藏的复杂性,在某些情况下“泄漏”出来,迫使使用者不得不理解它试图隐藏的东西。
好的系统原语和糟糕的系统原语之间的区别,往往就在于此。
让我讲一个故事。我认识一位工程师,他在一家电商公司工作。他们的系统里有一个叫做 BaseService 的类,每一个业务服务都继承自它。这个类有一百多个方法,涵盖了日志记录、数据库连接、缓存管理、错误处理等等功能。
听起来很合理,对吧?把所有公共功能放到一个基类里,所有服务都能复用。
问题是,这个“抽象”实际上是一个伪装成抽象的垃圾桶。每当有人不知道某个功能该放哪里时,就把它塞进 BaseService。几年下来,这个类变成了一个什么都做、什么都不精的庞然大物。更糟糕的是,因为所有服务都依赖它,任何对它的修改都可能影响整个系统。
这就是“假装的抽象”——它看起来像在简化事情,实际上在制造更多的问题。
当这个团队开始使用AI来生成新的服务代码时,灾难发生了。AI忠实地继承了 BaseService,在每个新服务中调用了那一百多个方法中的各种组合。很快,新代码和旧代码一样混乱——而且数量增长得更快。
与此形成对比的是另一家公司。他们的基础原语非常简洁:一个统一的错误类型、一个标准的请求-响应接口、一组明确的数据验证规则。每一个原语都只做一件事,而且做得很好。
当这个团队使用AI时,AI生成的代码自然而然地遵循了这些简洁的模式。新代码和旧代码一样清晰、一样可预测。
真正的抽象简化了思考。假装的抽象只是把复杂性换了个地方藏起来。
如何判断一个原语是真正的抽象还是假装的?有一个简单的测试:如果你需要了解一个抽象的内部实现才能正确使用它,那它就不是一个好的抽象。 好的抽象就像一扇门——你只需要知道推还是拉,不需要了解门铰链的力学原理。
在AI时代,这个标准变得更加严格。因为AI不像人类工程师那样拥有上下文和直觉来“绕过”一个有缺陷的抽象。人类可以看到 BaseService 的一百个方法,凭经验知道“这几个方法可以用,那几个方法千万别碰”。AI不会。它会公平地使用所有一百个方法,包括那些“千万别碰”的。
所以,清理你的系统原语,在AI时代不再是一个“等有空再做”的改善项目。它是你能否成功使用AI的前提条件。
2009年,美国航空公司1549号航班从纽约拉瓜迪亚机场起飞后不久,两个引擎同时被鸟群击中失去动力。机长切斯利·萨伦伯格在短短208秒内做出了一系列决策,最终将飞机安全迫降在哈德逊河上,机上155人全部生还。
这个故事被称为“哈德逊河上的奇迹”,萨伦伯格机长被誉为英雄。但如果你仔细研究这个事件,会发现一个有趣的细节:萨伦伯格之所以能做出正确的决策,不是因为他比其他飞行员更聪明或反应更快,而是因为航空业有一套极其严格的验证回路。
每一个飞行操作都有对应的检查清单。每一个异常情况都有标准的应对程序。机长和副驾驶之间有交叉验证的机制——一个人操作,另一个人确认。即使在那208秒的极端压力下,萨伦伯格和副驾驶斯基尔斯仍然在执行他们训练了无数次的验证流程。
奇迹不是即兴发挥的结果,而是系统化验证的产物。
在AI辅助编程中,我们面临一个类似的问题。很多人和公司把赌注押在“更强大的AI模型”上——他们相信,只要AI足够聪明,就能生成完美的代码。这就像相信只要飞行员足够优秀,就不需要检查清单一样。
事实是:验证回路比更强的模型更重要。
一个中等能力的AI模型配合严格的验证回路,会比一个顶级AI模型在没有验证的情况下工作得更好。原因很简单:再强大的模型也会犯错,而且犯错的方式往往是不可预测的。你无法通过让模型“更聪明”来消除所有错误——但你可以通过系统化的验证来捕获大部分错误。
什么是好的验证回路?至少包含三个层次:
第一层是自动化测试——让机器验证机器。这是最基础的,包括单元测试、集成测试、类型检查、静态分析。AI生成的每一段代码都应该在提交前通过这些自动化检查。
第二层是模式匹配——让规则验证结构。检查AI生成的代码是否遵循了既定的架构模式、命名规范、依赖规则。这不是检查“代码能不能跑”,而是检查“代码是不是在正确的轨道上”。
第三层是人类审查——让经验验证判断。这是最高层次的验证,关注的是那些无法被自动化工具捕获的问题:设计决策是否合理?抽象层次是否恰当?这段代码是否在解决正确的问题?
这三个层次缺一不可。只有自动化测试,你会错过设计层面的问题。只有人类审查,你会因为速度太慢而跟不上AI的产出。只有模式匹配,你会捕获形式上的偏差,但错过实质上的错误。
最好的工程团队不是那些使用最强AI模型的团队,而是那些建立了最严格验证回路的团队。
这里面有一个深刻的反直觉:在一个大家都在追求“更强模型”的时代,真正的竞争优势可能不在于你用了什么模型,而在于你用什么机制来验证模型的输出。就像在航空业,竞争优势不在于飞行员的天赋,而在于检查清单和训练系统的严谨程度。
1962年7月22日,美国发射了“水手1号”探测器,目标是飞越金星。火箭升空后不久就严重偏离航线,地面控制中心被迫在发射后293秒启动自毁程序。
后来的调查发现,原因是制导程序中的一个极其微小的错误:一个上划线符号被遗漏了。在Fortran语言中,这个符号表示一个平滑函数。没有了它,程序把雷达数据中的正常噪声当成了真实的速度变化来处理,导致了错误的航向修正。
一个符号,价值一千八百万美元(在1962年)。
但这个故事更深层的教训不是“要小心打字错误”。它是:这个bug揭示了一条从未被明确写下来的规则——“制导程序中的平滑函数必须使用上划线符号标记”。
在bug发生之前,这条规则存在于程序员的脑子里,存在于团队的口头约定中,存在于“大家都知道”的假设中。但它从未被写成一份明确的规格说明。
每一个bug,本质上都是一条未被写下的规格说明。
这个洞察在AI时代有着特殊的意义。当AI为你生成代码时,它依赖的是你给它的规格说明——无论是明确的提示词、代码注释、类型定义,还是隐含在现有代码模式中的约定。AI不知道那些你“大家都知道”但从未写下来的规则。
所以,每当AI生成的代码出现bug,你不应该只是修复bug本身。你应该问自己一个更深层的问题:“这个bug揭示了什么我认为理所当然但从未明确表达的知识?”
然后,把这个知识写下来——变成一条测试、一个类型约束、一段文档、一个代码检查规则。让它从隐性变成显性,从“大家都知道”变成“系统能验证”。
这是一个持续的过程。你永远不可能一次性把所有隐性知识都写下来,就像你永远不可能一次性发现所有bug一样。但每一次bug修复都是一次知识显性化的机会。
一位我非常敬佩的工程经理有一个习惯:每当团队修复了一个bug,她不仅要求修复代码,还要求回答两个问题——“这个bug教会了我们什么?”以及“我们如何让这类bug不可能再发生?”
第一个问题让团队学习。第二个问题让系统学习。
在AI时代,第二个问题尤其重要。因为AI不会从bug中学习——至少不会在你的上下文中学习。它明天可能会犯和今天一模一样的错误。唯一能“记住”教训的,是你构建的系统——你的测试、你的规则、你的约束、你的原语。
修bug不是终点,写下那条缺失的规格说明才是。
有一个关于米开朗基罗的著名故事(可能是虚构的,但它传达的道理是真实的)。
有人问米开朗基罗:“你是怎么雕出大卫像的?”
他回答:“大卫一直在那块大理石里面。我只是去掉了不属于他的部分。”
无论这个故事是真是假,它完美地描述了Harness Engineering时代工程师的新角色。
你不再是代码的“作者”。你是系统的“边界定义者”。
你的工作不是生成代码——AI可以做到这一点,而且速度和数量远超人类。你的工作是定义代码生成的边界:什么可以做,什么不能做,什么必须做,什么不值得做。
这种角色转变是深刻的,它改变了工程师日常工作的几乎每一个方面。
过去,你花80%的时间写代码,20%的时间思考设计。现在,这个比例可能需要反过来——甚至更极端。你可能花90%的时间在思考、定义、验证上,只花10%的时间在直接的代码操作上。
这让很多工程师感到不适。写代码有一种立即的满足感——你打出一行行字符,看到它们变成可运行的程序,就像画家在画布上看到色彩逐渐呈现。而“定义边界”是一种更抽象、更间接的工作,它的成果不那么直观,反馈循环也更长。
但这正是更高层次的工程实践。就像一个城市规划师和一个砌砖工人之间的区别——不是谁更有价值的问题,而是视野和影响范围不同。
一个优秀的“边界定义者”需要回答这些问题:
“这个系统的不变量是什么?” ——无论AI怎么生成代码,什么条件必须始终为真?用户数据必须加密?API响应必须在200毫秒内返回?每个操作必须有审计日志?这些是不可协商的边界。
“这个领域的陷阱在哪里?” ——基于你的经验,你知道哪些看似合理但实际上会导致问题的做法?浮点数精度问题?时区处理的边缘情况?并发环境下的竞态条件?这些陷阱需要被编码成明确的规则和检查。
“什么是足够好的?” ——这可能是最重要也最难回答的问题。AI可以无限制地优化、重构、添加功能。知道什么时候说“够了,这已经足够好了”,需要对业务目标、技术约束和用户需求的深刻理解。
米开朗基罗看到了大理石里的大卫,因为他知道大卫应该是什么样子。同样,一个优秀的工程师能定义系统的边界,因为他知道系统应该是什么样子——以及,同样重要的,不应该是什么样子。
每隔几个月,社交媒体上就会出现一轮新的恐慌。“AI将在X年内取代所有程序员!”“学编程已经没有意义了!”“软件工程已死!”
让我分享一个历史视角。
1995年,互联网开始商业化时,有人预言:“五年内,所有实体店都会关门。”三十年过去了,亚马逊确实改变了零售业,但实体店并没有消失——它们进化了。
2012年,深度学习取得突破时,有人预言:“放射科医生将在五年内被AI取代。”十四年过去了,放射科医生不仅没有被取代,他们在AI辅助下的诊断准确率比以前更高了。
每一次技术革命,都会伴随着两种声音:一种说“一切都会改变”,另一种说“什么都不会改变”。真相,一如既往,在两者之间——而且往往比任何一种极端预言都更有趣。
AI不会取代工程师,就像自动驾驶不会取代交通规划师。 它会改变工程师做的事情,但不会消除对工程师的需求。恰恰相反,当代码生成变得廉价时,那些决定“生成什么代码”和“如何验证生成的代码”的人会变得更加重要。
面对这些恐慌性的标语,保持冷静的方法其实很简单:看做法,不要看说法。
那些喊着“AI将取代一切”的人,他们自己在做什么?他们在雇佣工程师来构建和维护AI系统。那些声称“编程已死”的公司,他们的招聘页面上挂着多少个工程职位?
行动永远比言论更能说明真相。
而且,值得注意的是,那些对新技术最恐慌的人,往往是那些最不了解技术实际运作方式的人。真正在用AI写代码的工程师,对AI的能力和局限性有着清醒得多的认识。他们知道AI能做什么(生成大量样板代码、处理常见模式、快速原型开发),也知道AI不能做什么(理解业务上下文、做出架构决策、处理真正新颖的问题)。
最好的态度不是恐慌也不是忽视,而是好奇心驱动的务实主义。
到目前为止,我们讨论的很多概念可能听起来有些抽象。那么,对于一个普通的工程团队——没有谷歌的资源、没有OpenAI的人才密度——来说,这一切意味着什么?
让我描述一个我见过的最有效的实践框架。我称之为“三层操作系统”。
第一层:原语治理。 每个季度花一天时间,团队一起审视自己的系统原语。这不是一个宏大的架构重构项目,而是一个简单的健康检查。问三个问题:我们的基础模式还一致吗?有没有新的“假抽象”偷偷溜进来了?AI在使用这些原语时表现如何?
这就像定期体检——不是等到病了才去医院,而是定期确认一切正常。
我见过一个团队把这个做成了一个简单的看板。每个系统原语一张卡片,上面标注着“健康/需要关注/需要重构”三种状态。每次季度审查,大家一起更新这些状态。简单、直观、有效。
第二层:知识显性化。 建立一个持续的机制,把团队的隐性知识转化为AI能理解的显性规则。
具体来说:每次代码审查中,如果有人说了“这里不应该这样做”或“我们通常是那样处理的”,就把这条知识记录下来。每周花三十分钟,把这些零散的记录整理成明确的规则——可以是代码检查工具的新规则,可以是架构决策记录,可以是AI提示词模板中的新约束。
关键是把这个做成一个习惯,而不是一个项目。不需要一次性把所有知识都整理完,只需要每周比上周多一条明确的规则。
一位团队负责人告诉我他的做法:他在代码审查工具里加了一个标签叫“隐性知识”。每当审查者发现自己在解释一个“大家都应该知道”的规则时,就打上这个标签。每周五下午,他花半小时把这些标签汇总,选出最重要的一两条,转化成正式的团队规范。
六个月后,他们的AI代码审查通过率从47%提高到了82%。不是因为他们换了更好的AI模型,而是因为AI终于“知道了”那些以前只存在于人脑中的规则。
第三层:验证闭环。 为AI的每一种使用场景建立对应的验证机制。
这听起来复杂,但实际上可以从很小的地方开始。比如:AI生成的每段代码都必须通过现有的测试套件?好,这是最基础的验证。AI生成的每个新API端点都必须有对应的集成测试?很好,这是第二层验证。AI生成的每个架构变更都必须经过一位高级工程师的审查?完美,这是第三层验证。
关键不是一步到位建立一个完美的验证体系,而是为每一种AI的使用方式都建立至少一个对应的验证步骤。然后逐步加强。
一个实用的技巧是“红灯/绿灯”清单。对于AI生成的每一段代码,有一份简短的清单列出“绿灯条件”(必须满足才能合并)和“红灯条件”(出现任何一个就需要人工审查)。这份清单不需要很长——五到十条就够了——但它能捕获大部分常见问题。
这三层操作系统没有什么神奇之处。它不需要昂贵的工具、特殊的培训或天才的团队成员。它需要的只是纪律性和持续性——每天做一点,每周改进一点,每月回顾一次。
最好的系统不是最聪明的系统,而是最持久的系统。
让我以一个我最近在读的历史故事来结束这篇文章。
19世纪末,美国铁路行业经历了一段疯狂的扩张期。几乎每一家铁路公司都在拼命铺设更多的铁轨——更长的线路、更多的车站、更远的目的地。他们相信,谁拥有最多的铁轨,谁就赢了。
但最终胜出的不是拥有最多铁轨的公司。而是那些建立了最好的调度系统、最可靠的时刻表和最高效的货物转运网络的公司。铁轨是基础设施,但调度系统才是让铁轨产生价值的东西。
类比到今天:AI模型是铁轨,而你的工程系统——你的原语、你的验证回路、你的知识体系——是调度系统。
每家公司都可以使用同样的AI模型。GPT、Claude、Gemini,这些模型对所有人开放。真正的竞争优势不在于你使用什么模型,而在于你如何把组织的经验和知识转化为AI可以执行的系统。
让我把这个说得更具体一些。
公司A和公司B使用同一个AI模型来辅助开发。公司A的工程师只是简单地把需求描述扔给AI,然后手动检查输出。公司B花了几个月时间,把团队十年积累的工程经验——架构原则、常见陷阱、设计模式、质量标准——编码成了一套完整的约束系统和验证流程。
六个月后,公司A的工程师仍然在每段AI生成的代码上花大量时间做人工检查和修改。公司B的工程师已经能够信任AI生成的80%的代码,把精力集中在那些真正需要人类判断的20%上。
这不是技术差距,而是系统差距。是经验被编码的程度差距。
这也解释了为什么那些经验最丰富的团队,在AI时代的潜在优势最大。不是因为他们的个人技能更强——在代码生成速度上,没有人能和AI竞争。而是因为他们拥有最多的隐性知识可以被显性化、被编码、被系统化。
一个有十年经验的团队,脑子里装着数以万计的“这样做行得通/这样做行不通”的教训。如果他们能把这些教训转化成AI可以理解和遵循的规则——测试、类型约束、架构模板、验证检查——他们就拥有了一个其他团队无法轻易复制的竞争优势。
因为经验不是可以购买的。你可以购买最新的AI模型,但你不能购买十年的工程教训。你能做的,是把这些教训变成系统——让它们不仅仅存在于人的脑海中,而是融入到AI工作的每一个环节里。
让我回到文章开头的那些诺丁汉织布工。
历史最终证明,他们的恐惧是有道理的——但也是错位的。他们确实失去了“手工织布”这份具体的工作。但纺织业并没有消亡,反而经历了空前的繁荣。而那些适应了新现实的人——那些学会了操作机器、设计织物图案、管理生产流程的人——过上了比手工织布时代更好的生活。
同样的故事正在软件工程领域上演。“手写代码”这个具体的动作正在被部分自动化。但软件工程——设计系统、定义边界、验证质量、将人类经验编码为可执行规则——这个更宏大的事业,才刚刚迎来它最激动人心的篇章。
AI不是来取代工程师的判断力的。它是来放大工程师的判断力的。
前提是,你得先有判断力可以被放大。而这种判断力——来自经验、来自教训、来自无数次失败和成功的积累——恰恰是AI最无法替代的东西。
亨利·福特说过一句被广泛引用的话:“如果我问人们想要什么,他们会说更快的马。”
在AI时代,很多人想要的是“更快的代码生成器”。但真正需要的,是更好的系统来驾驭代码生成的力量——更清晰的原语、更严格的验证、更深刻的边界定义。
不是更快的马,而是更好的道路。
这就是Harness Engineering的本质。不是关于AI有多强大,而是关于我们如何驾驭这种力量。不是关于谁能生成最多的代码,而是关于谁能把最多的智慧编码进系统中。
而这种智慧,永远需要人来提供。
——Paul Graham风格:极简、反直觉、创业者视角
整理自一场三小时对谈。一个工作十年的程序员和一个大二学生,聊AI、聊代码、聊钱、聊人生。以下是最锋利的部分。
一个大学老师问学生:你不自己写代码,怎么知道AI写的是对的?
这个问题听起来很有道理。但它有一个隐含的假设——人读代码就能确保它是对的。
如果这个假设成立,公司就不需要测试人员了。
事实上,在工业界,没有人通过“读代码”来保证正确性。你通过测试来保证正确性。单元测试、集成测试、端到端测试。代码是否可测试,比代码是否被人类读过,重要一百倍。
而AI恰好让测试变得极其便宜。以前TDD(测试驱动开发)是个好主意但没人愿意做——太反人类了,先写测试再写实现,多出来的工作量谁愿意干?但AI不在乎。AI就是牛马,你说先写测试就先写测试。
所以一个有趣的反转出现了:TDD,一个存在了二十多年但一直被程序员抵制的方法论,在AI时代突然变成了最佳实践。不是因为人变了,而是因为做测试的成本变了。
这场对谈里最有意思的一个命题是——
一个人能有效烧掉的token数,约等于这个人的能力上限。
乍听之下这像是在开玩笑。但想想它的逻辑:
AI是一个放大器。你投入一个指令,它给你一个输出。输出的质量取决于两个变量:模型的能力,和你的指令的质量。
模型能力大家差不多(同样花钱用Opus)。差别在指令。而指令的质量取决于你的知识面、经验、判断力和想象力。
一个初级程序员可能只知道让AI“写一个登录页面”。一个高级程序员会说“用OAuth2.0实现SSO,考虑token刷新、CSRF防护、会话管理,然后写完整的测试套件”。同样一个模型,输出完全不同。
所以问题不是AI够不够聪明。问题是你能不能给它足够好的指令。你能给的指令越多、越精准、越有创造性,你能“烧掉”的token就越多,产出就越大。
Burn rate就是能力。
这个程序员每个月花1200到2400美元在AI工具上。他的一个重要发现是:
创新来自于浪费。
他一开始的200美元额度用不完。于是他开始做“没必要”的事——让AI控制浏览器帮他登录公司系统、让AI自己找优化方向而不是等他下指令、让AI从十个方案里自己选最好的。
这些在旧思维里都是“浪费token”的行为。但正是这些浪费让他发现了AI能力的新边界。如果他一直小心翼翼地省着用,他永远不会知道这些。
这跟创业一样。你不会通过精打细算发现product-market fit。你通过快速试错发现。试错就意味着浪费——但那些浪费是必要的学费。
他讲了一个例子。他让Cursor帮他优化登录流程,一开始要90秒。他说:“我希望你缩短到30秒以内,你现在是90秒,我很不满意,你自己去优化。”
注意他的措辞。他没有说“请把第三步改成并行执行”或者“把等待时间从5秒减到2秒”。他只说了目标,没说方法。
AI说60秒已经是极限了。他说“你是最智能的大模型,你一定可以”。最后真的降到了30秒。
这里面有一个深刻的管理学洞见:告诉下属目标而不是方法,是给对方最大自由度的工作方式。 大多数人会忍不住去指导过程——这恰恰限制了对方(不管是人还是AI)的可能性。
那个学生说了一句我觉得整场对话里最好的话——
“对AI的悲观,其实是对人类的盲目乐观。”
展开说:当你批评AI“不够好”的时候,你的参照系是什么?是人类吗?
那我问你:人类一行行读代码的正确率是多少?人类手动管理自己注意力的效果怎么样?人类凭直觉做的职业规划靠谱吗?
如果你诚实地回答这些问题,你会发现人类的基准线其实没那么高。
对AI的批评很多时候不是在维护一个更高的标准——而是在维护一种熟悉感。人们说“我不相信AI写的代码”的时候,他们真正在说的是“我习惯了相信自己写的代码”。但习惯不等于可靠。
这个程序员的哥哥第一次用ChatGPT时,问了NBA历史前十球员是谁,然后嘲笑答案。三年过去了,他可能还在嘲笑。而他弟弟已经用AI做了十几个APP、重构了整个工作流、每个月省下了几百个小时。
差距不在智商。差距在于:一个人把时间花在证明AI不行,另一个人把时间花在发现AI能做什么。
关于跨领域学习,有一个很精确的观察——
以前的比较维度很窄。你是后端程序员,就比后端能力。你是前端程序员,就比前端能力。分工明确,专长就是优势。
但现在分工在崩塌。前后端在融合。一个人用AI就能做全栈。如果你只会后端,别人不会专门搭配一个前端给你——你的人力成本就是两个人的。
所以关键能力变了。从“某一项技能有多精”,变成“能不能快速跨到一个新领域并达到及格线”。AI能帮你从0分到3分,但从3分到7分,需要你的学习能力和判断力。
这对“全面但不顶尖”的人来说其实是个好消息。以后的竞争越来越像CEO的工作——你不需要每个领域都是专家,但你需要知道每个领域的关键问题是什么、怎么用人(或用AI)、结果应该是什么样。
最后一个观点。这个程序员用了一套三步法来管理自己的注意力:量化→自动化→决策化。
第一步,量化。用APP记录阅读时间、喝水量、饮食、体重。不自动化,就手动记。
第二步,自动化。做成APP,让统计自动跑。手机一打开就记录。
第三步,决策化。基于数据给建议。连续几小时没喝水就提醒。连续几天喝太多就建议少喝。
这套方法论的本质是:不信任直觉,信任系统。
跟TDD的逻辑一样。你不信任“我觉得这段代码是对的”,你信任“测试跑通了”。你不信任“我觉得今天喝了够多水”,你信任“APP告诉我喝了1.5升”。
成功的路径可以复用。番茄APP验证了阅读,喝水APP验证了健康,饮食APP正在验证体重管理。每一个新场景都是同一个框架的新实例。
这场对谈的核心,用一句话概括就是——
在智能变得廉价的时代,瓶颈不是工具,是你的想象力。
你的想象力决定了你能给AI什么样的指令。你的指令质量决定了你能烧多少token。你的burn rate决定了你的能力上限。
所以,别省着用。