你让 AI 修改一个功能,它很快读了十几个文件,也给出了一份看起来完整的 patch。
但检查以后发现,它改的是已经废弃的入口,没有找到真正的测试文件,还把业务逻辑塞进了 UI 层。这个时候,问题不一定是模型能力不够,而是它没有被正确地带进项目。
看到更多文件,不等于理解项目
上下文窗口变大,确实可以让 AI 同时保留更多代码、文档和历史对话。但“看到了”与“知道它们之间的关系”是两回事。
大上下文能帮助 AI:
- 读取更多相关文件
- 保留更长的任务背景
- 对照更多实现细节
但它不会自动告诉 AI:
- 哪个文件是真正的应用入口
- 哪些目录是核心业务模块
- 哪些文件只是生成物或旧实现
- 哪个测试才覆盖当前行为
- 哪些边界不应该跨越
一个真实仓库不是文件的简单集合。它里面有入口、分层、调用链、构建关系、历史兼容逻辑和暂时不能动的配置。人类工程师接手项目时需要 onboarding,AI 同样需要。
什么是代码仓库地图
代码仓库地图不是目录树截图,也不是把所有文件都写一遍。它是一份面向新人和 AI 的项目导航说明,重点描述结构关系和常见行动路径。
它至少应该回答六个问题:
- 项目由哪些部分组成
- 每个部分负责什么
- 前端、后端和数据之间怎么流动
- 常见任务通常从哪里开始改
- 测试、构建和运行命令是什么
- 哪些地方风险高或不建议直接修改
这份地图的价值,不是替代 AI 阅读代码,而是减少它在错误方向上的探索。
一份最小的repo-map.md
# repo-map.md ## 项目概览 ## 主要目录 ## 前端入口 ## 后端入口 ## 数据流 ## 常见任务修改路径 ## 测试与验证命令 ## 生成文件与源文件 ## 不建议修改的文件 ## 常见坑每一节都不需要写成大部头文档。比如主要目录只要解释职责,常见任务路径只要列出从页面到接口再到测试的大致链路,就已经比让 AI 自己猜强很多。
仓库地图最重要的是“修改路径”
很多项目文档只描述目录,却不告诉读者怎么完成任务。对 AI 来说,后者更重要。
例如一个记账 App 可以这样写:
## 主要目录 - frontend/src/pages:页面级流程 - frontend/src/components:可复用展示组件 - backend/app/api:接口入口 - backend/app/services:业务逻辑 - backend/tests:后端测试 ## 常见任务修改路径 - 改页面交互:先看 pages,再看 components 和状态管理 - 改接口行为:先看 api,再看 service 和 schema - 改统计口径:先看 stats service,再看查询测试 - 改识别规则:先看 parser,再补 parser tests它没有解释每一行代码,但告诉了 AI 应该沿着哪条路查找。这样可以减少只改前端、不改接口,或者只改实现、不补测试的情况。
用仓库地图约束 AI 的行动顺序
我更推荐把地图放进任务的第一步,而不是等 AI 改错以后再补。
1. 先阅读 repo-map.md 2. 根据任务列出影响范围 3. 说明计划修改哪些文件 4. 标出不涉及的模块 5. 人类确认范围后再修改 6. 按地图中的命令执行验证 7. 把新发现的坑补回地图这里最关键的是第三步。让 AI 先说“我要改哪些文件”,本质上是在让它把自己的项目理解外显出来。人类可以在真正产生 diff 之前发现方向是否错了。
一个具体的对比
需求是:给交易列表增加按分类筛选。
没有仓库地图时,AI 可能直接修改列表组件,在前端本地过滤数据;它没有意识到项目已经有后端查询参数,也不知道统计页面使用了同一个查询服务。
有地图时,AI 应该先列出:
- 前端筛选控件和列表状态
- 后端查询参数与 service
- 交易列表相关测试
- 统计口径是否需要同步
这个结果不代表 AI 一定不会犯错,但至少让错误更早暴露,改动范围也更容易控制。
老项目尤其需要仓库地图
新项目的目录通常比较干净,老项目则经常有重名模块、废弃入口、迁移中的代码、临时脚本和不完整测试。
这些信息对熟悉项目的人可能是常识,对 AI 却完全不是。可以在地图里明确写出:
- 当前使用的入口和已经废弃的入口
- 哪些文件是生成物
- 哪些迁移文件不能删除
- 哪些命令必须在特定目录执行
- 哪些模块正在迁移,暂时不要扩展
仓库地图不是一次性完工的设计文档。每次 AI 踩到新坑,或者团队发现一条稳定的修改路径,都可以补充进去;如果结构发生变化,就及时删掉过期信息。
我给这个记账 App 写的最小地图
一开始不需要画复杂架构图。我会先写一份能帮助 AI 找路的文本地图:
# repo-map.md ## 项目入口 - 前端入口:frontend/src/main.ts - 路由:frontend/src/router/index.ts - 后端入口:backend/app/main.py - API 路由:backend/app/api/ ## 业务链路 - 录入:EntryPage -> /api/parse -> parser service - 保存:EntryPage -> /api/transactions -> transaction service - 统计:StatsPage -> /api/stats -> stats service - 预算提醒:HomePage -> /api/alerts -> alert service ## 常见修改路径 - 改输入解析:parser -> parser tests -> API integration test - 改账单列表:BillsPage -> TransactionList -> transactions API - 改统计口径:stats service -> stats tests -> API response ## 不要直接修改 - frontend/dist/:构建产物 - 已发布的数据库迁移:除非明确要求,不删除历史迁移 - runtime-logs/:只读日志,不当作源文件这份地图有一个重要特点:它不仅描述“文件在哪里”,还写了“任务怎么走”。AI 接到“修复最近 7 天查询结果不对”时,应该沿着 parser、stats service 和对应测试去查,而不是只在页面组件里找字符串。
让 AI 先证明自己看懂了地图
我会使用一个固定的任务前提示:
请先阅读 repo-map.md,不要修改代码。 针对“修复最近 7 天支出统计”这个任务,请输出: 1. 当前请求从哪个页面或接口进入 2. 可能涉及哪些模块 3. 哪些文件只是展示层,哪些文件负责统计口径 4. 计划修改的文件和不修改的文件 5. 最小验证命令 如果地图和实际代码不一致,请先列出不一致之处。这一步很有用,因为 AI 的错误会在改代码前暴露。比如它把StatsPage.vue当成统计计算入口,我就知道地图或它的理解至少有一个需要修正。
地图要记录“不能相信什么”
很多项目的问题不在缺少文件说明,而在于仓库里存在很多容易误导人的文件。因此我会专门记录:
- 哪些目录是构建产物
- 哪些模块已经废弃
- 哪些测试依赖本地数据库
- 哪些接口目前固定
user_id = 1 - 哪些查询只支持规则表达,不支持任意口语
这些负面信息很容易被忽略,却是 AI 接手项目时最容易踩的坑。好的仓库地图不只告诉 AI 去哪里,也告诉它哪些地方不要凭文件名做推断。
最后
大上下文让 AI 看到更多代码,仓库地图让 AI 知道这些代码之间的关系。
真正稳定的 AI 编程,需要的不只是更多材料,而是更好的结构。对于个人项目来说,一份几十行的repo-map.md,往往比一次性把整个仓库塞进对话更有价值。
仓库地图不是给 AI 看目录,而是告诉 AI 从哪里理解项目、从哪里开始修改、改完以后如何证明自己没有走错路。