◈

dsh-memory

给 DeepSeek Harness 装上跨会话项目记忆 · 原生 Cordis 插件(MIT)

十秒看懂它解决什么问题

会话 1 · 真实记录
> dsh "请记住:本项目是厦门大学期末工程,
  所有回答必须使用中文。"

[模型调用 memory_extract 工具]
✓ 沉淀 2 条新记忆:
  [fact]       本项目是厦门大学的期末工程。
  [preference] 用户要求所有回答必须使用中文。
会话 2 · 全新启动
> dsh "这个项目是什么?你怎么知道的?"

本项目是厦门大学的期末工程。
这**不是我从本次对话推出来的,而是来自
跨会话记忆**——记忆条目 #c32400e3,
沉淀于 2026-10-05。

六项核心能力

自动沉淀

每轮结束自动用一次辅助 LLM 调用抽取决策、约定、偏好、事实;无需用户喊"记住"。

语义去重

词项包含度判定复述,"用中文回答"与"用户要求中文回答"合并为一条——重复即强化置信度。

工作区隔离

记忆按项目路径打标,多项目互不污染;全局记忆处处可见。

相关性注入

新会话按有效置信度 + 关键词重合度排序注入 Top-N,拒绝无脑全量灌上下文。

差异化衰减

按类别设置半衰期——事实 14 天、决策 30 天、偏好 45 天;沉默的记忆自动淡出。

来源可解释

每条记忆带来源会话编号与日期,被问"你怎么知道的"能说清出处,错了可用 memory_forget 删除。

冲突消解

新信息推翻旧记忆时,旧条目标记"已被取代"退役留档,新事实独立入库——记忆不会自相矛盾。

审批准入

requireApproval 开启后,自动沉淀的记忆需人工批准才注入——对抗记忆污染。

架构:四个官方扩展点的组合

沉淀session/event 积累对话文本 → agent/turn-stopping 轮末触发抽取(headless 下 session/disposed 来不及触发,这是源码剖析得出的关键结论)
抽取ctx.llm.stream() 一次辅助调用输出 JSON 候选,不干扰 Agent 主循环
存储ctx.storageDomain 官方存储域 dsh_memory,per-record JSON 后端,零自建依赖
注入agent/created 时挂 systemPrompt.section(),按当前问题动态求值
管理ctx.tools.register() 暴露 memory_list / memory_forget / memory_extract

快速开始

bash
git clone https://github.com/ChenYueqi2024/dsh-memory && cd dsh-memory
npm install && npm run build && npm test     # 24 个单元用例(dsh-commit 另有 7 个)

# 装入你的 profile(复制到 node_modules 并在 cordis.patch.yml 插入一行)
# config: { provider: deepseek-official, model: deepseek-flash }

配套插件:dsh-commit

第二个原生插件,展示同一套插件机制的复用:读取 git 暂存区 diff,生成中文约定式提交信息。只生成、不提交——权限管线完整保留给模型自己的 shell 工具。

真实输出
> 用 git_commit_message 生成提交信息

chore(license): 添加 MIT 许可证

这条提交信息被原样用于 dsh-memory 仓库的真实提交——我们用自己开发的插件,开发了自己这个项目。