dsh-mem:爲 DSH 部署零依賴本地記憶層

前言

在 DeepSeek Harness(DSH)裏做長會話、多輪任務時,模型往往只能依賴當前上下文窗口。把歷史對話「摘要後塞回 prompt」會引入轉述誤差;接外部向量庫或常駐服務又增加依賴與運維面。若你希望記憶可複覈、可本地重建,且檢索階段只給出「去哪看」而不是替模型改寫原文,就需要一種與 DSH 會話日誌對齊的本地索引方案。dsh-mem 由社區維護者 cyanxi-eb 發佈,歸類爲「記憶」類 DSH 插件,當前 GitHub 星標爲 0;它在單機內用 SQLite FTS5 從 DSH 會話日誌派生可複覈指針,並遵守「只回指針 + 原文切片」的檢索契約。

這是什麼

dsh-mem 的定位是:零依賴本地記憶層——只回指針與原文切片,不摘要、不轉述、不開端口、不常駐、不調 API。實現上只 import node:*(含 node:sqlite),無第三方運行時依賴;可選向量能力通過 optionalDependencies 預留,默認關閉。

插件通過 cordis.patch.yml 一行插入,向 DSH 註冊五個工具:mem_search、mem_open、mem_ingest、mem_episodes、mem_stats。同一套邏輯也提供獨立 CLI:dsh-mem <cmd>,與 node bin/dsh-mem.mjs <cmd> 等價,可在不啓動 DSH 的情況下對純文本做 ingest / search / open。

社區目錄頁:https://www.skillhub.cn/plugins/cyanxi-eb/dsh-mem;源碼與說明:https://github.com/cyanxi-eb/dsh-mem。目錄站點爲社區生態索引,與 DeepSeek / 幻方無官方從屬關係。

三條不變量

理解 dsh-mem 的行爲,可以先看 README 裏寫明的三條不變量:

  • I1 原文永不改寫:turn.text 是會話源記錄 content[].text 的逐字鏡像,只 INSERT OR IGNORE,永不 UPDATE。
  • I2 索引可丟棄:刪除 .db 後重跑 ingest 可 100% 重建;不存在「只有庫裏纔有」的事實。
  • I3 只回指針 + 原文切片:返回 (sessionId, seq) 與原文子串;不摘要、不補全、不推斷。0 命中就返回 0。

README 中的紅線同樣值得遵守:檢索結果只用來判斷「要不要展開」,證據永遠是 mem_open(或 CLI open)輸出的原文。

核心功能

索引與檢索(P0–P2)

0.2 版本 README 將能力分爲多層:P0 查詢切分在整句中文 0 命中時切成相鄰 bigram 再 OR,且「先失敗才切」;P1 事件層 episode 只存區間與指紋,不存摘要文本;P2 詞面重排對 P0 候選集做字符 n-gram TF-IDF 餘弦重排。向量層(P3)配置鍵已進 config,但當前 rerank:'embedding' 按 off 處理,缺模型時不假裝可用。

插件 config 中 rerank 默認 'lexical';CLI 默認 'off',需顯式 --rerank lexical 才與插件側詞面重排一致——這是爲了 CLI 能與凍結的老實現逐字節對賬。

隱私閘與遷移

入庫前(非事後過濾)可配置 redact 正則替換與 excludePaths glob,跳過指定會話或文件。支持 NDJSON 導出 / 導入(schema dsh-mem/1),便於換機遷移;import 使用 INSERT OR IGNORE,冪等。

DSH 面板(0.2)

Web 端通過 dsh.client 加載 lib/client.js,在會話頂部頁籤「對話 | 軌跡 | 記憶庫」中提供庫健康、配置與 reindex 等能力;默認收起,展開後才請求 /dsh-mem/panel/state 等路由(契約見倉庫 docs/PANEL-CONTRACT.md)。

安裝與啓用

作爲 DSH 插件(推薦)

官方 README 給出的 GitHub 直裝命令如下(須帶 --profile):

dsh plugin --profile <profile> add github:cyanxi-eb/dsh-mem

資料中記錄:在 DSH 0.2.1-rc.5 下實測安裝成功,包落入 <DSH_HOME>/profiles/<profile>/node_modules/dsh-mem,dsh.profile.bundles 會自動包含 dsh-mem。裝完後需重啓 DSH,五個工具纔會進入工具表,面板纔會出現在「記憶庫」頁籤。

前置注意:dsh plugin 會 spawn 裸 pnpm;若系統 PATH 中沒有 pnpm,命令行可能報 'pnpm' is not recognized。可將 pnpm 加入 PATH,或改用宿主 GUI 的插件管理器。若 dsh 不在 PATH,可用 README 給出的 node "<DSH>/resources/app/dsh/node_modules/@deepseek-ai/dsh/lib/bin.js" plugin ... 形式調用。

運行環境:package.json 要求 Node >= 22;許可證 MIT;當前 package 版本 0.1.0。

獨立 CLI

在倉庫內可直接:

node bin/dsh-mem.mjs stats

README 說明 npm i -g dsh-mem 在發佈到 npm 之後可用,並註明當前未發佈。CLI 與插件共用 lib/core.mjs。

主要配置項

安裝後可通過 patch 注入的默認 config(節選)調整行爲;完整鍵名以 README 與 cordis.patch.yml 爲準:

config:
  workspace: ''            # 空 = 按優先級鏈解析工作區
  storeDir: ''             # 空 = $DSH_HOME/mem
  excludePaths: []
  redact: []
  autoIngest: false        # 默認不自動索引,需顯式觸發
  rerank: 'lexical'
  rerankLexical: true
  episodeEnabled: true
  episodeClosureMinutes: 10
  episodeMaxChars: 4000
  embeddingEnabled: false

workspace 解析順序(CLI 與插件共用 core.resolveWorkspace):配置 workspace > 宿主會話 cwd > process.cwd() > profile 目錄。一工作區一庫,庫文件按 <hash8>-<目錄名>.db 分片。

典型用法

下面步驟來自 README 的可復現示例,可按「先索引、再搜、再開原文」理解。

1、入庫前隱私檢查

先用 dry-run 看將入庫多少條、命中 redact 多少、跳過哪些路徑:

dsh-mem ingest --dry-run --redact 'sk-[A-Za-z0-9]{20,}' --exclude '*scratch*'

2、增量索引工作區會話

無 file 參數時重掃本工作區 DSH 會話;插件側對應工具 mem_ingest:

dsh-mem ingest
dsh-mem ingest --all          # 忽略水位全量重掃

也可喫外部文本:

dsh-mem ingest --file <path> [--source <name>]

3、檢索與展開原文

搜索返回指針與 ≤120 字 snippet;真正作證據的是 open:

dsh-mem search "Router Worker 分工" --k 8 [--rerank lexical] [--json]
dsh-mem open "07f38d2c-...-#seq=293" --context 2
dsh-mem open "07f38d2c-...#293-441"    # episode 區間,回區間全部原文

插件工具對應關係:mem_search(query, k)→ 命中列表;mem_open(pointer, context)→ 原文行;mem_stats / mem_episodes 查看庫水位與 episode 區間。

4、遷移

dsh-mem export --out mem.ndjson
dsh-mem import mem.ndjson --dry-run
dsh-mem import mem.ndjson

5、自檢

dsh-mem selftest

CLI 退出碼:0 正常;1 用法;2 指針不存在;3 讀不到輸入;4 數據損壞。空庫或目錄不存在會非 0 退出並說明原因。

適用場景與注意

適合誰:希望在 DSH 工作區內本地檢索歷史對話、又不想引入外部 API 或常駐服務的開發者;需要可審計證據鏈(指針 → 原文)而非模型側「記憶摘要」的場景;需要 NDJSON 導出、換機導入或入庫前 redact 的團隊流程。

務必注意:

  • 插件以當前 dsh 進程權限運行,安裝前應閱讀源碼與 MIT 許可證,自行評估 redact / excludePaths 是否覆蓋你的密鑰與敏感路徑。
  • 默認 autoIngest: false,不會悄悄建索引;首次使用需主動 mem_ingest 或 CLI ingest,或在面板觸發 reindex。
  • 檢索命中只應驅動是否調用 open;不要把 snippet 當作唯一事實來源。

結尾

dsh-mem 把 DSH 會話日誌變成可丟棄、可重建的 SQLite FTS 索引,用 <sessionId>#seq=<n> 指針和原文切片滿足「本地、零依賴、可複覈」的記憶需求。若要瀏覽插件摘要與分類,可打開社區目錄頁;若要安裝命令、配置鍵與 CLI 全貌,以 GitHub README 爲準。

羽毛球分组比赛记分
小程序二维码

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

小夜