news 2026/10/29 11:06:45

learn-claude-code为什么会反复压缩上下文?一次已合并的 PR 实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
learn-claude-code为什么会反复压缩上下文?一次已合并的 PR 实践

我给一个接近8 万 Star的开源项目提交了 PR,最近已经通过审核并合并!

这个项目就是最近爆火的 learn-claude-code,
这次我主要对他的上下文压缩模块的snip_compact函数进行了修改,引入滞回阈值,给压缩操作留出缓冲,避免 Agent 在后续对话中频繁裁剪消息、写入内容高度重叠的历史归档。

核心问题用一串数字就能说明:

修改前:50 → 52 → 压回 50 → 52 → 再压回 50…… 修改后:50 → 压到约 30 → 32 → 34 → …… → 50 → 再压缩

下面介绍这个项目,以及这次修改具体解决了什么。

learn-claude-code 是什么?

learn-claude-code 是 shareAI-lab 维护的教学项目,通过一系列递进式课程,演示如何从零搭建一个类似 Claude Code 的编程 Agent 运行框架。

如果你用过 AI 编程工具,应该见过这样的过程:它先读取文件,再搜索代码、执行命令,根据结果继续修改,直到完成任务。

这些操作背后需要一套工程机制:如何把工具提供给模型,如何执行模型发出的调用,如何保留历史,以及如何控制操作权限。项目把这套基础设施称为Harness。

最基本的运行过程可以理解为:

用户提出任务 ↓ 模型读取上下文,决定下一步 ↓ 调用工具,例如读取文件或执行命令 ↓ 把工具结果加入历史,再交给模型 ↓ 继续处理,直到给出最终回复

项目从这样的基础循环开始,逐步加入工具调用、权限控制、子 Agent、上下文压缩和任务管理等机制。

我这次修改涉及其中两处实现:S08 上下文压缩课程,以及复用这一机制的S15 集成 Harness 课程。

为什么 Agent 需要压缩上下文?

假设你让 Agent 修复一个报错,它可能连续完成这些操作:

读取报错日志 读取相关源文件 搜索函数的调用位置 修改代码 执行测试 根据测试结果继续修改

过程中,用户消息、模型回复、工具调用和工具结果都会不断加入历史。

模型的上下文容量有限。如果始终携带所有历史,长任务就会越来越难以继续。因此,项目提供了多种上下文管理方式,其中一种叫snip_compact。

它会先将完整历史保存到.transcripts/,再裁掉中间的一部分消息,保留开头和最近的内容,并插入一条归档标记,告诉模型较早的记录保存在哪里。

这一步主要通过裁剪消息控制历史长度,不需要额外调用模型生成摘要。

原来的问题:压缩完,马上又到门槛了

旧实现使用max_messages=50,同时控制触发条件和裁剪后的保留数量:

  • 消息超过 50 条时触发裁剪。
  • 裁剪后通常保留 50 条,包括归档标记。

问题出在第二点:裁剪后没有留下新增消息的空间。

举个不涉及工具调用边界的简单例子。历史第一次压缩后剩下 50 条,接下来用户问一句,模型答一句,又增加两条:

当前历史:50 条 新增一轮问答:+2 条 当前历史:52 条 再次触发裁剪:回到 50 条

下一轮又会重复这个过程。

而每次裁剪之前,代码都会保存一份完整的当前历史。因此,一旦越过门槛,后续问答或工具调用轮次就可能频繁触发归档,产生内容高度重叠的文件,并反复调整模型看到的近期上下文。

这里真正需要调整的是:触发压缩的数量,与压缩后的目标数量。

我的修改:达到 50 条,裁到约 30 条

这次 PR 将原来的一个参数拆成两个:

trigger_messages=50# 达到多少条时触发target_messages=30# 触发后希望保留多少条

新逻辑在消息数量达到 50 条时触发裁剪,通常将其缩减到 30 条,为后续新增消息留出约 20 条空间。

这就是这次修改中的“滞回”思路:触发点与处理后的目标之间保持距离,避免系统刚处理完就再次满足触发条件。

以 S08 为例,关键改动如下,省略了原有的归档和工具配对处理:

defsnip_compact(self,messages:list,trigger_messages:int=50,target_messages:int=30,)->list:ifnot5<=target_messages<trigger_messages:raiseValueError("Require 5 <= target_messages < trigger_messages")iflen(messages)<trigger_messages:returnmessages head_end=3tail_start=len(messages)-(target_messages-head_end-1)# 后续继续执行工具配对保护、归档和裁剪

正常情况下,保留内容的组成是:

最初 3 条消息 + 1 条归档标记 + 最近 26 条消息 = 30 条

参数校验中的下限5也来自这个结构:开头 3 条、归档标记 1 条,另外至少保留 1 条近期消息。目标数量还必须小于触发数量,才能留下缓冲空间。

用具体例子看看区别

假设每轮问答只新增两条普通文本消息,暂不考虑其他压缩机制和工具配对带来的数量变化。

阶段修改前修改后
首次触发裁剪后保留 50 条保留 30 条
新增第 1 轮问答52 条,再裁到 50 条32 条,不裁剪
新增第 2 轮问答52 条,再裁到 50 条34 条,不裁剪
新增第 9 轮问答仍可能每轮归档48 条,不裁剪
新增第 10 轮问答再次归档达到 50 条,再裁到 30 条

在这个例子里,新逻辑可以容纳 10 轮这样的问答后再触发下一次裁剪。

这里的“10 轮”来自每轮恰好新增两条消息的假设。实际 Agent 运行时,一次任务可能产生多轮工具调用,所以应以消息数量判断,不能简单理解成“每问 10 个问题压缩一次”。

裁剪时,还要保护工具调用和结果

Agent 的历史消息存在配对关系。例如:

assistant:调用工具,读取 main.py user:返回这次工具调用的文件内容

如果裁剪恰好把前面的工具调用删掉,却留下对应结果,下一次 API 请求就可能因为缺少匹配的调用而无效。

因此,这次修改保留了原有的工具配对边界保护。必要时会移动裁剪位置,把完整的一组调用和结果留下来。

这也意味着,30 条是目标数量,最终保留数量可能略高于它。消息结构完整比机械地凑够条数更重要。

“先归档、后裁剪”的行为也继续保留,较早内容仍有对应的历史记录可供取回。

我如何验证这个修改?

PR 中补充了覆盖完整上下文准备流程的回归测试,重点检查:

  • 49 条消息时,不生成归档。
  • 达到 50 条时,裁剪至 30 条,并保存裁剪前的完整历史。
  • 此后连续 9 次、每次新增两条消息,不产生新归档。
  • 第 10 次新增两条消息时,再次触发归档。

另外还覆盖了一次新增越过阈值、非法参数,以及头尾工具调用配对等情况。两处实现都接受了这些检查。

根据 PR 中记录的提交时验证结果,Python 测试共有485 项测试、112 项子测试通过;TypeScript 类型检查和网站构建也通过了。

由于它是教学项目,我还同步更新了中、英、日三种语言的相关文档、示意图和网站生成资源,让课程里的解释与代码行为保持一致。

这次修改也有取舍

留出缓冲空间,需要减少直接保留在上下文中的近期消息。

默认情况下,近期消息从原来的 46 条减少到 26 条,较早内容需要通过归档取回。减少重复归档的同时,模型直接看到的近期历史也变少了,这是 PR 中明确说明的取舍。

这次修改针对的是消息数量阈值引发的重复裁剪,没有提供整体任务速度或 Token 成本的性能对比,也没有解决所有上下文保留问题。

PR 已经合并

这个修改通过了维护者审核,并于2026 年 10 月 27 日合并:

PR #582:fix: add hysteresis to message-count compaction

这次贡献让我更具体地理解了 Agent 工程里的上下文管理:除了关注“什么时候该压缩”,还需要考虑压缩结束后,系统能继续运行多久才会再次碰到门槛。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/29 11:06:42

AI在软件测试的未来中处于什么位置?(2)

大家好&#xff0c;我是陈哥。 上次我们聊了AI对于测试领域的两项新技术&#xff0c;这周继续聊聊AI能帮我们做多少事。 这话听上去有点保守&#xff0c;我认为AI目前最有价值的位置其实是助手。AI真正的本事是让以前只能想想的自动化工具变得简单&#xff0c;或者说门槛一下子…

作者头像 李华
网站建设 2026/10/29 11:06:02

推理与Agent应用增长之后 AI数据中心如何做好动态热管理

用户向AI发出一次请求&#xff0c;背后可能是多轮模型推理、工具调用与结果处理。请求之间的计算量不同&#xff0c;同一次任务的各个阶段&#xff0c;也可能呈现不同的算力需求。这些变化最终会反映到基础设施上&#xff1a;服务器功率随任务变化&#xff0c;热量在不同节点和…

作者头像 李华
网站建设 2026/10/29 11:05:58

带你上手高通跃龙 QCS8550 (2): QNN底座与QAI AppBuilder完整安装指南

QNN 驱动与 QAI AppBuilder 的关系 原厂纯净的 Linux 系统&#xff08;如 Ubuntu 22.04 LTS&#xff09;并未内置高通 AI 驱动生态。要在这块芯片上运行 AI 应用&#xff0c;我们需要自底向上搭建两层核心软件栈&#xff1a; 底层驱动&#xff1a;Qualcomm AI Runtime (QAIRT…

作者头像 李华
网站建设 2026/10/29 11:05:10

为什么网上到处都是网盘资源链接?聊聊免费资源背后的商业逻辑

为什么网上到处都是网盘资源链接&#xff1f;聊聊免费资源背后的商业逻辑 不知道大家有没有发现&#xff0c;现在上网找资料&#xff0c;越来越容易遇到各种网盘链接。 比如搜索一个 Python 学习教程&#xff0c;打开文章&#xff0c;最后附着一个网盘链接&#xff1b;想下载一…

作者头像 李华
网站建设 2026/10/29 11:03:32

AI智能体批量涌入V模型:多智能体协作实现需求到测试全链路自动化

1. 从V模型说起&#xff1a;为什么AI智能体开始批量涌入这条赛道第一次听到“AI智能体批量进入V模型”这个说法&#xff0c;我脑子里蹦出来的画面是&#xff1a;一群数字员工排着队&#xff0c;走进一条叫V模型的流水线&#xff0c;然后各自领了工位开始干活。这个比喻不算严谨…

作者头像 李华