大家好,我是小木头。你有在做智能体吗?你的智能体上下文压缩质量如何呢?想不想让你的产品跟Codex、跟DeepSeek Harness一样,优秀的管理上下文呢?那本期视频我们就来学习DeepSeek Harness是怎么做上下文压缩的。

过去一段时间,我们分别介绍了Codex Harness和DeepSeek Harness,也拆解过它们各自的上下文工程。到这里我们已经知道,这两套coding agent Harness都不只是把聊天记录不断追加给模型,它们都在主动的管理模型下一轮真正能看到的上下文。而上下文压缩也就是compaction,正是整个上下文工程里非常重要的一环。

那么Codex和DeepSeek Harness的做法有什么不同呢?为什么它们看起来都叫compaction,底层走的却不是同一条路径呢?这个问题很难在一期视频里完完整整的讲完,所以这一期我们先把DeepSeek Harness单独的拆开,看看它目前到底是怎么做上下文压缩的。那我们现在就开始吧!

先看一个反直觉的例子:假设一个coding agent已经连续工作了很久,一个测试又突然返回了几万字的日志,把上下文窗口推到红线附近。你可能觉得接下来它就要调用模型,把前面的对话总结一遍。但在DeepSeek Harness里面,第一步很可能根本不需要模型。

它会先裁掉超大工具结果的中间部分,再重新测量。如果上下文已经回到安全范围,agent就继续工作,这个不会生成任何的摘要。这也是DeepSeek Harness上下文压缩最值得讲的地方:它不是塞在agent loop里面的一个总结函数,也不是某一个/compact插件包办了全部的工作。

更准确的说,它是一条由多个插件和服务组合出来的能力链。其中插件dsh-compaction只定义了一套叫做ctx.compaction的能力接口,规定压缩服务应该做些什么。而真正实现默认算法的是compaction-basic,它负责什么时候压缩、保留哪些内容、怎么生成摘要以及怎样提交新的checkpoint。

旁边还有一个独立的token meter,负责测量上下文的压力;一个可选的tool result pruner,负责裁剪超大的工具输出;以及一个command-compact给用户注册我们常常会使用的/compact命令。这个命令插件只是人工入口,它调用的是前面的压缩能力本身并没有摘要算法。

而且它也不是提供给模型调用的工具。DeepSeek Harness的dsh命令行接口可以启动Web或headless profile,Web应用提供了standard code、cordis等等的agent preset,分别对应了像标准模式、编程模式以及创造模式。

这三个preset都组合了basic pruner和/compact命令,所以从用户的角度来看,上下文压缩是默认可用的一套完整功能。在代码层面,它是由多个可以替换、可增减的插件来组成这套压缩能力有三种主要的入口。

第一种呢,是自动的压力检查。默认情况下,上一轮的assistant消息也就是AI回复的消息和工具结果已经写入日志以后,在下一次请求模型之前,它会检查上下文是否接近了上限。compaction-basic当前默认阈值是模型上下文窗口的80%,不过这个比例可以针对具体的provider和model做修改。

第2种入口是模型服务已经明确返回了context window exceeded,这个时候不需要提前知道窗口到底有多大,因为provider已经证明当前请求放不下了。Harness会尝试压缩,只有模型可见的历史真的发生了替换才会重新提交请求。

第3种就是用户输入了/compact这个命令,它要求agent当时处于空闲状态。即使还没有达到80%也会尝试压缩已有的历史,这个操作不会额外的创建一轮模型对话。不管从哪条入口进来,系统都需要先回答一个问题:当前上下文到底有多满?

这件事就由独立的token meter来完成。它会优先使用provider在之前请求中返回的token usage信息,但前提是那次请求的模型工具提示词等请求结构和现在呢能够对应起来。对后来新增或被替换的内容,它会使用启发式的规则来估算大致是4个字符算一个token。

再加上角色内容块请求结构的开销,对于中文和JSON schema这个估算呢可能明显会偏低。所以它更像是一个压力计而不是精确的一个tokenizer,在这里我们看到的占用率也应该理解成参考数字而不是一个精确的计费账单。

压力确认以后,官方的CLI默认安装的pruner会先寻找超大的工具结果。当前三个主要的preset使用的配置是这样的:一条工具结果超过了8,192个Unicode code point就保留开头的4096个和结尾的1024个,中间换成固定的裁剪标记。

这里的单位不是token而是Unicode code point,它甚至不保证一定沿着人眼理解的完整字符组合来切分。这步的优势不是语言质量,而是确定性和便宜,因为它不需要调用模型,而且对测试日志这类内容报错开头和调用栈结尾通常比中间大量重复行更重要。

裁剪完成以后basic会重新测量,如果压力已经下降就直接返回agent loop。只有工具结果裁剪以后仍然超限才会进入真正的会话摘要。接下来它要决定哪一段进入摘要,compaction-basic会从当前模型可见历史的尾部向前积累。

默认目标是逐字保留大约16%窗口的近期内容,更老的连续区间才是准备被压缩的部分。这里不能简单说成压缩以后只剩16%,近期16%或最近的16%是逐字保留的目标,较老的内容还会变成一个叫summary checkpoint。最终送给模型的是旧内容的checkpoint加上近期的原文。

切分位置也不能够随便选,如果AI或者assistant发起了一个工具调用也就是tool call对应的结果必须和它保持配对。算法会把边界移到工具和结果都完整的位置,要是最近还有一个没有闭合不能拆开的工具单元或者某个非工具消息本身就大到了无法处理,那么这次的压缩可能会被拒绝。

范围确定以后basic才会调用模型生成摘要,它不是只发一句请总结前面的对话。它会重新发送会话的系统提示词、工具定义以及准备压缩的那些消息,最后再追加一条固定的compaction instruction也就是压缩指令。

这条指令要求摘要保留8类信息,包括用户的主要目标、关键技术概念、修改过的文件和代码错误与修复、还没有完成的任务、当前的工作下一步做什么,以及继续执行必须知道的关键上下文。目的并不是写一篇好看的总结,而是让另一个模型拿到checkpoint之后可以继续当前的工作。

这种重放方式还有一个作用:摘要调用前面的系统提示词、工具和历史消息,尽量和原请求保持一致从而复用已经存在的KV缓存。不过摘要写回会话替换旧历史以后,从第一个发生变化的token开始未来请求的缓存仍然会失效。所以不能说压缩完全不会影响到提示词缓存。

摘要输出也有明确的失败条件:只有文本会进入checkpoint,reasoning和工具调用会被排除;图片输出会失败因为达到max tokens而被截断的摘要也会失败。最后还会比较大小,如果处理后的摘要并没有比原来的区间更小就不会提交这次的替换。

生成摘要还不等于压缩已经成功,DeepSeek Harness真正改变模型上下文的是随后的一次surface replacement也就是替换模型当前能够看到的会话表层。会话表面或者称为会话视图surface,我并不是很确定究竟该怎么翻译那大家理解这个意思就好。

一次成功的操作会在会话日志里依次的追加4组事实:首先呢写入compaction/start,它同时也是一把持久锁;然后写入compaction/summary记录摘要来源范围token估值provider和model等等信息。

接下来追加一条checkpoint消息,这条消息中会带有这么一个属性或键值surfaceOp等于replace。最后呢用compaction/end来结束事务,其中真正改变模型可见历史的只有那条replace消息。原来的事件没有从磁盘日志里消失或删除,只是不再出现在当前这个会话surface里面。

所以以后恢复会话时harness会重放这些操作也就是surface operation,得到checkpoint加近期原文的工作历史而不是把压缩前全部对话重新发送给模型。这也是设计带来的一个特点:这个设计呢也是被称为event sourced,开发者不仅能看到最后那段摘要还能知道它替换了哪段历史、引用了哪些事件、使用哪个模型以及压缩事务有没有正常结束。

它强调的是provenance也就是这份checkpoint是怎么产生的?所以回到最开始的问题:DeepSeek Harness的上下文压缩到底是一个独立插件还是融合在别的插件里的呢?答案是它是一项独立的能力,但完整的功能有多个插件组合出来。

agent loop提供触发机制,token meter提供测量,pruner负责相对比较便宜的第一层的裁剪compaction-basic负责摘要和替换而/compact这个呢是独立的人工作用的入口。通常我们人工想要进行会话的压缩呢就用这个命令,这种拆法意味着开发者可以替换另一套compaction backend或者选择不安装pruner和命令插件而不需要修改agent loop。

但它也不是万能的,token计量仍然有估算的误差不可分割的巨大单元仍然可能压不下去。而且我们现在分析的DeepSeek Harness还是预发布版本,默认参数和持久化协议以后呢都很有可能会发生变化。

DeepSeek Harness的上下文压缩表面上是把旧会话变短,底层呢真正做的是通过插件的组合维护一份能够继续工作的模型状态。好了这就是我们今天分享的关于DeepSeek Harness进行上下文压缩的内容,感兴趣的朋友就来给我们一波一键三连关注咱们频道吧。

好我是小木头,我们下期见。