3053 字
15 分钟
上下文管理:让 AI 理解一个真实项目

上下文管理:让 AI 理解一个真实项目#

本文是 AI Coding 系列 的第三篇。

上一篇:从 Prompt 到 Spec / SDD:AI Coding 中的需求约束

1. 为什么 Spec / SDD 之后要写上下文管理#

上一篇写 Spec / SDD,本质上是在讨论任务级约束:这一次要做什么,不做什么,应该怎么组织实现,修改范围在哪里。

但真实项目里,只写清楚这一次任务还不够。AI 还需要知道这个项目本身是什么样的:目录怎么分工,服务怎么启动,测试怎么跑,哪些文件不能碰,已有代码风格是什么,历史设计为什么这么写。

如果说 Spec / SDD 解决的是“这次任务的边界”,那么上下文管理解决的是“这个项目的边界”。

我现在越来越觉得,AI Coding 里很多问题不是模型不会写代码,而是它不知道在当前项目里应该怎么写。没有上下文时,它只能按通用经验工作;有上下文时,它才可能进入这个项目自己的工程约束。

上下文管理要解决的问题,是让 AI 知道“在这个项目里,正确范围到底是什么”。

2. Before:只靠 prompt 的项目修改#

先看没有上下文管理时的状态。

开发者通常会直接写一句 prompt:帮我实现这个功能,帮我修这个 bug,帮我把这段代码重构一下。AI 可以根据当前对话和被提供的文件开始工作,看起来很快,也经常能给出能跑的结果。

问题是,它知道的信息太少。

它可能不知道这个项目用什么命令启动,也不知道测试入口在哪里;它可能不知道某个目录只放展示组件,不能塞业务逻辑;它可能不知道某个旧接口虽然丑,但暂时不能动;它也可能不知道当前任务只需要改一个局部行为,而不是顺手重构一整个模块。

于是就会出现几类典型问题:

  1. 代码能跑,但风格和项目不一致。
  2. 局部问题被扩展成多文件重构。
  3. 新增抽象看起来更完整,但和已有结构冲突。
  4. AI 猜错启动命令或测试命令。
  5. 修改完成后没有验证,或者只验证了它自己新增的路径。
  6. 第二个 agent 接手时,又重新猜一遍项目规则。

这就是只靠 prompt 的局限。Prompt 可以让 AI 开始工作,但它很难长期保存项目规则,也很难让不同任务、不同 agent 复用同一套约束。

3. 上下文到底包括什么#

上下文不是把仓库所有文件都丢给 AI。

真正有用的上下文,应该能帮助 AI 做工程判断。对我来说,一个项目至少需要让 AI 知道这些东西:

  1. 项目结构:主要目录分别负责什么。
  2. 技术栈:用什么框架、语言、包管理器和构建方式。
  3. 运行命令:本地服务如何启动。
  4. 测试命令:单元测试、类型检查、构建检查怎么跑。
  5. 代码风格:命名、组件拆分、错误处理、注释习惯。
  6. 修改边界:哪些文件可以改,哪些文件不要动。
  7. 设计约束:已有接口、模块职责、数据流和依赖方向。
  8. 常见坑:项目里容易出错但不明显的地方。
  9. 验证原则:生成代码后必须做哪些检查。
  10. 协作上下文:issue、PR、review comment、CI 日志。

这些东西不一定都要写进同一个文件。它们应该按稳定程度和使用场景分层。

稳定规则适合放在 AGENTS.md 或 docs 里;长期偏好和项目经验可以进入 memory;可复用任务流程可以变成 skills;需要自动执行的检查可以交给 hooks;来自协作流程的信息,则更适合从 GitHub 插件里读取。

上下文管理不是“多给 AI 看一点”,而是“让 AI 在合适的时候看到合适的约束”。

4. After:有上下文基础设施之后#

有了上下文基础设施,AI Coding 的工作方式会发生变化。

Before 是这样:

  1. 写一句 prompt。
  2. AI 根据当前片段猜项目结构。
  3. AI 生成代码。
  4. 开发者检查哪里不对,再补充说明。
  5. AI 继续修改。
  6. 最后开发者自己收拾边界和验证问题。

After 更接近这样:

  1. 任务从 Spec / SDD 或明确说明开始。
  2. AI 先读取 AGENTS.md,知道项目规则和禁止事项。
  3. AI 根据任务读取相关 docs,而不是扫完整个仓库。
  4. AI 查看目标文件和相邻模块,理解局部结构。
  5. AI 制定修改计划,明确会改哪些文件。
  6. AI 执行修改后按项目命令运行检查。
  7. 如果涉及 PR 或 CI,再读取 GitHub 上的 review 和日志。
  8. 任务结束后,必要时更新 docs 或记录新的项目经验。

这个变化的关键不是流程看起来更正式,而是 AI 少猜了一些东西。

上下文越清楚,AI 越不容易把局部任务做成全局重构;验证入口越明确,AI 越不容易停在“代码看起来对”;协作信息越完整,AI 越不容易修错 reviewer 真正在意的问题。

5. AGENTS.md:给 agent 的项目入口#

AGENTS.md 适合放项目级规则。

它不应该写成很长的项目百科,也不应该把所有文档都复制进去。它更像 agent 进入仓库时先看的入口文件,重点告诉 AI:

  1. 这个项目是什么。
  2. 常用命令有哪些。
  3. 修改前应该先看哪些目录。
  4. 哪些文件或目录不要随便改。
  5. 提交前应该跑哪些检查。
  6. 当前项目偏好的代码风格是什么。
  7. 遇到不确定情况时应该怎么处理。

我现在更倾向把 AGENTS.md 写得短一点。太长的规则会增加 token 成本,也容易让 AI 抓不住重点。真正复杂的背景,可以通过链接指向 docs,让 AI 在需要时再读。

AGENTS.md 的价值不是让 AI 记住所有东西,而是让它知道下一步该看哪里、不能乱动哪里、做完之后怎么验证。

6. docs、memory、skills、hooks 各自负责什么#

docs 适合放稳定文档。比如架构说明、目录职责、接口约定、配置说明、常见问题。它面向人,也面向 AI。一个好的 docs 目录,不应该只是资料堆积,而应该能帮助后来的人和 agent 快速判断这个项目为什么这么写。

memory 更适合放长期偏好和经验。比如我更倾向复用旧接口,不轻易新增抽象;或者某个项目里构建命令经常失败,需要先检查环境变量。这些东西不一定适合写进正式文档,但适合影响后续任务的默认判断。

skills 适合固化可复用能力。比如处理 PR review、修 CI、写某类测试、整理某类文档。如果一个流程会反复发生,就不应该每次都靠 prompt 临时描述。skill 的意义是把“怎么做这类事”稳定下来。

hooks 适合处理自动检查。比如格式化、类型检查、单元测试、生成前后的安全检查。它们不负责告诉 AI 怎么想,但可以限制 AI 的输出必须经过某些流程。

这几个东西的关系可以粗略理解为:

  1. AGENTS.md:入口规则。
  2. docs:稳定知识。
  3. memory:长期经验。
  4. skills:可复用流程。
  5. hooks:自动化约束。

它们不是零散配置,而是项目上下文基础设施的不同层。

7. GitHub 插件:把协作信息纳入上下文#

在我目前使用 Codex 的场景里,先不谈 Vercel,最值得单独拿出来说的是 GitHub 插件。

本地仓库只能提供代码上下文,但真实项目的很多信息不在文件里,而在 issue、PR、review comment 和 CI 日志里。GitHub 插件补上的,就是这部分协作上下文。

Before 是这样:

  1. AI 只能看本地文件。
  2. 不知道这个改动来自哪个 issue。
  3. 不知道 reviewer 真正反对的是哪一行。
  4. 不知道 CI 是类型错误、测试失败,还是环境问题。
  5. 不知道当前分支和目标分支之间的真实差异。

After 是这样:

  1. 可以读取 issue / PR 背景,知道任务来源。
  2. 可以查看 review comment,把反馈转成待处理任务。
  3. 可以查看 CI 日志,把失败信息变成调试入口。
  4. 可以根据 PR diff 判断改动范围。
  5. 可以把本地修改提交、推送、开 PR,让流程闭环。

这个插件的意义不是让 AI 更会写代码,而是让 AI 看到真实协作流程里的上下文。

比如 github 能帮助获取 repo、issue、PR 的基本信息;gh-address-comments 更适合把 review comment 变成可执行任务;gh-fix-ci 适合从 CI 失败日志进入调试;yeet 则更偏把本地修改发布到 GitHub,形成 PR 工作流。

这些能力的共同点是:它们把“代码之外的项目状态”带进了 AI Coding。没有这些上下文,AI 很容易只修眼前代码;有了这些上下文,它才更可能修真正需要修的东西。

8. 上下文不是越多越好#

上下文管理很容易走到另一个极端:什么都想给 AI 看。

这也有问题。

第一,token 是成本。AGENTS.md、docs、skills、memory 只要被读取,就会占上下文窗口。文档越长,AI 越可能把注意力浪费在不相关信息上。

第二,过期文档会误导。一个旧的设计说明,如果没有及时更新,反而会让 AI 坚持错误约束。

第三,规则之间可能冲突。AGENTS.md 里说用一种命令,docs 里写另一种命令,AI 不一定知道该信谁。

第四,上下文太多会降低任务边界感。一个局部修改不需要读取全部架构文档,否则 AI 可能顺手把问题扩大。

所以我更接受一种分层策略:

  1. 默认只读入口规则。
  2. 根据任务读取相关 docs。
  3. 只在需要时使用 memory。
  4. 对重复任务调用对应 skills。
  5. 通过 hooks 和测试验证结果。

让 AI 读更多不是目标,让 AI 读对才是目标。穷人用 token,还是要讲究一下刀法。

9. 我现在会让 AI 先读什么#

如果是一个真实项目任务,我现在更倾向于按这个顺序给 AI 上下文:

  1. 任务说明或 Spec / SDD。
  2. AGENTS.md 里的项目规则。
  3. 和任务直接相关的 docs。
  4. 目标文件和相邻模块。
  5. 测试命令和验证方式。
  6. 如果是 PR 任务,再读取 review comment。
  7. 如果是 CI 任务,再读取失败日志。

这个顺序背后的判断很简单:先确定任务边界,再确认项目规则,然后才进入代码细节。

如果一上来就让 AI 扫完整个仓库,它可能看到了很多东西,但不知道哪些和当前任务真正相关。上下文管理不是信息量竞赛,而是决策顺序管理。

10. 让 AI 少猜一点#

上下文管理不是为了把项目文档写得很重,也不是为了给 AI 准备一座资料库。

它真正要做的,是减少 AI Coding 中的猜测空间。AI 不应该猜项目怎么启动,不应该猜测试怎么跑,不应该猜哪个目录能改,也不应该猜 reviewer 想让它修什么。

Spec / SDD 让 AI 理解这次任务的边界;上下文管理让 AI 理解这个项目的边界。

当这两层边界都更清楚时,AI Coding 才不只是更快生成代码,而是更稳定地进入一个真实项目的工程流程。