news 2026/7/18 3:33:04

Coding Agent 为什么压缩上下文后还能继续工作?上下文模块设计拆解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Coding Agent 为什么压缩上下文后还能继续工作?上下文模块设计拆解

你好,我是程序员无隅

🌈这是我的个人主页:无隅的主页

🌟“技术永无止境,希望我的内容能帮到你”


让 Coding Agent 修改一个稍微复杂的项目时,它通常要经历很多轮工具调用:读取文件、搜索符号、修改代码、运行测试,再根据报错继续调整。

任务刚开始时,Agent 往往反应很快。随着对话变长,工具结果和历史消息不断累积,输入 Token 越来越多,最终可能逼近模型的上下文窗口。

一个直观做法是把旧消息删掉或者生成一段摘要。

但真正实现时会遇到更棘手的问题:刚读过的文件还能不能记住?已经激活的 Skill 会不会丢失?用户最早给出的禁止项是否还有效?工具调用和工具结果会不会被拆开?压缩失败后会不会反复重试,拖垮整个 Agent 循环?

所以,生产级上下文管理解决的并不只是 Token 太多。

上下文模块的本质,是在有限窗口中完成信息分级、工作状态重建和失败兜底,让 Agent 在压缩之后仍然知道目标、约束、当前进度和下一步。

这篇文章从一个真实 Coding Agent 的上下文模块出发,拆解它如何通过工具结果预算、全对话压缩、恢复附件和会话持久化,让长任务可以继续运行。


一、上下文不是聊天记录,而是 Agent 的工作内存

上下文窗口可以理解成模型生成下一次响应时能够参考的工作内存。

它不只包含用户和助手的文字消息。系统提示词、工具定义、文件内容、命令输出、工具调用结果,以及模型即将生成的输出,都会占用窗口空间。Anthropic 的上下文窗口文档也明确指出,工具结果、图片、文档和工具定义都计入上下文。

这意味着 Coding Agent 的上下文增长速度通常比普通聊天更快。

用户可能只输入了一句“帮我修复这个问题”,但 Agent 为了完成任务读取了多个文件、执行了测试并拿到大量日志。真正占据上下文的,往往不是这句用户需求,而是执行过程中产生的工作材料。

上下文过长会带来三个直接问题:

  • 请求可能超过模型的硬窗口限制。
  • 每轮都要携带更多历史信息,延迟和成本随之增加。
  • 重要约束被大量旧工具结果淹没,模型的检索与判断会变得困难。

所以,上下文管理不能只在“快超限”时临时救火。它需要从每轮 Agent 循环开始,就决定什么内容保留原文、什么内容外移、什么内容摘要,以及压缩后怎样恢复。


二、上下文模块在 Agent 主循环中的位置

上下文管理不是一个独立运行的定时任务,它嵌在每轮模型请求之前和之后。

一次完整链路可以概括为:

  1. 解析当前模型的上下文窗口大小。
  2. 注入环境信息、系统提醒和当前任务状态。
  3. 检查原始对话是否接近窗口上限,必要时执行 Auto-Compact。
  4. 在发送模型请求前,对工具结果应用预算策略,生成本轮专用的 API 对话副本。
  5. 模型响应后记录真实 Token 用量,作为下一轮估算的锚点。
  6. 工具执行后,记录后续压缩可能需要恢复的文件和 Skill 状态。
  7. 如果发生压缩,将结构化压缩边界交给会话层持久化。

这里有一个很重要的职责划分:原始对话和真正发送给模型的对话副本不是同一个对象。

工具结果预算不会直接修改原始历史,而是基于原始对话构造一份api_conv。这样既能为当前请求减小输入,也能保留完整历史,供摘要、恢复和会话持久化使用。

Auto-Compact 则不同。它处理的是原始对话:把早期消息替换为摘要,再拼回近期原文,真正改变后续对话的基础状态。

一个负责“本轮怎么发”,一个负责“以后还保留什么”,两层不能混在一起。


三、压缩之前,先把 Token 预算算明白

上下文管理的所有阈值判断,都依赖两个基础数据:模型窗口有多大,以及当前用了多少 Token。

如果这两个数字不可靠,压缩可能触发太早,浪费可用空间;也可能触发太晚,在摘要请求发出前就已经撞上窗口限制。

1. 上下文窗口使用四层回退

不同模型、不同服务商甚至不同部署方式,窗口大小都可能不同。因此,这个上下文模块没有把窗口写死,而是按优先级解析:

  1. 用户在配置中显式指定的窗口。
  2. 运行时从服务商模型接口获取并缓存的窗口。
  3. 内置的“模型名称到窗口大小”映射。
  4. 无法识别时使用保守默认值。

这条回退链的设计原则是:显式配置永远优先,自动发现尽量准确,内置映射负责离线兜底,默认值保证系统仍能运行。

2. Token 估算使用“真实锚点 + 增量估算”

只用字符数估算整段历史,误差会随着对话增长不断累积。

更稳妥的方式是:每次模型响应后,把 API 返回的真实用量记录为锚点。下一轮检查时,只对锚点之后新增加的消息做字符估算。

可以把当前 Token 近似理解为:

当前用量 = 上次 API 返回的真实用量 + 上次响应后新增消息的估算值

如果系统刚启动,或者对话刚经历压缩、旧锚点已经失效,再退化为估算整段历史。下一次 API 响应到来后,重新建立真实锚点。

这样,估算误差只集中在最新增量,而不会污染整个会话。


四、第一层防线:给工具结果设置预算

Coding Agent 最容易制造大上下文的地方,是工具结果。

一次文件读取可能返回几万字符,一次测试可能输出大量日志,一轮并发工具调用还可能把多个中等结果聚合到同一条消息中。

这个上下文模块使用三步预算处理。

1. 单个结果过大:原文落盘,只保留预览

当单个工具结果超过设定上限时,完整内容写入会话目录,上下文中只保留前部预览、原始大小和文件位置。

这不是直接删除信息,而是把信息从昂贵的模型工作内存搬到便宜的外部存储。后续真的需要细节时,Agent 可以重新读取文件。

当前实现使用约 5 万字符作为单条结果阈值,并保留约 2000 字符预览。这个数字是工程配置,不是所有 Agent 都必须照抄的标准。

2. 多个结果聚合过大:优先外移最大的结果

单条结果没有超限,不代表整条消息安全。

如果一轮产生多个工具结果,它们的总量超过聚合预算,系统会按大小排序,优先把最大的结果外移,直到消息重新回到预算以内。

这种策略的好处是修改次数少:每外移一个大结果,都能回收更多空间,同时保留更多小结果原文。

3. 陈旧工具结果:只保留短预览

工具结果的价值会随任务推进而变化。

Agent 早期读过的文件可能已经被修改,早期测试日志也可能被新的测试结果替代。当前实现会保留近期若干轮的完整结果,对更早且较长的结果进行裁剪。

这一步体现了上下文管理的核心判断:信息价值不只由大小决定,也由新鲜度决定。


五、为什么替换决策必须冻结

工具结果预算还有一个容易被忽略的问题:同一段旧历史会在每轮请求前被重新处理。

如果系统每次都重新决定某个工具结果是否外移,或者每次生成的预览文本存在细微差异,那么发送给模型的历史前缀就会不断变化。

这不仅会让行为难以复现,还会影响 Prompt Cache。

Anthropic 的 Prompt Cache 使用提示词前缀进行匹配。官方文档说明,缓存覆盖tools → system → messages的有序前缀;缓存点之前的内容发生变化,会产生不同的前缀哈希,使原缓存无法复用。

因此,上下文模块会为每个工具调用结果记录两类状态:

  • 这个结果是否已经评估过。
  • 如果决定替换,固定使用哪一段预览文本。

一旦结果被判断为“保留原文”,后续不再重新评估;一旦被判断为“替换”,后续始终使用完全相同的预览。

替换记录还会追加写入会话目录。恢复会话时,系统根据当前消息中的工具调用 ID 重建状态,只恢复仍然存在的决策,避免旧记录污染新会话。

决策冻结表面上是在减少重复计算,本质上是在稳定请求前缀和跨轮行为。


六、第二层防线:摘要旧前缀,保留近期原文

第一层能够控制工具结果,但无法阻止普通消息持续增长。

当当前用量接近窗口上限时,系统会触发 Auto-Compact。它没有把整个历史粗暴压成一段摘要,而是把对话切成两部分:

  • 较早的前缀交给模型生成结构化摘要。
  • 最近一段消息保持原样,直接拼回压缩后的历史。

近期原文负责保存刚刚发生的代码修改、报错和工具交互;摘要负责保存更早的任务目标、关键决策和完成状态。

1. 阈值要给摘要本身留空间

压缩不是免费的。生成摘要同样需要一次模型调用,也需要输出空间。

因此,自动压缩阈值不能等于完整窗口,而应该从窗口中扣除摘要输出预留和安全余量:

压缩阈值 = 上下文窗口 − 摘要输出预留 − 安全余量

当前实现为自动压缩保留了更大的安全余量,手动压缩则使用较小余量。原因是手动操作发生得更可控,自动检查还要防止两轮之间突然出现大工具结果。

2. 尾部保留不能拆断工具调用

近期原文从历史尾部向前选择,同时考虑 Token 数、消息数量和硬上限。

但切分点不能随便落在消息之间。如果保留区从一条tool_result开始,却把前面的tool_use放进摘要区,模型会看到一个找不到来源的工具结果。

所以系统会把边界向前对齐,确保工具调用和对应结果成对保留。

3. 回收空间太少时,宁可不压缩

如果可摘要的前缀很短,生成摘要消耗的 Token 可能和回收空间差不多。

当前实现会检查前缀规模。收益不足时直接跳过压缩,避免为了“执行过压缩”而做一次没有实际价值的模型调用。


七、压缩后不失忆:重建 Agent 的工作现场

摘要最大的风险不是语句变短,而是工作状态被抽象掉。

例如,摘要可能记住“正在修改文件读取逻辑”,却没有保留刚读过的具体代码;可能记住“使用了某个 Skill”,却丢掉 Skill 规定的执行步骤;也可能把用户的原始禁止项改写成含义接近但不够精确的表达。

所以,压缩后的新历史不是只有摘要。

它由四部分组成:

1. 结构化摘要

摘要保存任务目标、关键技术点、涉及文件、错误与修复、当前工作和后续待办。

摘要模型只负责整理历史,不允许调用工具,也不能继续执行原任务。这样能够避免压缩过程意外改变业务状态。

2. 近期原文

最近的消息不经过摘要,直接拼回新历史。

Agent 因此还能看到刚刚执行的工具调用、最近一次测试结果和当前推理链附近的上下文,而不是完全依赖有损摘要。

3. 恢复附件

Agent 在运行过程中会记录最近读取的文件和已经激活的 Skill。压缩发生时,这些快照按预算重新附加到摘要消息中。

恢复附件还会列出当前可用工具的名称和简短描述,提醒模型压缩后仍然具备哪些操作能力。

文件快照不是永久真相。恢复信息会明确提示:如果需要当前字节内容,应该重新读取文件,不能根据旧快照猜测。

4. 关键用户约束原文

系统会从早期用户消息中挑选任务目标、禁止项、格式要求、路径、命令和验收标记,并尽量保留原文。

这相当于为摘要增加一条确定性防线:即使摘要模型遗漏了约束,关键要求仍然可以通过附件回到新上下文。

经过重建后,新的对话结构是:

摘要消息 + 关键约束 + 文件与 Skill 恢复附件 + 近期原文

这就是 Agent 压缩后还能继续工作的关键。它不是单纯“记住过去”,而是恢复继续执行任务所需的最小工作现场。


八、持久化、重试和熔断如何兜底

上下文压缩依赖模型调用,因此它本身也可能失败。

如果摘要请求仍然过长,系统会按对话轮次裁掉一部分最早内容,再重新尝试;如果连续多次失败,则记录失败次数并打开熔断器,停止自动压缩,提示用户改用手动处理。

当前实现把连续三次失败作为熔断条件。一次成功压缩后,失败计数会被清零。

这个机制防止 Agent 进入危险循环:

  1. 上下文超限。
  2. 自动压缩失败。
  3. 下一轮再次自动压缩。
  4. 不断消耗请求,却始终无法继续任务。

除了运行时熔断,压缩结果还会以结构化边界交给会话层。边界包含摘要和原样保留的尾部消息,恢复会话时可以直接重建压缩后的状态,而不必重新执行一次摘要。

工具结果的替换决策也会独立持久化。这样,恢复后的会话仍能保持与压缩前一致的预览文本和预算行为。

压缩负责减少上下文,持久化负责跨会话恢复,熔断负责在压缩失败时保护主循环。


九、这套设计仍然有哪些边界

上下文管理本质上是在信息完整性、Token 成本和执行连续性之间做取舍,不可能完全无损。

1. 摘要仍然是有损压缩

即使摘要 Prompt 规定了固定结构,模型仍可能遗漏细节。恢复附件只能保护部分高价值状态,不能保证还原完整对话。

因此,系统保留完整会话记录路径,需要精确代码、错误原文或用户原话时,应重新读取,而不是相信摘要中的近似表达。

2. 文件快照可能已经过时

压缩附件中的文件内容代表上次读取时的状态。如果文件后来被工具或用户修改,快照就不是当前版本。

它适合帮助模型恢复思路,不适合替代再次读取。

3. 固定阈值需要结合模型和任务调整

单条结果上限、聚合预算、摘要预留和尾部保留窗口都是工程参数。

文件分析型任务、命令执行型任务和多 Agent 协作产生的上下文结构并不相同。更成熟的实现可以结合真实运行指标,按模型窗口、工具类型和任务阶段动态调整。

4. Prompt Cache 不能替代上下文压缩

缓存能够降低重复前缀的处理成本和延迟,但缓存中的 Token 仍然占用上下文窗口。Anthropic 官方文档也明确说明:Prompt Cache 改变的是这些 Token 的处理方式和价格,不会让它们从窗口中消失。

所以,决策冻结和上下文压缩解决的是两个问题:前者保持前缀稳定,后者真正回收窗口空间。


十、总结

Coding Agent 的上下文模块不是一个简单的messages数组,也不是快超限时调用一次摘要函数。

一套能够支撑长任务的上下文设计,需要同时解决以下问题:

  1. 通过窗口回退链和真实用量锚点,判断什么时候需要压缩。
  2. 通过单条预算、聚合预算和陈旧裁剪,控制工具结果增长。
  3. 通过替换决策冻结,保持跨轮行为和请求前缀稳定。
  4. 通过“摘要旧前缀 + 保留近期原文”,回收空间又保留当前细节。
  5. 通过关键约束、文件快照、Skill 和工具列表,重建压缩后的工作现场。
  6. 通过压缩边界持久化、重试和熔断,保证失败不会拖垮 Agent 主循环。

所以,上下文管理真正要回答的不是“删掉多少 Token”,而是:

哪些信息必须留在模型眼前,哪些信息可以移到外部,需要压缩时如何保住任务状态,压缩失败时又怎样安全退场。

当这些边界被设计清楚,Coding Agent 才能从一次性的代码问答工具,变成能够持续执行长任务的工程系统。


参考资料

  • Anthropic:《Context windows》
    https://platform.claude.com/docs/en/build-with-claude/context-windows
  • Anthropic:《Prompt caching》
    https://platform.claude.com/docs/en/build-with-claude/prompt-caching
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/18 3:32:28

AI收益递减:重建人机协作的警戒线

1. 项目概述:当AI从“加速器”变成“减速带”,我们到底在依赖什么?“AI’s Diminishing Returns: Avoiding the Overreliance Trap”——这个标题不是一篇技术白皮书,也不是某家大厂的公关稿,而是我在过去18个月里&…

作者头像 李华
网站建设 2026/7/18 3:31:25

如何快速部署跨平台AI自动化:终极指南

如何快速部署跨平台AI自动化:终极指南 【免费下载链接】midscene AI-powered, vision-driven UI automation for every platform. 项目地址: https://gitcode.com/GitHub_Trending/mid/midscene Midscene.js是一款革命性的跨平台AI自动化框架,通过…

作者头像 李华
网站建设 2026/7/18 3:30:29

用LLM+Neo4j将会议纪要自动构建成可检索知识图谱

1. 项目概述:为什么会议纪要不该再躺在邮箱里吃灰?“Building a Self-Updating Knowledge Graph From Meeting Notes With LLM Extraction and Neo4j”——这个标题乍看像一篇学术论文的副标题,但在我过去三年帮十多家中型科技公司落地知识管…

作者头像 李华
网站建设 2026/7/18 3:29:12

Ionic项目打包安卓APK完整指南与优化技巧

1. Ionic项目打包安卓APK实战指南作为一款流行的跨平台移动应用开发框架,Ionic允许开发者使用Web技术(HTML/CSS/JavaScript)构建同时兼容iOS和Android的应用。但在实际开发中,将Ionic项目打包成安卓APK文件的过程往往会遇到各种&q…

作者头像 李华