前言¶
給 QQ 機器人接大模型時,上下文窗口只能帶最近幾輪對話,羣裏的約定、用戶說過的事實、前幾天的討論很難穩定進 prompt。常見做法是手寫 Redis 或全文搜索,中文分詞和語義召回往往要各搞一套,還要和 DSH 進程裏的插件生命週期對齊。
下面介紹維護者 Yslehui 在 DSH 插件生態裏發佈的 dsh-rag-memory:把羣聊/私聊消息、事實與摘要存進本地 SQLite,用中文友好的 BM25 與 Embedding 混合檢索,可選 Rerank 精排,再通過獨立 HTTP 接口供機器人調用。數據不上傳,未配置向量或 Rerank 時會自動降級爲純 BM25,插件仍可用。
這是什麼¶
dsh-rag-memory 是 DSH 分類「記憶」下的插件(npm 包名 dsh-rag-memory,當前版本 0.1.1,MIT 許可證)。定位是:面向 DeepSeek Harness(DSH)QQ 機器人的本地 RAG 長期記憶——存儲與檢索都在本機完成,經本地 HTTP 暴露 API,不經過 DSH Web 的登錄認證。
實現上依賴 Node 內置 node:sqlite,無原生編譯步驟,README 說明可在桌面與 Android(Node 環境)上使用。引擎要求:Node >=22.5.0,DSH >=0.2.1-rc.1。
核心功能¶
- 持久化:消息、事實、畫像、筆記等寫入 SQLite(默認 WAL),默認路徑爲
$DSH_HOME/dsh-rag-memory/memory.db。 - 按 scope 隔離:建議
group:<羣號>、private:<QQ號>,檢索與寫入均帶scope。 - 混合檢索:中文分詞 BM25 + Embedding 向量召回;開啓
rerank時可再精排。返回結果中sources標明命中通道(bm25/vector/rerank),degraded列出降級原因。 - 直接產出注入文本:
/context接口返回已格式化的記憶塊,可拼進 system prompt。 - 可選鑑權:配置非空
token時,請求需帶x-memory-token頭。
Embedding 與 Rerank 兼容 OpenAI 風格的 /v1/embeddings 與 /v1/rerank(文檔舉例硅基流動、Jina、Cohere 等)。API Key 寫在 cordis.patch.yml 中,勿提交到公開倉庫。
安裝與啓用¶
從 npm 安裝(README 給出的命令):
dsh plugin --profile web add dsh-rag-memory
本地目錄開發安裝:
dsh plugin --profile web add ./dsh-rag-memory
裝完後服務前綴爲 http://127.0.0.1:39001/rag-memory(獨立端口;被佔用時自動遞增到 39020)。README 寫明裝上即生效,無需重啓引擎。
在 cordis.patch.yml 的 config 中可調整數據庫路徑、默認檢索條數、Embedding 與 Rerank 開關及模型端點,例如:
config:
dbPath: '' # 空 = $DSH_HOME/dsh-rag-memory/memory.db
token: '' # 非空時,請求需帶 x-memory-token 頭
defaultK: 8
embedding:
enabled: true
baseURL: 'https://api.siliconflow.cn/v1'
apiKey: 'sk-...'
model: 'BAAI/bge-m3'
rerank:
enabled: true
baseURL: 'https://api.siliconflow.cn/v1'
apiKey: 'sk-...'
model: 'BAAI/bge-reranker-v2-m3'
HTTP 接口概覽¶
| 方法 | 路徑 | 作用 |
|---|---|---|
| GET | /health |
健康檢查與能力狀態 |
| GET | /stats |
各 scope 條數、向量條數 |
| POST | /ingest |
批量寫入消息 |
| POST | /search |
混合檢索 |
| POST | /context |
檢索並拼好可注入的文本塊 |
| POST | /save |
直接存一條事實/畫像/筆記 |
| GET | /profile?scope= |
列出事實類記憶 |
| POST | /delete |
按 id 刪除 |
| POST | /clear |
按 scope 清空(需 confirm: true) |
典型用法¶
寫入與檢索¶
收到消息後異步入庫,避免阻塞回復;調模型前按用戶輸入取相關記憶。
寫入示例(POST /ingest):
{
"scope": "group:123456",
"items": [
{ "text": "小明說他下週三去杭州出差", "speaker": "小明", "ts": 1700000000000 },
{ "text": "羣裏在討論週末去爬山", "kind": "message" }
]
}
kind 可爲 message(默認)、fact、profile、note、event。
檢索示例(POST /search):
{ "scope": "group:123456", "query": "小明什麼時候去杭州", "k": 8 }
需要可直接注入 prompt 的文本時,調用 POST /context:
{ "scope": "group:123456", "query": "小明出差", "k": 6, "maxChars": 2000 }
返回的 context 形如帶序號與時間的發言摘要,README 建議拼在機器人當輪的 system 段末尾。
Node 接入片段¶
README 中的最小接入方式如下(不配 token 時無需額外頭):
const MEMORY = 'http://127.0.0.1:39001/rag-memory'
const scope = `group:${groupId}`
// 收到消息:先入庫(不阻塞回復)
fetch(`${MEMORY}/ingest`, {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ scope, items: [{ text, speaker: nickname, ts: Date.now() }] }),
}).catch(() => {})
// 調模型前:取相關記憶
const res = await fetch(`${MEMORY}/context`, {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ scope, query: userText, k: 8 }),
})
const { context } = await res.json()
const system = context ? `${basePrompt}\n\n${context}` : basePrompt
適用場景與注意¶
適合:需要在 QQ 羣/私聊場景做長期記憶、又希望數據和索引留在本機的 DSH 機器人作者;願意按需配置 Embedding/Rerank 以提升中文問句召回,或接受純 BM25 降級。
注意:
- 插件以當前 DSH 進程權限運行,安裝前請閱讀 GitHub 源碼 與 MIT 許可證,自行評估安全與合規。
- 默認 HTTP 監聽本機;若暴露到公網需自行加固網絡與
token。 - 備份可複製
$DSH_HOME/dsh-rag-memory目錄,或使用 SQLite 的VACUUM INTO;按 scope 清空前建議先GET /stats確認條數。
DSH 社區插件目錄(如 SkillHub 條目)爲獨立索引站點,與 DeepSeek / 幻方無官方從屬關係;發現插件通常通過 DSH「插件 → 發現」添加市場索引源,而非官方應用商店。
結尾¶
經過上面的步驟,你可以把 dsh-rag-memory 當作機器人側的本地記憶層:入庫走 /ingest,進模型前走 /context,檢索鏈路在資料中已寫清降級行爲。進一步細節以倉庫 README 爲準。
- 目錄頁:https://www.skillhub.cn/plugins/Yslehui/dsh-rag-memory
- GitHub:https://github.com/Yslehui/dsh-rag-memory