前言¶
在 DeepSeek Harness(DSH)里跑智能体时,常见矛盾是:上下文一压缩就丢细节,RAG 能「再找回来」但每次新开会话仍要重新交代「你是谁、在做什么」。社区插件目录里归类为「记忆」的 dsh-lmmarr(维护者 RaganaBloodedge)换了一种组织方式:把长期记忆拆成原始日志、按任务拆分的文件和一份可投影的索引,让「当前在做什么、做到哪、和什么有关」尽量以低成本常驻,并按任务只读相关一块。
下面介绍插件定位、分层设计、安装配置与工具用法。事实以 GitHub 仓库 README 为准;目录页见 SkillHub 插件页。DSH 生态是「一切皆插件」;SkillHub 为独立社区目录,与 DeepSeek / 幻方无官方从属关系。
这是什么¶
lmmArr 即 long-memory, as a task graph。一句话定位:让「我在做什么、做到哪、和什么有关」零成本常驻,并且按任务只读那一块记忆。
插件为零运行时依赖的长期记忆方案,并附同源 Agent skill 形态(见仓库 skill/)。当前 npm 包版本为 0.2.0(见 package.json),许可证 MIT。GitHub 星标数为 0(以目录页线索为准)。
三层记忆怎么分工¶
本插件不做「压缩上下文」来省 token,而是用表格里的三层文件分工:
| 层 | 文件 | 谁在维护 | 成本 |
|---|---|---|---|
| 原始 | YYYY-MM-DD.md |
人手工写,append-only | 零(不进上下文) |
| 任务 | MEMORY_<任务ID>.md |
模型按需读写 | 只在召回该任务时进上下文 |
| 索引 | MEMORY.md |
工具自动重写 | 常驻(投影进系统提示,确定性、有预算) |
索引被逐字放进稳定前缀,引擎前缀缓存第一次算完后可复用。索引里不含时间戳,同一份记忆投影出的文本逐字相同——这是缓存能否命中的充要条件,也是仓库 docs/design.md 里论证的落地。
默认记忆目录为 <cwd>/.dsh-memory,可通过配置项 dir 修改。
核心能力:工具与写路径¶
插件向模型暴露五个工具(工具描述只说「能做什么」;何时用、何时不该写回由系统提示里的记忆协议约束):
| 工具 | 作用 |
|---|---|
lmmarr_index |
读完整索引(任务表 + 关系图 + 一致性问题)。索引已在上下文里,只在需要全表或要报告问题时调用 |
lmmarr_context |
读一个任务及其直接邻域,其余文件不碰。读记忆的正道 |
lmmarr_upsert |
建/改任务记忆文件;同 id 即更新,未传字段保留 |
lmmarr_link |
声明 child(拆解)/ depends(前置)/ relates(弱关联);child/depends 须无环,成环拒绝且不改任何数据 |
lmmarr_forget |
删任务文件并带走关系;破坏性操作,仅在用户明确要求或条目确实错误时使用 |
写路径收敛在服务的 refresh():采集问题 → 重写索引 → 返回快照。顺序不可换——先重写索引会自愈悬空边,先写再查则一致性问题报不出来。
内核 graph.ts / store.ts 只认 FsPort 接口,对外零依赖,可离线单测。
安装与启用¶
从源码直接挂载(免构建,README 标明当前可用):
dsh web --patch ./cordis.yml
从 npm 安装(README 写明包尚未发布,发布后可用):
dsh plugin --profile web add dsh-lmmarr
改配置后建议自检。DSH 对配置错误会静默忽略而非报错,务必确认插件已挂上:
dsh --profile web --dump-config | grep -A8 "id: lmmarr"
运行环境要求 Node >= 22.6(package.json 的 engines)。peer 依赖包括 @deepseek-ai/cordis ^4.0.4、@deepseek-ai/dsh-tools 0.2.0-rc.2。
配置项¶
| 字段 | 默认 | 说明 |
|---|---|---|
dir |
<cwd>/.dsh-memory |
记忆目录 |
depth |
1 |
lmmarr_context 的默认邻域跳数 |
writeEnabled |
true |
false 时整插件只读;写工具会明确拒绝并说明原因 |
guidance |
true |
是否注入记忆协议到系统提示 |
hotMemory |
true |
是否把索引投影进上下文 |
maxProjectionCharacters |
2000 |
投影字符预算;超出先丢关系、再裁任务,并显式说明截断 |
bodySoftLimit |
16000 |
单任务正文软上限;超出只在索引里提示「该拆了」,不自动改写 |
timeoutMs |
10000 |
工具执行超时 |
典型用法思路¶
- 用
lmmarr_upsert为当前工作建或更新任务条目,正文写在MEMORY_<任务ID>.md。 - 用
lmmarr_link表达拆解、前置或弱关联;注意child/depends不能成环。 - 需要细节时用
lmmarr_context拉取该任务及邻域,避免把整个记忆目录扫进上下文。 - 索引已在热记忆里时,仅在要全表或排查一致性问题时调用
lmmarr_index。 - 原始层用按日的
YYYY-MM-DD.md手工 append,不进模型上下文,适合流水账与审计。
维护者还提供与插件同源的记忆内核 skill,同步命令为:
npm run sync:skill # src/memory → skill/scripts,并安装到 ~/.workbuddy/skills/lmmarr-memory
skill/tools/agents-probe.mjs 用于探测宿主是否支持子代理,输出 MODE delegate|self-compress,供探索性工作是否委派的纪律分叉使用。
架构上,本插件的引导层、服务化与打包形态参考了 dsh-mnemon,但刻意不做多 provider 后端、React 客户端、Git 同步等更大维护面。
适用场景与注意¶
适合需要任务级长期记忆、关系可表达(依赖/拆解/关联)、且希望索引以有预算方式常驻前缀的 DSH 用户。不适合期待「一个 RAG 库替你做全部召回」或需要 mnemon 那类多后端/UI 集成的场景。
安装与使用前请自行阅读仓库源码与 MIT 许可证。插件以当前 dsh 进程权限读写 dir 下的文件;writeEnabled 为 true 时模型可通过工具改记忆,生产环境请结合 writeEnabled、备份与目录权限评估风险。npm 包若尚未发布,应以 README 中的源码挂载方式为准。
仓库内 index/ 为未接入的检索路线探索(embedding / 一致性哈希 / 任务归纳),论证见 docs/design.md,不应视为当前插件默认能力。
结尾¶
dsh-lmmarr 用分层文件 + 任务图 + 确定性索引投影,把「当前任务全景」放进稳定前缀,读记忆时再用 lmmarr_context 按需展开。若要试用或贡献,可从 SkillHub 目录页 进入说明,或直接查看 GitHub:RaganaBloodedge/dsh-lmmarr。