🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

QQ 对话记忆 Gentaine/dsh-qq-memory

DeepSeek Harness
Gentaine4 天前有提交已提供中文文档扫描:未发现敏感能力

把 QQ 聊天记录存入 SQLite,按话题自动召回旧消息

29.8/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/11/2 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add Gentaine/dsh-qq-memory
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:仅索引
是什么
dsh 原生插件 · platform
装得上吗
本站尚未做安装检查
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 4 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🟢 扫描:未发现敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描未发现敏感能力:最多只发网络请求、读取自身元数据或只读文件,未发现执行命令、文件写入或敏感信息读取。

扫描于 2026/11/2(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

DeepSeek Harness 的 QQ 桥接对话表记忆插件:SQLite 存储、自动召回、回忆计数、轮次与定期清理。

README

由 DeepSeek 最新模型翻译生成
dsh-qq-memory 给 qq-bridge + DeepSeek Harness 用的「对话表记忆」插件。 它把 QQ 聊天记录一行一条写进 SQLite,按话题自动召回旧消息;同时记录每条消息 被回忆的次数和所在对话轮次,并定期清理低价值旧消息。 不调用额外的模型,不注册新工具,因此不会被 qq-chat-v2 的 qq-tool-restrict 白名单挡住,也不需要修改 qq-bridge。 功能 - 落表:读取 qq-bridge 的 state/social-v2.json,把入站/出站消息写进 SQLite。 - 自动回忆:在 DSH 每轮第一步,从旧消息里按关键词 + 时间窗挑 1–8 条,作为 source.kind = "qq-table-memory" 的上下文追加给模型。 - 回忆计数:消息真正进入提示词时 recall_count + 1。 - 对话轮次:按「对方发起 → 我回应」的规则给每条消息标 turn_no。 - 定期清理:按「时间越久、被回忆越少、这一轮交流次数越少」的优先级删除旧消息。 - 同会话隔离:不会把 A 群的旧账带进 B 群或私聊。 - 可导出:list、search、Markdown / CSV / JSON 导出。 - 可回填:可选脚本从 DSH 会话日志里补更早的消息快照。
展开完整文档(README 剩余 1 节)
dsh-qq-memory

给 qq-bridge + DeepSeek Harness 用的「对话表记忆」插件。

它把 QQ 聊天记录一行一条写进 SQLite,按话题自动召回旧消息;同时记录每条消息 被回忆的次数和所在对话轮次,并定期清理低价值旧消息。

不调用额外的模型,不注册新工具,因此不会被 qq-chat-v2 的 qq-tool-restrict 白名单挡住,也不需要修改 qq-bridge。

功能

- 落表:读取 qq-bridge 的 state/social-v2.json,把入站/出站消息写进 SQLite。
- 自动回忆:在 DSH 每轮第一步,从旧消息里按关键词 + 时间窗挑 1–8 条,作为 source.kind = "qq-table-memory" 的上下文追加给模型。
- 回忆计数:消息真正进入提示词时 recall_count + 1。
- 对话轮次:按「对方发起 → 我回应」的规则给每条消息标 turn_no。
- 定期清理:按「时间越久、被回忆越少、这一轮交流次数越少」的优先级删除旧消息。
- 同会话隔离:不会把 A 群的旧账带进 B 群或私聊。
- 可导出:list、search、Markdown / CSV / JSON 导出。
- 可回填:可选脚本从 DSH 会话日志里补更早的消息快照。

前置条件

- DeepSeek Harness 0.2.x(插件在 0.2.1-rc.3 上开发和测试)
- Node.js >= 24(使用内置 node:sqlite)
- 已安装并运行的 qq-bridge
- qq-bridge 处于 reserved2 模式,并且 state/social-v2.json 正在更新

安装

1. 放到本机

git clone https://github.com/Gentaine/dsh-qq-memory.git
"$HOME\.dsh\plugins\dsh-qq-memory"

也可以放在任意目录,后面把路径换成实际路径。

2. 注册到 DSH 配置档

编辑 ~/.dsh/profiles/<profile>/package.json:

{
"dependencies": {
"dsh-qq-memory": "link:<绝对路径>/dsh-qq-memory" },
"dsh": {
"profile": {
"bundles": [
"@deepseek-ai/dsh-base",
"@deepseek-ai/dsh-web-app",
"dsh-qq-memory"
]
}
}
}

在配置档的 node_modules 里建立链接:

Windows
New-Item -ItemType Junction
-Path "$HOME\.dsh\profiles\<profile>\node_modules\dsh-qq-memory"
-Target "<绝对路径>\dsh-qq-memory"

Linux / macOS
ln -s "<绝对路径>/dsh-qq-memory" "$HOME/.dsh/profiles/<profile>/node_modules/dsh-qq-memory"

如果配置档里有 pnpm-lock.yaml,还需要让 lock 指向同一个本地路径,否则 DSH 启动时可能按旧 lock 重装。桌面版没有 lock 时直接重启即可。

3. 配置路径

插件自带的 cordis.patch.yml 使用以下默认值:

- bridgeStateDir:./qq-bridge/state(相对于 DSH 进程的 cwd)
- databasePath:~/.dsh/qq-memory/conversations.sqlite3

如果你的 qq-bridge 不在 DSH 工作区的 qq-bridge/ 下,打开 dsh-qq-memory/cordis.patch.yml,取消注释并改成实际路径:

- insert:
- id: qq-memory
name: dsh-qq-memory
config:
enabled: true
bridgeStateDir: '/absolute/path/to/qq-bridge/state'
databasePath: '/absolute/path/to/conversations.sqlite3'
...

Windows 路径请用单引号包起来,例如:

bridgeStateDir: 'D:\qq-bridge\state'

4. 重启 DSH

插件在 bundle 装配阶段加载,改完必须重启 DSH。

5. 确认

node dsh-qq-memory/scripts/qq-memory.mjs stats
--db "$HOME/.dsh/qq-memory/conversations.sqlite3"

看到消息数、会话数、总回忆次数、最大轮次就说明表已经建好。

表结构

CREATE TABLE messages (
id INTEGER PRIMARY KEY AUTOINCREMENT,
qq_key TEXT NOT NULL, -- group:群号 / private:QQ号 session_id TEXT, -- qq-bridge 映射的 DSH session seq INTEGER, -- 桥接本地序号 message_id TEXT, -- QQ message_id sent_at INTEGER NOT NULL, -- 毫秒时间戳 sender TEXT, user_id TEXT, direction TEXT NOT NULL CHECK (direction IN ('in', 'out')), text TEXT NOT NULL, search_text TEXT NOT NULL DEFAULT '', recall_count INTEGER NOT NULL DEFAULT 0, turn_no INTEGER NOT NULL DEFAULT 1, dedupe_key TEXT NOT NULL, raw TEXT, ingested_at INTEGER NOT NULL );

索引:

CREATE UNIQUE INDEX messages_dedupe ON messages (qq_key, dedupe_key);
CREATE INDEX messages_key_time ON messages (qq_key, sent_at);
CREATE INDEX messages_key_direction_time ON messages (qq_key, direction, sent_at);
CREATE INDEX messages_cleanup ON messages (qq_key, turn_no, sent_at);

去重优先级:message_id → seq → 内容哈希。同一条消息被 recentMessages 和 unread 同时带上时只会留一行。

轮次 turn_no

- 第一轮从第 1 条消息开始;
- 当“上一条是我发的、下一条是对方发的”时,进入下一轮;
- 连续几条对方消息算同一轮,我连续补充几句也算同一轮。

所以一轮通常就是“对方发起 → 我回应”。清理规则里的“交流次数”只数这一轮里 对方发的消息条数,不是总消息条数:我连续补很多句不会把这一轮撑成“高价值长讨论”。

回忆次数 recall_count

buildInjection 真正把某条旧消息塞进注入块时,调用 store.markRecalled(usedIds),对应行 recall_count + 1。被长度截断、没进入 prompt 的消息不计数;用 CLI 查看也不计数。

旧库第一次打开时会自动补 recall_count=0 并按上述规则重算 turn_no。

定期清理

默认每 6 小时检查一次,启动 10 秒后也检查一次。

只有单个会话超过 maxMessagesPerConversation(默认 5000 条)才触发;并且:

- 只清 minAgeDays(默认 14 天)以前的消息;
- 不动最近 keepRecentTurns(默认 30)轮。

对剩下的候选,按清理优先级从高到低删,每次最多 batchSize 条:

priority = ageScore * 0.5
+ recallScore * 0.3
+ turnExchangeScore * 0.2

ageScore = min(1, 消息年龄天数 / ageSaturationDays) // 越老越高
recallScore = 1 / (1 + recall_count) // 越少被回忆越高
turnExchangeScore = 1 / (1 + 这一轮里对方发的消息条数) // 交流次数越少越高

默认 ageSaturationDays = 90,权重为 age=0.5, recall=0.3, turnLength=0.2。
优先级越高越先删:

- 很久没提、从没被回忆、当时只有一两句的寒暄最先走;
- 经常被想起的、最近 30 轮的、长讨论里的关键消息留得更久。

配置

配置在 cordis.patch.yml 的 config 块:

| 字段 | 默认 | 作用 |
| enabled | true | 总开关 |
| bridgeStateDir | ./qq-bridge/state | 桥接状态目录 |
| databasePath | ~/.dsh/qq-memory/conversations.sqlite3 | SQLite 路径 |
| minAgeHours | 3 | 只把 N 小时以前的消息当“旧记忆” |
| maxInjectedMessages | 8 | 一次最多注入几条 |
| maxInjectedChars | 1800 | 注入块字符上限 |
| cooldownTurns | 5 | 普通关键词命中的冷却轮数 |
| memoryIntentCooldownTurns | 1 | 明确记忆问法的冷却轮数 |
| queryLookbackMinutes | 120 | 用最近多少分钟的消息当查询 |
| candidateLimit | 2500 | 单次检索最多扫多少条旧消息 |
| minScore | 2.2 | 关键词命中门槛 |
| pollMs | 15000 | 定时补录间隔 |
| timeZone | Asia/Shanghai | 展示时间用的时区 |
| debug | false | 打印每次导入的条数 |
| cleanup.enabled | true | 定期清理总开关 |
| cleanup.intervalHours | 6 | 每隔多少小时检查一次 |
| cleanup.minAgeDays | 14 | 只清 N 天以前的消息 |
| cleanup.keepRecentTurns | 30 | 保留最近 N 轮 |
| cleanup.maxMessagesPerConversation | 5000 | 单会话超过多少条才触发 |
| cleanup.batchSize | 200 | 单次最多删多少条 |
| cleanup.ageSaturationDays | 90 | 年龄多少天后 ageScore 达到 1 |
| cleanup.weights.age | 0.5 | 时间权重 |
| cleanup.weights.recall | 0.3 | 被回忆次数权重 |
| cleanup.weights.turnLength | 0.2 | 交流次数权重(只数对方消息) |

改 cordis.patch.yml 后重启 DSH。

命令行

DB="$HOME/.dsh/qq-memory/conversations.sqlite3"
node scripts/qq-memory.mjs stats --db "$DB"
node scripts/qq-memory.mjs list --db "$DB" --limit 30
node scripts/qq-memory.mjs search --db "$DB" --query '训练集'
node scripts/qq-memory.mjs export --db "$DB" --format markdown --out ./exports/对话表.md

Windows PowerShell:

$db = "$HOME\.dsh\qq-memory\conversations.sqlite3"
node scripts/qq-memory.mjs list --db $db --limit 30

list 和导出都带 turn_no(轮次)与 recall_count(被回忆次数)两列。

CSV 写文件时默认加 UTF-8 BOM,Excel 直接打开不会把中文显示成乱码;管道输出默认不带 BOM,需要纯净 UTF-8 时加 --no-bom。

预览 / 执行清理

只算不删(用很小的上限做演示)
node scripts/qq-memory.mjs cleanup --db $db
--dry-run --max 100 --min-age-days 0 --keep-turns 0

按默认参数真正执行
node scripts/qq-memory.mjs cleanup --db $db

默认规则下,只有会话超过 5000 条、消息超过 14 天、且不在最近 30 轮,才可能进入候选。

回填更早的会话日志

qq-bridge 的 recentMessages 只保留最近 100–200 条。DSH 会话日志里还留着模型过去读过的 qq_get_ 消息快照,可以补进表里:

node scripts/backfill-session-logs.mjs --db $db --dry-run
node scripts/backfill-session-logs.mjs --db $db

脚本只读 ~/.dsh/sessions 和桥接 sessions.json,不会改桥接状态;重复跑不会翻倍。

工作方式

qq-bridge 发给 DSH 的 user/message 是一大段唤醒提示词,真正的群消息在 mcp__snowluma__qq_get_ 的 tool result 里。按 DSH 事件反推既绕又容易漏。

桥接自己已经把入站/出站消息写进 state/social-v2.json 的 recentMessages,字段稳定(seq/messageId/sender/userId/text/isSelf/time),直接读它最贴近 QQ 的真实对话。

插件读取文件,不修改桥接状态,也不要求桥接进程额外装插件。

注入形式是一条 user 角色、source.kind = "qq-table-memory" 的上下文消息,不是系统提示词,也不是 QQ 群消息。这样:

- 不破坏 system prompt 的前缀缓存;
- 不会在 transcript 里被误认为群友发言;
- qq-bridge 不会把它当成新 QQ 消息。

已知限制

- 历史来源有限:桥接只保留最近 100–200 条;回填脚本也只能补到模型当时读过的快照。
- 纯词法检索:没有向量/同义词语义,「昨晚那个东西」这类没有具体词的问法只能靠时间窗兜底。
- 不生成摘要:注入原始片段,不是人物小传。
- 清理是硬删除:被清掉的消息不会进归档;需要留档请定期备份 SQLite 文件。
- 同会话作用域:默认不做跨群/跨私聊共享。
- 明文落盘:聊天内容原样进 SQLite,目录应按隐私数据处理。
- 坏 sender 兜底:SnowLuma 偶尔会把带控制字符的二进制串写进 sender,插件会用 群友<QQ 后四位> 代替。

License

MIT
预览分享卡片长什么样 ↓Gentaine/dsh-qq-memory
分享 · DeepSeek Harness Hub
Gentaine/dsh-qq-memory

把 QQ 聊天记录存入 SQLite,按话题自动召回旧消息

这是你的仓库?认领条目

回到顶部