dsh-context-saver:在提交给模型前裁剪上下文,本地会话仍完整保留

前言

在 DeepSeek Harness(DSH)里跑长会话智能体时,成本往往不来自「轮数多」,而是每一轮都会把同一段材料再次塞进请求:模型自己的 thinking 会随轮次单调增长;同一文件或页面被反复 read,内容在上下文里出现多次;终端工具每次回传完整命令参数,而决策通常只看输出;更早的轮次仍占窗口,却未必影响当前一步。

常见做法是手动删历史或换会话,本地 trajectory 与导出会丢信息。下面介绍维护者 DaVinci-2nd 的 dsh-context-saver:只在向模型提交的那一刻裁剪 outbound 副本,本地 session log、聊天记录与 trajectory 视图保持完整;插件关闭或所有选项关闭时,请求与未裁剪版本字节一致。

这是什么

dsh-context-saver 是 DSH 的 send-time 上下文裁剪插件,归类为模型推理相关能力。它解决的是长 agent 会话里 prompt token 膨胀、重复 payload 与 KV cache 前缀稳定性之间的平衡——裁剪仅作用于即将提交的 messages,不写入 session event,不改动本地深冻结的原始请求。

工作原理

DSH 中每次模型请求会经过 llm/stream waterfall,携带即将提交的完整 messages。插件在此拦截,按已启用规则构造新的 message 数组,再通过 ctx.llm.stream() 重新派发。原始请求不被修改。

因此:

  • 本地 session log、session/event、trajectory 与导出始终是全量历史;
  • 每一轮裁剪都从完整本地记录重新计算;
  • 裁剪是确定性的,相同输入得到相同输出,连续两次请求的公共前缀保持字节一致,KV cache 命中率基本不受影响。

Compaction 与 session-title 类请求(带 purpose)不会被裁剪,避免其输入在提交时被悄悄改掉。

插件发出的 message 形状围绕 DeepSeek Messages 适配器的结构约束设计并做过线上校验:例如 tool-call 块不会被移除,仅将 arguments 置为 {};tool 角色消息不会被移除,仅清空 content;reasoning 块不会被移除,仅清空 text 并保留 signature。

核心功能与界面

控制入口在 composer 工具栏,与模型、沙箱选择器同一行。点击后打开浮动面板(随 DSH 语言设置显示中文或英文)。设置保存在本机,对所有 session 生效:

$DSH_HOME/dsh-context-saver/settings.json

面板选项(与 README 默认一致):

选项 默认 作用
总开关 开 关闭后 outbound 与未裁剪一致
Strip thinking content 开 保留 think 块结构,清空 text,模型仍收到签名
Strip repeated reads 开 相同文件/页面 read 只保留第一份完整内容,后续保留标识与空结构
Strip terminal inputs and process 关 终端工具保留输出,去掉模型传入的参数
Strip the middle of the context 关 开启时会警告:可能去掉长对话中间仍重要的内容
Leading turns kept 5 仅在中部裁剪开启时生效
Trailing turns kept 5 仅在中部裁剪开启时生效

中部裁剪规则:一轮 = 一条 user 消息及其后的模型输出,边界以 user 消息为准。总轮数 N,保留开头 H 轮、末尾 T 轮;当 N ≤ H + T 时不裁剪;否则仅落在两窗口之外的轮次被清空内容但保留结构(tool 配对、reasoning 位置与 signature 等)。配置的 0 会被抬升为 1,保证首尾至少各保留一轮。

重复 read 的占位符使用固定序数描述(如第 N 次 tool result),短于 200 字符的 read 不处理,避免标记比原文更贵。

实测效果(README 披露)

README 在真实 deepseek-flash 端点上给出两组测量,供评估默认配置时使用,非第三方独立审计。

本机一段 65 轮真实 session(按适配器序列化规则回放,含该 session 的 34 个 tool 声明):

Prompt tokens 回复
未裁剪 867,787 accepted
默认裁剪 574,347 accepted

约少 33.8% prompt tokens。

60 轮合成 session(大量重复 read),比较第 N 轮与第 N+1 轮请求的前缀复用:

配置 Prompt tokens Cache hit rate
裁剪关闭 21,102 98.9%
默认(thinking + repeated reads) 3,242 94.8%
默认 + terminal 3,242 94.8%
默认 + terminal + middle 1,847 90.1%

默认配置在该合成场景下 prompt tokens 约为关闭时的 1/6.5,cache hit rate 94.8%;开启中部裁剪时命中率会下降,README 将其归因于任何中部裁剪方案在轮次滑出保留窗口时的固有代价。

安装与启用

插件为纯 JavaScript,无构建步骤、无 prepare script,从 GitHub 安装时 README 说明不需要 allowBuilds 权限。package.json 要求 DSH 版本 >=0.2.0-0 <0.3.0-0,许可证 MIT,当前包版本 0.1.0。

从 GitHub 安装:

dsh plugin add github:DaVinci-2nd/dsh-context-saver

需要可复现安装时,可固定 commit:

dsh plugin add github:DaVinci-2nd/dsh-context-saver#<sha>

也可在插件管理器中选择本地 checkout 目录,或将 install_bundle 指向该目录。安装后 bundle 中典型插入项为 id: dsh-context-saver。卸载时删除对应行或在插件管理器中卸载 bundle;settings.json 可手动删除。

典型用法

1、安装插件并确认 composer 工具栏出现 context saver 控件。

2、长会话中保持默认(thinking + 重复 read 裁剪)即可在 outbound 侧减 token,本地仍可在 trajectory 中查看完整 thinking 与 read 内容。

3、若终端命令参数在上下文中占比大,可在面板中打开 Strip terminal inputs and process(默认关闭)。

4、仅在明确接受「中间轮次内容不进入模型请求」的风险时,再开启中部裁剪,并按任务调整 Leading / Trailing turns kept;面板会给出英文警告文案。

5、调试对比时关闭总开关或全部子选项,请求应与未装插件时字节一致,便于确认问题是否来自裁剪逻辑。

核心裁剪逻辑在 src/trim.js(纯函数、单测覆盖),宿主拦截在 index.js。

适用场景与注意

适合:长时间 DSH agent 会话、频繁 read 同一文件、thinking 块随轮次累积、希望降低 prompt token 又要在本地保留完整审计轨迹的开发者。

注意:

  • 插件以当前 DSH 进程的权限运行;安装前请自行查看 GitHub 源码 与 MIT 许可证,确认符合你的安全策略。
  • 中部裁剪会结构性清空部分轮次内容,可能丢失对当前决策仍有用的中间信息;默认关闭是刻意设计。
  • 社区目录 SkillHub 插件页 与 GitHub 仓库由社区维护,与 DeepSeek / 幻方无官方从属关系;DSH 生态强调「一切皆插件」,目录站点是独立索引,不是官方应用商店。

结尾

dsh-context-saver 把裁剪限制在「提交给模型的那一刻」,本地记录与导出不受影响,并在 README 中给出了 token 与 KV cache 命中率的实测表格。若你在 DSH 里做长链路 agent 开发,可以从默认配置试起,再按需打开终端或中部裁剪。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜