前言¶
在 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或 CLIingest,或在面板觸發 reindex。 - 檢索命中只應驅動是否調用
open;不要把 snippet 當作唯一事實來源。
結尾¶
dsh-mem 把 DSH 會話日誌變成可丟棄、可重建的 SQLite FTS 索引,用 <sessionId>#seq=<n> 指針和原文切片滿足「本地、零依賴、可複覈」的記憶需求。若要瀏覽插件摘要與分類,可打開社區目錄頁;若要安裝命令、配置鍵與 CLI 全貌,以 GitHub README 爲準。