前言¶
给 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