dsh-flymemory
Structural long-term memory for DSH: supersede, decay and entity-state tracking across 15 MCP tools, automatic recall and capture hooks, and a bounded pointer index published per request instead of filling the window. Requires Python 3.10+ with torch and sentence-transformers; the first run download
Install
dsh plugin --profile web add dsh-flymemory
Sandbox test results
| Stage | Result |
|---|---|
| 1 install | ✓ |
| 2 list | ✓ |
| 3 mount | ✓ |
| 4 boot | — |
Four stages run in an isolated sandbox: install (network on) → list → mount → boot (last three with no network).
README
dsh-flymemory
[English](README.md) | 中文


给 DeepSeek Harness 加长期记忆。
这是一个 DSH 插件(bundle):把 FlyMemory
当作本地 MCP 服务跑起来,接进 harness。装完之后模型手里多出 16 个记忆工具,另外还有
两个钩子在背后干活——你干活的过程它自己记,下次用得上就自己翻出来。省掉每次开会话都
重新交代一遍背景的功夫。
所有东西都在你自己机器上:服务监听 127.0.0.1:8791,记忆就是 DSH home 底下的一个
文件,没有任何数据发到外面。
DSH 会话 ──┬── mcp__flymemory__* 模型可调的 16 个工具
└── 钩子 回合前召回,回合后记录
│
▼
FlyMemory 服务 127.0.0.1:8791
│
▼
$DSH_HOME/flymemory-data/flymemory_v3.pkl
和「向量检索式记忆」的区别
大多数 agent 记忆插件就是一张笔记表 + 余弦相似度。这是一个完整的库,差别在日常使用里就能看出来:
· 笔记表 + 余弦检索 · dsh-flymemory
同一个事实变了 · 新旧一起被召回 · supersede 让旧条目退场,除非显式查历史
同一件事说了两遍 · 越堆越多 · 按长度分级的去重会合并或加强
「X 现在是什么」 · 你得自己写对查询 · state_key/state_value 保存当前值 + 历史链
时间新旧 · 看起来一样新鲜 · 幂律衰减按保留度加权
条目从哪来 · 丢失 · source(模型判断 vs 机械捕获)+ app:<name>
多个客户端 · 各存一份 · ZCode / Qoder / DSH 可共享同一份库,app= 标签标明作者
每轮开销 · 要么全文要么没有 · 有界指针索引(≤1.2KB),正文由模型自己拉
有没有被用 · 不知道 · usegate.jsonl:每个注入的指针都记为 expanded / recalled / superseded
上游实测数字(这里不重跑,协议见 FlyMemory 仓库):
- 聚合类问题:单发 top-5 严格正确率 6%,「广收集 + 逐条读原文抽事实」16%(P-ANSWER);
- 多跳问题:让检索器先做相关性过滤,证据从 100% 掉到 75%(P-COMBO);
- 指针注入把「证据进池率」从 63.9% 提到 74.4%,但池 token 涨到 12.15 倍(P-USEGATE,判定 PARTIAL)——这正是本插件只指路、绝不自行展开的原因。
本页不声称:装了记忆模型就变聪明,或者召回在每个指标上都赢。上游记录的诚实结论是:结构化记忆可复现,自适应读取策略至今还没有通过独立复现。
它像一本笔记本,以及「谁在思考」
用笔记本讲比讲架构清楚得多。
你说的每句话各占一行,主题不会糊在一起。说了几乎一样的话,老那行只是被划得更重,
不会复制出第二条。你说「其实我搬到杭州了」这种更正,老那行被划掉但没撕掉——问历史
的时候还能翻到划掉的行。零散短句会定期压成摘要条目;几个月没人碰的会慢慢褪色(幂律,
真实半衰期是 3τ,默认 90 天)。找一行有两种走法:按意思找,以及按嵌入看不见的精确关键词
找——料号、文件路径、ID。
分工是这套东西的设计赌注:服务端永不运行 LLM。 机械的部分全归它——切分、去重、融合、
衰减计算、血缘清理、持久化;所有判断归调用方模型——什么重要、什么过期、什么该忘。所以
判错会留下判错的记录:supersede 留下带 valid_from/valid_to 的墓碑,而不是一个洞。
一条记忆的一生:
1. 写入 —— 钩子自动捕获,或模型显式存(source 把两者区分开);
2. 加强 —— 近似重复更新原条目而不是新增一份;去重按长度分级,且倾向不合并;
3. 取代 —— supersede(旧, 新) 让过期状态退场;include_superseded 查历史时仍能看到;
4. 归并 —— consolidate(ids, 结论) 生成更高层的条目,并保留 evidence_ids 回链,
抽象不销毁原材料;
5. 褪色或遗忘 —— 幂律衰减清理无人问津的;forget 直接删掉确实错的。
这些规则的消融版本(包括那些实测比什么都不做还差的)都留在引擎仓库:
源码 ·
研究总账。
*引擎的两条定律。左:替换式抽象比「什么都不存」还低 10 分,所以归并只能叠加。
右:同样 48 轮、两种收集策略——锚定式判断近乎机械(预注册配对实验,不一致 13:0)。*
拿到什么
16 个工具,调用时都带 mcp__flymemory__ 前缀:
工具 · 干什么用的
flymemory_remember · 存一条决定或发现。近似重复会自动合并。compartment 按主题分区;state_key/state_value 记「某个东西当前是什么」,旧值自动退场。
flymemory_recall · 搜。向量相似度和关键词匹配融合排序,旧条目随时间衰减,返回结果带 id、年龄和来源。加 include_superseded 能翻历史。
flymemory_auto · 一次调用同时做召回和存储,钩子用的就是它。
flymemory_recall_index / flymemory_get_memory · 先看索引再读正文:先给一行摘要,觉得有用再取全文。
flymemory_supersede · 标明「这条过时了,被那条取代」。
flymemory_state_lookup / flymemory_state_history · 某个实体键当前的值,或者它的全部历史。
flymemory_consolidate · 把几条归纳成一条结论,原始条目留着当证据。
flymemory_find_conflicts / flymemory_insights · 看起来互相矛盾的配对;有价值但快衰减掉的条目。
flymemory_forget / flymemory_cleanup · 删单条,或者按衰减阈值批量清理。
flymemory_session_pack · 近期轨迹 + 最新结论的短包。
flymemory_stats · 条数、年龄、访问次数。
另外两个钩子自己跑,不用模型操心:
- 每条提示:把提示存下来,再把匹配得上的记忆附到这一轮里。纯本地检索,不调用模型。
- 会话开始:塞一个近期活动的恢复包,新会话不至于两眼一抹黑。
服务不在线时两个钩子都静默跳过,也绝不会卡住回合。
需要什么
- 带
@deepseek-ai/dsh-mcp-client的 DeepSeek Harness。在0.2.0-rc.2与44.7.0
上开发验证。
- Node 20 以上(插件本体和 CLI)。
- Python 3.10 以上,装引擎的依赖:
pip install torch sentence-transformers "mcp>=1.30,<2" numpy
解释器不用你指定:插件会依次看 FLYMEMORY_PYTHON、常见安装位置、PATH,而且
先确认这个解释器真能 import sentence_transformers 才选它。机器上装了好几个
Python 的时候,这一步能省掉半小时的「为什么起不来」。
第一次运行会把多语言嵌入模型(约 470MB)下载进 HuggingFace 缓存,之后离线可用。
安装
# 从 npm 安装(2026-10-26 已发布) dsh plugin --profile desktop add dsh-flymemory # 从 GitHub 安装(profile 名换成你自己的) dsh plugin --profile desktop add github:aujurd22/dsh-flymemory # 从本地目录安装(绝对路径) dsh plugin --profile desktop add /absolute/path/to/dsh-flymemory
或者在会话里用 plugin_manager 工具指向同一个 spec:
plugin_manager(action: "install_bundle", target: "dsh-flymemory") plugin_manager(action: "install_bundle", target: "github:aujurd22/dsh-flymemory") plugin_manager(action: "install_bundle", target: "/absolute/path/to/dsh-flymemory")
或者打开 Web 侧边栏的 Plugins 页面,选这个文件夹。harness 重新加载后会有两行
插件起来(flymemory、flymemory-mcp),工具就出现了。
信任信息。 许可证 MIT;适用于任何 base-backed profile(desktop/web);
按 DSH 0.2.0-rc.2 编写、在 44.7.0 上验证。权限范围:只在 $DSH_HOME 下写一个数据
目录、拉起一个 Python 子进程、并且只走 127.0.0.1 本机通信——不需要任何凭据,也没有
对外网络请求。外部依赖:Python 3.10+ 及 torch / sentence-transformers(见上);引擎已随包,
不需要另外 clone FlyMemory。
自检:
node bin/flymemory.mjs status # 解析出来的配置 + 当前实际状态 node bin/flymemory.mjs doctor # 解释器、依赖、端点
然后让模型记一条东西再搜一次。工具没出来,doctor 基本能告诉你卡在哪。
卸载就是反过来:
plugin_manager(action: "remove_bundle", target: "dsh-flymemory")
记忆文件不会被删,想清掉自己动手。
运行方式
bundle 插入两行:
行 · 模块 · 干的事
flymemory · 本包 · 探端口;没人应答就拉起引擎;记录解析结果;注册召回/捕获钩子
flymemory-mcp · @deepseek-ai/dsh-mcp-client · 把服务端的工具变成 mcp__flymemory__<tool>
钩子以前挂在 DSH 的 Claude-Code hook bridge 上。44.7 开始的版本不再带那个包,所以同样的
逻辑改成跑在插件自己的 agent/pre-step 上,bundle 也不再依赖 hook bridge。
harness 启动时第一行先探 127.0.0.1:8791:已经有 FlyMemory 服务在应答就直接复用,
两个 harness 窗口共享同一个引擎和同一份记忆;端口空着就后台把自带引擎拉起来,等它
就绪了再让下一行去连;端口被别的程序占
…(truncated)
Rendered from the README published on npm. Formatted only, not edited.
Versions
Published on npm::22,最后更新 2026-10-31