Skip to content

第 12 章 质量门禁

这一章讲的东西,我自己大部分还没做到。所以与其说是"经验分享",不如说是"一个反例展览"——我把我项目里缺的东西摆出来,讲清楚为什么缺、应该补什么、优先级怎么排。

开篇:一个尴尬的事实

先说一个让我有点不好意思的事实。

我做了好几个 Agent 项目,代码量加起来好几万行。但直到现在,没有一个是配了 CI 的。

没有 GitHub Actions,没有提交时自动跑测试,没有 lint 强制检查。测试要靠人肉想起来才跑一次,代码风格靠自觉。我知道这不对,但就是这么过来的。

为什么会这样?因为在做 Agent 项目的过程中,兴奋点永远在"让 Agent 做新事情"上。每次有了新想法,我打开编辑器就开始写,写完在本地跑一遍——"诶,能用了"——就提交了。配 CI?下次再说吧。加测试?先让功能跑起来再说。

这个"下次再说"一拖就是好几个项目。回头看,这是 Agent 开发中最容易掉进去的坑——新功能的正反馈太即时了(跑一遍就能看到效果),而质量基础设施的正反馈太延迟了(不出事你感觉不到它的价值)。

缺了什么

我把缺的东西分成三类,按优先级从高到低排。

第一类:CI / 质量门禁(最该补)

这是最基本的。每次提交代码时,自动跑一遍:

  • 单元测试——有没有改坏了什么
  • lint——代码风格和常见问题
  • 类型检查——类型安全

这些东西在传统软件开发里是标配。Jenkins、GitLab CI、GitHub Actions,随便挑一个,配起来也就半天的事。但它的价值不是"半天配完就完了",而是每次提交都自动验证,改坏了立刻知道

没有 CI 的后果是什么?你改了一行代码,本地跑了跑没问题就提交了。但你不知道这行代码影响了另外三个地方——那三个地方你没跑。过了两周,某个用户触发了那个路径,报错了,你查了半天才发现是两周前那次改动引起的。有 CI 的话,提交的那一刻就会告诉你"你改坏了 X 测试"。

我所有的 Agent 项目都没有 CI。 这意味着我每次改动都是"手动跑我能想到的测试",而不是"自动跑所有测试"。漏测是必然的。

第二类:测试覆盖失衡

比"没有 CI"稍微好一点的是"有测试",但我的测试覆盖是失衡的。

我的 Agent 项目里,有的维度测得还行——比如 eval 框架(第 6 章讲的),有十几个用例覆盖了触发、记忆、工具调用。但有的维度基本没测——比如 HTTP 层、数据层、调度层。这些传统意义上"该测"的部分,我在 Agent 项目里几乎没写。

反过来,我做过的非 Agent 项目,测试集中在算法层——计算逻辑测得很细。但那个项目里的 LLM Agent 部分,一个行为测试都没有。

失衡的本质是:精力都花在了"Agent 行为"和"核心算法"上,基础设施层和集成层的测试被忽略了。 这跟没有 CI 是同一个毛病——兴奋点不在那里。

第三类:监控告警未闭环

这是最隐蔽的问题。不是"没有监控代码",而是监控代码写了,但没接通

我写过告警推送的功能——检测到异常就发通知。代码写完了,本地调试也过了。但它从来没有被接入定时任务。也就是说,告警能检测到问题,但永远不会推送出来,因为没人触发它。

我还写过决策记录的功能——有个 save_decision() 函数,记录 Agent 每次重要决策。但这个函数从来没有被业务代码调用过。表是空的,功能是空壳。

这种"有代码无闭环"的状态,在 AI 协作开发里特别容易出现。因为写一个独立功能(比如告警服务)很容易交付,但把它接进系统的主干流程——定时任务调它、决策流程记录到它——需要全局视角。而 AI 协作开发是"你让我做啥我做啥",你不主动说"把告警接进 scheduler",它就不会接。

该补什么,什么优先级

讲了这么多缺的东西,如果我现在停下来补,会按什么顺序?我给自己排了个优先级:

P0:CI。 这是最该补的,性价比最高。半天配好,以后每次提交自动验证。不用多想,先做这个。

P1:接通空壳闭环。 告警推送接入定时任务、决策记录接入业务流程。代码都写了,差的是"串"。这一步不写新代码,只是把已有功能接通。

P2:补基础设施测试。 HTTP 层、数据层、调度层的测试。不追求完美,先把"改一行代码会不会崩"这个问题用 CI 答上。

P3:eval 工程化。 eval 框架有了(第 6 章),但跑 eval 的结果还是靠肉眼比对 log。应该做成自动化的——每次提交自动跑 eval,结果自动比对回归基线,不通过的自动标红。

这个优先级的逻辑是:先解决"不知道改坏了什么"(CI),再解决"写了没用"(闭环),再解决"漏测"(测试),最后解决"eval 不自动"(工程化)。

一个更深的问题:为什么总是排在后面?

诚实地说,上面这些我都知道该做,但一直没做。为什么?

不是不知道怎么做,也不是做不了。是Agent 开发的节奏天然排斥防御性工程。

你用 Claude Code 写代码,让它配一个 CI——它可以配,但配完之后你没有"跑一遍看看"的即时快感。CI 的价值在"下次提交时自动验证",而那种延迟的、隐性的价值,和"让 Agent 学会一个新技能"的即时正反馈比起来,太弱了。

所以防御性工程总是排在后面。不是它不重要,是新功能的诱惑太强。这个心理陷阱,我自己到现在还在跟它搏斗。

我能给的建议只有一个:别等。 别等"功能做完了再补 CI"——功能永远做不完。在你写第三个功能之前,花半天把 CI 配上。它会改变你后续所有开发的安全感。

这一章的工具:质量门禁检查清单

🔧 质量门禁检查清单

对照你当前的 Agent 项目,过一遍:

CI(最基本)

  • [ ] 提交代码时,有没有自动跑测试?
  • [ ] 有没有自动跑 lint 和类型检查?
  • [ ] 测试不通过时,能不能阻止代码合并?

测试覆盖

  • [ ] 你的测试覆盖了哪些层?(算法层?HTTP 层?数据层?Agent 行为层?)
  • [ ] 有没有"测了 Agent 行为但没测基础设施"的失衡?
  • [ ] eval 用例跑完的结果,是自动比对还是肉眼判断?

闭环

  • [ ] 有没有"代码写了但从没被调用"的功能?(告警、日志、审计……)
  • [ ] 你的告警能真的推送到你手里吗?还是写完了但没接通?
  • [ ] 定时任务里调用的功能,都确认接通了吗?

危险信号

  • [ ] 你做的所有项目都没有 CI → 你和上面那些坑之间只差一个提交
  • [ ] 你的测试全集中在某个层 → 未覆盖的层就是下一个 bug 的来源
  • [ ] 你有"写了但没接通"的功能 → 不接通等于没写

小结

这一章是一个反例展览。我把自己项目里缺的质量基础设施——CI、测试覆盖、监控闭环——摆出来,讲清楚缺了什么、该怎么补、什么优先级。

核心结论就一句:"能跑的 demo"和"可靠的生产系统"之间,差的就是这些不性感但不能没有的东西。 而这些东西之所以总被忽略,不是不知道重要,是新功能的即时正反馈太强了,防御性工程永远排在后面。

这些我大部分还没做到。但知道该做、排出了优先级,至少是走出了第一步。

下一章

第 13 章 · 驾驭曲线 —— 你和智能体的协作关系,经历了什么变化?四个阶段,每阶段的标志是什么?