前段时间,我做了一个有点狠的决定。
把已经做出来的第一版质检平台,放弃了。
不是改几个页面。
也不是某个功能推翻重做。
是整个 V1 到此为止,重新开 V2。
问题是,V1 其实已经做得挺像那么回事了。
账号有了。
云端数据库接上了。
检测数据能录。
Excel 能批量导入。
检测台账有了。
甚至不同检测参数之间的相关性分析,我都已经做出来了。
所以如果你只看页面,可能会觉得。
这东西不是已经快做完了吗?
我当时也这么觉得。
每多出来一个功能,我都会点进去看一圈。
嗯。
好像真有点那个意思了。
然后,我把它放弃了。
不是因为 Codex 写不出来。
恰恰相反。
就是因为它太能写了,我才慢慢发现,再这么写下去,好像要出事。
故事得从几个月前说起。
当时我舅舅跟我聊他们厂里的事情,问了我一个问题。
现在 AI 已经这么厉害了,有没有可能给厂里做一套这样的东西出来。
他想要的其实不只是一个填质检数据的软件。
而是希望以后厂里的机器和零件,从设计开始,到加工、装配、检测、使用、维修,再到最后报废,中间发生过什么,最好全部能查得到。
谁设计的。
改过几次。
装到了哪台机器。
什么时候检测过。
检测结果怎么样。
后来有没有换过。
最后为什么报废。
我后来觉得,用一句特别简单的话解释最好。
一个零件从出生到报废,最好都有自己的一本档案。
这个想法我听完觉得挺有意思。
但问题也很明显。
我那时候,连 PLM 是什么都不知道。。。
Product Lifecycle Management,产品生命周期管理。
这个名字还是后来真正开始往下做,我才慢慢知道的。
软件工程没系统学过。
数据库不熟。
后端不熟。
权限不熟。
架构更不用说。
如果这个问题早几年出现在我面前,答案大概率就两个字。
不会。
没了。
但 Agent 出现以后,这里面有一个变化,我现在回头看觉得特别重要。
问题第一次从「我不会,所以做不了」,变成了
「我不会,但要不先试试?」
就这么开始了。
第一版其实非常朴素。
没研究什么 PLM 软件。
没先搞一套完整架构。
也没有想清楚几年以后的系统到底会长成什么样。
我当时用的还是智谱 GLM 5.1,目标就一个。
先想办法把数据存下来。
最后弄出来一个很轻量的小网页。
能录。
能存。
能查。
就这样。
现在回头看,这跟什么全生命周期数据平台差得非常远。
充其量就是一个数据存储网页。
但当时我还挺开心。
因为它至少证明了一件事。
脑子里的东西,真的可以变成一个能点、能输入、能保存数据的软件。
然后这个事情就开始变味了。。。
人很容易贪心。
既然数据已经能存,那是不是可以加账号?
有账号以后,是不是可以让不同的人看不同的数据?
那是不是可以把数据接到云端?
既然检测数据已经有了,是不是可以做统计?
做分析?
Excel 导入?
再把设备、零件、检测记录慢慢串起来?
于是这个小网页就开始一层一层往上长。
后来我开始正式用 Codex 承接这个项目。
也是从这时候开始,我第一次真正感觉到,Agent 编程和我以前理解的「让 AI 帮我写代码」,不是一个东西。
以前用 ChatGPT 写代码,很多时候还是我把代码拿给它。
你看看这个。
它看完。
告诉我这里怎么改。
我复制回来。
再粘进去。
其实 AI 还是坐在聊天框里,等着我把东西喂给它。
Codex 给我的感觉不一样。
它可以自己进仓库。
自己找文件。
自己看项目结构。
自己判断这一处修改还会牵扯什么。
改完以后自己跑命令。
出错。
看报错。
继续修。
有一次,它自己在两个后端 Route,也就是两个路由文件里,发现了一段重复的搜索和筛选逻辑。
这两个文件并不是我专门找出来贴给它的。
它自己翻出来了。
然后把重复的东西抽成共享逻辑,再补测试。
现在天天用 Agent 的人看到这里,可能觉得也就这样。
但第一次看到的时候,我确实挺兴奋。
以前的 AI 更像
你给我一道题,我帮你解。
Agent 开始变成
你告诉我想做到什么,我进去自己找活干。
这两个体验完全不一样。
还有一件特别小的事,我到现在都记得。
以前我用另一个 Agent 的时候,为了省事,干过一件现在想想挺离谱的事。
直接把 GitHub API Key 发进去。
当时脑子里没什么安全意识。
就是,赶紧弄完,能跑就行。
到了 Codex 这里,它反而明确提醒我,这个东西不要这么发,有泄露风险,换一种方式。
那一刻其实挺有意思的。
因为它第一次给我的感觉不是「你说啥我干啥」。
而是它会反过来告诉我
你这个做法,可能不太对。
所以后面一段时间,我对 Codex 的信心涨得非常快。
我的开发方式也越来越简单。
想要一个东西。
写 Prompt。
交给 Codex。
做完。
我看看页面。
能用。
下一个。
登录。
账号。
云端。
检测录入。
Excel 导入。
数据分析。
台账。
当时是真的爽。
上午想到的东西,下午可能已经能点了。
对一个本身软件工程基础很弱的人来说,这种反馈速度非常容易让人产生一种错觉。
原来开发软件,也没那么难嘛。
结果很快就被教育了。
我慢慢发现了一件特别奇怪的事情。
Codex 明明越来越强。
项目里的功能也越来越多。
但我开发一个新东西的速度,反而越来越慢。
刚开始,一个功能很快。
多一个字段,很快。
再加一个页面,也快。
问题就在于,每一次「都挺快」,最后会叠成一个特别慢的东西。
我当时一直用的其实就是 Prompt Engineering 那套思路。
脑子里冒出来一个需求。
描述给 AI。
让 AI 决定怎么实现。
做完以后,我主要看两个东西。
页面是不是我要的。
功能能不能用。
不对。
继续改 Prompt。
这个方法在项目早期真的非常舒服。
因为你看得见的反馈来得太快。
但我当时忽略了一个东西。
页面,我看得见。
按钮,我也看得见。
页面下面那一大坨东西,我看不见。
数据到底怎么组织。
模块之间怎么依赖。
权限到底应该放哪。
哪些逻辑应该共用。
以后再新增一个功能,到底从哪里往里接。
这一次为了图快塞进去的东西,会不会给以后留一个雷。
这些东西我没有定义。
那最后是谁在定义?
Codex。
所以我后来回看 V1,会发现自己当时其实干了一件很有意思的事情。
产品上,我管得特别细。
这个按钮放哪。
这个页面怎么展示。
这个流程我要怎么走。
底层工程上,我反而非常豪放。
你看着办。
于是就出现了一个特别诡异的结果。
前端越来越像我想要的软件。
底层却越来越不像一个我能控制的软件。
最明显的一次,是做账号权限。
当时我要设置五类账号。
不同的人能看什么。
能修改什么。
哪些只能查看。
哪些操作压根不能碰。
我一开始寻思了一下。
五个账号嘛。
最多一个星期。
差不多了。
结果真开始做。
第一个账号。
两天。
反复改。
反复测。
这里刚通,那里又有问题。
这边改一条权限,又会牵扯以前留下来的东西。
做到后面,Codex自己都得先花越来越多的时间,弄明白之前到底是怎么写的。
我当时看着这个速度,心里已经开始犯嘀咕了。
不对。
绝对不对。
一个功能难,不一定说明什么。
但如果每往后走一步,都比上一步更难,那一定有什么地方出问题了。
而我还有四个账号。
账号后面还有设备。
零件。
安装关系。
检测。
审计。
生命周期。
……
这要继续补到什么时候?
差不多也是这个时候,我第一次真正理解了「技术债」这个词。
以前看到技术债,我一直觉得这多少带点程序员黑话的味道。
代码不够优雅。
该重构了。
真撞上一次以后才知道,它其实一点都不抽象。
你今天为了快一点省掉的时间,迟早会换一种方式回来找你。
有时候还带利息。。。
而 Agent 把这个问题放大了。
因为它真的太擅长先把眼前这一题做出来。
你让它在墙上开个门。
可以。
再开一个。
也行。
今天这里埋一根管。
明天旁边再接一根。
每一次看起来都完成得挺好。
直到有一天你又想加一个房间。
突然发现墙不能拆。
管线全挤在一起。
门的位置也不对。
这时候你才发现,问题早就已经不是「这个房间怎么装修」了。
而是这栋房子最开始根本没想过,未来还要不停往外盖。
账号权限做了一半以后,我基本确定了一件事。
V1 不能这么救了。
重新开始。
V2。
这个决定其实还是挺肉疼的。
因为 V1 不是不能用。
甚至恰恰因为它已经挺能用了,放弃的时候才更舍不得。
那些页面,我真的是一个一个看着它长出来的。
但后来我想通了。
V1 其实已经完成了自己的任务。
它证明了
Agent 确实可以帮一个软件工程基础很弱的人,把一个真实的软件做出来。
到了 V2,我想验证的是另外一件事。
怎么才能让 Agent 连续干几个月,项目还不至于越干越乱?
也是这个时候,我开始了解一个词。
Harness Engineering。
刚看到这个词的时候,我其实没觉得有多神。
现在 Agent 圈的新词真的很多。。。
今天一个 Engineering。
明天一个 Workflow。
我有时候看完名字,都不知道这几个东西到底有什么区别。
但 Harness Engineering 我往下了解以后,突然发现它刚好回答了一个我自己已经撞过的问题。
我以前一直在研究
怎么把 Prompt 写得更好?
需求是不是应该再详细一点?
上下文是不是应该给得更多?
是不是让 Agent 先分析、再规划、最后执行?
这些当然都有用。
但我突然发现一件事。
假如每次 Codex 开始工作以前,我都得重新写一大坨东西告诉它
这个项目是什么。
现在做到哪。
之前为什么这么设计。
什么能动。
什么不能动。
做到什么程度必须停。
最后用什么证明真的完成了。
那可能问题已经不是 Prompt 写得够不够漂亮了。
是我压根没给它一个适合长期工作的环境。
我自己后来用一个特别土的方式理解这两个词。
Prompt Engineering,是研究这一件事,我到底应该怎么跟 Agent 讲。
Harness Engineering,是研究怎么把资料、规则、边界、流程、检查标准都提前铺好,让 Agent 进来以后自己就知道该怎么干。
一个是在研究对话。
一个是在研究环境。
我 V1 最大的问题其实就在这里。
我一直把 Codex 当临时工用。
来。
今天登录。
明天权限。
后天分析。
至于整个项目以前发生过什么。
为什么这么设计。
什么东西绝对不能碰。
做到哪里要停。
什么才算真正完成。
有些在我脑子里。
有些躺在不知道哪一段 ChatGPT 对话里。
还有一些东西更干脆。
我自己都没想过。。。
然后我还希望 Codex 把这些全部拼出来。
现在回头想想。
多少有点欺负它了。
所以 V2 开始以后,我第一件事反而不是继续加业务功能。
我先停下来,开始给 Agent 铺轨道。
以前我想的是
下一条 Prompt 怎么写。
V2 开始以后,我想的是
这套东西以后应该怎么一直跑。
这里面的做法其实没那么玄学。
我先把项目大量的「记忆」写回仓库。
产品到底做什么。
这一阶段明确不做什么。
系统里有哪些核心对象。
模块之间是什么关系。
以前有哪些重要决策。
当前做到哪里。
下一步是什么。
慢慢仓库里面开始出现很多这样的东西。
PRODUCT_SCOPE
DOMAIN_MODEL
ARCHITECTURE
CURRENT_STATE
ACTIVE_PLAN
……
后来我给自己定了一个目标。
哪怕今天换一个完全新的 Agent 进来,它最好也能只靠仓库,知道这里到底发生过什么。
而不是我重新给它从盘古开天讲一遍。
这时候仓库就不再只是放代码的地方了。
它开始变成项目自己的记忆。
然后是拆任务。
V1 我特别喜欢一句话把事情交出去。
「把账号权限做完。」
「把设备管理完善一下。」
「把检测模块做完。」
听着都没啥问题。
但真的想一下就会发现,「做完」这两个字里面能藏的东西太多了。
什么叫做完?
做到哪?
哪些属于这一次?
哪些可以顺手做?
AI自己有非常大的解释空间。
所以 V2 里面,我开始把工作切成 Slice。
名字不重要。
你就理解成,每次只给 Agent 一块足够小,而且可以单独验收的工作。
这一块做完。
停。
测试。
Review。
确定没问题。
再往下一块走。
我以前特别喜欢问
Codex 这一次能不能帮我多干一点?
后来我更关心的是
它这一次做完的东西,我到底能不能证明它是对的?
这个变化看起来很小。
实际上对我的影响特别大。
还有一个变化更加反直觉。
我开始越来越认真地告诉 Codex
什么不要做。
以前会觉得 AI 这么强,那当然做得越多越好。
最好我讲一句,它顺手帮我把后面十件事全干了。
多爽。
V1 被教育完以后,我现在看到它「顺便」就有点警觉。
因为 Agent 很容易自己往下推。
这个接口既然改了,要不要顺便把旁边也统一?
这一块后面反正要做,要不要提前铺一下?
这里既然出现问题,要不要顺手重构?
每一个单独拿出来都挺有道理。
然后你的项目就在一堆「挺有道理」里面又开始自己生长。
所以现在我的 ACTIVE PLAN 里面,会出现很多以前的我看了肯定觉得特别啰嗦的话。
当前 Slice 到底允许做什么。
什么不允许做。
哪些模块不准提前碰。
甚至直接写
不得自动开始任何后续 Slice。
以前我最怕 AI 做得不够。
现在反而有时候会怕它做得太多。
我觉得这可能也是很多刚开始接触 Agent 的人后面都会遇到的一次认知变化。
Agent 越来越强以后,一个重要能力不只是继续告诉它
你还能干这个。
还能干那个。
有时候更重要的是告诉它
这里不要动。
那个不是你的任务。
做到这里。
停。
再然后,就是验收。
这个坑我也踩了很久。
Agent 特别喜欢给人一种完成感。
Completed。
Done。
All tests passed。
Implemented successfully。
一开始看到这些词真的很舒服。
绿了。
过了。
今天又推进一大截。
但我后来慢慢养成了一个习惯。
它说 Done,不算 Done。
它说完成,只能说明它认为自己完成了。
所以 V2 里面,代码写完只是中间一步。
后面还有测试。
Review。
文档。
Closure,也就是确认这个阶段到底有没有真的收口。
有些东西还必须真的去页面上手动操作。
我的项目里甚至出现过一个特别典型的情况。
113 个测试。
113 个全部通过。
Typecheck PASS。
Lint PASS。
Build PASS。
看着已经绿得不能再绿了。
结果继续去真实运行环境里验收。
还是有东西没有真正关闭。
那一次我对「测试通过」这四个字的理解都变了。
测试通过,只能说明
你写进测试里的那些东西通过了。
至于真正重要的事情,你是不是全部想到了,这是另一回事。
所以现在我越来越觉得一句话很重要。
Agent 很擅长达到你给它定义出来的标准。
真正危险的是
你自己根本没把重要的标准定义出来。
做到这里以后,Codex 在 V2 里面干的事情,已经越来越不像单纯帮我写代码。
它开始读 SPEC。
对边界。
跑测试。
看状态。
更新 Closure。
判断当前 Slice 到底能不能结束。
而我的工作也慢慢从
这段代码到底怎么写,
变成了
这个任务到底怎么定义?
什么叫完成?
它有没有跑出去?
这个选择放回整个系统里,到底对不对?
这也是我目前对 Harness Engineering 最朴素的理解。
不是研究一条更牛的 Prompt。
而是给 Agent 搭一个能理解、能执行、能检查,也知道什么时候该停下来的环境。
说到这里还有一个变化挺有意思。
我现在反而越来越少研究什么「神级 Prompt」了。
不是说 Prompt 不重要。
重要。
但它没有我一开始以为的那么重要。
因为 Prompt 更多解决这一轮怎么沟通。
一个真实项目的问题是,下一轮呢?
下下轮呢?
一个月以后呢?
换一个 Agent 呢?
今天这个需求和两个星期以前的设计打架了呢?
这些东西不是靠一条两千字 Prompt 就能永久解决的。
所以如果屏幕前的你也是刚开始接触 Agent,我现在反而觉得,有几件事比疯狂收集 Prompt 模板更值得练。
比如把模糊的东西讲清楚。
「我要一个账号系统。」
听起来很清楚对吧?
真做就知道,根本不是。
谁能登录?
谁创建账号?
一个账号能登录几个地方?
账号冻结以后,已经登录的 Session 怎么办?
不同身份能看什么?
能改什么?
Codex当然可以帮你一起回答这些东西。
但有一件事它替代不了。
你得知道这里有问题需要被回答。
再比如拆问题。
以前我希望 Agent 一次做得越多越好。
现在我反而愿意花时间,把一个大任务切成几个能够验收的小任务。
不是因为 Codex 干不了大的。
而是任务越大,你越难发现它从哪里开始偏。
还有「什么叫做完」。
这个东西我以前根本不会认真想。
能点。
算做完。
后来测试通过。
算做完。
再后来发现测试全过,也可能没做完。
我现在越来越觉得,未来 Agent 越强,「完成」这个词反而越需要人来定义。
因为它可以非常非常快地,给你一个看起来已经做好的东西。
以及最后一个。
别太相信 Agent。
这话写在一篇讲我怎么用 Codex 开发软件的文章里,多少有点奇怪。
但我确实比刚开始更不容易相信它了。
它说完成。
我会问证据呢?
它说这个方案最好。
我会问还有没有别的方案?
它说没风险。
我会让它继续查。
有时候甚至单独拉一个没参与实现的 Agent,再来 Review 一遍。
不是因为这些模型不聪明。
恰恰是它们已经足够聪明了。
聪明到有些错的东西,也能讲得特别像那么回事。
所以别因为一个 Agent 说话越来越像专家,就顺手把自己的判断权也交出去。
然后肯定还有一个问题。
既然 Codex 已经能干这么多,我们还要不要学编程?
我自己的答案是,要。
至少你准备真正把一个东西做深,就绕不过去。
我就是这么一路被逼着学过来的。
最开始 PLM 都不知道是什么。
往后做。
数据库来了。
权限来了。
Session 来了。
测试来了。
事务。
Migration。
架构。
Audit。
一个接一个。
但 Agent 给我带来的变化并不是
这些东西终于都不用学了。
而是学习顺序变了。
以前可能是
先学。
学会以后再开始做。
现在对很多年轻人来说,第一次有了另一条路。
先开始。
先真的做一个东西。
先撞墙。
然后站在一个真实的问题面前,去学此刻真正需要的知识。
为什么要做架构?
因为我真的把 V1 做到越来越难扩展过。
为什么测试很重要?
因为我真的遇到过页面能跑,但系统并没有真正闭环。
为什么要认真做权限?
因为五账号权限真的把我干懵过。
为什么一定要写文档?
因为我真的一遍又一遍给 Agent 重新解释过同一个项目。
以前看这些词,都是知识。
后来再看。
都是伤疤。。。
但我觉得这反而是 Agent 给年轻人特别有意思的一次机会。
它没有把学习变得不重要。
它只是第一次大幅降低了「开始」的成本。
以前你可能要站在门外学很久,才有机会进去做一次真的。
现在门开了一条缝。
你可以先进来。
然后在做的过程中,知道自己到底缺什么。
所以如果你刚接触 Agent,我其实不太建议第一件事就是找几十套万能 Prompt 存进收藏夹。
挑一个自己真的想做的东西。
别太大。
但最好也别只是为了练习而练习。
让它真的解决一个问题。
然后开始。
搞坏了怎么办?
搞坏了就搞坏了。
我第一版整个都放弃了。
但没有 V1,我大概率永远不可能真正理解 Harness Engineering 为什么有用。
很多东西就是这样。
不是你全部想明白了以后,才终于可以开始。
是你真的开始以后,才第一次有东西可以想明白。
写到这里,其实这篇文章应该结束了。
Harness 搭起来以后,V2 确实比 V1 稳定太多。
Codex 不再随便往外长。
我知道项目现在在哪。
知道当前 Slice 在做什么。
出了问题也更容易追。
换一个新的对话,Agent 可以先读仓库,而不是等着我给它从盘古开天重新讲故事。
挺好的。
然后新的问题来了。
项目不乱了。
我开始忙了。
我的工作流慢慢变成这样。
Codex 做完。
我把结果拿回来。
丢给 ChatGPT Review。
ChatGPT 找出问题,帮我整理下一轮。
我复制。
贴给 Codex。
Codex 再改。
改完回来。
再 Review。
再复制。
再贴过去。
来来回回。
有时候搞一天,我会突然觉得这件事特别抽象。
代码不是我写的。
测试不是我跑的。
Review甚至都能交给 AI。
结果整个系统里最忙的那个,好像还是我。
我的核心竞争力最后变成了两个快捷键。
Ctrl+C。
Ctrl+V。
绕了一大圈。
我又成了两个 AI 中间的快递员。。。
然后我突然想到一个问题。
Codex已经能自己读仓库、写代码、跑测试、看报错、继续修。
ChatGPT也能 Review、拆任务、检查风险、规划下一步。
那为什么中间这一轮一轮的东西,
还一定需要我亲手搬?
如果一次开发其实就是不断执行、验证、发现问题、修正,再验证,直到达到退出条件。
有没有可能让这套循环自己转起来?
我现在就在折腾这个。
我暂时把自己接下来想做的这套东西,叫做Loop Engineering。
如果 Prompt Engineering 是研究怎么跟 Agent 说话。
Harness Engineering 是研究怎么给 Agent 搭一个能长期工作的环境。
那我现在想解决的,就是怎么让 Agent 的执行、检查、修正这套循环,尽可能自己跑起来。
几个月前,我面对这个质检平台的时候,想的还是
怎么让 AI 帮我把代码写出来。
现在我想的已经变成了
怎么让一群 Agent 自己把这套工程跑起来。
中间也就隔了一个,被我彻底放弃的 V1。。。
至于这套 Loop 到底能不能跑通。
能跑到什么程度。
最后人在这里面又应该干什么。
我现在也不知道。
所以先不吹。
等我把这个坑再踩深一点。
下一篇,再聊。