dsh-time-memory:按时间归档、分层回忆的 DSH 聊天记忆插件

前言

DeepSeek Harness(DSH)里,模型上下文没有天然的长期记忆。常见做法要么把整段历史塞进 prompt,token 随对话线性增长;要么让模型自己「回想」,容易编造细节。社区插件 dsh-time-memory(仓库名 Moontail-Ling/dsh-time-memory,维护者 Moontail-Ling)换了一条路:对话按发生时间写成磁盘上的事件,只有用户点名的那段时间才会被检索进上下文;两次扩大仍无命中时,只允许回答「我忘记了」,不推测、不编造。

这是什么

dsh-time-memory 是 DSH 分类为「记忆」的插件 bundle。它给会话注册 memory_recall 与 memory_save 两个工具,并可选附带「时忆」人格:回答与检索相关的问题前,会先输出几行 [调试] 自检,把「时间锚点 → 检索层数 → 命中数 → 判定」摊开可见。

记忆默认落在 $DSH_HOME/time-memory/events.jsonl(未设置 $DSH_HOME 时,Windows 上为 %USERPROFILE%\.dsh\time-memory\events.jsonl),一行一条 JSON;插件不导入 DSH 包,只依赖 Node 内置模块。当前 package.json 版本为 0.1.0,许可证 MIT,Node 仅在跑离线测试时需要 ≥ 22.19。

三条由代码保证的规则

README 把行为归纳成三条,不靠模型自觉:

  1. 按时间存 —— 每条真实的用户消息与助手回复,按事件时间写入 jsonl(capture 默认开启)。
  2. 按时间查 —— 用户提到时间段时,应先调用 memory_recall。
  3. 查不到就说忘了 —— maxExpansions 次扩大仍无结果时,verdict="forgot",人格只能回答「我忘记了」。

检索流程

用户通过 time_hint 指认时间(共 26 种说法,含相对、周历、时段、绝对日期与整句抠时间)。检索在时间窗内用关键词打分(中文按二元组切词),不是向量语义检索。

层 窗口 结果
第 0 层 用户指认的时段 命中即返回
第 1 层 以窗口中心等比扩大 × expandFactor(默认 3) 命中即返回,并标注扩大 1 次
第 2 层 再扩大一次(默认 1 天 → 3 天 → 9 天) 命中即返回
两次扩大后仍空 — verdict="forgot"
时间说法解析不了 — verdict="unparsed",提示改用 2026-10-20 这类写法

典型调试输出形态如下(摘自 README):

[记忆检索] 时间锚点:"上周二" → 2026-10-20(周二)全天
[记忆检索] 线索:海边
[记忆检索] 第 0 层(原始时段):2026-10-20(周二)全天 · 库内 3 条 · 命中 0 条 → 扩大
[记忆检索] 第 1 层(扩大 1 次):2026-10-19 至 2026-10-21(3 天) · 库内 9 条 · 命中 1 条
[记忆检索] 说明:原始时段没有命中,扩大 1 次后才找到,引用时要说明大致范围。
[记忆] 2026-10-20 20:14 · 用户:我说想去海边看日出,风很大

两个工具

装好后正常聊天即可;说起某段时间会自动走检索,值得单独记的事可由模型调用 memory_save 钉在指定时间点。PTC 代码也可直接调用同一套工具。

工具 参数 作用
memory_recall time_hint(必填)、query、limit 按时间段 + 关键词检索,自带分层扩大与忘记判定
memory_save summary(必填)、happened_at、details、tags 手工归档一条事件到指定时间点

安装与启用

前提:DeepSeek Harness(Desktop 或源码 checkout)已能正常使用。

官方 README 给出的安装步骤是先克隆仓库,再在 DSH Web GUI 里指向本地目录(资料中没有 dsh plugin add github:… 一类命令):

git clone https://github.com/Moontail-Ling/dsh-time-memory.git

然后在 DSH 里:

  1. 侧边栏 插件 页 → 安装;
  2. 粘贴克隆下来的绝对路径,例如 D:\code\dsh-time-memory;
  3. 确认,插件默认启用。

装完对当前 profile 的所有会话生效(启用 HMR 时热加载,否则重启 DSH)。Creator 模式下也可用 plugin_manager 的 install_bundle,target 填同一路径。卸载时在插件页移除 bundle 即可,记忆文件不会被删。

插件以当前 DSH 进程权限运行;安装前应自行查看仓库源码与 MIT 许可证,确认路径与数据文件位置可接受。

配置

在 profile 的 cordis.patch.yml 中覆盖 time-memory 条目,例如:

- id: time-memory
  name: dsh-time-memory
  config:
    dataFile: 'D:\my-memories\events.jsonl'
    expandFactor: 3
    maxExpansions: 2

常用字段(完整表见 README):

字段 默认值 含义
dataFile $DSH_HOME/time-memory/events.jsonl 记忆库 jsonl
capture true 是否自动把对话按时间入库
expandFactor 3 每次扩大窗口的倍数
maxExpansions 2 最多扩大几次
maxResults 3 单次最多返回几条记忆
minScore 2 关键词命中阈值
includePersona true 是否把人设放进 charter

人格是 profile 级的;若只想在某类会话启用,把 time-memory 放进对应 agent preset 的 patch。检索是「时间窗 + 关键词」,换说法(如「看海」与「海边」)可能不中;扩大窗口只能兜时间偏差,兜不住词义偏差。

token 与记忆文件

README 说明:人格、认知、协议为静态文本,稳态下可命中前缀缓存;单次检索输出有上界(默认约 3 条 × 90 字),成本与库大小无关,但多一轮工具调用。记忆库很小时,直接滚上下文可能更省 token——本插件买的是按时间精确定位与不随库增长。

jsonl 单行示例:

{"v":1,"id":"m_…","t":1792500000000,"kind":"user","text":"……","session":"…","seq":42,"source":"auto","stored":1792500000123}

同一会话同一条事件用 session + seq 去重;清空记忆需在停掉插件后删除该文件。

离线测试(不依赖 DSH):

node test/run.mjs

结尾

dsh-time-memory 把聊天记忆做成时间轴上的事件库:先查用户点名的时段,没命中就扩大两次,仍没有就如实忘记。适合需要「按时间段回忆、控制上下文体积、禁止瞎编历史」的 DSH 用户。

DSH 生态强调「一切皆插件」;SkillHub 等社区目录为独立站点,与 DeepSeek / 幻方无官方从属关系。

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

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

小夜