cache-sentinel:在 DSH 里拦截「缓存已过期」会话的误发

前言

在 DeepSeek Harness(DSH)里长时间挂着旧会话再补一句,很常见。若距上次模型回复已过 prompt cache 的有效窗口,整条累积对话会按未缓存输入计费,成本会突然上去。靠自觉记时间或翻账单并不稳。

下面介绍社区插件 cache-sentinel(维护者 AliceSaikawa,分类 admin-security)。它根据「距上次回复/更新过了多久」判断缓存是否可能已失效,用拦截发送或自动归档两种方式,减少误点发送。

这是什么

cache-sentinel 是 DSH 的 Host 插件:在 prompt cache 可能已过期时,阻止向旧会话误发消息,或把长期未更新的会话归档。简介与 package.json 中的描述一致:DSH host plugin that guards against uncached prompts: blocks sends (read-only) and/or archives sessions after the prompt cache likely expired.

社区插件目录为独立站点,与 DeepSeek / 幻方无官方从属关系;安装前请自行审阅源码与许可证。插件在当前 DSH 进程权限下运行。

核心功能

插件在缓存生命周期可能已过的会话上,提供两种防护(可单独或组合使用):

  1. 输入拦截(block)
    会话仍可打开、阅读,但会阻止会调用模型的发送。需要继续对话时,可在输入框上方按钮或 /unlock 放行「下一次」发送。

  2. 自动归档(archive)
    一段时间未更新的会话会被自动归档,从侧栏隐藏且无法打开,避免误进旧会话。

聊天内可用 /sentinel 查看状态并在 block、archive、both、off 之间切换。both 为组合模式:默认在距上次回复 60 分钟后拦截输入,在距上次更新 1440 分钟(24 小时)后归档。

模式 行为(默认值见 README)
block(默认) 距上次回复超过 idleMinutes(默认 60)后拦截发送;/unlock 可放行单次发送
archive 距上次更新超过 idleMinutes(默认 60)后自动归档
both 拦截与归档阈值分别由 idleMinutes 与 archiveAfterMinutes(默认 1440)控制
off 不拦截、不归档;/sentinel 与 /unlock 仍可用

拦截逻辑在 agent/pre-step 钩子头部执行(prepend: true),早于自动 compaction,过期会话上也不会因 compaction 触发模型调用(README「How It Works」)。

官方 Web UI 会在输入区上方显示缓存状态横幅;M3E(dsh-webui-m3e)在拦截时会在对话中显示说明,但预发送横幅需 M3E 侧支持加载其他插件的 client bundle。另提供 GET /api/cache-sentinel.status?sessionId=<id>(需 Connection 认证)查询会话状态。

界面文案随环境语言(英/日/简中);日志行前缀 [cache-sentinel] 为日语。

安装与启用

  1. 在实际使用的 profile 下执行安装命令(web 仅为示例;需包含 Web 应用的 profile,如 web、desktop):
dsh plugin --profile web add github:AliceSaikawa/cache-sentinel

若要固定版本,可在末尾加 #v<version>(例如 github:AliceSaikawa/cache-sentinel#v1.2.3)。README 注明:截至 v0.5.0 及更早的 tag 不含构建产物lib/,无法以此方式安装;也可使用 GitHub Release 附带的cache-sentinel.tgz` URL 安装。

  1. 重启 DSH。插件在进程启动时加载;若用 systemd 用户服务,示例为:
systemctl --user restart deepseek-harness

检查、更新、移除:

dsh plugin --profile web list cache-sentinel --depth 0
dsh plugin --profile web remove cache-sentinel

更新需重新执行安装命令并再次重启;仅在重启前开关插件不会换掉已加载的旧代码。

典型用法

聊天命令

  • /sentinel:显示当前生效模式及来源(聊天设置或 YAML)、阈值、本会话距上次回复的分钟数、dryRun 状态。
  • /sentinel block | archive | both | off:切换模式,写入 $DSH_HOME/cache-sentinel/state.json,重启后仍有效(优先于 YAML 中的 mode)。
  • /sentinel default:清除聊天中保存的模式,回到 YAML 的 mode。
  • /unlock:在 block / both 下对已过期会话放行下一次发送;权限在 unlockTtlMinutes(默认 10 分钟)内有效。模型返回后若会话未再过期,可正常继续对话。

配置示例

在 profile 的 cordis.patch.yml 中调整(省略项用默认值)。修改后无需重启 DSH,但会清空内存中的 /unlock 权限:

- id: cache-sentinel
  config:
    mode: block               # block / archive / both / off
    idleMinutes: 60
    archiveAfterMinutes: 1440
    unlockTtlMinutes: 10
    checkIntervalSeconds: 60  # 10 或以上
    skipPinned: true
    archiveExisting: false
    maxPerCycle: 20
    dryRun: false

dryRun: true 时只记录日志,不真正拦截或归档,便于验证阈值。

适用场景与注意

适合经常保留 DSH 长会话、又担心隔几小时再发一句触发全量未缓存计费的开发者。若希望旧会话从侧栏消失、减少误开,可选用 archive 或 both;若仍需阅读历史但禁止误发,默认 block 更合适。

注意:

  • 仅适用于包含 Web 应用的 profile;环境与版本说明见仓库 README 的 Supported Versions and Environment。
  • 归档模式下 pinned 会话默认跳过(skipPinned: true)。
  • 连续拒绝零输入消息的自动续跑步骤时,同会话通知最多每 10 分钟一次。
  • 插件以 DSH 进程权限运行,安装前请阅读源码与 MIT 许可证。

结尾

cache-sentinel 把「缓存可能已过期」变成可配置的拦截或归档策略,用 /sentinel、/unlock 和 YAML 即可落地,减轻误向旧会话发送带来的计费风险。

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

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

小夜