dsh-memory-search:Markdown 筆記的本地記憶檢索插件

前言

DeepSeek Harness (DSH) 採用插件化架構,生態中已有多個記憶插件。dsh-memory-search 是由 JackZo400 開發的一個長期記憶檢索插件。它不依賴雲端 API,通過本地 embedding 和 SQLite FTS5 實現混合召回,解決了 Agent 隨時間推移遺忘上下文的問題。

核心功能

該插件專注於將本地 Markdown 筆記轉化爲 Agent 可檢索的記憶。

  1. 混合召回:結合本地 embedding 向量檢索與 SQLite FTS5 關鍵詞檢索。
  2. RRF 融合:使用 Reciprocal Rank Fusion 算法融合兩路召回結果,兼顧語義與關鍵詞。
  3. 零 API 花費:向量模型跑在本地,無需調用外部服務。
  4. 降級能力:不安裝模型也能使用(僅跑關鍵詞),適合輕量級場景。
  5. 雙出口:支持 Agent 主動調用 memory_search 工具,也支持每輪對話自動召回相關記憶注入上下文。
  6. 密級過濾:支持根據文件名或會話映射過濾記憶可見性(如公開、個人、私密)。
  7. 增量索引:支持按文件修改時間(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,不做過濾。

工作原理與語料準備

工作流程

  1. 掃描與切塊:插件按 roots 掃描 .md 文件,根據空行、列表項、標題等啓發式規則進行切塊。
  2. 索引建立:
    • 向量索引:將切塊內容轉爲向量存入 SQLite BLOB。
    • 關鍵詞索引:使用中文 bigram 分詞建立 FTS5 索引。
  3. 查詢召回:
    • 用戶查詢分別進入向量檢索和關鍵詞檢索。
    • 兩路結果按名次進行 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

已知侷限

  1. 切塊規則:依賴啓發式規則(空行/列表/標題),對長段落筆記的處理不如專門的分詞模型精準。
  2. 中文分詞:僅支持 bigram 分詞,缺乏詞表,語法理解能力有限。
  3. 模型兼容性:僅在 Qwen3-Embedding-0.6B 上驗證,更換模型需注意維度及 queryInstruction 配置。
  4. 性能:向量檢索採用全量掃描,語料量過大(上萬塊)時性能可能下降。
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜