摘要

在 AI 编程过程中,很多开发者会遇到一个问题:明明模型能力很强,但生成的代码却经常“不符合项目结构”“改错文件”“遗漏已有逻辑”“重复造轮子”。

这类问题很多时候不是 AI 不会写代码,而是因为它没有拿到正确的上下文。

而本文要介绍的 上下文管理,解决的是另一个更基础的问题:

AI 在写代码之前,到底应该先知道哪些信息?

本文将从 AI 编程实战角度出发,介绍什么是上下文、为什么上下文会影响代码质量、如何组织项目上下文、如何减少无效 Token 消耗,以及如何让 Claude Code、Cursor、Codex 等 AI 编程工具更准确地理解项目。


一、前言

很多人在使用 AI 编程工具时,会直接这样提问:

帮我修复这个 bug。

或者:

帮我新增一个用户管理模块。

如果项目很简单,这样可能也能得到可用结果。

但如果是一个真实项目,比如包含:

  • 前端页面
  • 后端接口
  • 数据库表
  • 权限逻辑
  • 配置文件
  • 日志系统
  • 历史兼容逻辑
  • 多个业务模块

那么只给 AI 一个简单需求,通常是不够的。

AI 很可能会出现以下问题:

  • 不知道项目目录结构
  • 不知道应该修改哪个文件
  • 不知道已有接口规范
  • 不知道数据库表结构
  • 不知道前端状态管理方式
  • 不知道已有错误处理方式
  • 不知道哪些代码不能动
  • 不知道最终应该如何测试

更好的方式是:

先给 AI 正确的上下文,再让 AI 开始分析和修改代码。


二、什么是 AI 编程中的上下文?

在 AI 编程中,上下文可以理解为 AI 完成任务所需要的背景信息。

它通常包括以下几类内容:

上下文类型 说明
项目背景 项目是做什么的,主要业务场景是什么
技术栈 前端、后端、数据库、框架、运行环境
目录结构 哪些目录放前端,哪些目录放后端,配置文件在哪里
相关代码 本次任务真正涉及的核心文件
数据结构 数据库表、接口返回格式、JSON 输出格式
业务规则 哪些情况算成功,哪些情况算异常
历史约束 哪些代码不能改,哪些接口必须兼容
错误信息 报错日志、终端输出、浏览器控制台信息
期望结果 修改后要达到什么效果
验证方式 如何确认代码真的修好了

简单来说:

上下文 = AI 完成当前任务前必须知道的信息

上下文给得越准确,AI 的输出越稳定。

上下文给得越混乱,AI 就越容易乱改。


三、为什么上下文管理很重要?

1. AI 并不天然理解你的项目

AI 模型虽然具备大量通用编程知识,但它并不知道你本地项目的真实情况。

例如它不知道:

  • 你的接口返回格式是什么
  • 你的数据库连接方式是什么
  • 你的前端组件是如何拆分的
  • 你的后端是否已经有统一异常处理
  • 你的项目是否有历史兼容逻辑
  • 你的某个目录是否已经废弃

如果不提供上下文,AI 只能根据通用经验猜测。

而真实项目开发中,很多问题不能靠猜。


2. 上下文不足会导致 AI 重复造轮子

比如项目中已经有一个统一请求方法:

request.get('/api/users')

但如果 AI 没有看到这个文件,它可能会重新写一个:

fetch('/api/users')

这样看起来功能能跑,但会破坏项目统一规范。

常见表现包括:

  • 重写已有工具函数
  • 新增重复接口封装
  • 不使用已有组件
  • 不遵守已有错误处理
  • 不复用已有类型定义
  • 新增和项目风格不一致的代码

这就是上下文不足导致的典型问题。


3. 上下文过多也会降低效果

很多人会走向另一个极端:

既然 AI 需要上下文,那我把整个项目都丢给它。

这也不一定正确。

因为上下文窗口是有限的,Token 也是有成本的。

如果一次性给 AI 太多无关文件,会带来几个问题:

  • 重要信息被淹没
  • AI 注意力分散
  • 输出速度变慢
  • Token 消耗增加
  • 更容易误判修改范围
  • 可能修改无关代码

所以,好的上下文管理不是“越多越好”,而是:

给足够相关的信息,不给大量无关的信息。


四、AI 编程上下文应该包含哪些内容?

在实际使用 Claude Code、Cursor、Codex 等工具时,可以把上下文分成 6 层。


4.1、第一层:项目整体背景

AI 首先需要知道项目是做什么的。

可以这样描述:

这是一个前后端分离项目。

前端使用 Vue 3 + Vite + TypeScript。
后端使用 FastAPI + MySQL。
项目主要用于本地 AI 模型管理,包括模型配置、目录监听、图片识别、结果展示和日志管理。

本次任务只涉及后端监听配置模块和前端配置页面,不要修改模型推理逻辑。

这一层的作用是让 AI 先建立整体认知。

尤其是复杂项目,不能一上来就让 AI 改代码。


4.2、第二层:技术栈和运行环境

技术栈会直接影响 AI 的代码生成方式。

例如:

后端:
- Python 3.10
- FastAPI
- SQLAlchemy
- MySQL
- watchdog

前端:
- Vue 3
- TypeScript
- Vite
- Element Plus

运行环境:
- Windows Server
- Conda 虚拟环境
- MySQL 数据库名为 yolo_admin

如果不说明技术栈,AI 可能会生成不适合项目的代码。

例如:

  • 后端项目是 FastAPI,它却写成 Flask
  • 前端项目是 Vue,它却写成 React
  • 数据库是 MySQL,它却给 SQLite 示例
  • 项目运行在 Windows,它却写 Linux 路径

所以,技术栈和运行环境必须尽量明确。


4.3、第三层:目录结构

AI 修改代码前,最好先了解项目目录。

可以给出简化后的目录结构:

project/
├─ backend/
│  ├─ app/
│  │  ├─ api/
│  │  ├─ models/
│  │  ├─ services/
│  │  └─ core/
│  ├─ main.py
│  └─ requirements.txt
│
├─ frontend/
│  ├─ src/
│  │  ├─ api/
│  │  ├─ views/
│  │  ├─ components/
│  │  └─ router/
│  └─ package.json
│
└─ README.md

然后告诉 AI:

本次任务重点关注:
- backend/app/api/watch_config.py
- backend/app/services/watch_service.py
- frontend/src/views/WatchConfig.vue
- frontend/src/api/watch.ts

这样 AI 就不会盲目扫描或修改无关文件。


4.4、第四层:相关代码文件

这是最关键的一层。

AI 真正写代码时,需要看到本次任务相关的核心文件。

但注意,不要一开始就把所有文件都丢进去。

更好的方式是让 AI 先分析:

请你先阅读以下几个文件,不要直接修改。
先判断本次需求主要涉及哪些代码路径。
然后告诉我你准备修改哪些文件,以及为什么。

适合提供的文件包括:

  • 当前报错文件
  • 调用它的上游文件
  • 被它调用的下游文件
  • 类型定义文件
  • 接口封装文件
  • 数据库模型文件
  • 配置文件
  • 路由文件

例如一个后端接口问题,通常至少要看:

api 文件
service 文件
model 文件
schema 文件
数据库表结构
前端调用代码

如果只看 API 文件,很容易修得不完整。


4.5、第五层:业务规则和约束

AI 写代码最容易出问题的地方,不是语法,而是业务逻辑。

所以业务规则必须明确。

例如:

识别结果 code 的含义如下:
0 表示未识别
1 表示识别成功且无违规
2 表示识别成功且有违规

只要检测到 no-helmet 或 no-vest,就应该判定为违规。
不要只根据单个类别判断。

再例如:

输出 JSON 必须保存在识别结果图片同级目录。
不要放到固定目录。
不同模型应该有不同结果目录:
- helmet 模型输出到 helmet 目录
- vest 模型输出到 vest 目录

这类信息如果不告诉 AI,它很容易只从代码表面推断,最后生成不符合业务要求的实现。


4.6、第六层:期望输出和验证方式

很多人只告诉 AI “我要实现什么”,但没有告诉 AI “怎么判断实现成功”。

这会导致 AI 写完代码后,没有明确验证标准。

建议每次任务都补充:

完成后请给出:
1. 修改了哪些文件
2. 每个文件修改了什么
3. 如何启动后端
4. 如何启动前端
5. 如何测试接口
6. 如何验证页面功能
7. 是否涉及数据库变更

例如:

验证方式:
1. 启动后端服务
2. 打开监听配置页面
3. 新增一条监听配置
4. 选择 raw 目录
5. 启动监听
6. 放入一张 jpg 图片
7. 确认识别结果图片生成在 raw 同级 helmet 目录
8. 确认 JSON 文件同步生成
9. 确认数据库中记录正常写入

五、上下文管理的常见错误

1. 只给需求,不给代码

错误示例:

帮我修复监听配置新增失败的问题。

问题是 AI 不知道:

  • 报错是什么
  • 请求接口是什么
  • 前端参数是什么
  • 后端接收参数是什么
  • 数据库字段是什么
  • 哪一步失败

更好的写法:

我在新增监听配置时报错。
前端请求参数如下:
...

后端接口代码如下:
...

报错信息如下:
...

请你先分析是前端参数问题、后端校验问题,还是数据库字段不一致。
不要直接大改代码。

2. 只给报错,不给触发步骤

错误示例:

报错 422,帮我修。

更好的写法:

我在前端点击“新增监听配置”后,请求 /watch-config 接口返回 422。

触发步骤:
1. 打开监听配置页面
2. 点击新增配置
3. 输入模型名称和监听目录
4. 点击保存
5. 接口返回 422

请你根据前端请求参数和后端接口定义,判断是字段名不一致还是必填字段缺失。

3. 一次性让 AI 修改太多目标

错误示例:

帮我优化整个系统。

这种需求太大,AI 很容易乱改。

更好的拆分方式:

第一步:只分析系统当前有哪些模块。
第二步:只优化监听配置页面。
第三步:只优化任务队列逻辑。
第四步:只优化结果分页。
第五步:只补充日志和异常处理。

AI 编程更适合小步迭代,而不是一次性大改。


4. 没有限制修改范围

错误示例:

帮我重构一下。

AI 可能会修改大量文件。

更好的写法:

请只修改以下文件:
- backend/app/api/watch_config.py
- backend/app/services/watch_service.py

不要修改数据库结构。
不要修改模型推理代码。
不要修改前端页面。

5. 没有说明兼容要求

真实项目中,很多接口不能随便改返回格式。

错误示例:

帮我优化这个接口。

更好的写法:

请在不改变现有接口返回结构的前提下优化代码。
前端已经依赖当前字段名,因此不要修改 response 的字段名称。

六、一个推荐的上下文模板

下面这个模板适合大多数 AI 编程任务。

你现在需要帮助我完成一个代码修改任务。

【项目背景】
这是一个 xxx 项目,主要用于 xxx。

【技术栈】
前端:
后端:
数据库:
运行环境:

【本次任务】
我要实现/修复:

【相关文件】
请重点阅读以下文件:
1.
2.
3.

【当前问题】
目前现象是:

【触发步骤】
1.
2.
3.

【报错信息】
终端/浏览器/接口返回如下:

【业务规则】
需要遵守以下规则:
1.
2.
3.

【修改限制】
1. 不要修改无关文件
2. 不要改变已有接口返回结构
3. 不要删除已有功能
4. 不要引入新的大型依赖
5. 不要重构无关模块

【期望输出】
请先分析问题原因。
然后给出修改方案。
最后说明需要修改哪些文件。
如果需要写代码,请给出完整修改后的代码或明确的 diff。
完成后给出测试方法。

这个模板的核心是:

先让 AI 理解,再让 AI 动手。


七、适合 Claude Code 的上下文提示词

如果使用 Claude Code,可以这样写:

请你先阅读当前项目结构和相关文件,不要直接修改代码。

你的任务是:
1. 分析本次需求涉及哪些模块
2. 找出应该修改的最小文件范围
3. 说明当前代码的问题
4. 给出修改方案
5. 等我确认后再开始修改

注意:
- 不要重构无关代码
- 不要修改数据库结构
- 不要改变现有接口返回格式
- 不要删除已有日志

如果你希望它直接修改,也可以这样写:

请你在最小修改范围内完成这个需求。

要求:
1. 先分析相关代码路径
2. 只修改必要文件
3. 保持现有接口兼容
4. 修改完成后说明每个文件改了什么
5. 给出启动和测试方法
6. 如果发现需求中有风险,请在修改前说明

八、如何减少 Token 浪费?

上下文管理还有一个现实问题:Token 成本。

如果每次都把大量无关文件发给 AI,不仅浪费 Token,还会降低效果。

建议遵守以下原则。

1. 先给目录,再给文件

不要一开始就上传所有代码。

先让 AI 看目录结构:

请你先根据目录结构判断本次需求可能涉及哪些文件。

然后再提供核心文件。


2. 先给核心链路,再给辅助文件

例如一个接口问题,优先给:

前端调用代码
后端 API 代码
service 代码
schema/model 代码
报错信息

不相关的样式文件、静态资源、历史文档可以先不提供。


3. 删除无关日志

很多日志中包含大量重复内容。

可以只保留关键部分:

请求地址:
请求参数:
响应状态码:
错误堆栈核心部分:

不要把几千行无关日志全部贴进去。


4. 用总结替代重复代码

如果某些文件很长,可以先人工总结:

这个文件主要负责监听目录变化。
其中 WatchService.start_watch 用于启动监听。
WatchService.stop_watch 用于停止监听。
当前问题主要出现在 start_watch 中对路径的处理。

这样比直接贴完整文件更节省 Token。


5. 让 AI 先列文件清单

可以这样要求:

请你先根据当前需求判断需要阅读哪些文件。
不要直接修改。
请输出你需要查看的文件清单和原因。

这样可以避免盲目提供全部项目文件。


九、上下文管理和 Skills 的关系

上一篇文章介绍的 Skills,解决的是任务流程问题。

例如 rest-api Skill 可以规定:

  • 如何设计接口
  • 如何选择状态码
  • 如何做参数校验
  • 如何设计错误返回
  • 如何验证接口

而上下文管理解决的是信息输入问题。

两者关系可以这样理解:

内容 解决的问题
上下文管理 AI 需要知道什么
Skills AI 应该按照什么流程做
CLAUDE.md AI 在项目中长期遵守什么规则
普通提示词 当前这次任务的临时要求

一个完整的 AI 编程任务,应该是:

正确上下文 + 项目规则 + 专项 Skill + 明确提示词

而不是只靠一句:

帮我改一下代码。

十、推荐的 AI 编程上下文工作流

实际使用中,可以按照下面流程操作。

1. 说明项目背景
   ↓
2. 提供技术栈和目录结构
   ↓
3. 描述当前任务
   ↓
4. 提供相关代码和报错
   ↓
5. 说明业务规则和限制
   ↓
6. 让 AI 先分析问题
   ↓
7. 确认修改范围
   ↓
8. 让 AI 小步修改
   ↓
9. 查看 diff
   ↓
10. 运行测试
   ↓
11. 总结经验,沉淀到 CLAUDE.md 或 Skills

其中最重要的三个点是:

先分析
小步改
可验证

十一、一个完整示例

假设你有一个接口返回 422 的问题。

不推荐这样问:

接口 422 了,帮我修。

推荐这样问:

这是一个前后端分离项目。

前端使用 Vue 3 + TypeScript + Vite。
后端使用 FastAPI + MySQL。

当前问题:
我在监听配置页面点击“新增配置”后,接口返回 422。

触发步骤:
1. 打开监听配置页面
2. 点击新增配置
3. 输入模型名称、监听目录、输出目录
4. 点击保存
5. 请求 /api/watch-config 返回 422

前端请求参数:
{
  "modelName": "helmet",
  "watchDir": "D:/html/upload/cam/4116_864_1",
  "outputDir": "D:/html/upload/cam/4116_864_1"
}

后端接口期望字段:
{
  "model_name": "string",
  "watch_dir": "string",
  "output_dir": "string"
}

请你分析是否是前后端字段命名不一致导致的问题。

要求:
1. 不要修改数据库结构
2. 不要改变接口返回格式
3. 优先保持后端 snake_case
4. 如果需要修改前端,请只修改请求参数映射
5. 给出修改后的代码和测试方法

这个提示词给了 AI 足够上下文:

  • 项目技术栈
  • 当前问题
  • 触发步骤
  • 前端参数
  • 后端参数
  • 可能原因
  • 修改限制
  • 期望输出

这比一句“帮我修 422”效果要稳定得多。


十二、上下文管理检查清单

每次让 AI 修改代码前,可以先检查下面这些问题:

我是否说明了项目背景?
我是否说明了技术栈?
我是否说明了当前任务?
我是否提供了相关文件?
我是否提供了报错信息?
我是否说明了触发步骤?
我是否说明了业务规则?
我是否说明了哪些文件不能改?
我是否说明了接口兼容要求?
我是否要求 AI 先分析再修改?
我是否要求 AI 给出测试方法?

如果这些问题大部分都没有回答,就不要急着让 AI 写代码。


十三、常见误区总结

误区 问题 正确做法
只给一句需求 AI 不知道项目情况 补充项目背景和相关文件
把整个项目都丢给 AI Token 浪费,重点不清 只提供相关上下文
不给报错日志 AI 只能猜原因 提供关键错误信息
不给触发步骤 难以复现问题 写清楚操作路径
不限制修改范围 AI 容易大改 明确哪些文件能改
不说明兼容要求 可能破坏已有功能 明确接口和字段不能变
不要求测试 代码可能不可验证 要求给出验证步骤

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐