dsh-memory

by vpromise

2 记忆github收录于 08-23

给每个 agent 的跨会话持久上下文:捕获活动的 DeepSeek Harness Cordis 插件

Persistent context across sessions for every agent: a DeepSeek Harness Cordis plugin that captures activity, c

安装

dsh plugin --profile web add github:vpromise/dsh-memory

GitHub 源码安装:首次需按提示配置 allowBuilds 构建授权后重试

安装与环境配置指引、插件开发教程见 DSH 中文社区文档 ↗

安装即在你的机器上以你的权限运行第三方代码——它可读写文件、使用凭据、访问网络,DSH 的工具审批不会为插件代码加沙箱。「检测到 manifest」仅代表发现 dsh.bundle / dsh.plugin 清单,不构成兼容性或安全审查;安装前请审阅源码,不熟悉的插件先在不含密钥的环境试用。

README

目录

Persistent Context Across Sessions for Every Agent。

English | 中文

一个 DeepSeek Harness 插件 (Cordis),为每个 agent 提供长期记忆:监听每个会话的活动,用 LLM 将其蒸馏为 持久语义记忆,按项目落盘,并在未来的会话中自动注入相关内容。

灵感来自 claude-mem 的核心循环—— 捕获会话活动 → LLM 压缩为语义记忆 → 新会话自动注入相关上下文——但完全 基于 DeepSeek Harness 的原语从零实现:原生会话事件、agent 生命周期瀑布和内置 LLM 服务。无外部进程、无数据库服务。

license version

为什么

  • 每个会话都从零开始。dsh-memory 闭环解决:一个会话学到的内容——决策及其 理由、用户偏好、代码库事实、已解决的问题——会被下一个会话自动回忆。
  • 零基础设施:每个项目在 $DSH_HOME/memory 下一个 JSONL 文件 + 常驻内存索引
    • 你已有的 LLM。除插件本身外无需安装任何东西。
  • 模型可调用工具(memory_search / memory_save / memory_list)让 agent 能显式查询和写入同一份记忆库。

工作方式

  1. 捕获 — 监听每个会话的持久化事件流(session/event):
    • 人类直接提示(user/message,仅 source.kind === 'user',插件注入的 上下文不会被二次记忆),
    • 模型回复摘要(assistant/message,截断),
    • 工具调用及结果(tool/call + tool/result,按 callId 配对,含失败 标记)。
  2. 压缩 — 每个 turn 结束时(或缓冲达到阈值时),把缓冲的观测发给 LLM (复用 ctx.llm.stream),要求输出 [{text, tags}] 形状的 JSON 数组。 请求默认走 agent 的模型路由,也可用配置显式指定 provider/model。所有失败 只记日志并静默丢弃——压缩绝不阻塞或破坏 agent 循环。
  3. 存储 — 每个项目一个 JSONL 文件 ($DSH_HOME/memory/<项目>-<sha1-8>.jsonl),每行一条记忆,含 id、文本、 标签、时间戳和来源会话。索引常驻内存(读取同步),追加写串行化,损坏行 跳过而不报错。
  4. 注入 — 在 agent/pre-step 瀑布中,于首个 step 以及每 N 个 turn,把 「最近记忆 + 与当前提示关键词相关的记忆」渲染进 system-reminder 帧, 以 source.kind === 'memory'、form 为 recall 的持久化 user 消息折入 step 批次,紧跟在直接提示之后。字节预算受限;同一载荷不会在可见表面重复 注入。
  5. 工具 — memory_search、memory_save、memory_list 作为模型可调用 工具暴露,让 agent 能显式查询和写入同一份记忆库(对应 claude-mem 的 MCP 搜索工具)。

安装

要求:已运行的 DeepSeek Harness 安装。从源码构建需要 Node.js ≥ 20。

发布产物 dist/index.js 自包含:只使用 Node 内建模块,外加一行对 @deepseek-ai/cordis 的空引用(peer 依赖,任何 DSH 安装都自带)。产物已提交 进本仓库,安装无需构建步骤。

  1. 克隆仓库(或下载最新 tag 的源码):
    git clone https://github.com/vpromise/dsh-memory
    
  2. 在你的 profile 补丁文件里加一条:
    - insert:
        - id: memory
          name: /path/to/dsh-memory/dist/index.js
    
    • 仅本机 web profile:$DSH_HOME/profiles/web/cordis.patch.yml
    • 全部 profile:$DSH_HOME/cordis.patch.yml
  3. 重启 DSH host。新会话的第一条回复前会自动出现记忆上下文;会话结束时 (turn/end——自然完成或缓冲满阈值)后台压缩运行,下个会话即可见。

一次性 headless CLI 注意:长驻 host(web GUI 等)的压缩在后台可靠完成。 一次性 headless CLI 在退出时只给压缩约 4 秒的收尾窗口(受 CLI 5 秒优雅停机 限制),届时未返回的压缩请求会被丢弃。显式 memory_save 不受影响——同步 持久化。

配置

所有字段都有默认值,config 块可以完全省略:

字段 默认 说明
enabled true 总开关
autoCapture true 捕获会话事件
autoCompress true 用 LLM 压缩缓冲观测
autoInject true 向新/继续会话注入记忆
maxInjectedBytes 4096 单次注入上下文的最大字节数
maxRecentMemories 6 优先注入的最近记忆条数
maxRelevantMemories 4 按关键词相关性追加的条数
refreshEveryTurns 6 同一会话中每隔多少 turn 重新注入
compressAfterItems 5 缓冲多少条观测触发压缩
maxCompressInputBytes 24000 单次压缩输入的上限
maxObservationChars 3000 单条观测的字符上限
maxMemoryChars 800 单条存储记忆的字符上限
maxOutputTokens 1024 压缩请求输出 token 上限
timeoutMs 60000 压缩请求超时
provider / model 空 压缩路由;为空时用 agent 默认模型
storageDir 空 记忆目录;为空时用 $DSH_HOME/memory

存储

  • 项目根通过 .git / .hg / .svn / pnpm-workspace.yaml 标记向上探测。
  • 每个项目一个 JSONL 文件: $DSH_HOME/memory/<basename>-<sha1-8>.jsonl;无项目根目录的会话写入 global.jsonl。
  • 文件是纯 JSONL——可直接查看/编辑;删除某行后重启即生效。

开发

pnpm install        # 依赖(含 tsdown/vitest/typescript)
pnpm test           # 46 个单元 + 集成测试
pnpm typecheck      # tsc --noEmit
pnpm build          # 产出 dist/index.js(自包含 ESM)
  • 类型解析:tsconfig.json 将 @deepseek-ai/* 映射到本机 DeepSeek Harness checkout 的已构建 lib 类型;vitest 用 vitest.config.ts 的 alias 映射到 checkout 源码。
  • 集成测试用 mock LLM 适配器驱动完整循环:捕获 → 压缩 → 落盘 → 注入 → 去重 → 工具读写,并验证 llm/tools 服务缺失时的优雅降级。
  • tests/dist.spec.ts 校验打包产物满足 loader 契约(name / inject / Config / apply)。
  • 真实 loader 冒烟:设 DSH_CHECKOUT 指向编译好的 checkout,在 smoke/ 下 运行:
    DSH_CHECKOUT=/path/to/deepseek-harness node smoke.mjs
    
  • 真实 LLM e2e:在仓库根运行,走 deepseek-v4-flash 真实调用穿过插件压缩 管线。凭据来自 DEEPSEEK_API_KEY 或指向 .credentials.yaml 的 DSH_CREDENTIALS:
    DSH_CHECKOUT=/path/to/deepseek-harness node e2e/compress-live.mjs
    

与 claude-mem 的对照

claude-mem dsh-memory
5 个生命周期 Hook 脚本 原生 session/event + agent/pre-step 事件
独立 Bun worker + HTTP API 进程内 Cordis 插件,零外部进程
SQLite + FTS5 + Chroma 向量库 每项目 JSONL + 内存索引 + 词元重叠打分
Stop hook 触发压缩 turn/end 触发,串行尾部去重
SessionStart hook 注入 折入 agent/pre-step 瀑布,带 recall 上下文形式
MCP 搜索工具 memory_search / memory_save / memory_list
项目级 worker 数据 每项目独立 JSONL 文件

License

MIT — 见 LICENSE。

原始 README: https://github.com/vpromise/dsh-memory/blob/main/README.zh.md ↗