让 AI 理解代码库:仓库说明、AGENTS.md 与项目上下文
摘要
AI 编程助手能搜索代码,却不一定知道项目为何选择某种目录结构、哪些命令才是有效的测试入口,以及哪些文件属于不可修改的生成物。要让它可靠地参与开发,既要提供简短、准确的仓库说明,也要让它通过实际文件和命令核对说明是否过期。
下面从 README、任务说明、项目级 AGENTS.md 三种上下文入手,给出一份可复用的说明样例,并用一个 Python 小项目演示“先读说明—定位入口—运行检查—控制改动范围”的完整过程。
一、背景与问题
同一句“修复订单折扣计算”,放在两个仓库里可能需要完全不同的实现:一个仓库用整数分保存金额,另一个使用 Decimal;一个入口是 HTTP 控制器,另一个入口是消息消费者。只读取名字相近的文件,很容易修改到并非真实调用链的旧实现。
开发者通常能从团队约定和项目历史中补足这些信息,但新的 AI 会话并不天然知道。把全部项目代码一次性粘进对话并不划算:信息过多会淹没关键约束,还可能把日志、密钥或不相关数据带入上下文。
更可维护的做法是把长期有效的工程事实放在仓库可见的文档里,把本次任务的目标放在任务描述里;让助手按需搜索代码,发现文档与实际实现不一致时主动报告。
二、核心概念
| README | 项目用途、快速启动、公开目录入口 | 面向人和工具,随项目变更更新 |
| 项目指令文件 | 每次协作都需要的命令、不可破坏的业务约束、编辑边界 | 短小、可执行、随仓库评审 |
| 任务描述 | 本次目标、允许范围、验收和禁止动作 | 每项任务单独写,不常驻仓库 |
| 源码与测试 | 实际调用链、行为和可执行契约 | 通过搜索、运行和测试核实 |
AGENTS.md 是一种仓库内写给 AI 编程助手的说明文件名。不同工具对它的发现范围、加载方式和指令冲突的处理可能不同,不能假定只要创建文件,所有工具就会自动读取。同类机制还包括 Claude Code 使用的 CLAUDE.md;README 通常是所有读者都能找到的入口。若团队使用多种工具,可以把共同的事实维护在 README 和可复用的短文档中,再在相应工具的指令入口指向它们;不要维护几份逐渐不一致的长篇副本。
重要区别:项目说明是提供上下文,不是严格的安全隔离。涉及密钥、生产数据、文件系统写入和部署时,仍要依靠文件权限、沙箱、审批流程与 CI 等强制机制。
三、工作原理
让助手认识仓库,不是让它记住每个文件,而是建立“入口—调用链—验证点”的地图:
任务目标与项目说明
↓
确认仓库根目录、工作区状态、项目类型
↓
寻找入口、相关模块、测试与配置
↓
用真实代码和命令校验说明中的事实
↓
列出影响文件、不确定点、最小验证路径
↓
实施改动 → 聚焦测试 → 回归检查 → 审查差异
项目说明最有价值的是无法轻易从代码推断的事实,例如“金额存储为整数分”“生成代码由脚本覆盖”“新接口必须沿用旧的错误包装”。反之,“src/ 放源代码”这类从目录名就能发现的信息,无须重复几百字。
更新频率也决定存放位置:稳定的测试命令适合写进项目说明;一次性排障时的日志、订单号和当前实验分支不适合长期保留。文档里出现“上次用了某个版本”的说法时,助手应重新核对本次运行环境。
四、实战示例
假设我们有一个简单的折扣计算仓库:
shop-demo/
├─ README.md
├─ AGENTS.md
├─ src/
│ └─ shop/
│ └─ pricing.py
└─ tests/
└─ test_pricing.py
这里的目录是示意,不依赖特定工具或真实外部服务。pricing.py 中的金额统一使用整数分,函数只负责计算,不访问数据库:
# src/shop/pricing.py
def apply_discount(total_cents: int, discount_cents: int) –> int:
if total_cents < 0 or discount_cents < 0:
raise ValueError("amounts must be non-negative")
return max(0, total_cents – discount_cents)
最小测试使用 Python 标准库,直接验证这段代码:
# tests/test_pricing.py
import sys
import unittest
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
from shop.pricing import apply_discount
class PricingTests(unittest.TestCase):
def test_discount(self):
self.assertEqual(apply_discount(1500, 200), 1300)
self.assertEqual(apply_discount(100, 200), 0)
def test_invalid_amount(self):
with self.assertRaises(ValueError):
apply_discount(–1, 0)
if __name__ == "__main__":
unittest.main()
在仓库根目录运行 python -m unittest discover -s tests -v 即可执行示例测试;若使用 Windows PowerShell,也可用 python -m unittest discover -s tests -v。项目目录不需要先修改全局 PYTHONPATH,因为示例测试已经显式加入 src。真实项目应优先沿用现有安装与测试配置,而不是照搬这一临时演示写法。
1. 写短而准的仓库说明
README 的作用是帮助人和助手从仓库根目录找到入口:
# shop-demo
这是一个演示整数分金额计算的小型 Python 项目。
– 代码入口:src/shop/pricing.py
– 测试入口:tests/test_pricing.py
– 从仓库根目录运行:python -m unittest discover -s tests -v
– 金额单位:整数分;不要引入浮点金额运算。
项目级 AGENTS.md 可以聚焦协作边界:
# Project instructions
– 修改前先检查 git status,报告已有未提交改动。
– 金额单位始终为整数分;折扣结果不得小于零。
– 只修改当前任务相关文件,不顺手调整公开函数签名。
– 编辑后运行 python -m unittest discover -s tests -v。
– 汇报实际命令、测试失败和未验证事项;不要擅自提交或推送。
这个文件没有复制整个 README,也没有写“必须永远正确”之类无法验证的口号。它只提供稳定、具体、和执行行为直接相关的事实。注意不要把示例命令当作所有仓库的通用命令;写入真实项目之前先实际运行一次。
2. 给出任务专属上下文
本次任务如果是“增加百分比折扣”,还需要单独说明舍入规则:
目标:增加按整数百分比计算折扣的能力。
先调查:现有金额计算的入口、测试结构与调用位置。
约束:金额继续用整数分;百分比只允许 0 到 100;
舍入规则先提出备选方案,确认后再实现。
范围:只修改 pricing.py 和对应测试,不改变旧函数签名。
验收:0%、100%、非法百分比、奇数分舍入,以及旧测试全部通过。
交付:先只读说明影响范围;确认舍入规则后再动手,不提交。
“奇数分打五折”会出现 0.5 分,究竟四舍五入、向下取整还是银行家舍入,属于业务决策,不能由助手默默决定。项目说明负责存放稳定的整数分约定;任务描述负责询问这次新增行为的未定规则。
3. 让助手证明它理解了仓库
在授权修改之前,先要求它提交一份简短的仓库地图:
请只读检查 README、AGENTS.md、与定价相关的实现和测试。
先给出:仓库根目录、工作区状态、真实调用入口、现有测试命令、
金额单位,以及你发现的说明与代码不一致之处。
列出你打算改的文件,并说明每个文件为什么需要改。
遇到未确定的舍入规则先提问,暂不修改文件。
如果它说“测试已经运行”,检查是否附有实际执行命令和输出结果;如果它声称 README 的规则在代码中成立,检查相应函数或测试。对仓库之外的商业规则,让业务负责人确认,不强迫助手猜测。
五、常见问题与实践建议
1. 项目指令堆成百科全书
每多一条陈旧命令,都可能误导新会话。只保留常用构建与测试、必须保持的契约、容易犯错的目录边界。可发现的目录结构写成入口链接即可。
2. 文档过期但没人核对
把“文档中的命令能在干净环境执行”作为变更检查的一部分。修改目录或脚本时同步更新 README 和项目指令;助手遇到文档与代码冲突时先报告,而不是选一边默默执行。
3. 把所有环境信息写入仓库
不要在仓库说明里放真实密钥、生产库地址、个人令牌或客户数据。用示例变量名说明需要哪些配置,机密值交给部署环境或秘密管理系统。
4. 假设不同工具自动共享同一份指令
逐个确认所用工具实际会读取哪些文件、从何处读取;没有读取的工具,需要显式提供入口或对应配置。对工具特有的优先级与路径规则,使用时核对当前官方文档和真实会话反馈。
5. 没有检查 Git 工作区
已有的未提交修改可能属于其他人。开始新任务时先看 git status,不要让助手把别人的改动归入自己的成果,更不能因为项目说明写了“保持干净”就擅自清理工作区。
六、进阶思考
当仓库变大时,可以按领域建立短小的架构说明,记录入口、关键数据流和已确定的设计决策,再让根目录 README 指向它们。任务阶段按需读取相关文档,避免每次加载一整套系统百科。
可以把项目说明也当作代码评审对象:每条命令有谁维护?什么时候验证过?对应哪个测试或脚本?如果一次变更让指令与代码不一致,应像修复失败测试一样修复说明。说明越精炼,就越容易发现矛盾。
涉及多团队协作时,需要区分“文档建议”与“必须满足的门禁”。格式和惯用测试命令可通过仓库说明引导;敏感文件读取、发布、生产写入等风险必须在权限、隔离环境与审批中受控。再清楚的上下文也不能替代强制访问控制。
结论
让 AI 理解代码库,靠的是一张可信而简短的仓库地图,以及让它用真实代码、测试和命令核对地图的工作流程。README 负责引导,项目指令负责稳定的协作约定,任务描述负责本次目标;任何说明与事实冲突时,都应以可验证证据推动澄清。
下一篇将从一个具体 Issue 出发,把仓库调查结果转为分阶段实施计划,避免一上来就改文件。
参考资料
- OpenAI Developers:Codex guides
- Claude Code:How Claude remembers your project
- Python:unittest 文档
- Git:git status



