过去一个多月里,我在创建 Routa 项目时,做了一个很激进的决定:让 AI 来驱动这个项目,把我的 idea 变成 issue,再把 issue 推进成可运行的代码。
真正让我敢这么做的,不只是兴趣,也不只是模型能力,而是我终于拿到了足够多的 AI 工具额度,可以把这件事当成一场持续实验来推进。按我自己的实践看,所谓 100% Agent,并不是买一个会员就够了。你大概要有 3 倍 max 额度,或者接近 600 美元量级的持续模型资源,AI 才可能真正成为每天的主力,而不是偶尔帮一下忙。
在这一个多月里,我前后使用过这些工具:
- 前期是 Copilot Pro(开源赞助)、按 request 计算的 Cursor,以及 2 月底 requests 用完后转用的 Augment Code(开源赞助)
- 当前主要使用 Codex(开源赞助)、按 credits 计算的 Kiro Opus 4.6,以及 Augment Code
- 另外还包括用在流水线里的 GLM,以及 Qoder、Antigravity、Kimi Code 等其它工具
但很快我发现,真正重要的并不是我接了多少个 AI,而是:当 AI 真正开始参与项目之后,项目本身会发生什么变化。
差不多一年前,我写过一篇文章《两周 3 万行代码!我们的 7 个 AI “粪堆”求生编程实践》,记录我们如何用 AI 做一场实验性色彩很强的 Vibe Coding。那次实践的重点,是验证 AI 能不能写、能不能堆出结果。说得更直接一点,当时的问题还是“AI 可不可用”。
但这一次不一样。Routa 这轮实践里,我开始真正把 AI Agent 当成队友。一旦关系从“工具”变成“队友”,问题就不再是它能不能产出代码,而是它能不能进入项目的协作系统:它有没有明确边界,是否遵守当前规则,写出来的东西是不是还落在共享契约之内,失败后能不能被及时拉回,这些失败又能不能继续沉淀成更稳定的 Harness Engineering。
这篇文章真正想讲的,就是这件事:25 万行代码只是结果,关键是一个全 AI 项目如何逐步长出自己的规则入口、反馈环和治理闭环。
队友:AI 已经不是助手,而是在系统里工作的成员
从仓库里的 co-author 统计看,这已经不是某一个 AI 在“帮忙”写代码。在 Routa 里,累计出现了 846 条 Co-authored-by,分布在 834 次提交中,背后是 24 种工具、25 种模型共同参与。数量最多的是 OpenAI Codex / GPT-5,但同时也能看到 Kiro、Claude、Augment、GitHub Copilot Agent、QoderAI、Cursor 等不同工具持续进入交付链路。
这说明一个很重要的变化:问题已经不是“AI 出现在 Contributors 里”,而是 AI 开始像人一样进入工程系统,并留下可被治理的操作痕迹。
在这种情况下,GitHub 的 Contributors 视图已经不够了。它最多只能说明“谁参与过”,却回答不了工程治理真正关心的问题:哪类 AI 在什么场景下写了什么代码,哪些问题可能和特定 tool/model 组合相关,哪些规则应该优先反馈给哪类 agent。
所以,Co-authored-by 在这里不是礼仪性的署名,而是出处。项目开始知道一段代码是谁、通过哪个模型写出来的,后续的规则反馈、失败归因和架构适度函数,才有机会变成真正可治理的系统能力。
换句话说,Routa 最值得讲的,不是“有 25 万行代码由 AI 生成”,而是 当 AI 真正成为项目劳动力之后,这个项目如何逐步长出自己的反馈系统。
一、第一个反馈环:Agent + AGENTS.md,把协作规则写成统一入口
这套系统的起点,不是 contract,也不是 CI,而是 Rule。
Routa 的规则入口是 AGENTS.md,CLAUDE.md 只是指向它的软链接。也就是说,规则只有一个单一事实源,而不是为不同工具分别维护多套副本。
渐进式披露:不是把所有知识一次性塞给 Agent
这看起来只是文件组织问题,背后其实体现的是治理思路:规则不能分散在不同工具的局部配置里,而要收敛成整个工程系统都能引用的统一入口。
但更重要的是,这个入口并不是把所有知识一次性灌给 Agent,而是承担“渐进式披露”的角色。
AGENTS.md 更像目录和操作合同,而不是百科全书。它先告诉 Agent 这个仓库有哪些稳定入口:产品边界去 docs/product-specs/FEATURE_TREE.md,系统边界去 docs/ARCHITECTURE.md,设计意图去 docs/design-docs/,执行计划去 docs/exec-plans/,质量与验证去 docs/fitness/。只有在处理对应问题时,Agent 才继续下钻到下一层文档和实现细节。
这种组织方式的意义在于,它避免了 prompt 过载。对 AI 来说,一次性灌入过多规则,并不等于更强约束,很多时候只会退化成噪音;反而是把入口、边界和下钻路径设计清楚,Agent 更容易在正确时机读到正确约束。
AGENTS.md 的演进:从协作纪律到治理引擎
它的大致演进可以分成三段。
第一阶段,是协作纪律成文。规则逐步明确了 baby-step commit、co-author 规范、提交前检查、issue 反馈流程。重点还是把“怎么和 AI 协作”写清楚,让编码行为开始具备可重复性。
第二阶段,是 Fitness 化。质量门禁开始被明确写进流程。规则不再只是“建议”,而是开始进入可执行检查链。系统不再只是告诉 AI “应该怎么做”,而是开始具备“做错了会被拦住”的机制。
第三阶段,是治理向 entrix 收敛。原本分散在文档、hook、CI 里的规则,开始围绕统一治理引擎收敛。Fitness 不再是若干孤立脚本,而是变成一套一致的工程裁决逻辑。
所以这里的 Rule,并不是“写一份超长提示词交给 Agent”,而是把协作规则做成一个分层知识入口:先暴露最小但稳定的协作契约,再通过文档树、Hook、Contract、Fitness 把更强的约束逐层展开。
这一步非常关键。我们把“AI 应该怎么做”,从自然语言提示,升级成了带结构、可下钻、可执行的工程约束系统。
二、第二个反馈环:Monorepo + Contract,把实现收回共享边界
如果说第一层反馈环约束的是 Agent 的行为,那么第二层反馈环约束的,就是实现本身。
Monorepo:把项目级变更放回同一上下文
很多团队谈 Monorepo,第一反应还是代码托管方式:把前端、后端、脚本和工具放进同一个仓库。但在 AI 项目里,它更重要的意义其实是共享上下文工程。
AI 最容易出问题的地方,不是不会写某一层代码,而是当一个需求同时跨前端、后端、桌面壳和多个服务时,它拿到的往往是几个彼此割裂的局部上下文。每个局部都能写一点,每一点看起来也都成立,但缺少统一工作面时,Agent 很难把这些修改收敛成一次完整、可验证的项目级变更。
所以,Monorepo 在这里不只是“代码集中”,而是“上下文收敛”。
在分散协作模式下,一个需求会被拆到前端、后端、桌面端、脚本和多个服务里,多 repo 或多目录各自演进,依赖关系隐式存在,Agent 也常常在不同会话间切换,结果就是上下文断裂。
而在共享上下文模式下,项目级变更会被收敛到同一个工作区里。产品边界、架构边界、实现代码、治理脚本、Fitness 证据和 issue 反馈都放进一个连续上下文,AI 才有机会从“局部编码”走到“跨层联动、一次完成”。
Routa 现在的做法,本质上就是把共享上下文做成工程结构,而不是靠人脑记忆去补:
AGENTS.md和docs/提供统一导航,让 Agent 先进入同一个项目入口src/、crates/、apps/、tools/共处一个仓库,让前端、Rust 后端、桌面壳和治理工具在同一个工作面里联动docs/fitness/、docs/issues/、docs/exec-plans/则把验证证据、失败反馈和执行计划也放进同一个上下文,而不是散落在外部系统
只有先把上下文收敛起来,后面的 Contract 才真正有地方落地。
Contract:把系统边界前置为共享契约
全 AI 项目最先失控的,往往不是代码风格,而是边界漂移。尤其像 Routa 这样的双后端项目,如果没有一个强约束的单一事实来源,AI 很容易在某一端写出“局部合理”的实现,却在系统层面制造偏差。
api-contract.yaml 的作用就在这里。它不只是一个接口描述文件,而是双后端共享的边界定义。Next.js 和 Rust 两端都必须实现同一套 endpoint,并保持请求和响应 shape 一致。
更重要的是,这不是一个静态文档。它已经进入验证流程:先改 contract,再改实现;先定义边界,再允许编码。项目不再默认“先把代码写出来,再去补一致性”,而是要求实现从一开始就落在共享契约里。
从当前实现看,这套 Contract 至少有三层约束同时生效。
第一层,是 docs/fitness/api-contract.md 明确把 api-contract.yaml 定义为 single source of truth,并要求新增 endpoint 按“先改 contract,再改 src/app/api/,再改 crates/routa-server/src/api/”的顺序推进。
第二层,是 npm run api:schema:validate 和 npm run api:check 这组检查,把 schema 合法性、Next.js 实现、Rust 实现拉到同一个对照面上。这里检查的不只是“有没有这个接口”,还包括 breaking change 是否被无意引入。
第三层,是 tests/api-contract/test-schema-validation.ts 这种运行时契约测试。它会直接读取 contract,检查 operationId、request schema、response schema,并对真实 API 响应做 AJV 校验。也就是说,Contract 在 Routa 里既约束设计时边界,也约束运行时 shape。
这意味着 AI 可以探索实现,但不能随意改写边界。对于全 AI 项目来说,这一点非常关键。因为系统最先崩掉的,往往不是功能本身,而是一致性。
三、第三个反馈环:Git Hooks + Lifecycle,把约束前移到提交前
如果说 Rule 解决的是“Agent 应该怎么做”,Contract 解决的是“实现边界不能漂移”,那么第三层反馈环解决的就是:AI 不能先在本地制造过大的偏差,再把问题整体抛给远端 CI 或人工评审。
Git Hook Lifecycle:本地不只是检查,而是前移裁决
当前仓库里的 pre-commit 很轻,只跑 lint。真正关键的是 pre-push 和 smart-check.sh。它们不仅运行基于 entrix 的检查,还会识别当前是不是 AI agent 环境:如果是 AI,就返回结构化失败信息,要求修复后重试;如果是人类环境,则保留更有弹性的交互修复路径。
也就是说,这里的 Hook 已经不只是 Git Hook,而是一个前移裁决器。
scripts/smart-check.sh在 push 前实际调用的是python3 -m entrix.cli run,默认跑eslint_pass、ts_typecheck_pass、ts_test_pass、markdown_external_links这些明确指标,而不是随意拼一串 shell- 同一个脚本还会额外执行
entrix.cli review-trigger。这一步不是测对错,而是测风险:例如docs/fitness/review-triggers.yaml已经把src/core/acp/**、src/core/orchestration/**、crates/routa-server/src/api/**这些目录标成高风险边界;一旦改到api-contract.yaml、defense.yaml,或同时跨越web/rust/tools多个边界,就会触发 human review - 更关键的是,evidence gap 也被前移到了 Hook 里。也就是说,不只是“代码改了要不要过测试”,而是“你改了核心路径,却没有同步更新
docs/fitness/**或契约证据”,这种行为本身就会被识别出来
这里体现的不是脚本技巧,而是一种治理思路:同一个反馈环,应该针对不同执行主体返回不同类型的反馈。对 AI,反馈必须足够明确;对人,反馈可以保留判断空间。
自动触发重构:先阻止继续恶化,再谈彻底治愈
更进一步,代码规模治理也不再只是简单的 wc -l。现在仓库已经把它演进为预算与冻结机制:变更文件必须控制在预算内,而历史上已经过大的热点文件,不要求一次性治愈,但不能继续膨胀,只能逐步收缩。
这件事在 Routa 里已经有了很具体的实现。
tools/entrix/file_budgets.json把预算写成了配置:默认ts/tsx文件上限是 1000 行,.rs文件上限是 800 行tools/entrix/entrix/file_budgets.py并不是静态比对绝对阈值,它会读取HEAD里的历史版本行数,把已经超标的文件按当前基线冻结- 这就形成了一个很实用的 ratchet 机制:正常文件不能超预算;历史热点文件不用一次性回到理想状态,但它的天花板被锁死,后续提交只能把它做小,不能继续做大
- 这种机制已经进入 Fitness。
docs/fitness/code-quality.md里,一条指标检查变更文件是否满足预算,另一条legacy_hotspot_budget_guard直接作为 hard gate,专门守住这些已登记热点文件“只许缩小、不许膨胀” - 同时,它也进入 Hook 与重构工作流:
.husky/post-commit会调用entrix hook file-length给出预算告警,docs/REFACTOR.md则把“先处理 budget violation,再按热点和变化频率排序”写成明确顺序
这类机制的意义在于,它不是试图一次性消灭历史包袱,而是先建立“不能继续恶化”的边界。对全 AI 项目来说,这比完美治理更现实,也更重要。
四、第四个反馈环:CI/CD + Fitness,把本地约束升级成仓库级裁决
前面三层反馈环,更多发生在本地和开发过程中。但如果项目真的进入全 AI 状态,仅靠本地约束还不够。团队还需要一个仓库级、共享的、可审计的系统,来判断当前变更到底处于什么质量状态。
这就是 docs/fitness/、entrix 和 Defense workflow 的作用。
在 Routa 里,Fitness 已经不再是“测试补充”,而是一套仓库级的裁决机制。它强调 contract-first、blast radius control 和 anti-entropy,把仓库治理拆成多个质量维度,并通过统一引擎执行。
从实现细节看,这套 Fitness 至少有几个值得注意的点。
第一,它是 Markdown frontmatter 驱动的。docs/fitness/*.md 不是普通说明文档,而是维度声明文件。每个文件都会定义 dimension、weight、tier、threshold、metrics,把规则和证据放在同一个载体里。
第二,它有明确的分层执行模型。当前 docs/fitness/README.md 把检查分成 fast、normal、deep 三层,对应从 lint / 契约检查,到单元测试 / API 测试,再到 E2E / 安全扫描。也就是说,Fitness 在这里不是一个一次性的大总检,而是按反馈时机分层组织。
第三,它已经有统一执行引擎。tools/entrix/entrix/engine.py 会加载这些维度,按 metric 类型分派给 shell runner、SARIF runner、graph probe runner,再统一汇总成 report。像 graph:impact、graph:test-radius 这样的 probe 指标,也已经进入同一套执行路径,而不是散落在脚本角落里。
第四,它不只是算分,还会做 incremental filtering。entrix 会基于 changed files 推导 domain,只运行和当前改动相关的 metrics。这样 AI 拿到的反馈会更集中,不会每次都被整仓库噪音淹没。
我们再通过 GitHub Action(.github/workflows/defense.yaml)把这件事真正展开。它不再只是传统意义上的 CI,而是把 Code Quality、Testability、Security、API Contract、Design System、Evolvability、UI Consistency、Observability、Performance 等维度拆成独立 jobs,分别执行、分别汇总。
这带来的变化很重要:团队不再只知道“这次提交挂了”,而是知道它挂在契约、测试性、安全还是可演进性上。质量问题不再是一个黑盒结果,而是一组可以被讨论、被分工、被持续优化的治理维度。
自动修复 CI:失败不只是被拦住,还要能回流
更进一步,当夜里 CI 失败时,系统会交给 Coding Agent 做自动修复。这说明系统的目标不只是“把错误挡在门外”,而是在尝试构建一个失败可回流、规则可沉淀、修复可自动化的闭环。
这恰恰是全 AI 项目成熟的标志:不是 AI 总能一次成功,而是系统能不能把失败转化为下一轮收敛的输入。
真正的门槛,不是模型能力,而是治理能力
很多团队谈 AI 开发时,容易把注意力放在模型、agent 和自动化程度上。但这些更多是供给侧能力。
真正拉开差距的,是项目有没有准备好一套系统去接住这些能力。
Routa 当前展示出来的,不只是“AI 大量写代码”,而是“项目逐步把 AI 纳入工程系统”:先用 Rule 约束 Agent,再用 Monorepo 收敛上下文,再用 Contract 锁定边界,再用 Hooks 把约束前移,最后用 Fitness 和 CI 做仓库级裁决。
代码本身只是结果,真正支撑这个结果的,是一套持续收紧、持续反馈、持续收敛的工程闭环。
这条路径说明了一件事:在 AI 编程时代,真正的竞争力,未必首先来自模型有多强,而更可能来自团队能否把规则、验证、反馈和修复织成一套稳定运转的工程系统。
代码规模只是结果,治理能力才是护城河。
结语:全 AI 不是放弃治理,而是强化治理
很多人谈“全 AI 项目”时,容易带着一种自动驾驶式想象:只要模型足够强,系统就会自己越跑越稳。
但工程现实往往相反。
越是大量依赖 AI,越需要更清晰的边界、更显式的规则、更高频的反馈和更系统的验证。真正支撑全 AI 项目的,不是放弃治理,而是把治理前移、细化并自动化。
所以,对 Routa 这样的项目来说,最值得讲述的并不是“25 万行代码由 AI 写成”这个结果本身,而是这个结果背后的工程判断:团队并没有把 AI 当成一个更快的代码生成器,而是在持续把它纳入一个越来越严密的反馈系统中。
这才是全 AI 项目真正开始成立的时刻。
或许您还需要下面的文章: