前言¶
DSH 的智能体默认只会活在一次会话里。会话结束之后,那些关于用户偏好、项目约定、上次进展的信息就全丢了,下一次又要重新问一遍。常见的解法是自己挂一个向量库做检索,或者把日志塞进一个 JSON 文件,但前者运维重,后者记到最后往往变成一锅粥——什么都想留,最后什么也找不到。
dsh-journal 走的是第三条路:不追求相似度检索,而是给每条记忆打上分级,让重要的留得久、不重要的按时淡出。下面介绍这个插件。
这是什么¶
dsh-journal 是 Ghill-0131 维护的一个 DeepSeek Harness 插件,属「记忆」分类,目前星标为 0。它把一个纯文本的 JSONL 文件包装成宿主里一等公民的 journal 工具,核心能力是分级长期记忆:每条记录带一个级别、一个过期时间和一个复核日期,让长期运行的智能体把对的东西留对的时间,其余的自动交给时间处理。
一句话定位:它是一个小的、可人工审阅的、手工整理的日志,更接近记事本而不是数据库。
分级模型¶
插件的逻辑是:写的时候要问的不是「这条重要吗」,而是「这条属于骨架还是文件」。等级直接决定生命周期:
| 级别 | 含义 | 生命周期 |
|---|---|---|
S |
关系、情绪、共同经历、承诺 | 永不自动删除,钉住 |
A |
持久事实、偏好、关键决策 | 365 天 |
B |
项目上下文、任务进展 | 60 天 |
C |
临时细节、一次性操作 | 7 天 |
规则很简单,但很实用:怎么跟人说话归 S,昨天排查的端口号归 B,留给下个会话的交接说明归 A,因为它只需要活到被读一次。
过期不会物理删除。prune 是软删除,把过期行移进 archive/;被钉住的行豁免。
核心功能¶
插件暴露一个工具、八种动作:
| 动作 | 作用 |
|---|---|
add |
写入一条记录(level、title、text 必填) |
list |
列出记录,可按级别 / 状态过滤 |
search |
在标题、正文、标签里做子串搜索 |
digest |
输出 S + A 摘要,新会话最先该读的内容 |
stats |
各级别计数、文件大小、已过期但未清理的数量 |
review |
把某条记录的过期时间往后推 |
prune |
软删除所有超期记录 |
render |
重写 JOURNAL.md,生成可读摘要 |
存储只有一个文件:<root>/journal.jsonl,一行一个 JSON 对象。写入走临时文件再 rename,中途崩溃不会撕裂存储;读取时如果最后一行为残行则跳过,而不是让调用失败。记录结构如下:
{
"id": "j-20261104-140902-479d",
"ts": "2026-11-04T14:09:02+00:00",
"level": "B",
"kind": "fact",
"title": "short one-line title",
"text": "the body; facts, not reflections",
"tags": ["..."],
"pinned": false,
"status": "active",
"expires_at": "2027-01-03T14:09:02+00:00",
"reviewed_at": null,
"source": ""
}
格式刻意保持朴素:任何能读 JSONL 的脚本都能读它,任何能写一行的脚本都能往里加。
安装与启用¶
这个插件的安装方式和一般的 npm 依赖不同,需要特别注意。DSH 插件只有在以 link 形式安装时才能拿到宿主包(@deepseek-ai/*);普通的 npm 依赖会导入失败并被静默跳过。README 给出的安装步骤如下。
1、先把代码放到一个稳定的位置,不要放在 profile 目录里,例如 D:\DSH-Plugins\dsh-journal\0.1.0\。
2、用真正的 junction 建立链接。跨盘 symlink 可能被建成坏链且不会报错,所以这里要用 junction:
New-Item -ItemType Junction `
-Path "$env:USERPROFILE\.dsh\profiles\desktop\node_modules\dsh-journal" `
-Target "D:\DSH-Plugins\dsh-journal\0.1.0"
3、profile 的 package.json 里两个列表都要加上它:
// dependencies
"dsh-journal": "link:D:/DSH-Plugins/dsh-journal/0.1.0"
// dsh.profile.bundles
"dsh-journal"
此处要让 Node 来改文件,不要做纯文本替换:多一个逗号就会让 profile 无法解析,harness 直接起不来。
4、重启 harness。
配置写在 bundle 层的 cordis.patch.yml 里:
# key / 默认值 / 含义
# root: D:/dsh-data/journal (Windows) 或 /dsh-data/journal
# —— journal.jsonl 所在目录
# toolName: journal
# —— 该工具在模型工具集里的名字
另外 JOURNAL_ROOT 环境变量可以覆盖 root。
典型用法¶
下面是在 agent 循环里的典型调用,直接来自 README:
journal action=digest # 每次新会话开始时跑一次
journal action=add level=S title="..." text="..."
journal action=search query=备考
journal action=prune dryRun=true # 先看哪些会过期,不做任何改动
日常的节奏是:会话开始读 digest 拿到该知道的部分;过程中把不断产生的信息按级别写进去;结束前跑一次 prune dryRun=true 确认没有要提前 review 的内容,需要延长就 review,不需要就让过期项自然归档。
适用场景与注意事项¶
适合那些需要跨会话延续上下文、但不想引入向量库和检索链路的 DSH 开发者。它的赌注是:一个写下几百条关键行、并按时遗忘其余内容的智能体,胜过一个什么都要存、再靠搜索找回来智能体。
要注意几点:
- 这是一个插件,以当前 dsh 进程的权限运行,安装前应先检查源码与许可证(MIT)。
- 它不是向量库,不做相似度检索,无法替代语义召回。
journal工具会出现在模型的工具集里,级别划分是否合理、过期时间是否合适,需要结合实际任务调。- 依赖 Node >= 22.13。
结尾¶
dsh-journal 的价值不在于存储量,而在于它给了智能体一套「该记什么、记多久」的明确规则,并且整个存储是纯 JSONL,可以人工读、可以脚本读写。如果你在用 DSH 做长期运行的助手,值得把它作为第一个记忆层试一下。
- 目录页:https://www.skillhub.cn/plugins/Ghill-0131/dsh-journal
- GitHub:https://github.com/Ghill-0131/dsh-journal