把多仓库项目的 AI 上下文整理成轻量 wiki:用仓内文档、架构图和 OpenAPI 建统一入口,让新会话少读废话、快进正题。
案例:一个前后端分离的多仓库业务项目
完成时间:2026-05-25
本篇定位:把体系建起来,并让它进入日常开发节奏。
核心结论
在多仓库项目里用 AI coding,最卡人的往往不是“AI 会不会写代码”,而是它能不能稳定拿到正确、足够、又不过载的上下文。
这个项目最终选择了一套轻量方案:瘦身 CLAUDE.md,用仓内 .wiki/ 承接项目语义,用 C4 Container 图表达前后端仓库拓扑,用 OpenAPI 作为前后端契约真相源,再让 AI 半自动维护 wiki。
这套方案没有追求一步到位的完美工程化,目标反而很朴素:
- AI 新会话能快速理解项目,不再每次重读 1496 行上下文。
- 人和 AI 都有统一入口,能按需深入模块、接口、数据流和约定。
- 后端接口变更能通过 OpenAPI 同步到前端类型,减少口头传递和跨仓 drift。
- 文档维护成本足够低,开发者只需在关键变更后说一句“更新 wiki”。
一、为什么要做这套体系
1.1 背景:前后端分离项目正在高频使用 AI coding
这个案例项目采用前后端分离架构,并拆成多个独立仓库:
| 仓库 | 职责 |
|---|---|
| 后端仓 | 提供业务 API、认证、数据模型和服务端模块 |
| 前端用户端仓 | 面向用户侧的 Web / H5 应用 |
| 前端管理端仓 | 面向运营或后台管理的 Web 应用 |
在 vibe coding 节奏下,AI 不只是补代码,而是参与设计、实现、测试、重构和跨仓影响分析。它需要知道四类信息:
- 项目结构:技术栈、目录、模块边界。
- 协作规则:命名、安全、TDD、token、i18n、commit 格式。
- 跨仓关系:前端 service 调哪个后端 endpoint,后端 schema 改动会影响哪些页面。
- 当前状态:正在做哪个模块,处于什么阶段,有哪些已知约束。
1.2 冲突:CLAUDE.md 已经从入口变成负担
过去这些信息主要塞在各仓 CLAUDE.md 里:
| 文件 | 行数 |
|---|---|
根 CLAUDE.md |
449 |
api/CLAUDE.md |
216 |
web/CLAUDE.md |
425 |
pc/CLAUDE.md |
406 |
| 合计 | 1496 |
麻烦不只是文档多,而是这些内容会在新会话里默认加载。结果就是:
- 小任务也要携带大量无关上下文,浪费 token 和注意力。
- 规则越多,AI 越容易漏掉某条关键约束。
- 跨仓调用、接口契约、模块边界仍然需要人肉搜索。
- 新协作者没有清晰入口,只能从长文档里自己找线索。
1.3 问题:怎样让上下文既完整又不过载
真正要解决的是这个问题:
如何在前后端分离、多仓库既定事实下,为人和 AI 建立一套可读、可维护、可增量更新的项目上下文系统?
我的结论不是继续往 CLAUDE.md 里塞内容,而是把上下文拆成几个层级:
CLAUDE.md只保留高频硬规则和入口链接。.wiki/记录模块、实体、流程、跨仓调用和约定。ARCHITECTURE.md用一张 C4 Container 图说明前后端仓库拓扑。openapi.yaml成为前后端接口契约的真相源。
二、方案怎么选
2.1 业界共识:上下文文件必须短,细节按需展开
调研后的核心判断有四个:
| 方向 | 可采用的原则 |
|---|---|
| AI 上下文文件 | CLAUDE.md / AGENTS.md 应短而稳定,主文件只放 WHY / WHAT / HOW |
| LLM Wiki | 让 AI 根据 commit 增量维护项目语义快照,而不是写流水账 |
| 架构表达 | 多仓拓扑用 C4 Container 层足够,不必一上来写完整 arc42 |
| API 契约 | Springdoc / Knife4j 输出 OpenAPI,前端由 spec 生成类型 |
这些原则共同指向一个结论:文档要进 git,格式要简单,维护要能被 AI 接手,真相源要尽量机器可校验。
2.2 关键取舍:选择轻量方案,而不是完整文档平台
项目评估过两条路线:
| 维度 | A:Markdown + Git | B:DeepWiki / arc42 / 外部文档站 |
|---|---|---|
| 上手成本 | 约 30 分钟 | 数天,且可能涉及私有仓付费 |
| AI 读取 | 直接读本地仓库 | 需要远端同步或 webhook |
| 离线使用 | 支持 | 依赖平台 |
| 协作者门槛 | 任意 IDE 可读 | 需要学习平台和文档模型 |
| 当前阶段匹配度 | 高 | 偏重 |
最后选了 A。它足够轻、足够快,也不会堵死以后升级到 DeepWiki、Mintlify 或完整 arc42 的路。
2.3 七项设计决策
| 决策 | 选择 | 理由 |
|---|---|---|
| Wiki 维护机制 | 半自动 AI + 人工触发 | 用户说“更新 wiki”后,AI 增量扫描 commit 并修改 .wiki/ |
CLAUDE.md 与 .wiki 关系 |
CLAUDE.md 瘦身,细节下沉 |
减少默认上下文,保留入口和硬规则 |
| 启动范围 | 前后端仓库并行 | 避免一半新体系、一半旧体系造成混乱 |
.wiki/ 粒度 |
5 件套 | 覆盖 modules、entities、flows、cross-repo、conventions |
| OpenAPI 同步 | api 仓为唯一源 | 前端从 GitHub raw 拉取 spec 并生成类型 |
| 架构入口 | 只画 C4 Container | 一张图说明前端、后端、数据库和协议关系 |
| Drift 检测 | 放进“更新 wiki”协议 | 零额外工具起步,后续再 CI 化 |
三、最终体系长什么样
3.1 三个入口文件分工明确
| 入口 | 解决的问题 |
|---|---|
ARCHITECTURE.md |
5 分钟理解系统拓扑、仓库边界、基础设施和通信协议 |
docs/wiki-usage-guide.md |
日常操作手册,说明何时更新 wiki、如何跑 OpenAPI、如何排障 |
各仓 CLAUDE.md |
AI 每次会话自动加载的最小规则集 |
3.2 每个仓库都有 .wiki/ 五件套
.wiki/ 是给人和 AI 共用的项目语义层:
| 文件 | 内容 |
|---|---|
_index.yaml |
wiki 索引、源文件映射、last_ingested_sha |
modules.md |
模块划分、职责、入口文件 |
entities.md |
核心实体、表、DTO、状态结构 |
flows.md |
关键业务流程和时序 |
cross-repo.md |
跨仓 endpoint、调用点、影响面 |
conventions.md |
命名、安全、Flyway、前端约定等横切规则 |
_index.yaml 是维护协议的关键。AI 更新 wiki 时,不需要重读全仓,而是从上次记录的 commit SHA 开始,只处理新增变更。
3.3 OpenAPI 是跨仓契约的中心
后端输出:
cd <backend-repo>
./scripts/export-openapi.sh
脚本会抓取多个服务的 /v3/api-docs.yaml,用 openapi-merge-cli 合并,经过 swagger-cli validate 校验后生成:
<backend-repo>/docs/openapi.yaml
前端消费:
cd <frontend-user-repo> # 或 <frontend-admin-repo>
npm run gen:api
前端脚本从 GitHub raw URL 拉取最新 openapi.yaml,用 openapi-typescript 生成:
src/api/types.ts
这样一来,后端字段变更会进入 git diff,前端类型也会立刻出现 IDE 红线和补全变化。跨仓协作就不再主要靠口头提醒。
四、日常怎么用
4.1 改了后端 Controller:先同步契约,再通知前端类型
适用场景:新增接口、修改参数、修改响应字段。
cd <backend-repo>
mvn -pl <backend-module> test
git add .
git commit -m "feat(<module>): add xxx endpoint"
git push origin main
./scripts/export-openapi.sh
git diff docs/openapi.yaml
git add docs/openapi.yaml
git commit -m "chore(api): sync OpenAPI contract"
git push origin main
前端随后执行:
cd ../<frontend-user-repo> # 或 ../<frontend-admin-repo>
npm run gen:api
git diff src/api/types.ts
4.2 前端要调新接口:先查契约,再决定是否补后端
先确认接口是否已经存在:
grep -i "<keyword>" <repo>/.wiki/cross-repo.md
grep -A 5 "<keyword>" <backend-repo>/docs/openapi.yaml
如果已存在,前端拉最新类型后实现 service 和页面调用:
npm run gen:api
如果不存在,先在模块设计文档里补 endpoint 设计,再切到后端仓实现 Controller,回到后端同步契约流程。
4.3 开始新模块:先写边界,再拆前后端任务
新模块不应直接开写代码。先建立设计文档:
mkdir -p docs/design/<module>
$EDITOR docs/design/<module>/01-architecture.md
最少包含六部分:
- 范围与边界:明确做什么、不做什么。
- 数据模型:ER、Flyway、核心实体。
- 接口契约:HTTP、DTO、错误码。
- 安全与权限:登录态、角色、限流。
- 前后端任务拆解:后端、用户端前端、管理端前端分别做什么。
- 测试策略:按 TDD 列出用例。
模块完成后,再说“更新 wiki”,让 AI 把新增模块写进 .wiki/modules.md、.wiki/entities.md 和 .wiki/cross-repo.md。
4.4 改了两个前端仓的同源副本:必须双端对齐
以下文件属于高风险同源副本:
utils/axios.jsutils/viewerSoul.jscomponents/ui/UiReveal.vuei18n/index.jsi18n/detect.jsstores/locale.jsstores/user.jsscripts/gen-api-types.mjs
提交前检查:
diff <frontend-user-repo>/scripts/gen-api-types.mjs <frontend-admin-repo>/scripts/gen-api-types.mjs
diff <frontend-user-repo>/utils/axios.js <frontend-admin-repo>/utils/axios.js | grep -v "APP_NAMESPACE\\|DEVICE_TYPE"
除了明确允许的 namespace 和 device type 差异,其余差异都要解释或修正。
五、怎么和 AI 协作
5.1 新会话只给任务,不要一次塞满所有文档
推荐说法:
我要改
<module>的登录流程,先读<repo>/.wiki/modules.md找入口,再看.wiki/cross-repo.md里的相关 endpoint。
不要把所有 wiki 全量贴给 AI。正确方式是让它从 CLAUDE.md 入口进入,再按任务需要读取具体 wiki 文件。
5.2 “更新 wiki”要有触发时机
必须更新的场景:
| 场景 | 原因 |
|---|---|
| 完成一个 Phase 或大功能 | 项目结构和状态发生变化 |
| 跨仓 schema 变更 | 前后端调用关系可能变化 |
| 新增或删除后端模块 | 后端模块边界变化 |
| 新增关键 store、util、service | 前端数据流变化 |
| 修改两个前端仓的同源副本 | 双端一致性需要记录 |
不必更新的场景:
- 修一个局部 bug。
- 重命名局部变量。
- 改几行样式。
- 不影响模块边界、数据流或接口契约的实现细节。
我的经验法则是:只要改动会影响别人理解项目结构、模块边界或跨仓关系,就更新 wiki。
5.3 AI 写业务代码前必须先过 TDD 自检
AI 在写实现前必须先做四件事:
- 列出涉及的公开 API:函数、store action、组件 emit、route、controller。
- 列测试用例:happy path、null、边界、非法字符、并发、限流。
- 写第一个测试并跑红。
- 等确认测试列表后再写实现。
如果 AI 试图跳过测试,可以直接拒绝:
TDD 是项目强制条款,不能跳。要么先写测试再写实现,要么缩小 scope。
六、它解决什么,不解决什么
6.1 立即解决的问题
第一,跨仓调用关系可索引。
以前查 /auth/login 的前端调用点,要分别 grep 用户端前端、管理端前端、view 和 service。现在优先看 .wiki/cross-repo.md 的 path:line 索引,再由 AI 或人工跳到源文件验证。
第二,API 契约有真相源。
后端接口变化进入 docs/openapi.yaml,前端通过 npm run gen:api 生成 src/api/types.ts。字段变化不再只靠 review 或运行时报错发现。
第三,新协作者有系统入口。
新人或新 AI 会话先看 ARCHITECTURE.md,再按任务进入对应 .wiki/,不用从 1496 行旧 CLAUDE.md 里硬找。
第四,默认上下文显著瘦身。
CLAUDE.md 总行数从 1496 行降到 783 行,下降约 48%。详细规则和历史资料转移到 docs/ 与 .wiki/ 中按需读取。
6.2 中期才会体现的价值
这套体系跑一两个月后,价值会从“好找文档”变成“文档不容易腐烂”:
.wiki/_index.yaml记录上次 ingest 的 commit。- AI 更新时只看新增 diff,不重写整篇 wiki。
- OpenAPI 让后端 schema 变更进入前端类型系统。
.wiki/cross-repo.md可以逐渐沉淀 breaking change watch list。
6.3 明确不解决的问题
这套体系不是万能工具。它不替代:
- 真正的代码 review。
- 对外文档站。
- CI 强制契约校验。
- mock fixture 与真实 schema 的自动对账。
- 权限、审计和访问控制。
换句话说,wiki 是地图,不是代码本身;OpenAPI 是契约,也不是完整的质量保障。
七、常见故障怎么排查
7.1 export-openapi.sh 报 no services available
通常是服务没起来。先检查服务端口:
curl -s http://localhost:9211/v3/api-docs.yaml | head
curl -s http://localhost:9216/v3/api-docs.yaml | head
lsof -i :9219
7.2 npm run gen:api 报 404
通常是 <backend-repo>/docs/openapi.yaml 还没推到远端 main。
cd ../<backend-repo>
./scripts/export-openapi.sh
git add docs/openapi.yaml
git commit -m "chore(api): generate OpenAPI contract"
git push origin main
cd ../<frontend-user-repo>
npm run gen:api
也可以临时用本地 spec:
npm run gen:api:local
7.3 OpenAPI merge 出现 schema 冲突
通常是多个服务定义了同名但不同结构的 schema。
./scripts/export-openapi.sh --keep-raw
cd /tmp/project-openapi-raw-*
diff auth.yaml user.yaml | grep -A 5 UserVO
优先把公共 DTO 收敛到后端公共模块;必要时给 schema 加 namespace,例如 AuthUserVO、UserUserVO。
7.4 CLAUDE.md 瘦身后 AI 忘了规则
先让 AI 去读对应 wiki:
这个规则在
.wiki/conventions.md,读完再继续。
如果某条规则特别关键、特别高频、特别容易被忘,再把它加回 CLAUDE.md 的 Forbidden 或速查区。
八、当前交付结果
截至 2026-05-25,已完成:
| 类别 | 内容 |
|---|---|
| 新建文件 | 31 个 |
| 编辑文件 | 6 个 |
| 结构化文档 | 约 3000+ 行 |
CLAUDE.md 瘦身 |
1496 行降到 783 行,约 48% 下降 |
主要新增内容包括:
ARCHITECTURE.mddocs/wiki-migration-plan.mddocs/wiki-usage-guide.mddocs/design-system.mddocs/PHASE_HISTORY.mddocs/testing-templates.md<backend-repo>/scripts/export-openapi.sh<frontend-user-repo>与<frontend-admin-repo>的scripts/gen-api-types.mjs- 前后端各仓
.wiki/五件套与_index.yaml
仍需本地端到端验证:
| 验证项 | 命令 |
|---|---|
| OpenAPI 导出 | cd <backend-repo> && ./scripts/export-openapi.sh |
| 契约推送 | git add docs/openapi.yaml && git commit && git push origin main |
| 前端类型生成 | cd <frontend-user-repo> && npm install && npm run gen:api |
| 双端脚本同源 | diff <frontend-user-repo>/scripts/gen-api-types.mjs <frontend-admin-repo>/scripts/gen-api-types.mjs |
| AI 增量维护 | 对 AI 说“更新 wiki”,观察是否按 _index.yaml 协议执行 |
九、为什么这是“够好”的方案
理想状态下,工程化当然还能更完整:monorepo、Nx、共享 schema package、CI 强制契约、DeepWiki 对外站、arc42 12 章文档,都可以继续往上加。
但当前阶段不需要一步到位,因为:
- 前后端多仓已经是事实,改 monorepo 成本大于收益。
- vibe coding 阶段更需要快速试错,而不是重流程。
- 单人或双人开发不需要完整 arc42 文档体系。
- 工程预算应该优先投入 design system、i18n、TDD 和真实功能。
这套方案的“够好”标准是:
- AI 能拿到必要上下文,少走弯路。
- 人有系统入口,30 分钟能上手。
- 跨仓 schema 变更不靠口头沟通。
- 文档维护成本接近零。
- 未来可以平滑升级到更重的方案,而不必推翻重来。
十、后续演进路线
| 优先级 | 演进项 | 触发条件 |
|---|---|---|
| P1 | 端到端验证 | 用户本地起服务时 |
| P2 | OpenAPI 导出接 Maven plugin | CI 成熟或上线前 |
| P2 | .wiki/ 维护协议实测 |
第一次正式说“更新 wiki” |
| P3 | 跨仓同源副本 lint 脚本 | 同源副本数量继续增加 |
| P3 | breaking change watch list 进入 PR template | 第一次发生跨仓破坏性变更后 |
| P4 | DeepWiki / Mintlify 对外站 | 准备开源或对外展示时 |
后续可以拆成两篇:
- 进阶篇:CI 化、Maven plugin、AI hook、full client codegen 评估。
- 上线篇:对外文档站、API 版本治理、breaking change governance。
一句话总结
这套实践没有发明新概念,而是把 CLAUDE.md 瘦身、LLM Wiki、C4 Container、OpenAPI 和前端类型生成 组合成一条适合前后端分离多仓项目的轻量工作流:让 AI 和人都能更快理解项目、更稳修改代码、更少在跨仓协作中丢上下文。
