当项目规模增长到一定程度,AI 代理在修改代码时最大的挑战不是"写不出来",而是"不知道该遵守什么规则、该改哪些文件"。本文分享一套在实际大型项目中验证过的分层导航式文档体系,让 AI 代理能够自助获取上下文、遵守架构约束、并在跨域修改时不遗漏任何文件。
问题:AI 代理的上下文困境
大型项目中使用 AI 编程代理(GitHub Copilot、Claude、Cursor 等)时,常见的痛点包括:
- 规则遗忘:你告诉它"必须用某个异步框架",它在另一个文件里又写出了被禁止的写法
- 改错地方:需要同时修改 3 个模块的代码,它只改了 1 个
- 缺乏领域知识:不了解初始化顺序、事件总线约定、数据字段命名规范
- 重复解释:每次开新对话都要从头描述一遍项目架构
根本原因是:AI 代理没有结构化的、可自助检索的项目知识库。
我们的解决方案是一套四层文档体系:Constitution → Root Router → Domain Routers → Cookbook,外加 AI 代理自身的记忆系统作为第五层。
第一层:Constitution — 宪法(铁律)
文件:.github/copilot-instructions.md
这是整个体系的基石。它定义了在任何情况下都不可违反的全局硬规则。
GitHub Copilot 会自动将此文件注入到每次对话的上下文中(这是 GitHub 的原生功能),其他代理(如 Claude Code)需在启动时手动读取。
Constitution 的内容按类别组织,以下是一些典型条目(已脱敏):
设计原则:
- 只写"什么不能做",不涉及导航或具体实现
- 每条规则都源于一次真实的 Bug 或返工 — 比如"DTO 字段名是
id,不是entityId"就是因为 AI 代理曾多次用错字段名 - 格式精简,确保在 token 限制内能完整加载
Constitution 就像法律体系中的宪法:它不告诉你该做什么,但它明确告诉你什么绝对不能做。
第二层:Root CLAUDE.md — 项目路由器
文件:项目根目录的 CLAUDE.md
如果 Constitution 是"法律",Root CLAUDE.md 就是"地图"。它提供项目全貌和任务路由表:
AI 代理拿到一个任务后,首先查这张表,就知道该去读哪个领域文档。不需要盲目搜索整个代码库。
Root CLAUDE.md 还包含:
- 项目简介和核心业务循环描述
- 技术栈速查表
- 目录结构图
- 关键架构模式速览(事件驱动、依赖注入、接口隔离等)
设计原则:只导航,不定义规则。 规则全部在 Constitution 中;Root 只负责告诉你"往哪看"。
第三层:Domain CLAUDE.md — 领域路由器
分布:每个主要子目录下各一个,项目中共 18 个。
这是体系的核心工作层。每个领域路由器包含:
3.1 父级声明
每个文件都显式声明自己的上级和最终权威来源,形成清晰的引用链。
3.2 文件角色表
列出该目录下每个文件是什么、做什么:
这让 AI 代理不需要打开每个文件去读代码就能判断"我应该改哪个文件"。
3.3 初始化顺序和依赖约束
3.4 子域路由
大领域(如 Core)会继续向下分层:
树状引用网络
所有 CLAUDE.md 形成一棵引用树:
引用方向:
- 向上:每个文件声明父级 + Constitution
- 向下:父级列出子领域
- 平级:任务路由表指向兄弟领域
- 跨域:指向 Cookbook
设计原则:每个 CLAUDE.md 都是自包含的上下文包。 读完它,你就知道在这个目录下能做什么、不能做什么、以及要改别的东西该去哪里。
第四层:Cookbook — 跨域操作手册
目录:Docs/Cookbook/
前三层解决的是"在一个领域内怎么改"的问题。但现实中,很多任务需要同时修改多个领域。比如:
- 添加一个新的运行时服务 → 要改 DI 注册、启动序列、存档系统、可能还有 UI
- 添加一个新的数据模型类型 → 要改模型定义、接口、数据管理器、UGC 模式支持
Cookbook 为这类常见操作提供步骤式检查清单:
每个 Cookbook 条目都会标注:
- 需要修改哪些文件(跨多个领域)
- 修改的顺序
- 需要遵守的约束(来自 Constitution)
- 常见踩坑点
设计原则:Cookbook 是过程知识,不是结构知识。 Domain CLAUDE.md 告诉你"这里有什么";Cookbook 告诉你"做这件事要走什么流程"。
第五层:AI 记忆系统 — 临时与持久
文档体系解决了项目知识的问题,但 AI 代理还需要工作记忆。我们利用代理自带的记忆机制分三个作用域:
| 作用域 | 路径 | 生命周期 | 用途 |
|---|---|---|---|
| Session Memory | /memories/session/ | 当前对话 | 任务进度、中间发现、临时笔记 |
| User Memory | /memories/ | 跨所有对话 | 用户偏好、常用命令、经验教训 |
| Repo Memory | /memories/repo/ | 跨对话、绑定仓库 | 代码库约定、已验证的构建命令 |
Session Memory 特别重要:当一个任务需要多步完成时,AI 代理可以在 Session Memory 中记录"我做到哪一步了、发现了什么、还剩什么要做",即使中间被打断也能恢复上下文。
实际工作流
当 AI 代理收到任务"给实体添加一个新的属性维度"时,完整的工作流是:
整个过程中,AI 代理不需要人类逐步指导,也不需要搜索整个代码库碰运气。
设计心得
为什么选择 Markdown 而非代码注释?
代码注释是局部的——你只有打开那个文件时才能看到。而 AI 代理需要的是在打开文件之前就知道该打开哪个文件。CLAUDE.md 提供的是元信息(meta-information),它超越了任何单个源文件的范围。
为什么要分层而不是一个大文档?
一个 10000 行的文档会撑爆 AI 的上下文窗口。分层设计确保每次只加载当前任务相关的上下文——Constitution(~100 行)+ Root(~150 行)+ 1-2 个 Domain(各 ~100 行)= 总共约 500 行,远在 token 预算之内。
为什么 Constitution 放在 .github/ 下?
因为 GitHub Copilot 原生支持自动加载 .github/copilot-instructions.md。这意味着最重要的规则不需要任何额外操作就会被注入到每次对话中。其他代理也可以通过类似机制(如 Claude Code 的 CLAUDE.md、Cursor 的 .cursorrules)自动加载对应文件。
每条 Constitution 规则背后都有一个故事
我们不会"预防性地"添加规则。每一条铁律都源于一次真实的 Bug、一次返工、或一次 AI 代理的错误输出。比如:
- "DTO 字段名是
id,不是entityId" — 因为 AI 代理三次把字段名猜错 - "Deep-copy reference-type lists in save data" — 因为浅拷贝导致了一次隐蔽的存档损坏
- "动画 tween 必须绑定生命周期" — 因为场景切换时 tween 没有被清理,导致空引用
关于 CLAUDE.md 的命名
CLAUDE.md 这个名字来自 Anthropic 的 Claude Code 约定——Claude Code 会自动读取工作目录下的 CLAUDE.md 文件。但在我们的体系中,它的作用已经超越了特定 AI 工具:任何 AI 代理(甚至人类开发者)都可以沿着这套导航体系找到所需的上下文。你也完全可以改用 AGENTS.md、CONTEXT.md 或任何你喜欢的名字——关键是分层导航的结构,而非文件名本身。
总结
| 层级 | 文件 | 职责 | 加载方式 |
|---|---|---|---|
| Constitution | .github/copilot-instructions.md | 不可违反的全局铁律 | Copilot 自动 / 其他代理手动 |
| Root Router | CLAUDE.md(根目录) | 项目概览 + 任务路由表 | 代理按约定自动读取 |
| Domain Router | 各子目录 CLAUDE.md(×18) | 领域知识 + 文件角色 + 子域路由 | 按需读取 |
| Cookbook | Docs/Cookbook/*.md | 跨域操作步骤清单 | 按需读取 |
| Memory | /memories/session/ 等 | 工作记忆 + 持久经验 | 代理自行管理 |
这套体系的核心理念是:把 AI 代理当作一个需要入职培训的新同事。Constitution 是公司制度手册,Root CLAUDE.md 是组织架构图,Domain CLAUDE.md 是部门指南,Cookbook 是标准操作流程(SOP),Memory 是个人笔记本。
当这些层级配合得当时,AI 代理可以在几乎不需要人类干预的情况下,安全、准确地完成复杂的跨域代码修改。