这套机制最早来自 Routa 项目内部的 fitness 实践。我们最初把它以 routa-fitness
的名字发布到 PyPI,作为 Routa 内部 fitness orchestration 的对外抽象;后来,随着它逐渐从项目内规则执行器演化成一套更独立的
change-lifecycle guardrails,我们把项目改名为 entrix。名字变了,但核心没有变:它仍然围绕 docs/fitness
里的规则定义、基于变更生命周期的质量门槛、风险分流、深度验证,以及在高风险场景下触发人工 review 的机制展开。
真正值得问的问题,不是“这个包能做什么”,而是:
当 AI 开始参与交付,工程系统靠什么判断一项变更到底算不算完成?
Vibe Coding 最迷人的地方,是局部反馈会变得非常顺滑。
你给出一个目标,AI 很快补全代码、修掉报错、加几条测试,终端持续吐出绿色信号:编译通过了,接口通了,页面能点了,测试也过了。整个过程看起来比传统开发更流畅,也更像“事情正在快速推进”。
但问题也恰恰出在这里。
Vibe Coding 提升的是局部推进速度,不会自动提升系统整体可信度。很多时候,熵增就是这样发生的:表面上的“已完成”越来越多,真正决定系统可靠性的约束、不变量和上下文,却没有同步进入自动化流程。代码变多了,绿灯变多了,提交变密了,但工程系统对“这次改动到底安不安全”的判断,并没有一起升级。
过去,这种空白可以靠人来吸收。一个资深评审者会本能地知道:这次改动虽然测试都过了,但仍然值得怀疑;这组 API 虽然都返回成功,但业务规则可能已经在 use case 层失真。可一旦执行者里加入 agent,这些原本依赖经验和默契的判断,如果没有被显式化,就会逐渐变成系统性风险。
所以,Vibe Coding 带来的最大变化,不是单纯的效率提升,而是完成条件开始漂移。 代码更快生成了,但“什么叫真的做完了”反而变得更模糊了。
几乎所有团队在引入自动化验证时,都会先从测试和覆盖率开始。我们也不例外。覆盖率直观、可量化、容易进入 CI,看起来像一个不错的工程控制面板。它至少能回答一个问题:哪些代码被跑到了。
但 Vibe Coding 里的问题,已经不再只是“有没有跑到”。
功能路径跑通了,负向路径有没有被验证?接口返回 200 了,契约字段有没有漂移?一组 endpoint 看起来都正常,跨层业务不变量是不是已经悄悄被破坏了?改动规模和风险半径已经变大了,系统有没有自动把它升级到需要人工复核的等级?
覆盖率对这些问题的回答能力是有限的。它可以是信号,但不是结论;可以是输入,但不是完成条件。真正重要的,从来不是数字本身,而是 变更之后,系统最关键的行为到底有没有被证明**。
后来,entrix 的 fitness 规则手册里留下了一句很重要的话:目标不是“覆盖率数字”,而是“变更后核心行为可被验证”。
这句话背后其实是一次方向转折。问题不再是“怎么让 agent 多跑几个测试”,而是:
怎么把完成条件从人脑里的经验,迁移成系统可执行的结构。
如果把 AI 看成只是一个更快的代码生成器,那么工程系统面对的似乎只是熟悉的问题:代码更多了,提交更密了,反馈更快了。可真实情况要难得多。
AI 可以很快把局部问题修平,也可以很快制造一种“已经差不多了”的完成感。构建通过了,接口通了,覆盖率也没掉,看起来一切都在朝“完成”推进。问题在于, 局部信号的增长,并不自动等于系统整体可信度的增长。
过去很多真正关键的判断,其实从来都不在 CI 里,而在人脑里:
这些判断一直存在,只是过去团队默认靠经验和默契来承担它们。Vibe Coding 的问题,不是凭空制造了新的风险,而是让这些原本隐性的判断权失去了稳定载体。
所以,AI 增加的不是单纯的代码量,而是系统对判断权显式化的压力。
真正失效的,不是某一条测试,而是那套默认由人脑兜底的完成标准。
很多团队谈 AI 工程化,第一反应是“把更多事情自动化”。这个方向没有错,但它不够。因为真正棘手的问题常常不是自动化做得太少,而是系统不知道什么时候不该继续自动化下沉。
这也是我们后来越来越清楚的一件事:反熵不是让机器做更多决定,而是重新设计哪些判断该交给机器,哪些判断只能由机器辅助,哪些判断必须留给人 。
在 entrix 里,我们最后把这条路径收敛成五个阶段:
rust-api-test、security 扫描,以及面向 desktop shell 的
E2E、Accessibility、Visual Regression、performance smoke。这个划分最重要的意义,不是看起来更流程化,而是把一个长期含混的问题讲清楚了:
Fitness 不是 SDLC 里的一个步骤,而是嵌在变更生命周期里的多阶段守护层。
越靠左,问题越确定,越便宜,越适合直接自动阻断;越往右,问题越依赖语义、上下文和后果判断,也越需要人的专业介入。真正成熟的人机协同,不是尽量消灭人,而是 把人的判断放在最值得花成本的位置。
如果再说得更直白一点: 反熵不是补更多测试,而是把判断结构重新设计清楚。
这套东西之所以会慢慢成形,不是因为我们先设计了一套漂亮的方法论,再回头找工具实现;恰恰相反,是因为项目里的真实问题不断逼着我们承认:很多原本依赖 review 经验和团队默契的判断,已经不能继续停留在口头层面了。
所以我们做了三件很朴素、但很关键的事。
第一,把规则写进仓库。
我们把治理规则收进 docs/fitness/*.md,用 frontmatter 去定义 metrics、threshold、tier、hard_gate
,把“应该这样做”变成“系统能读取、能执行、能追责”的结构。
第二,把证据写进仓库。
我们把 unit-test.md、rust-api-test.md 这类文件逐渐做成证据账本,不再只写“应该补测试”,而是明确写出哪些条目是 VERIFIED
,哪些仍然是 TODO,哪些已经 BLOCKED。它还远没有完美,但至少证据开始在仓库里有稳定落点,而不是继续漂浮在口头说明里。
第三,把解释收进执行器。
再往后,我们把规则解释和执行统一收进 routa-fitness 里,让系统不只是“跑几条命令”,而是开始承认哪些信号算 hard gate,哪些该按
tier 分层运行,哪些变化该触发人工 review,哪些检查只应该在 changed-only 场景里执行。
这件事的意义,不在于 Markdown 比 YAML 更优雅,而在于它改变了知识的存在方式。过去,很多判断只存在于人脑里;现在,它们至少开始以仓库内的形式稳定存在。过去,很多“完成”只是口头感觉;现在,它们开始带着证据状态进入系统。
说到底,我们真正固化的,不是检查命令,也不是某几条测试,而是:
在什么地方由机器直接判断,在什么地方由系统辅助标记,在什么地方必须把人拉回来。
这才是代码化固化真正重要的部分。
如果要挑一个最能说明这套方法是怎么从项目里逼出来的例子,我会选那个关于 Rust fitness 曾经缺少 application/use-case test
layer 的问题。
这个问题的关键不在于“测试不够多”,而在于测试分层本身出了问题。那时证据主要落在两端:一端是 store / 规则映射层的单元测试,但很多还是 TODO;另一端是 endpoint 级 API 回归和大型 E2E。中间缺掉了一层真正承载业务规则编排的 use case 级验证。
于是结果就变成:很多本来应该建立在业务规则上的信心,被迫建立在 handler 层接口测试数量上。
这和“覆盖率不够”其实是同一个问题的更深版本。问题不再只是数字失真,而是验证结构本身失真 。如果验证结构错了,哪怕测试很多,系统仍然可能对关键不变量缺乏直接证据。
后来我们把 tasks 和 sessions 的部分编排逻辑抽进了 application
service,并补上对应测试。这个案例让我们更清楚地看到:反熵不是简单地“加检查”,而是按风险重新分配验证成本。便宜、确定的问题要尽早自动拦下;昂贵、复杂的问题不应该平均铺开,而应该只在高风险时触发;真正高语义密度的判断,则必须承认机器只能辅助,不能代替。
问题不在于测试少,而在于验证结构可能是错的。
当规则、证据和执行器逐渐稳定下来之后,fitness 的角色也变了。它不再只是回答“通过没”,而开始回答“下一步该交给谁”。
这也是 changed-only、review-trigger、graph review context
这些能力真正有意思的地方。它们表面上看像功能增强,实际上代表了一种治理思路的变化:系统不再满足于对所有改动一视同仁地跑完一遍检查,而开始承认
变化感知本身就是治理能力的一部分。
不过就当前实现来说,这套能力还主要落在路径命中、diff 规模和 graph 辅助上下文上,离更完整的风险分流系统还有距离。但方向已经很清楚了:系统开始从“检查器”慢慢长成“调度器”。
尤其是 review-trigger,它背后的判断非常值得保留。不是所有风险都适合继续自动化下沉。有些改动如果触达高风险目录、扩大 diff
半径、碰到契约敏感区域,最合理的动作不是再补几条检查,而是明确要求人工参与。
这件事听起来并不“酷”,但它很真实。成熟的工程治理,不是尽量消灭人,而是知道什么时候必须把人拉回来。自动化的边界被画清楚,反而说明系统开始成熟了。
如果要把这段演进压缩成几条方法论,我会总结成四点。
第一,覆盖率不是完成条件。它是输入,不是结论。真正重要的是关键行为、负向路径、契约一致性和风险升级能不能被联合判断。
第二,治理规则必须进入仓库。一个 agent 在运行时发现不了的规则,在工程上就等于不存在。
第三,证据比口头说明重要。VERIFIED、TODO、BLOCKED 这样的状态看起来很笨,但它们比“应该已经测过了”可靠得多。
第四,自动化系统必须知道何时引入人工。成熟的 Harness Engineering,不是把一切都自动化,而是在高不确定性和高风险场景里增加 可计算的摩擦**。
如果再把这四点压成一句话,那就是:
AI 参与交付之后,真正重要的不是让生成更快,而是让完成条件、验证证据和审查升级变得可计算。
这也是为什么我们越来越把 fitness function 理解成一种反熵实践。它的目标不是让工程系统看起来更漂亮,而是让它在 AI 参与之后不那么容易失控。
今天你已经可以直接安装 routa-fitness。它远没有成熟到可以自称平台,也未必天然适合任何仓库;但对于那些已经感受到 AI coding
带来验证压力的团队来说,它至少提供了一个足够具体的起点。
不要再只问“agent 能不能写得更快”,而要开始问:
系统如何判断,它什么时候才算真正完成?
这就是我们最终想表达的事情。Vibe Coding 不是一个 prompt 问题,也不是一个“再补几条测试”的问题。它本质上是一个治理基础设施问题。只要 AI 进入交付闭环,完成条件、验证证据和人工升级路径就不能继续漂浮在口头经验里,它们必须被写进仓库、被执行器读取、被 agent 理解,也被组织持续演化。
未来,我们也许会把 routa-fitness 进一步做成一个 skill,让 agent 在进入项目的第一天,就带着一套可执行的 fitness
结构开始工作。但在那之前,这个项目至少已经证明了一件事:
代码治理不必永远藏在 CI 配置、review 经验和团队默契里。它可以被写进 Markdown,可以被执行器读取,可以被 agent 理解,也可以被组织持续演化。
围观我的Github Idea墙, 也许,你会遇到心仪的项目