按会话分开的长期记忆,会随时间变淡,按证据分召回、每轮注入几条到系统提示词里。
安装
# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)
dsh plugin --profile web add github:Yuuyuko-uu/dsh-fish-memory
装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 或 ERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yaml 的 allowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。
README
给 DSH 里的会话一份会淡忘的长期记忆 —— 每条都带时间。
聊得越久,上下文越挤。压缩一次,前面的事就淡了。 这个插件替它记着:该记的记下来,想起来的时候自己会想起来,不重要的事慢慢淡掉。
名字里的「鱼」来自 DeepSeek 的鲸鱼 —— 鲸鱼也是鱼嘛。 另一半是「七秒记忆」那个梗:鱼的记性差,所以得替它记着。 但它不是硬盘 —— 它会淡忘,跟人一样。
它做什么
| 说明 | |
|---|---|
| 会淡忘 | 每条记忆有「鲜活度」,越久越淡。半衰期默认 30 天 —— 不删,只是越来越难被想起来 |
| 自己挑重点 | 不是每句话都记。它按轮次判断哪句值得留下,每天还有配额,防止把上下文塞满 |
| 想起来靠证据 | 你问什么,它按「命中的词够不够特别」找,再按鲜活度、重要度、情绪排序,最多注入几条。分词用的是一份通用中文词表,所以「车」不会撞进「车站」里 |
| 要记一辈子的不淡 | 画像、喜好、约定这种标成「长期事实」,平着放着,不会过期 |
| 带时间 | 每条都记着「这是什么时候的事」。跨年了会写「去年 09-17」 |
| 能导入旧档案 | 以前写过的 markdown / 纯文本档案,扫一遍出候选,你挑完它再改写成记忆 |
| 全都看得见 | 记了什么、哪条被想起来了、为什么没被想起来、删掉的都还在 |
需要什么
- DSH(DeepSeek Harness),带 Web 界面
- 一个能用的模型 —— 它借用你 DSH 里正在用的那个,不用另外配 key、不额外花钱
「提炼」和「扩词」这两步会调用模型(走你现有的)。不点它们就不会调用。
装法
在 DSH 里:设置 → 插件 → 安装,填下面这一行;或者命令行:
github:Yuuyuko-uu/dsh-fish-memory
dsh plugin --profile web add github:Yuuyuko-uu/dsh-fish-memory
(--profile 照你平时那个写:网页端一般 web,桌面端一般 desktop。)
装完重启一次 DSH。
重启后,打开 设置 → 鱼的记忆。
还没上 npm,所以要用上面那条 GitHub 的。 (以后要是上了 npm,
dsh plugin add dsh-fish-memory也能用。) ⭐ 最省事的一条:把仓库链接贴给你自己的 DSH,说「帮我装这个插件」。
装完起不来?先看这个
如果 DSH 弹「The application could not start」,错误里有 Unexpected token ''、is not valid JSON、
readProfileManifest —— 那是 profile 的 package.json 被存成了 UTF-8 带 BOM。
跟插件无关:内容都是对的,只是开头多了三个看不见的字节,DSH 读它就崩。
先找出来(不同装法位置不一样,别猜 —— 真正的 profile 目录里同时有 cordis.yml、cordis.patch.yml、package.json;机器上别处那些同名的都不算):
Get-ChildItem C:\,D:\,E:\ -Directory -Filter profiles -Recurse -Depth 4 -ErrorAction SilentlyContinue |
ForEach-Object {
Get-ChildItem $_.FullName -Directory -ErrorAction SilentlyContinue | ForEach-Object {
$p = Join-Path $_.FullName 'package.json'
if ((Test-Path (Join-Path $_.FullName 'cordis.patch.yml')) -and (Test-Path $p)) {
$b = [System.IO.File]::ReadAllBytes($p)
$bom = ($b.Length -ge 3 -and $b[0] -eq 0xEF -and $b[1] -eq 0xBB -and $b[2] -eq 0xBF)
"{0} BOM={1}" -f $p, $bom
}
}
}
输出里 BOM=True 的那一行,就是要修的文件(标准安装在 C:\Users\<你>\.dsh\profiles\<档名>\package.json)。
去掉 BOM(路径换成上面那一行):
$p = "把上面 BOM=True 那一行的路径粘到这里"
[System.IO.File]::WriteAllText($p, [System.IO.File]::ReadAllText($p), (New-Object System.Text.UTF8Encoding($false)))
然后重启 DSH 就好,数据一点没丢。实在进不去时,那个错误框里的 「Disable third-party plugins, back up profile patch, and restart」 能先起来,再一个个开回去定位。
⚠️ 手动改 profile 里的文件,一律存 UTF-8 无 BOM。让 AI 帮你改时,别让它用
Set-Content -Encoding UTF8或Out-File -Encoding utf8(Windows 自带的这两个默认带 BOM)。
怎么用
第一步:打开你要用的会话
默认全是关的。 这个很重要 —— 不是每个会话都该记东西(比如你写代码的会话)。
列表里找到要开的那个,点一下「关」变成「开」。
第二步:正常聊
开着之后,它自己会判断该记什么。你不用管。
记的时候有两条线:
- 一天最多记几条(默认 8 条)—— 防止它把鸡毛蒜皮都记下来
- 一次最多注入几条(默认 6 条)—— 防止占太多上下文
第三步:想知道它记了什么
展开「记忆列表」,能看到每一条:
- 最左边是日期(能按日期排、也能只看有日期的)
- 中间是内容
- 右边是鲜活度、重要度
还有「最近一次召回」—— 能看到这次问话它挑了哪几条、哪几条没挑上、为什么没挑上。
如果你以前写过档案
很多人早就给自己的 AI 写过设定、记忆卡、日记。不用重写,导进来就行。
- 设置页展开「从旧档案导入」
- 选文件夹(或填路径)→ 点「扫描档案」
- 它把档案拆成一条条候选,列给你看
- 你勾掉不要的 → 点「导入选中的」
- 再点「开始提炼」—— 它把这些原文改写成第一人称的记忆,顺手给每条出检索词、日期、重要度
提炼会调用模型(走你 DSH 里的那个),一批几条、慢慢跑,可以随时停。 它会从较新的内容往前做,已经提炼过的不再重复。
认得的格式:.md .markdown .txt .text .log .rst .org
子文件夹会往下找两层。
参数(都能调)
设置页里有一组旋钮,每一项都有说明,鼠标放上去能看到它在干什么。大致分三组:
| 组 | 管什么 |
|---|---|
| 权重 | 鲜活度 / 重要度 / 情绪各占多少分(四项合计 100%) |
| 时间 | 多久淡一半 |
| 门槛 | 命中多少才算相关、一次最多注入几条、每天最多记几条 |
一个建议:证据门槛 卡的是「证据」不是「鲜活度」,所以调它不会误伤该想起来的。
想让它更少说话就调高,想让它更容易想起来就调低。
人称
记忆里你自己是「我」,用户是「她 / 他 / ta」—— 默认 ta,可以在设置页改。
改完之后:
- 以后新记的会按你设的写
- 已有的记忆里那个字也会跟着换
- 提炼旧档案时也按你设的来
说名字本身的句子不会被换掉(「我的名字叫某某」不会变成「我的名字叫我」)。
事实键(同一条事只留最新)
有些记忆记的是会变的东西,光看句子像不像判不出来:
- 「身高一米七」和「长胖到 55 公斤」几乎是两件事,词面上却很像
- 「拼团还没开」和「拼团开了」是同一件事的前后,词面上却不像
所以每条记忆可以带一个事实键,写「对象.方面」,像 她.身高、约定.身边位置。
同一个键 = 同一件事 → 只留最新那条,旧的标成「已被取代」(不再被想起来,但东西留着、能撤销)。
键从三个地方来,都是顺手给的,不多花一次调用:
- 模型记的时候自己填(
remember的可选参数) - 提炼旧档案时顺手出(第六格)
- 设置页的「清洗补键」按钮,给以前那些还没有键的旧条目补上
⚠ 键里不许写具体的值 —— 写 她.身高,不写 她.身高170。
写了值就成了摘要:身高真变了,键也跟着变,两条永远碰不上。
拿不准就留空,留空完全没关系(留空只是享受不到这个便利,给错键却会埋掉一条正经记忆)。
清洗补键那一步是后台活:先「试 8 条看看」(一个字节都不写,只把键摆出来给你看), 确认了再真洗。跑完能一键「把补的键全摘掉」回到洗之前 —— 只摘自动补的,你自己填的键不动。
它不做什么
- 不会自动删除记忆。 淡忘只是越来越难想起来,内容一直在,设置页里看得到
- 不会把删掉的东西弄回来。 删过的再导一次档案也不会复活
- 不会每个会话都开。 默认全关,你自己挑
- 不会替你写档案。 它只把档案拆开、改写、存起来,写什么还是你的事
常见问题
Q:会不会很占上下文? 一次最多注入 6 条、加起来不超过 800 字(都能调)。超了的这次先进不来,下次可能就进了。
Q:为什么它有时候想不起来? 先看「最近一次召回」那张表 —— 它会写清楚哪条没进去、为什么。 常见原因:命中的词太普通(证据不够)、或者那条太旧淡下去了。
Q:导入扫出来 0 条? 它会告诉你为什么。常见的是:整篇是一大段话没分行、每行太短、或者内容都在表格/代码块里。
Q:数据存在哪?
%USERPROFILE%\.dsh\fish-memory\ 里,一个会话一个文件。纯文本 JSON,你自己能打开看。
每次改动前它会自动备份一份。
Q:装完包大了将近 900 KB? 那里面是一份通用中文词表,用来分词。它只在本地当查找表用 —— 不占上下文、不影响每轮对话的 token,也不会因为你聊得多就变大。
许可
MIT
分词用的词表来自 jieba 的 extra_dict/dict.txt.small
(MIT 协议),只保留了词条本身、去掉了词频和词性两列。
完整声明见 lib/词典-来源.txt。
链接
同类插件
vectorize-io/hindsight#coding-agents★ 52424
Hindsight:会学习的 Agent 长期记忆系统,自动召回/保存、知识页、深度反思与按仓库隔离的记忆银行。
volcengine/OpenViking#examples/dsh-memory-plugin★ 40541
面向 DeepSeek Harness 的 OpenViking 记忆与上下文插件:pre-step 自动召回与画像注入、会话捕获、`viking://` URI 防护,以及对接 OpenViking 服务端的 recall/write 记忆工具。
agentscope-ai/ReMe#dsh★ 3667
将 DeepSeek Harness 接入 ReMe 本地优先、自进化的个人知识库:自动把已完成的主 Agent 对话沉淀为用户掌控的 Markdown 记忆,通过 reme_search 结合 BM25、可选向量检索和 wikilink 展开搜索对话与资料,并按日整理长期记忆。
zilliztech/memsearch#MemSearch★ 2770
供 DSH 与其他编程 Agent 共享的 Markdown 记忆,支持自动捕获、步骤前上下文注入、搜索召回,以及通过审阅面板实现 memory-to-skill 自进化。
vshulcz/deja-vu#extensions/dsh★ 1275
读取本机上其他三十三个编程智能体已经写下的会话文件——Claude Code、Codex、Cursor、VS Code Copilot Chat、opencode、OpenClaw、Hermes、Kimi、Cline、Zed 等,包括安装之前的历史:提供 deja_recall、deja_session、deja_blame、deja_fix、deja_how、deja_remember 六个工具与 /deja 命令,并可选地把召回结果加入运行时上下文。本地 BM25 索引,不用大模型,不用向量嵌入,不联网(dsh plugin --profile web add dsh-deja)。
adoresever/graph-memory★ 658
DeepSeek Harness 的可追溯、可检索跨会话记忆:把对话知识沉淀为带类型的图节点(任务/技能/事件)与关系边。
社区评论
评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。