前言¶
DeepSeek Harness (DSH) 采用插件化架构,生态中已有多个记忆插件。dsh-memory-search 是由 JackZo400 开发的一个长期记忆检索插件。它不依赖云端 API,通过本地 embedding 和 SQLite FTS5 实现混合召回,解决了 Agent 随时间推移遗忘上下文的问题。
核心功能¶
该插件专注于将本地 Markdown 笔记转化为 Agent 可检索的记忆。
- 混合召回:结合本地 embedding 向量检索与 SQLite FTS5 关键词检索。
- RRF 融合:使用 Reciprocal Rank Fusion 算法融合两路召回结果,兼顾语义与关键词。
- 零 API 花费:向量模型跑在本地,无需调用外部服务。
- 降级能力:不安装模型也能使用(仅跑关键词),适合轻量级场景。
- 双出口:支持 Agent 主动调用
memory_search工具,也支持每轮对话自动召回相关记忆注入上下文。 - 密级过滤:支持根据文件名或会话映射过滤记忆可见性(如公开、个人、私密)。
- 增量索引:支持按文件修改时间(mtime)和大小增量重建索引。
安装与配置¶
安装¶
安装命令如下:
dsh plugin --profile web add github:JackZo400/dsh-memory-search
环境要求¶
- Node.js 版本需 ≥ 22.5(使用内置
node:sqlite)。 - 若需开启向量检索,需安装
node-llama-cpp及对应的 GGUF 嵌入模型(该依赖列在 optionalDependencies 中,不影响关键词检索)。
配置示例¶
安装后,需在对应 profile 的 patch 中插入配置。以下是一个基础配置示例:
- insert:
- id: memory-search
name: dsh-memory-search
config:
dbPath: .dsh-memory/index.db # 索引库路径,相对路径基于 dsh 工作目录
roots: # 语料根目录,递归收集 .md 文件
- ./memory
modelPath: '' # 嵌入模型路径;留空则只跑关键词
recall:
enabled: true # 开启每轮自动召回
limit: 4 # 每轮最多召回条数
budgetChars: 1600 # 注入上下文的字符预算
order: 130 # 在系统提示中的排序位置
embedding:
enabled: true
threads: 6 # CPU 线程数
contextSize: 1024 # 上下文窗口
batchSize: 256
queryInstruction: '' # 可选:嵌入指令前缀
search:
candidatePool: 40 # 每路召回的候选数量
rrfK: 10 # RRF 平滑常数
exclude: ['**/.index/**', '**/node_modules/**']
syncIntervalMs: 300000 # 扫描语料变更的时间间隔(毫秒)
acceptSpecChange: false # 换切块规则时需设为 true
配置要点¶
- 语料根目录 (
roots):不配置即为空索引。建议将 Markdown 笔记放在该目录下。 - 模型路径 (
modelPath):留空时插件仅建立关键词索引。若开启embedding.enabled但未填模型路径,语义检索将不可用。 - 切块规则 (
acceptSpecChange):插件采用启发式切块(基于空行、列表、标题)。若需修改切块逻辑并重新计算向量,必须将acceptSpecChange设为true。 - 密级过滤:不配置
sessionMap时,所有会话视为 owner,不做过滤。
工作原理与语料准备¶
工作流程¶
- 扫描与切块:插件按
roots扫描.md文件,根据空行、列表项、标题等启发式规则进行切块。 - 索引建立:
- 向量索引:将切块内容转为向量存入 SQLite BLOB。
- 关键词索引:使用中文 bigram 分词建立 FTS5 索引。
- 查询召回:
- 用户查询分别进入向量检索和关键词检索。
- 两路结果按名次进行 RRF 融合。
- 根据密级配置和来源权重进行过滤。
- 返回 Top-K 结果。
语料准备建议¶
- 切块规范:建议一条一事,段落间空行,避免将两件相关的事塞入同一块,影响检索精度。
- 密级文件:可利用文件名区分密级,例如
public.md、personal.md、secret.md。
测试¶
项目提供了测试脚本,用于验证切块、分词、索引及检索功能。
node test/selftest.mjs # 自检切块、分词、索引与检索
node test/plugin-selftest.mjs # 插件契约测试(工具注册、提示注入等)
node test/spec-guard.mjs # 切块规范闸测试
npm test # 执行上述所有测试
若需评估召回质量,可运行评测脚本(需根据自身语料修改题目):
node test/recall-eval.mjs --db .dsh-memory/index.db --corpus ./memory
已知局限¶
- 切块规则:依赖启发式规则(空行/列表/标题),对长段落笔记的处理不如专门的分词模型精准。
- 中文分词:仅支持 bigram 分词,缺乏词表,语法理解能力有限。
- 模型兼容性:仅在 Qwen3-Embedding-0.6B 上验证,更换模型需注意维度及
queryInstruction配置。 - 性能:向量检索采用全量扫描,语料量过大(上万块)时性能可能下降。