DSHarness 系统拆解 固定基线 47f943859b · 36 已复核 / 0 撰写中 / 36 章
English
上下文治理·第 13 章

压缩体系与上下文压力

工具结果裁剪、摘要替换、溢出恢复分别是什么语义

已复核上游 47f943859b范围: 确认压缩层级、触发器、token 计量、pruner、summary、surface generation、手动 compact 与失败恢复。

结论:没有固定的“多级压缩”,只有两种可递归组合的 Surface 变换

DeepSeek Harness 的上下文治理不是 L1/L2/L3 固定流水线。生产实现只有两种真正缩短模型 Surface 的机制:先对超大工具结果做确定性中段裁剪;若仍超预算,再让模型把一个平衡的历史前缀写成 checkpoint。Checkpoint 本身是普通的 model-visible user message,未来仍可落入新的压缩区间,因此所谓“多级”来自递归代数,而不是配置里的预设层数。

Pressure 与 context overflow 是两条触发路径,不是两个压缩层级。默认 compactionRetries: 1 表示首次摘要后最多再做一次摘要,而不是一个会话一生只能压缩两次;后续 Step 还可再次触发并把旧 checkpoint 合并进新 checkpoint。

源码结论

公共 compaction seam 明确区分自动判断、idle maintenance 和显式 region 三个入口;所有成功路径最终都用带 plugin: "compact" 来源标记的 user message 替换一个 Surface span。COMPACT-SEAM

1. 先分清机制、触发器、尝试次数和递归代数

维度实际取值不是
缩短机制Tool-result prune;LLM summary replacement不是三段式固定层级
自动触发下一 Step 前的 pressure;Provider canonical overflow 后的 recovery不是两种不同 checkpoint 格式
单次预算有界 summary retries;有界 overflow retries不是会话生命周期上限
递归深度旧 checkpoint 可以再次被摘要没有显式 generation cap
手动入口/compact 在 idle maintenance 中压缩 useful head不是绕过日志的直接内存修改
Surface₀
  ├─ prune(large tool result)        → Surface₁
  ├─ summarize(balanced head span)   → checkpoint₁ + retained tail
  └─ later summarize(checkpoint₁ …)  → checkpoint₂ + newer tail

这一区分很重要:重试参数回答“一次压力处理最多再试几次”,recursive checkpoint 回答“长期运行中压缩结果是否还能继续压缩”。两者相乘才形成实际可见的多代历史。

2. 配置按精确 Provider / Model route 解析

默认项默认值语义
thresholdRatio0.8估算请求压力达到 context capacity 的 80% 后启动 proactive compaction
retainRatio0.16摘要时尽量保留最近约 16% capacity 对应的 Surface tail
maxTokens8192摘要调用的输出上限
compactionRetries1首次摘要后,若压力仍高,允许一次额外摘要
maxOverflowRetries1一次 canonical overflow 的有界恢复预算
autotrue启用自动 pressure/overflow 处理
解析规则

全局配置可被 exact provider/model 项部分覆盖;ratio 只有拿到 adapter 声明的 context capacity 后才会换算成 absolute tokens。retainRatioretainTokens 互斥,并要求 retention 小于 threshold。COMPACT-CONFIG

Proactive pressure 因而必须同时具备两项证据:最近一次耐久 request header 能确定 route,且对应 adapter 暴露 context capacity。Overflow 已经由 Provider 给出事实,因此无需 threshold/capacity 即可进入恢复。

3. Token meter 估的是“下一次请求压力”,不是给每个节点精确分词

1

寻找 anchor

若当前 route/header 与最近一次成功请求匹配,使用 Provider usage 作为已知 prompt 样本。

2

重建当时 Surface

在 final assistant message 处,从其引用的 raw chunks 重组 Provider output,并把 Step-start Surface 作为 anchor。

3

累计 signed delta

普通 append 增加价格;prune/summary replacement 用 shadow price 把旧 span 价格减掉、加入新节点价格。

4

无 anchor 时全量估算

对 system、tools 和当前 Surface 统一运行固定密度 heuristic。

保守 anchor

如果 Provider 报告的 usage 反而低于完整 heuristic anchor,meter 退回估算值,避免负 delta 把当前压力系统性压低。每次测量仍克隆并返回带位置价格的 Surface nodes,复杂度为 O(surface)。COMPACT-TOKEN-MEASURECOMPACT-TOKEN-ANCHOR

精度边界

无 anchor 的估算按每四个 JavaScript code units 一个 token,加固定 block/role overhead;tool schema 与 arguments 按 JSON 长度估算。它不是任一模型的真实 tokenizer,对 CJK、密集 JSON 和特殊词表的节点级定价可能偏差。Provider anchor 能改善总压力,却不能反向给每个旧节点提供真实 token 分摊。COMPACT-ESTIMATOR

4. Proactive pressure 发生在两个 Step 之间,但看不到即将提交的输入批次

claim inbox messages
→ assemble system/tools
→ compute runtime-context candidate
→ dispatch agent/pre-step waterfall
     └─ pressure listener measures current durable Surface
→ append step/start
→ append claimed user/context messages
→ dispatch Provider request
已确认顺序

真实 loop 测试要求 pressure compaction 位于上一 step/end 与下一 step/start 之间;但 Agent 已经认领本批输入,却要等 waterfall 返回才把它们写入 Session。因此 pressure listener 测到的是“此前 Surface”,不含本 Step 的 entering batch。COMPACT-REAL-LOOP-TESTCOMPACT-RUNTIME-ORDER

实际后果

若一条很大的新输入、动态上下文或单个不可分割节点把请求从阈值下直接推过窗口,proactive pass 无法预防;只有 adapter 把 Provider 错误准确归一成 canonical context overflow 时,same-Step recovery 才能接手。

5. 第一种缩短机制:模型无关的工具结果中段裁剪

规则默认行为保真边界
触发长度text blocks 合计超过 8192 Unicode code points非文本 rich blocks 不计入此 pruner 的预算
保留前 4096 + marker + 后 1024 code points保留 code point,不会切半 surrogate pair,但可切开 grapheme cluster
替换范围只替换 tool/result 的 contentcall ID、name、error/metadata 等事件语义保持
顺序rich blocks 原顺序保留,text slices 在原位置重组图片等 rich content 不会被这个机制缩小
Replay-safe commit

每个候选先追加 compaction/prune 记录旧节点 token price,再追加引用原 seq 的 content-only replacement。新建 Session 重放同一日志会得到相同 Surface,不需要再次执行 pruner。COMPACT-PRUNER-CONFIGCOMPACT-PRUNER

Pressure 尚未跨阈值时不会机会式裁剪。跨阈值或 overflow 后先 prune 并重测;若已足够低则完全不调用摘要模型,若仍高才让 summary 看见已裁剪后的 Surface。测试源码覆盖了这三个分支。COMPACT-PRUNE-TEST

6. 第二种缩短机制:保留近期 tail,摘要一个 head-anchored span

Pressure path 从 Surface 尾部向前累加节点价格,直到满足 retention budget;然后继续向 head 移动 cut,寻找 tool-call/result 平衡的位置。最终压缩的是 head,而不是随意挑选最“没用”的散点消息。Overflow path 则把 retain budget 设为零,目标是尽可能释放空间。

Range selector

即使 retain 为零,尾部扫描也会保留至少最后一个 Surface node。若只有一个不可分割单位、没有可压缩 head,或找不到合法平衡 cut,selector 返回 null。COMPACT-RANGE

设计含义

这是一种 recency-first 策略:近期原文保真,较老上下文被整段合并。它没有语义重要性评分,因此旧而关键的约束能否保留完全依赖摘要质量;相反,它的边界和复杂度可预测,也不需要额外检索系统。

7. 合法 cut 只保证 tool pairing,不保证位于 Step 或 Turn 边界

Pairing fold 按当前 Surface 顺序扫描:assistant message 中每个 tool call 令余额加一,对应 tool result 令余额减一,并计算 N 个节点之间的 N+1 个 cut。Replacement generation 变化时全量重建;只有普通 append 时增量扩展。

平衡条件

Selector 不会把 tool call 留在 checkpoint 一侧、result 留在另一侧。这个条件与 durable Step bracket 无关;一个高 seq 的旧 checkpoint 作为普通 user node,在两侧都可能是 balanced,因此未来能再次进入压缩区间。COMPACT-PAIRING

由此可以精确回答“压缩有几层”:日志里可能观察到任意多代 checkpoint,但每次 transaction 仍只做一次 span replacement;层数是历史递归次数,不是运行时拥有多少个专门阶段。

8. Summary call 重用会话形状,但不是隐藏的第二个 Agent loop

summary request
= current system prompt
+ current ordered tool schemas
+ selected region as model messages
+ one fixed English compaction directive
→ one provider stream (purpose = "compaction")
→ collect non-empty text only
→ frame as <compacted-summary>…</compacted-summary>
路由和输出

目标优先级为显式 summary provider/model,其次最近一次 routed request,最后 Agent options。调用带 session ID、purpose 与 maxTokens;max-token truncation、abort、image output、空 text 或调用错误都判失败。Reasoning 与 tool-call blocks 可保存在 rawOutput 供审计,但 checkpoint 只取 text;即使输出同时带 tool call 和 text,也不会执行那个 tool。COMPACT-SUMMARIZER

请求保留原 system/tools/region 前缀,只把固定指令放在末尾,为同 route 的 provider cache reuse 创造形状条件;若配置了另一 provider/model,只是保持形状,并不能跨 route 共享缓存。

质量合同

固定英文指令要求八个结构化标题,并要求遇到旧 checkpoint 时合并而非逐字复制。但实现不解析标题、不做事实一致性校验,也不检查实体、承诺或未完成任务是否齐全;唯一内容门槛是 framed checkpoint 的估算 token 数严格小于旧 span。非英语会话被要求输出英文,也引入一次额外的翻译损失面。

9. 一次 summary 是有锁、可重验、分段提交的日志 transaction

1

验证并加锁

检查 range、owner 和现有活跃 compaction,同步追加 compaction/start

2

Snapshot 与调用

冻结选中消息和 positional prices,在锁外 await Provider summary。

3

重验稳定性

自动模式要求整个 Surface 未变;手动模式只要求选中 span 未变。

4

同步 commit body

依次 append summary audit event,再 append replacement user message。

5

关闭 bracket

append success end;任意 start 后失败只尝试一次 error end。

锁的本质

compaction/start 是 durable log lock。自动任务记录所属 Turn number;manual 使用 turn:null。摘要期间自动模式拒绝任何 Surface 变化,manual 则允许 span 外 append。COMPACT-TRANSACTIONCOMPACT-COMMIT

10. Checkpoint 同时保存模型文本、来源跨度和实际调用证据

记录保存内容是否进入模型 Surface
compaction/starttransaction ID、owner turn、可选 command ID
compaction/summarysummary、shadowed seq/range/token price、route、maxTokens、usage、rawOutput
replacement user/messageframed checkpoint 与 plugin source marker,引用 start/summary/shadowed seqs是,替换旧 span
compaction/endtransaction closure 或 error
compaction/prune单节点 shadow price否,紧随 replacement 才改 Surface
可审计性

摘要文本、原始模型输出、provider/model、usage、被遮蔽范围和最终 model-visible checkpoint 分开保存。查询者可以审计“模型实际说了什么”“系统采用了哪段 text”“替换了哪些节点”,而无需把 raw summary tool/reasoning blocks重新暴露给主会话。COMPACT-EVENTS

11. 递归 checkpoint 怎样形成实际的“多代压缩”

Generation 0:  [old raw history .............][recent tail]
Generation 1:  [checkpoint A][recent tail .................]
Generation 2:  [checkpoint B merges A + later history][tail]
Generation n:  [checkpoint N][newest retained tail]

每代 replacement 都推进 surface.replaceGeneration,pairing cache 和 token pressure projection 随之更新。下一次压力到来时,checkpoint A 没有特殊“永不压缩”身份;它只是带 provenance 的 user message。固定指令要求模型合并旧 checkpoint,防止简单嵌套整段 XML,但这仍是 prompt-level 要求。

长期误差模型

每代都严格要求“估算后更短”,却没有可执行的语义保真 invariant。长度单调下降不等于事实误差单调受控;反复摘要可能累积遗漏、翻译和归纳偏差。日志保留原始被遮蔽事件,可供人或离线工具追溯,但主模型只看当前 checkpoint。

12. Overflow recovery 在同一 Step 内重试,并以 generation 前进作为进展证明

控制流

Adapter 把错误归一为 canonical context overflow 后,handler 在独立 overflow budget 内先 prune、重测,再以 retain=0 尝试 summary。只有 surface.replaceGeneration 前进才返回 retry;因此已经提交 prune、随后 summary 失败也算有进展。成功 assistant message 或 Agent 回到 idle 会重置 retry counter,取消信号最终优先。COMPACT-AUTO-TRIGGERSCOMPACT-POLICY-LOOP

真实 loop 测试

测试源码要求 recovery 不开启新 Step:第二次 Provider request 发生在原 Step 内,旧 sentinel 已从 messages 消失,checkpoint 已进入同一 Session log。Upstream 依赖未安装,本研究核对了测试合同但未执行。COMPACT-REAL-LOOP-TEST

同 Step retry 会复用此前组装的 system/tools/request config;变化来自 Session Surface replacement,而不是重新执行完整 pre-step assembly。若 overflow 来自过大的 system prompt、tool schema 或一个不可分割节点,Surface compaction 可能仍无合法空间可释放。

13. 手动 /compact 是 idle maintenance,不是并发强制改写

进入条件

compactNow() 通过 runMaintenance 只在 Agent idle 且没有 waking queued work 时进入,retain 为零,owner turn 为 null。Summary 等待期间 span 外 append 可以存在;提交前只重验被选 span。Closed attempt 在返回前通过 Session flush barrier。COMPACT-MANUAL

人类命令不接参数,并把 busy、cancelled、surface changed、summary、commit 和 persistence failure 分类成不同结果;成功时报告被遮蔽 items/tokens,并用 source command ID 与 summary seq 关联日志/UI。插件 teardown 会等待活跃 handlers drain。COMPACT-COMMAND

14. Runtime context 依靠 replacement provenance 再注入,但存在一个条件性窗口

动态 runtime-context projection 记住最近仍存于 Surface 的 owned snapshot;当 replacement 的 source seqs 遮蔽该 snapshot 时,projection 把 retained 置空。下一次 project(currentText) 因而会再次生成 context candidate,避免摘要后永久丢失当前运行时状态。COMPACT-RUNTIME-PROJECTION

高置信控制流推断,未运行复现

Agent 在 pre-step waterfall 之前已经计算 candidate。如果当时 current text 与 retained 相同,candidate 为 undefined;随后 waterfall 内 compaction 遮蔽 retained,事件 listener 把它清空,但本 Step 不重新计算 candidate。于是紧随其后的请求可能暂时缺少当前 runtime context,下一 Step 才会重新注入。现有测试覆盖“先手动 compact、再 preStep”,没有覆盖这一精确 interleaving。COMPACT-RUNTIME-ORDERCOMPACT-RUNTIME-PROJECTION

这是一个窄的一请求窗口,不是“压缩会永久删除 runtime context”。要消除它,需在 waterfall 后重算 candidate,或把 pressure pass 提前到 candidate projection 之前。

15. Usage、pressure 和 shadow price 是三个不同的观测面

Projection / event回答什么不包含什么
tokenUsage主对话 assistant requests 的 usage,按 Turn/Step last-wins 累计compaction/summary.data.usage 不进入累计
contextPressure基于最近 Provider prompt sample + Surface delta 的下一请求压力不是全部调用的账单成本
Summary event usage某次辅助摘要调用的 route 与 usage audit不会自动汇总到主 usage projection
Shadow priceO(1) projection 更新时旧 span 的估算价格不是语义重要性或真实 tokenizer 分摊
确认语义

Usage fold 只处理 assistant usage chunk/message;summary 调用的 usage 虽已持久记录,却不计入累计 tokenUsage。因此该 projection 描述主对话请求,而不是进程为此会话发出的所有 Provider 调用。是否属于有意的辅助成本排除,源码注释并未完全说清。COMPACT-USAGE-PROJECTION

16. O(1) pressure projection 依赖“shadow-price 紧邻 replacement”的局部协议

Surface token projection 只保留 running total 和一个 pending claim。看到 compaction/summarycompaction/prune 时暂存旧价格;下一条 replacement 消耗它并计算 signed delta。任何夹在中间的其它 event 都使 claim 过期;没有 claim 的历史 replacement 为兼容旧日志按 zero delta 降级,而不是 fail closed。

已确认 invariant coverage gap

正常 summary/pruner producer 都同步相邻 append,因而满足协议;compaction runtime invariant 会检查 bracket、ID、owner、shadow endpoints/token count、checkpoint source 和 success end,却没有检查 summary/prune 与对应 replacement 必须紧邻。一个有缺陷的插件或外部日志 writer 可生成“结构上通过 invariant、pressure projection 却漂移”的序列。COMPACT-SHADOW-PRICECOMPACT-INVARIANT

17. 已确认的限制、缺口与有意取舍

发现分类影响
Pre-step pressure 看不到 entering batch时序限制大输入只能依赖 overflow recovery
Runtime context 可能有一请求遗漏窗口高置信静态推断下一 Step 会恢复;尚未运行复现
摘要只验证非空和更短质量边界八标题、事实保真和任务完整性不受代码保证
固定英文 summary directive国际化取舍非英语上下文可能发生翻译损失
辅助 summary usage 不进 tokenUsage观测口径累计值不是全部 Provider 成本
Invariant 不检查 shadow-price adjacency覆盖缺口非标准 writer 可使 bounded projection 静默漂移
固定密度 heuristic精度取舍CJK/JSON 的节点 retention 定价可能偏差
System/tools 与单个不可分割节点不可压缩能力边界即使总压力高,也可能没有合法 span
Rich tool blocks 不被 text pruner 缩小机制边界图片等压力需要其它治理
多结果 prune 部分提交有意局部进展后项失败不会回滚前项

这些发现不应统一叫作漏洞。不可压缩的 system/tools 是 Surface seam 的自然边界;partial prune 是可重放的局部进展策略;摘要保真则是当前实现没有机器可验证合同的真实风险面。

18. 设计评价与验证状态

选择收益成本
先确定性 prune,再模型摘要能不付模型调用和语义损失时就不付只覆盖 text-heavy tool results
Checkpoint 也是可重放事件恢复、Fork、UI 与下一请求得到同一 Surface日志和当前模型视图必须区分
递归而非固定层级适合无限长会话,不需要迁移层级格式重复摘要误差缺少硬上界
Provider usage anchor + signed delta总压力比纯 heuristic 更贴近真实请求节点级 cut 仍依赖估算与 adjacency 协议
Durable bracket 与 provenance每次压缩可审计、可重放、可关联命令多次 append 不是后端原子事务,失败状态更复杂
本章验证范围

本章交叉核对了 compaction seam/events/invariant、basic policy/region/summarizer、tool-result pruner、token meter/projections、Agent pre-step 顺序、runtime-context projection、manual command 以及真实 loop 和组合测试源码。Upstream 没有安装依赖,因此没有声称测试在本机通过;涉及精确竞态和 crash path 的项目已明确标为静态推断。

我的学习体会

内容仅自动保存到当前浏览器,不上传、不进入仓库。你可以导出 Markdown 自行归档。