☰
AI编码代理上下文工程:从ChatMemory滑动窗口到MCP优化实践
2026/10/3 5:54:02 网站建设 项目流程

1. 拿到上下文工程这个问题,先从一次现场事故说起

先说个我自己遇到的事。上个月我用 AI 编码代理做一个中型的重构任务,大概涉及十几个文件的改动。项目本身不算复杂,但业务逻辑绕,很多约束分散在不同模块里。刚开始的半小时,代理表现得很聪明,能准确引用我之前提过的设计约束,改动也基本符合预期。但一个小时后,情况开始不对劲:它先是"忘了"我们约定好的命名规范,接着把已经废弃的接口又重新用上了,最离谱的是,在一次批量修改里,它因为只看到局部代码,直接把一个被多处依赖的函数签名给改了,导致整个模块编译失败。

我当时的第一反应是"模型不够聪明",换了更强的模型,问题依旧。后来我才意识到,这根本不是模型能力的问题,而是上下文管理的问题——代理能塞进"脑子"里的信息就那么多,当窗口被无关内容占满,真正重要的约束就排不上号了。这就是上下文工程要解决的核心矛盾。

上下文工程(Context Engineering),说白了就是研究"给 AI 模型什么样的信息、以什么顺序给、给多少、什么时候给",让它在有限上下文窗口里发挥出最大能力。对于 AI 编码代理来说,这个问题尤其尖锐,因为它不仅要理解你的指令,还要跟踪多轮对话、读取多文件内容、记住工具调用结果,同时保持对项目全局的感知。

如果你也在用 AI 编码代理做真实的项目开发,尤其是那些动辄十几个文件、持续数小时的改动任务,这篇内容应该能帮你省下不少排查时间。我会从 ChatMemory 滑动窗口讲起,再一步步延伸到 Context-mode MCP 的上下文优化实践,中间会穿插一些踩坑记录和配置参考。内容不会太深奥,但都是能直接抄作业的。

2. 为什么简单的"清空重来"解决不了问题:上下文失忆的根因

2.1 上下文窗口的物理限制:token 不是越大越好

很多人以为上下文窗口越大越好,比如 200K、1M token 的模型,听起来很美好,实际上问题更多。我自己做过测试:当代理的上下文使用量超过窗口的 70% 后,它对早期指令的遵循能力会明显下降。这不是玄学,而是注意力机制的天然特性——信息太多时,模型很难在生成每个 token 时都"关注"到所有关键内容。

更现实的问题在于,编码任务中塞进上下文的内容,大部分是代码文件、编译报错、工具输出,这些信息密度高但去重性差。你让代理读一个 500 行的文件,它真正需要关注的可能是其中两个函数。如果直接全量塞进去,窗口很快就满了,留给"用户真实意图"的空间反而被压缩。

所以上下文优化的第一个原则:不要什么都往窗口里塞,要像做笔记一样,先提炼再传递。

2.2 "失忆"场景的典型特征:你其实在跟一个金鱼脑的实习生合作

我用一个类比来解释这个问题:AI 编码代理就像一个记忆力只有几个小时的实习生。你上午跟他交代了项目规范、代码风格、注意事项,他当时听懂了,但下午你再让他干活,他脑子里只剩最近半小时聊的内容。如果你恰好在这半小时里讨论的是某个细节 bug,那项目级的约束就会被挤出去。

这个类比在工程上有对应表现,我总结了三类常见的"失忆"场景:

失忆类型典型表现根因
约束漂移前期约定的规范/方案,后期被代理无意违反早期对话被挤出窗口,或被摘要压缩后失真
引用失效代理使用已废弃接口、旧函数名文件修改历史未正确同步,工具结果覆盖了真实代码状态
局部盲区修改一个函数时不考虑其他调用方上下文聚焦在局部文件,全局依赖信息缺失

这三类问题,靠"多轮对话里反复强调"几乎没用,因为代理不会主动把你说的每一句话都当成永久记忆。你必须从机制上解决问题,而不是靠提示词补救。

2.3 为什么"清空重来"不可行:上下文不是一次性消费品

有朋友会问:那我干脆每次任务都新开会话,不就没失忆问题了?理论上可以,但实际代价很高。新会话意味着你要重新解释项目背景、技术栈、代码结构、当前进度,这些"重复劳动"本身消耗的时间,可能比代理帮你省下的时间还多。而且,编码任务往往有很强的连续性——你刚定位到一个 bug 的根因,新会话里代理就得从头再来。

所以,上下文工程的目标不是"避免失忆",而是"让失忆发生在可控的位置"。这就像人类的记忆管理:有些事情要长期记住,有些事情短期记住就行,还有些事情根本不重要,连记都不用记。ChatMemory 滑动窗口,就是一套让代理区分"重要/不重要""长期/短期"的机制。

3. ChatMemory 滑动窗口拆解:它到底在"滑"什么

3.1 不是简单的 FIFO 队列:滑动窗口的三个核心维度

ChatMemory 里的滑动窗口,如果只是"删掉最早的消息",那跟直接截断上下文没什么区别,也解决不了约束漂移的问题。真正的滑动窗口至少要考虑三个维度:

窗口大小(size):决定保留多少条消息或多少 token。这个值不是拍脑袋定的,要根据你使用的模型上下文上限、任务复杂度、单条消息的平均长度来综合估算。我常用的起步值是:窗口 token 数不超过模型上下文上限的 30%——留出足够的空间给代码文件和工具结果。

步长(stride):决定窗口每次移动多少。步长太小,窗口几乎不动,失去"滑动"的意义;步长太大,又可能跳过重要信息。实际操作中,我更倾向于"按消息条数滑动 + 按 token 数触发移动"的双重策略:消息多了滑一次,token 超了也滑一次,触发条件更灵敏。

重要性保留(importance retention):这是滑动窗口真正值钱的部分。不是所有被滑出去的消息都同等对待,系统提示、用户核心指令、项目级约束,应该被优先保留或转移。很多 ChatMemory 实现支持对消息打标签,滑出窗口的消息如果标签重要,就会进入"长期记忆区",而不是直接丢弃。

3.2 我的 ChatMemory 配置参考:参数怎么定

分享一个我目前在用的配置模板,基于 Claude 类模型(200K 上下文)做参考。不同模型、不同场景需要微调,但思路通用:

chat_memory: window: max_tokens: 60000 # 窗口最大 token 数(约上下文上限 30%) min_messages: 20 # 至少保留 20 条消息 max_messages: 60 # 最多保留 60 条消息 slide_trigger: "either" # token 超限或消息超限,任一触发即滑动 stride_messages: 10 # 每次滑动移出 10 条消息(按消息数) stride_tokens: 15000 # 每次滑动释放 15000 token(按 token 数) retention: tags: ["system", "user_goal", "project_rule", "architecture"] priority_order: ["system", "project_rule", "architecture", "user_goal", "general"] auto_promote: true # 用户明确说"记住"的消息自动提升优先级 compression: enabled: true mode: "summary" # 对滑出窗口的非关键消息做摘要 summary_max_tokens: 5000

几个参数值得展开说说:

  • max_tokens 设在 30% 而不是更高,是我踩过坑后得出的经验值。设太高,留给代码文件的空间就少了,代理在读取文件时会频繁触发截断;设太低,对话连续性和任务跟踪又会变差。30% 是兼顾两者的平衡点。
  • min_messages 和 max_messages 双上限,是为了防止极端情况:如果单条消息特别长(比如贴了一段完整报错),token 超限但消息条数很少,窗口可能被一条消息占满;反过来,如果都是短消息,条数超限但 token 占用很低,滑动太多又浪费。双上限可以互相兜底。
  • auto_promote 是我最推荐开启的选项。它让用户侧的主动记忆意图生效——你告诉代理"记住这个约定",这条消息就会被打上高优先级标签,滑出窗口时不会被直接丢进摘要,而是转移到长期记忆区。这个功能极大减少了我在对话里重复强调同一件事的次数。

3.3 滑动窗口的"摘要陷阱":压缩不是免费的

刚才配置里我开了 compression 功能,但这里有个必须警惕的坑:摘要是有损压缩。滑出窗口的消息不是被删除,而是被总结成摘要留在上下文里。问题在于,摘要过程本身就是一次生成任务,模型在总结时可能丢掉细节、甚至引入错误信息。

我遇到过一个典型案例:我让代理记住一个第三方库的版本兼容性约束,原文是"注意:A 库 1.x 版本与 B 库 2.x 版本不兼容,如果升级 B 库,需要同步升级 A 库到 2.x"。这版的摘要变成"A 库与 B 库存在兼容性问题,升级时注意",但"同步升级"这个关键动作没了。后面代理在处理依赖升级时,只升级了 B 库,A 库没动,直接导致运行时报错。

所以我对 compression 的建议是:摘要可以开,但只对"一般性讨论"开,对"明确的规则约束"不要开。上面配置里我把 project_rule 标签的消息设为不参与压缩,就是出于这个考虑。如果你的 ChatMemory 实现不支持按标签排除压缩,那就把规则约束写在一个单独的持久化文件里,每次会话开始前重新注入,这比任何记忆机制都可靠。

4. Context-mode MCP 是做什么的:把上下文优化的能力做出成工具

4.1 MCP 在上下文管理里的角色

聊到 Context-mode MCP,先得说清楚 MCP(Model Context Protocol)在这套体系里是什么位置。MCP 是一套标准化协议,让 AI 代理能够连接外部工具和数据源。你可以把它理解成"代理的 USB 接口"——凡是支持 MCP 的工具,都能用统一的方式插到代理上。

在上下文管理的场景里,MCP 的作用是:把"上下文怎么处理"从代理内核里抽出来,变成可插拔的工具。默认情况下,代理的上下文策略是写死在实现里的(比如固定的截断策略、固定的摘要方式),你只能被动接受。有了 MCP,你就可以接入一个专门的"上下文优化工具",让代理按你定义的策略管理记忆。

Context-mode 是这类 MCP 工具里值得关注的一个方向。它不只是一个简单的"记忆存取"接口,而是一套完整的上下文处理流程:检索、压缩、分层、注入、遗忘。你可以把它理解成给代理装了一个"可编程的记忆管理系统"。

4.2 Context-mode 的工作机制:检索、分层和按需注入

Context-mode MCP 的核心思路和直接塞全部上下文不同,它把上下文当成一个"数据库"来管理。工作流程大致分三步:

第一步,分层存储。所有对话内容、文件内容、工具结果进入上下文系统后,先进行分类和索引。哪些是系统指令、哪些是用户目标、哪些是代码内容、哪些是临时输出,分开存放,各自标注优先级和有效期。这个分层很重要,它让后续的检索和压缩有据可依。

第二步,按需检索。代理在生成回复前,不是直接看全部历史,而是先发起一次"查询"——从分层存储中检索与当前任务最相关的片段。这有点像人类工作时的记忆调用:你写代码的时候不会回忆起昨天晚饭吃了什么,只会调取跟手头任务相关的经验。检索结果注入到当前上下文窗口,供模型参考。

第三步,动态遗忘。上下文系统的"遗忘"策略不是简单淘汰旧内容,而是根据内容的访问频率、重要性标签、关联度动态调整。低频且不重要的内容,会被逐渐压缩成摘要,再进一步沉淀成精简的索引条目;高频且重要的内容,则永远保持在可快速访问的位置。

这套机制最大的好处是:代理的上下文窗口不再是"一条河流"(过去的全被冲走),而是一个"储物柜"(常用的东西放在手边,不常用的收进仓库,偶尔需要的能按标签找到)。我接入 Context-mode MCP 后,最直观的感受是,代理在处理长任务时的"早期约束遵循能力"明显回升,不太需要我反复提醒项目规范了。

4.3 怎么把 Context-mode MCP 接到你的代理上

配置步骤不复杂,但有几个细节容易踩坑。以我用的方案为例:

# 1. 以 MCP 客户端方式注册 Context-mode 服务 mcp add context-mode --transport stdio --command "context-mode-server" # 2. 配置上下文策略(YAML 格式) context_mode: storage: backend: "sqlite" # 持久化存储后端 index_strategy: "bm25" # 检索算法,bm25 适合代码场景 retrieval: top_k: 15 # 每次检索注入的片段数 max_tokens_per_retrieval: 8000 include_high_priority: true # 高优先级内容永远注入 compression: summary_threshold: 0.7 # 上下文占用 70% 时触发压缩 preserve_tags: ["system", "project_rule"] # 3. 在代理的 system prompt 里声明使用策略 # "使用 context_mode 工具管理你的上下文,每次回复前调用 retrieve 获取相关信息,不要直接依赖全部对话历史"

接入之后,有几个配置参数需要根据你的实际场景微调:

  • top_k 和 max_tokens_per_retrieval:这两个值决定了每次回复前注入多少检索内容。设太小,检索不到足够信息;设太大,上下文又会膨胀回检索前的状态。我的经验是宁可 top_k 小一点(8~10),但每个片段内容质量要高——开启索引时优先索引函数签名、类定义、TODO 注释这些高信息密度区域。
  • include_high_priority:这个要设为 true。它保证系统提示和项目级约束永远在上下文中,不被检索逻辑挤掉。这相当于给关键信息开了"免检通道"。
  • summary_threshold:0.7 是我验证过的值。太早压缩会频繁打断对话连续性,太晚压缩又起不到节省空间的作用。

我接入后做了一个大概的量化对比:在完成一个中等规模功能开发任务时,旧方案(纯 ChatMemory 滑动窗口)需要大约 35 次对话交互,中途有 4 次明显的"失忆"问题需要我介入纠正;接入 Context-mode MCP 后,交互次数降到 22 次,失忆问题只出现 1 次,而且是发生在非核心的 UI 细节上。整体效率提升不是幻觉。

5. 一条可落地的上下文优化管线:从原始对话到可复用记忆

5.1 完整管线的五层结构

把 ChatMemory 和 Context-mode MCP 串起来,我目前在用的上下文优化管线是这样的,覆盖从"原始对话流"到"可复用的项目记忆"的完整链路:

第一层:原始对话流。这是代理本地收到的全部消息,包括用户输入、工具结果、代码输出。这一层的关键策略是"尽可能完整记录",不做任何主动淘汰,因为这是后续所有处理的事实来源。

第二层:ChatMemory 滑动窗口。对原始对话流做第一轮治理:控制窗口大小,滑出低优先级内容,重点保留高优先级消息。这一层的输出是"当前工作集"——代理在本次会话中需要随时可见的信息。

第三层:Compression/摘要层。滑出工作集但仍有价值的内容,在这里被压缩成摘要。摘要的质量直接影响后续检索的有效性,所以这一层我通常配置为"只对 general 类型消息做摘要,规则类消息直接进持久层"。

第四层:Context-mode 存储/索引层。经过治理的内容写入分层存储,建立索引。这一层是长期记忆的基础,它让上下文管理不再局限于"本次会话",而是跨会话可复用。项目规范、架构决策、踩坑记录,都在这一层沉淀。

第五层:检索注入层。代理每次生成回复前,从存储中检索相关片段,注入当前上下文窗口。这层决定了代理"此刻能看到什么",也是 Context-mode MCP 实际发挥作用的地方。

5.2 项目启动时的上下文初始化模板

怎么把一条空管线变成"开箱即用"的项目记忆?我建议在每次启动大型编码任务前,先执行一次"上下文播种"(context seeding),把项目级的关键信息注入系统。以下是我常用的五条种子消息:

# seed_message_1: 项目总体描述 "项目是XX系统,目标是解决XX领域的问题。技术栈为XX框架+XX数据库,部署在XX环境。当前阶段主要开发XX模块。" # seed_message_2: 架构约束 "本项目遵循分层架构,禁止跨层调用。业务逻辑必须放在 service 层,controller 只做参数校验和路由分发。数据访问统一走 repository 接口。" # seed_message_3: 代码规范 "命名规范:类名用驼峰,方法名用驼峰,常量用大写+下划线。禁止使用拼音缩写。错误处理统一使用自定义异常,禁止返回 null 表示失败的约定。" # seed_message_4: 当前任务 "本次任务是实现XX功能,涉及文件:A.java, B.java, C.java。需要新增接口XX,修改现有逻辑YY,同时兼容旧版本调用方。" # seed_message_5: 验证标准 "完成标准:所有单测通过,新增代码覆盖率不低于80%,接口兼容旧版本客户端,通过代码评审要求的静态检查。"

这五条种子消息在会话开始时注入,并打上 system 和 project_rule 标签。在 ChatMemory 滑动窗口策略下,这些消息拥有最高优先级,正常情况下不会被滑出;即使因为极端情况被滑出,也会原样进入长期记忆区,并通过 Context-mode 的 include_high_priority 参数再次注入。效果就是:无论对话进行到多深,项目的基本盘始终在代理的视野里。

5.3 会话结束后的记忆归档操作

编码任务告一段落,不代表上下文管理就结束了。我养成了一个习惯:每次长时间会话结束后,都会执行一次"记忆归档",把本次会话中产生的有效信息沉淀到项目的长期记忆中。具体操作分三步:

  1. 提取会话摘要:让代理生成本次会话的总结,包括完成了什么、修改了哪些文件、解决了哪些问题、还有哪些遗留事项。摘要需要标注日期和关联的需求编号。
  2. 识别可复用规则:如果会话中产生了新的架构决策、新的规范约定、新的踩坑教训,单独提取出来,以规则的形式写入项目记忆库,而不是只留在摘要里。
  3. 清理冗余索引:删除那些已经过时、被重写、不再有参考价值的内容。比如临时调试用的代码、废弃接口的备注、已经被后续方案取代的中间设计。

这样做的价值在跨会话任务里体现得最明显。比如一个持续数天的大项目,每天都会产生大量对话和代码修改。如果不做归档,第三天启动新会话时,代理对前两天的"记忆"基本是空白的;做完归档后,新会话可以通过 Context-mode 检索到前两天的关键决策和进度,任务连续性会好很多。

6. 实测对比:滑动窗口、上下文压缩、MCP 检索,各自的表现边界

6.1 测试任务与基线设置

为了给前面的分析一个量化参考,我设计了一个基准测试。测试任务是一个自动化脚本的改造:原始代码约 300 行,需要增加新的配置解析、重构核心逻辑、补充单元测试,涉及 4 个文件改动。任务本身难度适中,关键是有几个约束需要代理在多个文件修改中始终遵守(比如某个配置项优先级、某个日志格式规范)。

测试分四组:

方案配置说明
A 基线固定窗口上下文,超过窗口直接截断,无记忆策略
B 滑动窗口ChatMemory,窗口配置见前文,无压缩
C 滑动窗口+压缩ChatMemory + 摘要压缩,压缩策略开启
D 完整管线ChatMemory + Context-mode MCP 检索注入

每组测试重复 3 次,取中间值。所有测试在同一个代码仓库上进行,使用相同的模型(Claude 类 200K 上下文模型)和相同的提示词启动。

6.2 结果数据与观察

指标A 基线B 滑动窗口C 滑动窗口+压缩D 完整管线
任务完成时间(min)64524835
交互轮数41332922
需要人工介入的次数7431
早期约束遵守率(%)61787493
最终代码单测通过率(%)82928896

有几个数据值得深入解读:

方案 A 到方案 B 的提升主要来自"约束不再那么快被挤出窗口"。基线方案在下半场基本进入"半失忆"状态,所以需要大量人工提醒;滑动窗口至少保证核心约束在多数时间可见。

方案 C 反而比 B 差一点,这个结果很耐人寻味。摘要压缩节约了 token,但压缩后的信息密度下降,代理有时会参考"残缺的摘要"做出错误判断。正如前面说的,摘要是有损压缩,在约束类信息上代价尤为明显。这也验证了我之前的配置经验:规则类消息不能参与压缩。

方案 D 是最优的,但它的优势不只是"上下文更多"。在完整管线中,约束信息是作为高优先级内容被直接注入的,而不是靠"留在窗口里"被动维持。检索机制让代理在需要时能精确取回相关信息,不必把所有东西都堆在窗口里等着被看到。任务完成时间缩短,主要原因是人工介入减少了。

6.3 什么时候选什么方案:务实的选择建议

如果看数据就认为"一定要上完整管线",那又走到了另一个极端。上下文优化方案的选型要考虑你的实际情况:

  • 短任务(30 分钟内完成):A 基线完全够用。窗口还没满,任务就结束了,加记忆策略纯属多余。
  • 中等任务(1~2 小时):方案 B 就够了。滑动窗口可以保证约束不丢失,配置成本低,稳定性好。
  • 长任务或跨会话(数小时以上):直接上方案 D。但前提是你愿意投入一点配置时间,并接受检索机制偶尔返回不相关内容的"噪音"。方案 C 这种"只压缩不检索"的组合,我建议谨慎使用,摘要失真带来的坑有时候比收益还要大。

7. 绕过这些坑,你能少走不少弯路

7.1 滑动窗口的"半句话"截断问题

滑动窗口是按 token 或消息条数滑动。如果一条消息特别长(比如贴了一个 300 行的报错日志),滑动时可能只截掉消息的一半,剩下的一半残留在上下文里。这会导致代理看到一段无头无尾的日志,反而产生错误理解。我遇到过一次:一条报错日志被截断后只剩堆栈的下半部分,代理以为错误来自某个函数,实际却来自另一个调用方,白白排查了半小时。

规避方式:在 ChatMemory 实现里,如果支持的话,配置"按完整消息滑动"而不是"按 token 滑动"。如果不支持,就把大段内容拆成多条消息输入(比如让代理分段输出日志),减小单条消息的体积。

7.2 压缩摘要的"幻觉累积"问题

摘要是有损压缩,每一次压缩都可能引入一点失真,而失真是会累积的。早期对话被压缩成摘要A,摘要A和后续内容又被压缩成摘要B,B 的信息密度可能比 A 更低。几轮压缩之后,原始的核心语义可能已经被扭曲得不成样子。这个问题在长会话中特别明显。

规避方式:对需要准确传递的信息(规则、约束、数字、API 签名)使用持久化存储,而不是"内存摘要"。Context-mode 的 storage 层可以作为事实来源,摘要层只保留"大致语义"级别的信息。建议你全程打开"规则类消息不参与压缩"的选项。

7.3 工具调用历史和用户对话的优先级反转

AI 编码代理会频繁调用工具(读文件、执行命令、搜索代码)。工具调用的输入输出往往很长,而且大部分是一次性的——跑一个命令,拿一个结果,用完后这个结果就不再需要了。但如果不加区分,这些工具消息会和用户的核心指令一样占用窗口,甚至因为消息最新而"压制"了更重要的早期指令。

我观察到一个反转:代理在决策时,常常优先参考"最近的工具输出",而不是"更早的系统约束"。比如系统里约定"不要在 controller 层写业务逻辑",但刚才一条工具输出里出现了一个反例,代理可能会参考这个反例来行为,因为它看起来更"新鲜"。

规避方式:给工具调用消息设置更短的保留期。在 ChatMemory 配置里,让工具结果按"使用完即弃"的策略处理——单个工具结果保留一段时间,一旦后续对话确认已消化,就允许被滑出。用户的指令目标保持更长的保留期。如果使用 Context-mode,可以通过标签系统把工具结果和用户目标分开检索,避免优先级互相干扰。

7.4 多文件修改时的"上下文引用漂移"

多文件任务里,代理经常需要同时记住多个文件的当前状态。但当窗口因为滑动而"遗忘"了某个文件的早期版本时,代理可能基于旧版本做修改,造成引用漂移。我在测试中遇到过:代理改了一个函数签名,但上下文里的"旧引用记录"还在,导致后续代码仍然调用旧签名,编译直接报错。

规避方式:在涉及多文件修改的任务中,让代理在执行修改前先生成一份"文件状态快照"——列出所有相关文件的当前关键内容(函数签名、类名、依赖关系)。这份快照作为高优先级消息保留在上下文中。之后任何文件变更后,先更新快照再继续,避免代理基于过时信息工作。这就像在团队协作里维护一份"当前主干状态"文档。

7.5 性能开销:每次检索都是在"烧 token"

Context-mode 检索能提升质量,但这个机制本身是有成本的。每次回复前调用 retrieve,会额外消耗 token;如果检索结果质量不高,注入了一些无关片段,还会占用窗口空间,反而降低整体效率。我试过把 top_k 调到 30,结果检索回来的片段有一半是无关的,上下文占用比不检索还高,模型回复质量也没提升。

规避方式:top_k 从小值开始调,不要一上来就给大。同时注意观察检索结果的相关性:如果经常是噪音,试试调整索引粒度和检索策略。在 Context-mode 里,bm25 对代码场景通常比 embedding 检索更稳定——因为代码里很多关键信息是符号、函数名这种"精确词汇",词法匹配比语义相似更可靠。

8. 我现在的固定工作流和最终建议

经过一段时间的试错,我现在处理涉及 AI 编码代理的开发任务时,已经形成了一套固定的工作流。简单分享出来,供参考:

启动一个大型编码任务前,我会:

  1. 执行上下文播种:注入项目描述、架构约束、代码规范、当前任务、验证标准五条种子消息,并标记为高优先级。
  2. 开启 ChatMemory 滑动窗口:窗口 token 上限设为模型上下文上限的 30%,保留高优先级消息,关闭规则类消息的压缩。
  3. 接入 Context-mode MCP 检索:top_k 设为 10~15,检索算法选 bm25,include_high_priority 设为 true。
  4. 任务执行过程中:定期检查上下文占用率,超过 70% 时手动触发一次"记忆整理",把已完成的子任务内容移出窗口,为后续工作腾出空间。
  5. 任务结束后执行归档:提取会话摘要、识别可复用规则、清理冗余索引,保证下次会话能"接得上"。

这套工作流不是银弹。上下文工程本身的定位是"把模型能力发挥到边界内最优",它不能弥补模型本身的缺陷,也不能替代清晰的需求表达。但对于编码代理这种需要长时间跟随、频繁引用早期约定的场景,一套好的上下文管线的确能把"碰运气式的可靠"变成"有机制保障的可靠"。

如果你正在被代理"失忆"问题困扰,我建议先从 ChatMemory 滑动窗口的配置入手,把窗口参数和消息优先级理清楚。这一步成本低,收益立竿见影。等你的任务复杂度进一步提升,再考虑接入 Context-mode MCP 做检索和长期记忆的沉淀。上下文工程是个持续迭代的过程,没有一次配好永远适用的方案,关键是理解每层机制在做什么,然后根据你的任务特点做对应调整。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询