最初做「回响」和县志通 App 时,我对 AI coding 其实挺兴奋的,直到项目慢慢变大,问题开始反复出现:已经修过的 bug 会重新回来。

说完成的功能,换个 AI 一 review,才发现里面不是 mock 数据,就是根本还没实现。

到后来我才意识到,AI 写代码最麻烦的地方,可能不是它不会做,而是它会把同一个问题一遍遍做错,还能很有把握地告诉你已经完成了。

这类问题最麻烦的地方,不是修起来有多难,而是它们很容易被“看起来完成了”这件事盖过去。

AI 会继续往下做,也会很有把握地告诉你完成了,真正需要补的却是我们自己对过程的检查。

所以我最近一直在实践 Harness Engineering ,这段时间也慢慢对这件事有了比较清楚的认知。

学着学着发现,我真正担心的不是 AI 不够聪明。

而是项目变大以后,它没有一个能持续记住上下文、复用结论、拦住半成品的工作流。

我重新理解了「仓库即真相」

我最深的一条实践心得,其实是“仓库即真相”。这里的“真相”不只是当前代码,还应该包括历史需求、做过的决策,以及为什么当时要这么做。

在过去的开发模式里,这些知识通常是碎片化的:API 文档、PRD、代码,分别维护在不同的系统里。人还能靠经验和到处翻,把它们拼出一个大概。

AI 拿不到完整上下文,做判断时自然容易偏。

我以前在字节搞过 monorepo,当时它主要是为了服务同一业务领域下不同微服务仓库的共同组件复用。这个模式带来的协作和研发效率问题,有时可能大于收益。

但放到 AI coding 里,monorepo 的价值变了,特别适合把一个业务里的微服务放在一起管理,代码、migration 文件、网关策略、Terraform 资源都在同一个仓库里。

这样一来,AI 才有机会看到业务的全貌。

所以我现在理解的 monorepo,不只是复用组件的工程方案,而是实现“仓库即真相”的一个基础设施。

AGENTS.md 只做入口,不做百科全书

在这种大仓库里,另一个问题是信息太多,不能把所有规则一股脑塞给 AI,所以要靠渐进式披露,把信息放在它需要出现的地方。

现在我更愿意让 AGENTS.md 只承载项目介绍、极少的指令,比如项目怎么启动、怎么测试,再加一个清楚的 md 目录,让 AI 知道下一步该去哪找。

具体的规则、模块说明和操作细节,跟着目录和代码往下放。这样顶层入口不会膨胀,信息也更容易和真实项目保持一致。

我开始给 AI 的“完成”加硬 gate

AI 提前完成、虚假完成,是我在大项目里遇到的另一个问题。它说“完成了”,不代表功能真的存在,更不代表它没有用 mock 把流程跑通。

所以硬 gate 不能只靠 AI 自己汇报,而要用 test、文件 hash 这类工作证明,把“完成”变成可以检查的 evidence。

具体需要什么证据,要看任务本身,但原则是一样的:AI 不能只说自己做完了,仓库里要留下能被检查的结果。

这比在对话里反复追问“到底完成没有”可靠得多,也能直接拦住那些看起来已经完成、实际还停留在 mock 或半成品状态的功能。

状态不能存在对话里

长程任务不能只存在对话里。项目一大,对话很容易断,靠聊天记录维持状态,基本迟早会漏东西。

所以我开始用 feature-listprogress.md 这类文件给任务加一个状态层,里面记录任务简介、任务状态、验收标准和 evidence。

AI 每次进场先读,离场前更新,下一次接着做时不用再从一团对话里猜上下文。

还有一个原则是 WIP=1,同一时间只做一个任务。这个道理很普通,但我自己也经常破戒,然后在发现 A、B、C 被顺手混在一起之后后悔。

限制 WIP 不是为了显得专注,只是为了让改动范围别失控。

系统会烂掉,review 不是可选项

再好的结构,放久了也会烂。文档会断链,AGENTS.md 会越写越长,orphan 附件会越来越多,规则也会慢慢和代码对不上。

我以前主要靠自己巡检,但我很清楚自己不是那种能坚持定期大扫除的人。

所以 review 也可以被做成机制,定期检查断链的文档、过时的信息、膨胀的 AGENTS.md,以及其他慢慢积累出来的问题。

这个 review 可以基于 skill 来做,让 AI 按照 rubric 给仓库打分,再把具体问题列出来。需要时跑一遍,比等我哪天突然想起来靠谱得多。

这不是为了偷懒,只是承认我会忘、会拖、会姑息。既然知道自己有这个毛病,就别把系统建立在自律上。

说到底,我是在给 AI 编程套一个工程壳

学完之后,我对 harness engineering 的理解变得具体了:它不是教你写更花哨的 prompt,而是把仓库、入口、硬 gate、状态记录和 review 串成一套能持续运行的工程结构。

这套结构默认 AI 会犯错、会过早宣布完成,甚至会在系统慢慢腐化之后继续基于过时的信息做判断。

它和普通软件开发里的 review、CI、测试、监控、日志,其实是同一类事情:不是因为工程师笨,而是因为人和 AI 都需要一套外部机制来约束自己。

我现在对工作流的要求变得很朴素:能跑、能测、能追踪、能 review。具体的活可以交给 AI,但怎么约束、怎么验收,还是得由我来决定。

我是在任务跑不通后修 harness

我现在也没有先把一整套 harness 设计好再去用,实际情况更像是:任务跑不通了,我就回头修 harness,修完再继续。

可能是上下文没放对,可能是 gate 没拦住,可能是状态没有记下来,具体哪一层出问题,就补哪一层。

所以这套东西是被回响、县志通里一个个跑不通的任务逼出来的,不是我一开始就想清楚的。

后面会长成什么样我不知道,先把眼前这个任务跑通再说。