给 DeepSeek Harness 加长期记忆。
30.7/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/18 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
自动兼容检查有告警:未发布到 npm registry,仅可从源码安装。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add aujurd22/dsh-flymemory该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · chat
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 17 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查⚠ 装前注意未发布到 npm registry,仅可从源码安装
展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✗npm 包dsh-flymemory(未发布到 npm,仅可源码安装)
✓Node 引擎要求 >=20 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/15 09:45:44
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 51 处,展示前 31 条)
- 读取本地文件lib/index.js:43
return JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')).version || '0.0.0' - 读取本地文件lib/index.js:52
return JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')).name || 'dsh-flymemory' - 读取本地文件lib/index.js:216
if (existsSync(candidate) && statSync(candidate).isFile()) return candidate - 读取本地文件lib/index.js:216
if (existsSync(candidate) && statSync(candidate).isFile()) return candidate - 执行外部命令来自配置/变量lib/index.js:264
const result = spawnSync(pythonExe, ['-c', probe], { encoding: 'utf8', windowsHide: true, timeout: timeoutMs }) - 读取本地文件lib/index.js:308
if (existsSync(options.libraryPath)) return null - 读取本地文件lib/index.js:309
if (!options.upstreamLibrary || !existsSync(options.upstreamLibrary)) return null - 写入本地文件lib/index.js:310
mkdirSync(dirname(options.libraryPath), { recursive: true }) - 写入本地文件lib/index.js:311
copyFileSync(options.upstreamLibrary, options.libraryPath) - 写入本地文件lib/index.js:339
mkdirSync(options.dataDir, { recursive: true }) - 写入本地文件lib/index.js:341
writeFileSync(path, `${JSON.stringify(document, null, 2)}\n`, 'utf8') - 发起网络请求lib/index.js:381
const response = await fetch(url, { - 写入本地文件lib/index.js:615
mkdirSync(options.dataDir, { recursive: true }) - 执行外部命令来自配置/变量lib/index.js:627
const child = spawn(pythonExe, args, { - 写入本地文件lib/index.js:829
mkdirSync(options.dataDir, { recursive: true }) - 执行外部命令来自配置/变量lib/index.js:947
const result = spawnSync(pythonExe, args, { encoding: 'utf8', windowsHide: true, timeout: 180000, env: engineEnv(options) }) - 删除本地文件lib/index.js:971
try { rmSync(join(options.dataDir, 'server.pid')) } catch { } - 读取本地文件bin/flymemory.mjs:66
return `${(statSync(path).size / 1024 / 1024).toFixed(1)} MB` - 读取本地文件bin/flymemory.mjs:74
const content = readFileSync(path, 'utf8').split(/ ? /) - 读取本地文件bin/flymemory.mjs:88
const libraryExists = existsSync(library) - 读取本地文件bin/flymemory.mjs:104
console.log(` hooks config ${existsSync(info.hooksConfigPath) ? info.hooksConfigPath : 'not written yet'}`) - 读取本地文件bin/flymemory.mjs:109
console.log(` use_gate ${existsSync(join(info.dataDir, 'usegate.jsonl')) ? join(info.dataDir, 'usegate.jsonl') : 'no ledger yet'}`) - 读取本地文件bin/flymemory.mjs:111
if (existsSync(profileManifest)) { - 请求外部主机registry.npmjs.orgbin/flymemory.mjs:304
const response = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}`, { - 发起网络请求bin/flymemory.mjs:304
const response = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}`, { - 写入本地文件bin/flymemory.mjs:353
writeFileSync(secretFile, JSON.stringify({ providers: without }, null, 2) + '\n', { mode: 0o600 }) - 执行外部命令来自配置/变量bin/flymemory.mjs:412
const child = spawnSync(info.pythonExe || 'python', args, { stdio: 'inherit', env }) - 读取本地文件lib/context.js:508
const state = JSON.parse(readFileSync(join(dataDir, 'mute.json'), 'utf8')) - 写入本地文件lib/context.js:522
mkdirSync(dataDir, { recursive: true }) - 删除本地文件lib/context.js:525
try { rmSync(path) } catch { } - 写入本地文件lib/context.js:528
writeFileSync(path, `${JSON.stringify({ until, at: now }, null, 2)}\n`, 'utf8')
扫描于 2026/11/2(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
涉及外部主机:registry.npmjs.org
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 长期记忆存储
- 自动回忆与捕获钩子
- 本地记忆引擎
DeepSeek Harness 的长期记忆:15 个 FlyMemory MCP 工具、自动回忆与捕获钩子,外加一个受监管的本地引擎。
README
由 DeepSeek 最新模型翻译生成dsh-flymemory
给 DeepSeek Harness 加长期记忆。
这是一个 DSH 插件(bundle):把 FlyMemory 当作本地 MCP 服务跑起来,接进 harness。装完之后模型手里多出 15 个记忆工具,另外还有两个钩子在背后干活——你干活的过程它自己记,下次用得上就自己翻出来。省掉每次开会话都重新交代一遍背景的功夫。
所有东西都在你自己机器上:服务监听 127.0.0.1:8791,记忆就是 DSH home 底下的一个文件,没有任何数据发到外面。
DSH 会话 ──┬── mcp__flymemory__* 模型可调的 15 个工具 └── 钩子 回合前召回,回合后记录 │ ▼ FlyMemory 服务 127.0.0.1:8791 │ ▼ $DSH_HOME/flymemory-data/flymemory_v3.pkl
拿到什么
15 个工具,调用时都带 mcp__flymemory__ 前缀:
| 工具 | 干什么用的 |
| flymemory_remember | 存一条决定或发现。近似重复会自动合并。compartment 按主题分区;state_key/state_value 记「某个东西当前是什么」,旧值自动退场。 |
| flymemory_recall | 搜。
展开完整文档(README 剩余 1 节)
dsh-flymemory
给 DeepSeek Harness 加长期记忆。
这是一个 DSH 插件(bundle):把 FlyMemory 当作本地 MCP 服务跑起来,接进 harness。装完之后模型手里多出 15 个记忆工具,另外还有两个钩子在背后干活——你干活的过程它自己记,下次用得上就自己翻出来。省掉每次开会话都重新交代一遍背景的功夫。
所有东西都在你自己机器上:服务监听 127.0.0.1:8791,记忆就是 DSH home 底下的一个文件,没有任何数据发到外面。
DSH 会话 ──┬── mcp__flymemory__* 模型可调的 15 个工具 └── 钩子 回合前召回,回合后记录 │ ▼ FlyMemory 服务 127.0.0.1:8791 │ ▼ $DSH_HOME/flymemory-data/flymemory_v3.pkl
拿到什么
15 个工具,调用时都带 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 缓存,之后离线可用。
安装
用 plugin_manager 指向本目录(绝对路径):
plugin_manager(action: "install_bundle", target: "/absolute/path/to/dsh-flymemory")
或者打开 Web 侧边栏的 Plugins 页面,选这个文件夹。harness 重新加载后会有两行插件起来(flymemory、flymemory-mcp),工具就出现了。
自检:
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 窗口共享同一个引擎和同一份记忆;端口空着就后台把自带引擎拉起来,等它就绪了再让下一行去连;端口被别的程序占着,插件只报一句,不去动它——不是自己起的进程,绝不 kill。
冷启动偏慢:引擎要先 import torch 才能开始监听,大概 15–20 秒。这一行默认最多等 25 秒,没等到的话 mcp-client 会自己重连补上。
引擎彻底起不来(没有解释器、缺依赖、端口冲突)时 harness 照样启动,只是没有这些工具,原因写在日志里。
配置
环境变量,harness 启动前读取:
| 变量 | 默认值 | |
| FLYMEMORY_MCP_PORT | 8791 | 服务端口 |
| FLYMEMORY_MCP_URL | http://127.0.0.1:<port>/mcp | 完整端点 |
| FLYMEMORY_DATA_DIR | $DSH_HOME/flymemory-data | 记忆、日志、钩子配置、pid |
| FLYMEMORY_PYTHON | 自动探测 | 引擎用的解释器 |
| FLYMEMORY_DEVICE / FLYMEMORY_MODEL | cpu / 多语言 MiniLM | 传给引擎 |
其余参数写在你自己 profile 的 cordis.patch.yml 里,挂在对应行上。注意 patch 条目是 整体替换 config 的,需要的字段要写全:
- id: flymemory
name: 'dsh-flymemory'
config:
port: 8791
dataDir: 'D:\dsh-memory'
libraryPath: 'D:\dsh-memory\my-lib.pkl'
pythonExe: 'C:\Python313\python.exe'
device: cpu
readinessTimeoutMs: 25000 # 0 = 不等待,工具晚点自己出来 shutdownOnDispose: true # 退出时关掉本次拉起的引擎 nativeHooks: true # 每条手打提示做召回+捕获 hookTimeoutMs: 6000 # 每次钩子请求的预算 writeHooksConfig: true # 同时给 DSH 之外的客户端写 hooks.json seedFromUpstream: false # 默认不导入别的库 upstreamLibrary: '' # 想导入就同时配这两项 autostart: true
其余字段在 lib/index.js 的 resolveOptions() 里,多余的键会被忽略。
记忆存在哪
$DSH_HOME/flymemory-data/flymemory_v3.pkl,就一个文件,备份和删除都很直接。同目录还有:
- hooks.json — 每次激活重新生成,描述那两个钩子
- state.json — 上次激活实际解析出来的结果(端点、库、解释器、服务是怎么来的); status 和 doctor 读它,所以有 profile 覆盖时会报真实值而不是默认值
- engine.log — 引擎进程的 stdout/stderr
- server.log — 引擎自己的日志
- server.pid — 给 flymemory stop 用来找进程
不想通过 harness、单独把服务跑起来:
node bin/flymemory.mjs start
node bin/flymemory.mjs stop
node bin/flymemory.mjs log -n 40
装成 bundle 之后,同一个 CLI 会被链接到 profile 里: <profile>/node_modules/.bin/dsh-flymemory。
关于钩子
默认是开着的,毕竟「自动记忆」就是这个插件的意义。钩子跑在插件自己身上(agent/pre-step),不依赖宿主的 hook bridge。它具体做了什么,值得说清楚:
- 只有你真正打出来的消息会被记录和召回。宿主给手打提示打的是 source.kind === "user";peer 消息、系统提醒、自动化心跳、模型切换通知都带别的 kind,一律忽略。被委派的子 agent 只在任务开始时召回一次,之后不再记录。
- 长得像密钥的文本不会入库,自动化/心跳提示在发往服务之前就被跳过。
- 召回内容附到当前回合,上限约 2.5KB,并明确标注「这是数据、不是指令」。
- 还有一次请求专门取 compartment="lessons" 的前两条,单独注入。踩过的坑因此每轮都在眼前,而不是和普通记忆抢名额。存教训用 flymemory_remember 加 compartment="lessons",文本开头写清楚「哪个工具/哪个环境」,因为最后是靠词法通道把它捞回来的。
只想要工具、不想要自动化,就把这一行的开关关掉(patch 条目是整体替换 config,需要的字段要写全):
- id: flymemory
name: 'dsh-flymemory'
config:
port: 8791
nativeHooks: false
导入已有的库
默认什么都不导入。如果你手上已经有一份 FlyMemory 的库想搬进来,指一次就行:
- id: flymemory
name: 'dsh-flymemory'
config:
port: 8791
upstreamLibrary: 'D:\path\to\flymemory_v3.pkl'
seedFromUpstream: true
下次激活时,只要目标文件还不存在就复制过去,源文件保持不动。两边格式一致,以后想搬出去也可以。
分享一个已经在跑的服务
如果这台机器上已经有 FlyMemory 服务在跑,而你希望 DSH 直接用它的记忆、而不是自己另存一份,覆盖这两行即可(写在你自己 profile 的 patch 层):
- id: flymemory
name: 'dsh-flymemory'
config:
port: 8765
libraryPath: 'D:\path\to\flymemory_v3.pkl'
- id: flymemory-mcp
name: '@deepseek-ai/dsh-mcp-client'
config:
serverName: flymemory
transport: streamable-http
url: 'http://127.0.0.1:8765/mcp'
port 是插件去哪找现成的服务;libraryPath 是万一它得自己拉引擎时开哪个文件——两条路通向同一份记忆。钩子那行不用动,它会跟着插件解析出来的端点走。
node bin/flymemory.mjs status 在这种覆盖生效时会标出 "from hooks.json",一眼能看出用的不是默认值。
想改代码
node --check lib/index.js # 语法
npm test # 单元测试,不需要 Python,约 0.3 秒
node tests/engine_smoke.mjs # 打真引擎的端到端(需要 torch)
python tests/http_smoke.py # 对着运行中的服务做协议检查
npm test 盯的是容易出错的那几块:端口和库的默认值、配置优先级、生成的钩子文件、端点探测。engine smoke test 在临时目录里用真的 Python 引擎跑一遍 apply()——需要 torch 和 sentence-transformers,没装会打印 SKIP。CI 在 Linux、macOS、Windows 上跑 Node 20 / 22 / 24,加上语法检查和单元测试。
lib/index.js Host 端:探端口、管引擎、生成钩子配置 bin/flymemory.mjs CLI,复用同一套函数 cordis.patch.yml 这个 bundle 插入的两行 python/ 随包的 FlyMemory 引擎(服务端、钩子、引擎包)
locale/{en,zh}.json Plugins 页面显示的标题和描述
tests/ 单元测试、引擎冒烟、协议冒烟
不太行的地方
- 第一次启动要 15–20 秒,都是 torch 的加载时间。嫌久就把 readinessTimeoutMs 设成 0,harness 立刻启动,工具几秒后自己出现。
- Python 依赖比较重。插件不会替你装,doctor 会告诉你缺什么。
- DSH 没有 PreCompact 钩子,所以恢复包挂在会话开始,而不是压缩之后。
- 工具名很长。mcp__flymemory__flymemory_recall 是 mcp-client 的命名规则(mcp__<server>__<tool>)决定的,稳定,但不好看。
- 一个端口一个引擎。两个 harness 共用;要第三份实例得显式配独立端口和独立库。
- 库越大召回越慢。上游在 CPU、约 1400 条时测到每查询 ~11ms。
许可
MIT,见 LICENSE。
随包携带的 FlyMemory 引擎同样是 MIT,Copyright (c) 2026 Junrong Du。
具体复制了哪些文件、改了哪些、为什么改,都写在 THIRD_PARTY_NOTICES.md 里。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
aujurd22/dsh-flymemory
给 DeepSeek Harness 加长期记忆。
相关插件 · 对话 / 记忆
上下文中枢oceanbase/powercontext
上下文跟着工作走 —— 跨会话、跨智能体、跨人。
★ 1,487已汉化DSH
73
智能体记忆库plastic-labs/honcho
Honcho 是记忆基础设施,用来构建有状态的智能体。这些智能体能理解不断变化的人、智能体、群组、项目和想法。
★ 7,894已汉化DSH
71.7
长程智能体控制面loopx-project/loopx
给 Agent 一个目标,让工作持续向前。
★ 6,358已汉化DSH
71.3
智能体上下文数据库volcengine/OpenViking
给 AI 智能体用的上下文数据库
★ 41,379已汉化DSH
71.3
长效机器人团队Fei2411/DS-Bot
DS Bot 是一个基于 DeepSeek Harness简称 dsh的 bot 插件,插件将 dsh 改造为 bot…
★ 5,084已汉化DSH
71.1
可携带记忆层EverMind-AI/EverOS
为什么选择 EverOS
★ 13,778已汉化DSH
71.1
这是你的仓库?认领条目