
说个我自己的经历。有段时间我在一个中型的Python后端项目上重度使用AI编程助手结果连续好几次遇到同一个怪现象刚开始的十几分钟AI非常靠谱能准确按需求改代码但只要对话超过一个小时它就开始“犯迷糊”有时候甚至把一个早就不用的变量名翻出来用。我一开始以为是模型输出不稳定后来排查了很久才发现问题出在我自己的用法上——我没有管理AI的上下文。context-mode这个词说白了就是在讨论一件事你如何控制“AI每次思考时能看到的材料范围”。这篇文章我会从原理到实操把我验证过的上下文管理方法完整写出来希望能帮到那些觉得AI编程“时灵时不灵”的人。1. 先搞清楚上下文模式到底在解决什么问题1.1 AI的“工作记忆”边界所有对话式大模型都有一个上下文窗口context window可以理解为AI同一时间能“看见”的文本长度。这个窗口是有限的短则几万token长则几十万token但不管多长都是有限资源。编程任务恰恰是信息消耗大户一段代码、几份依赖配置、十几个文件的结构、一条编译报错、一段测试输出……加在一起很快就会触顶。我经常用一个比喻这就像给一个能力很强的工程师配了一张只能写两百字的便签纸。模型本身能力在线但便签纸就那么大要写新东西就得先擦掉旧的。问题不在于模型而在于谁来决定擦掉什么、保留什么默认情况下AI的擦除规则是“先来后到最老的先走”——这对简单问答没问题但对复杂的多文件开发任务来说往往最先被挤出去的反而是最重要的架构约定。所以context-mode的核心任务不是“塞更多东西”而是“在有限空间里让AI始终握着最关键的信息”。这一点想明白之后后面所有技巧都有了方向。1.2 上下文缺失与上下文过载在实际项目中我们遇到的绝大多数“AI变笨了”可以归为两类。第一类是上下文缺失。比如你让AI改一个函数但它根本不知道这个函数在哪个模块、被谁调用、依赖哪些全局状态。它只能瞎猜然后给你一个看起来合理但根本跑不通的方案。这种情况在刚接入一个项目、或者新开一个会话时特别常见。AI会一本正经地用臆想的接口名写代码你看到报错才意识到它在画饼。第二类则是上下文过载。你一股脑把所有代码、日志、文档都塞给AI它被海量信息淹没抓不住真正重要的约束条件。这比缺失更隐蔽因为AI不会直接说自己“看不完”而是会在一堆限制条件里选几个遵守剩下的悄悄忽略最终输出一个“部分正确”的方案——比如记住了安全要求却忘了性能约束或者遵循了新的接口规范但把旧的兼容逻辑删了。这两个方向的问题正好构成context-mode的两条主线既要让AI知道“该知道的”又要让它免于被“不该知道的”干扰。我在后面讲的所有配置和实操本质上都是围绕这两条线展开的。1.3 不要神化context-mode这里我想先泼一盆冷水。很多教程把上下文管理说得神乎其神好像掌握了它就能让AI编程脱胎换骨。实际没那么玄。context-mode是一个偏重“工程纪律”的东西它不是让模型变聪明而是让模型的聪明用在刀刃上。它更像版本管理Git不会让代码质量变高但没有Git多人协作一定会乱成一锅粥。上下文管理也是同样的道理——它不会替你写出更好的架构但能让AI稳定输出你已经定好的架构。这也是为什么我建议不要把“上下文模式”当成某个具体开关而是当成一整套工作习惯。下面讲的三种模式本质上是三种不同的习惯组合。2. 三种上下文模式的设计与取舍2.1 自动压缩模式AI自己决定保留什么第一种是自动压缩模式很多AI编程工具内置了这套机制。当对话变长时系统会把早期的对话内容压缩成摘要释放上下文空间让对话可以继续下去。这种设计的出发点是“不打断用户”你可以一直聊AI在后台悄悄做减法。但实测下来自动压缩有一个明显的代价压缩策略通常按时间衰减早期信息最容易先被丢掉。一份压缩摘要能保留“用户要求实现登录功能”这种主题描述却很难保留“用户明确说过数据库连接池最大值必须是20”这种精确数字。结果就是对话越往后AI对细节的执行越松开始出现变量名拼写偏差、参数默认值乱改、边界条件被忽略等问题。我对自动压缩模式的使用建议是它适合“随手问一句”的场景比如快速查API用法、写一小段脚本、解释报错含义。这类任务对精确的历史依赖低AI就算“忘”了一点也不影响产出。但如果你在一个功能模块的开发过程中已经聊了几十轮、改了好几轮代码自动压缩就会开始拖后腿——这时候你需要主动介入切换到手动管理。2.2 白名单指令模式你替AI划边界第二种是白名单指令模式这是我在真实项目里用得最多的。核心思路很简单不依赖AI自己从海量信息里“淘金”而是你在任务开始前主动声明它必须知道的内容。最典型的做法是在项目根目录放一个CONTEXT.md或CLAUDE.md里面用固定格式写清楚项目背景、技术栈、目录结构、编码规范、当前迭代目标等。每次新开会话时让AI先读这个文件再开始干活。我把这理解为“提词器”——演员上台前扫一眼关键词就能避免在台上自由发挥到跑偏。操作上我推荐一个最小可用的白名单模板# 项目上下文 ## 一句话说明 这是一个内部数据可视化平台的后端服务。 ## 技术栈 - Python 3.11 / FastAPI / SQLAlchemy 2.0 - PostgreSQL 15 / Redis 7 - Docker Compose 编排 ## 核心目录 - app/api/路由层只负责参数校验和响应 - app/services/业务逻辑禁止直接访问数据库 - app/models/SQLAlchemy 模型 - app/core/配置、安全、依赖注入 ## 不可违背的约定 1. service 层不允许出现 ORM 查询外的原始 SQL 2. 所有对外接口必须返回统一 JSON 结构 3. 数据库迁移只允许通过 Alembic 生成 ## 当前迭代目标 正在开发“告警规则”模块支持 CRUD、启停切换、触发记录。关键点在“不可违背的约定”这一节。这里的条目不是给AI参考的而是给AI划红线的。填三到五条就够了多了反而稀释重要性。每次任务开始时让AI读一遍能明显减少“AI自己发挥出一套新风格”的概率。2.3 记忆沉淀模式把经验变成复利第三种是记忆沉淀模式可以理解成前两种的升级版。自动压缩和白名单都是“单次会话内”的上下文管理而记忆沉淀解决的是“跨会话复用”的问题——把这次任务里踩过的坑、定过的规矩、总结出的经验保存下来下次新开会话时直接成为AI的默认认知。我自己的习惯是在项目根目录维护一个docs/decisions/目录每次和AI协作解决了一个有价值的问题比如“为什么不能用RabbitMQ替代Redis做延迟队列”“当前服务为什么必须保留幂等逻辑”就把结论沉淀成一个简短的Markdown文件。下次涉及相关功能时在任务指令里加上一句“先看docs/decisions下的相关记录”AI就能站在上次的经验上继续工作而不是每次都从零开始。用生活化的话说自动模式像“听力”让AI自己听听到多少算多少白名单模式像“提词器”你提前写好关键词AI照着发挥记忆沉淀模式像“肌肉记忆”长期反复出现的动作不用想就能做对。三种模式不是替代关系而是搭配使用——大部分时候靠白名单保证单次任务的质量靠记忆沉淀让一次次会话产生复利。3. 实操落地为一个真实项目配置 context-mode前面讲的是原理和模式这一节我们直接上手。我会用一个虚拟但很典型的项目来演示一个FastAPI后端正在开发“告警规则”模块。这是我踩了无数坑之后整理出来的一套可复制的操作流程。3.1 定义最小可用的项目级上下文包第一步不是急着写代码而是先花二十分钟把项目的上下文包建起来。放在Git仓库里的用白名单模式维护。在工作目录创建CONTEXT.md内容按我上一节给的模板展开。这里我补充几个容易忽略的细节。目录说明不要只写“这个目录是干嘛的”要写“这个目录里什么不该出现”。比如- app/services/业务逻辑禁止直接访问数据库 - app/schemas/Pydantic 模型只做数据校验不允许写业务逻辑这种“否定式约定”比“肯定式描述”有效得多。AI是生成模型你告诉它“做什么”它会做得过火告诉它“不许做什么”反而能拦住大部分跑偏。技术栈条目要带版本。因为AI的训练数据里包含了各种版本的差异你不写版本号它就会默认选最常见可能是两年前的写法。写清楚Python 3.11 / SQLAlchemy 2.0它就不会给你生成ThreadingMixIn之类的老古董。3.2 任务开始前的上下文启动动作项目上下文文件建好之后每次新开一个任务我建议按固定顺序做三个动作。第一步让AI“热读”上下文。在对话开头输入请先阅读仓库根目录的 CONTEXT.md然后总结这个项目在做什么、有哪些不可违背的约定再开始处理我的任务。注意顺序先让AI复述再让它干活。如果AI对上下文的总结有明显错误说明项目文件表述有歧义要么改CONTEXT.md要么补充说明。这个“复述验证”的步骤能帮我提前发现上下文质量问题而不是等代码写砸了才回头查。第二步把本次任务的关键信息用独立段落写清楚不要混在一大段描述里。比如本次任务为“告警规则”模块新增一个“触发记录查询”接口。 - 输入rule_id整数、时间范围起止时间戳、分页参数 - 输出符合统一响应结构的记录列表包含触发时间、触发值、恢复时间 - 限制单次查询最多返回 30 天数据超过要提示用户缩小范围 - 涉及文件app/api/rules.py、app/services/rule_trigger.py、app/schemas/rule.py“涉及文件”这一条非常重要。AI编代码时经常会因为找不到相关实现而自己造一套接口你预先告诉它文件位置和依赖关系它就只能在真实代码的基础上改幻觉率会大幅下降。第三步开始第一轮修改前让AI先给计划不要直接出代码请先说明你打算怎么实现列出修改文件和关键函数签名我再确认。这一步花不了两分钟但能拦住“AI闷头写了20分钟后发现方向错了”的尴尬。计划的语气会暴露AI是否真的理解了上下文比如它如果计划里说“新建一个工具函数”但项目里其实已经有对应工具你就能立刻纠正省掉后面一大段无用功。3.3 对话中途的状态维护动作自动压缩会在长对话中途悄悄发生所以不能开个头就撒手不管。我在对话超过二十分钟后会手动做一次“状态固化”逻辑很简单让AI把当前进度压缩成一段完整的快照然后我把它存到一个临时地方。指令可以这么写请暂时停止编码。现在整理一份当前进度报告 1. 已完成的功能点 2. 已修改的文件及改动摘要 3. 当前尚未解决的问题 4. 下一步计划 5. 本次改动中出现的任何命名或接口约定这段快照有几个用途。比如对话意外被压缩我可以把快照贴回去让AI快速恢复状态如果当天没做完第二天直接基于快照开新会话不用翻半天聊天记录再就是排查Bug时有了“已改动文件清单”能少走很多弯路。我还会在每完成一个功能点之后把关键的决定更新进CONTEXT.md的“当前迭代目标”一节。这样即使对话彻底重置新会话也能从正确状态继续。4. 踩坑记录上下文管理失败的五种典型表现这一节专门讲我真实遇到过的“翻车现场”。我尽量把现象、根因、排查思路和解决方案都写清楚方便你对照自己的情况。4.1 返工链AI忘了自己刚定的设计现象让AI先设计数据模型字段再写service层再写API层。第二步它还能对上字段名到第三步就开始出现一个不存在的字段比如把trigger_value写成current_value。问它为什么它说“根据之前的上下文推测的”。根因多轮对话中早期信息被压缩或淹没。模型处理长对话时对越早出现的内容权重衰减越严重它记不清精确字段名就会按概率补一个“看起来很像”的词。排查思路这种问题非常隐蔽因为AI不会主动说“我忘了”。可以回滚对话历史检查是从哪一轮开始出现不一致的另一种方式是用前面提到的“状态固化”在任何一步让AI复述字段定义看它是否复述准确。解决方案关键命名信息必须写进某个“不会衰减”的地方也就是你说的、它读的、但不能被对话历史冲淡的东西。最稳妥的做法是把数据模型字段定义放进CONTEXT.md下面的独立小节每次涉及这个模块时明确引用退而求其次在任务开始时把“本次涉及的字段清单和类型定义”单独贴在指令里而不是让它从第一轮对话里找。4.2 多文件修改的前后矛盾现象一个功能涉及A、B、C三个文件AI只改了A文件B文件还在用旧接口。代码能跑但运行逻辑是错的而且报错信息不明显排错花了一个多小时。根因我只告诉AI“修改A文件”没有明确说“这次改动影响B、C文件”。AI按最小改动原则只动了它看到的文件上下文里根本没有B、C的存在自然谈不上同步。排查思路发现异常后先看这个功能的完整调用链从API入口到service再到模型层把所有相关文件列出来再检查AI是否全部改到。别只看报错的位置报错位置往往是最后一个被波及的地方。解决方案在任务开始时用“涉及文件”白名单物理性地把相关文件列全。AI工具通常允许把特定文件加入上下文这样它会同时读取所有关联文件而不是只见树木不见森林。我在3.2节模板里已经写了这一条这里再强调一次这是成本最低但收益最高的一项操作。4.3 压缩后“失忆”与“幻觉式补全”现象自动压缩发生之后AI突然开始用错误的老变量名。比如项目已经统一改成user_repo压缩后它又写回user_repository而且加了注释说明“不做大的改动以防破坏”。根因压缩摘要保留了“语义”但丢失了“字面量”。摘要可能是“UserRepository已重命名为user_repo所有模块统一使用”按理说名字还在但实际上压缩算法可能只保留了一层抽象“统一仓库访问方式”具体命名就丢了。AI推断不出精确名称只能生成一个它认为合理的。排查思路判断是不是压缩引发的很简单——看AI是否重新提到了早期对话中的细节但细节和当时不一致。典型表现是“AI开始用解释性的措辞来回避精确内容”比如“使用统一的数据访问方式”而不是“使用user_repo”。解决方案一是把精确命名写进项目上下文二是当对话接近压缩阈值时主动手动开会话而不是等自动压缩发生。怎么判断接近阈值我经验是每聊半小时左右强制做一次状态固化把“精确事实”从对话历史中转移到外部文件里。4.4 上下文被日志刷屏的错误示范现象排查一个接口超时问题我把完整日志复制给AI包含几千行的框架日志和健康检查输出。AI分析了一堆无关内容最后给出了一篇“可能是网络问题”的万金油答案。根因是我自己在污染上下文。日志里真正有用的只有报错堆栈的前后几行、耗时分布、以及SQL的执行记录其余全是噪音。AI为了回应我的指令会把注意力分摊到每一行日志上信号被埋没了。排查思路以后给AI看日志之前先自己花三十秒扫一遍只截取三段内容时间线上离报错最近的5~10行、报错类型和详细信息、引起报错的入口请求参数。其他一概不贴。这一步想过之后我才发现以前很多“AI排查不出问题”根本是输入质量太差。解决方案写一个自己的“日志提炼模板”第一段放请求信息URL、参数、耗时第二段放报错堆栈第三段放与该次请求相关的业务日志用trace_id过滤。按这个结构贴给AI它的排错准确率会翻倍。4.5 长时间对话的偏好漂移现象项目一开始我明确要求“所有service层方法都要写类型注解和docstring”前几轮AI一直遵守写到后面慢慢变成有一搭没一搭最后彻底不写了。问它为什么它说“这轮代码比较简单我就省略了”。根因长对话中早期指令的约束力会被后期新信息冲淡尤其当任务列表不断增大时AI会“选择性”遵守最近强调的规则而把更早的规则当成“旧需求”。这是一种注意力衰减不是模型在执行什么高级策略。排查思路如果发现某个AI输出从“完全遵守规则”逐渐滑向“部分遵守”不要急着批评AI先检查这个规则是否还存在于上下文里。很多时候它已经被后续对话挤出去了。解决方案把“必须长期遵守的标准”放在不会是上下文牺牲品的位置——也就是CONTEXT.md的“不可违背的约定”。任何对话开始前都让AI重新读一遍。口头强调只对当前这一轮有效写进上下文文件才对整个项目周期有效。5. 进阶思路把 context-mode 沉淀成团队规范单个人用会context-mode效率能提高但真正的价值在于把这一套变成团队基础设施。这个阶段我还在持续探索想分享两个我觉得最有潜力的方向。5.1 团队共享上下文包原则很简单把项目级CONTEXT.md、模块级说明、决策记录一起放进Git仓库与代码同步迭代。每个开发者用同一套上下文AI输出的代码风格和质量下限就趋于一致。实际操作时要注意几点CONTEXT.md要跟随代码评审一起更新。如果有人在评审时改了公共工具函数的命名规则必须同步改上下文文件否则AI还在按旧规矩写新代码。不同模块可以有不同的上下文子文件。我的做法是根目录CONTEXT.md放全局约定app/api/CONTEXT.md放宽行业务规则app/services/CONTEXT.md放领域逻辑约定。任务涉及哪个模块就引用哪个子文件。上下文文件不能太长。我见过团队把CONTEXT.md写到两千行结果AI读完之后重点全丢。单文件的合理范围在一百到两百行超过这个量就要拆分或者用“摘要详细文档链接”的结构。5.2 上下文即文档让新人也能快速上手这个方向我给很多人安利过一份高质量的CONTEXT.md对AI和真人同样有用。新同学加入项目时与其让他去啃历史文档不如先让他读上下文文件——它能用最短篇幅告诉新人“项目在干什么、为什么这样设计、有哪些雷区”。我个人的体会是上下文文件的维护应该像维护测试用例一样认真。它不是给AI的“提示词魔法”而是项目知识库中最活跃、最常被引用的那份“活文档”。当我发现AI对某个模块频繁出错时第一反应不是换模型而是问自己是不是上下文里对这个模块的描述不够准确这个思维转变是context-mode给我带来最大的回报。顺着这个方向往下走我最近在尝试的是把每次“AI协作完成的关键重构”都写成简短的决策记录统一放在docs/decisions/下。这些记录既是团队知识资产又是AI后续任务可引用的高质量上下文。等这一套跑顺了AI在我们的项目里就不再是一个“偶尔靠谱的代码生成器”而是一个真正了解项目历史的协作者。