在 QQ 群里聊天、归档消息、生成图片视频并召唤本地模型
30.8/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/20 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add suixin-sky/dsh-Qagent-bot该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:需留意
是什么
dsh 原生插件 · platform
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 14 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
⚠︎ 实装验证未通过(dependency_conflict · 2026/10/20) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件读取剪贴板或密钥环境变量发起外部网络请求
查看扫描证据(共 104 处,展示前 89 条)
- 发起网络请求lib/client.js:188
const res = await fetch(BIND_STATE_PATH, { cache: "no-store" }); - 发起网络请求lib/client.js:240
const res = await fetch(BIND_MANUAL_PATH, { - 发起网络请求lib/client.js:343
fetch(BIND_UNBIND_PATH, { method: "POST" }).then(async (res) => { - 发起网络请求lib/client.js:393
fetch(BIND_REFRESH_PATH, { method: "POST" }).catch(() => {}); - 发起网络请求lib/client.js:692
fetch(BIND_CONFIG_PATH, { cache: "no-store" }).then(async (res) => { - 发起网络请求lib/client.js:719
fetch(BIND_CONFIG_PATH, { - 读取密钥环境变量dist/gateway/bootstrap.js:45
tokenBaseUrl: process.env.QQBOT_TOKEN_BASE_URL?.replace(/ +$/, '') || 'https://api.bot.qq.com', - 读取本地文件dist/shared/utils.js:18
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8')); - 读取本地文件dist/shared/utils.js:52
const byPatch = findProfileAncestor(baseDir, (dir) => existsSync(resolve(dir, 'cordis.patch.yml')) ? dir : null); - 读取本地文件dist/shared/utils.js:55
const byWorkspace = findProfileAncestor(baseDir, (dir) => existsSync(resolve(dir, 'pnpm-workspace.yaml')) ? dir : null); - 读取密钥环境变量dist/setup/bind-routes.js:228
delete process.env.QQBOT_SECRET; - 执行外部命令来自配置/变量dist/setup/presenters.js:74
const child = spawn(command, args, { detached: true, stdio: 'ignore', windowsHide: true }); - 读取本地文件dist/setup/persist.js:30
if (existsSync(patchPath)) { - 读取本地文件dist/setup/persist.js:31
entries = parsePatchEntries(readFileSync(patchPath, 'utf8')); - 写入本地文件dist/setup/persist.js:56
mkdirSync(dir, { recursive: true }); - 写入本地文件dist/setup/persist.js:57
writeFileSync(patchPath, output, 'utf8'); - 读取本地文件dist/setup/persist.js:82
if (!existsSync(patchPath)) - 读取本地文件dist/setup/persist.js:84
const entries = parsePatchEntries(readFileSync(patchPath, 'utf8')); - 写入本地文件dist/setup/persist.js:93
mkdirSync(profileDir, { recursive: true }); - 写入本地文件dist/setup/persist.js:94
writeFileSync(patchPath, yaml.dump(entries), 'utf8'); - 读取本地文件dist/setup/persist.js:122
if (existsSync(patchPath)) { - 读取本地文件dist/setup/persist.js:123
entries = parsePatchEntries(readFileSync(patchPath, 'utf8')); - 写入本地文件dist/setup/persist.js:141
mkdirSync(profileDir, { recursive: true }); - 写入本地文件dist/setup/persist.js:142
writeFileSync(patchPath, yaml.dump(entries), 'utf8'); - 发起网络请求dist/features/summon-mode.js:223
const response = await fetch(url, { signal: controller.signal }); - 读取本地文件dist/features/chat-archive.js:100
if (existsSync(file)) { - 读取本地文件dist/features/chat-archive.js:101
const content = readFileSync(file, 'utf8'); - 写入本地文件dist/features/chat-archive.js:108
appendFileSync(file, `\n## ${day}\n\n`, 'utf8'); - 读取本地文件dist/features/chat-archive.js:113
if (existsSync(file)) - 写入本地文件dist/features/chat-archive.js:115
mkdirSync(dirname(file), { recursive: true }); - 写入本地文件dist/features/chat-archive.js:116
appendFileSync(file, `# QQ 聊天记录 · ${scope} · ${peerId}\n`, 'utf8'); - 写入本地文件dist/features/chat-archive.js:170
mkdirSync(destDir, { recursive: true }); - 写入本地文件dist/features/chat-archive.js:171
copyFileSync(hit.localPath, join(destDir, name)); - 写入本地文件dist/features/chat-archive.js:195
mkdirSync(dir, { recursive: true }); - 读取本地文件dist/features/chat-archive.js:206
const result = { file, exists: existsSync(file), text: '', images: [] }; - 读取本地文件dist/features/chat-archive.js:211
content = readFileSync(file, 'utf8'); - 读取本地文件dist/features/chat-archive.js:370
if (!existsSync(root)) - 删除本地文件dist/features/chat-archive.js:467
unlinkSync(abs); - 读取本地文件dist/media/media-cleaner.js:24
if (!existsSync(MEDIA_ROOT)) - 读取本地文件dist/media/media-cleaner.js:28
const entries = await readdir(MEDIA_ROOT, { withFileTypes: true }); - 读取本地文件dist/media/media-cleaner.js:33
const info = await stat(filePath); - 删除本地文件dist/media/media-cleaner.js:36
await rm(filePath, { force: true }); - 发起网络请求dist/media/vision-tool.js:48
const resp = await fetch(image, { signal, redirect: 'error' }); - 读取本地文件dist/media/vision-tool.js:57
const info = await stat(image).catch(() => null); - 读取本地文件dist/media/vision-tool.js:62
data = new Uint8Array(await readFile(image)); - 读取本地文件dist/media/vision-tool.js:142
if (!existsSync(settingsPath)) - 读取本地文件dist/media/vision-tool.js:145
const raw = readFileSync(settingsPath, 'utf8'); - 写入本地文件dist/media/vision-tool.js:166
writeFileSync(settingsPath, yaml.dump(doc), 'utf8'); - 读取本地文件dist/media/send-file-tool.js:117
if (!existsSync(absPath)) { - 读取本地文件dist/media/send-file-tool.js:120
const info = await stat(absPath); - 读取本地文件dist/features/stickers.js:29
if (existsSync(dir)) { - 读取本地文件dist/features/stickers.js:38
entries = readdirSync(dir, { withFileTypes: true }); - 读取本地文件dist/features/stickers.js:59
return statSync(path).isFile(); - 读取本地文件dist/features/stickers.js:95
const raw = readFileSync(join(dir, 'manifest.json'), 'utf8').replace(/^ FEFF/, ''); - 读取本地文件dist/features/comfyui.js:36
const stat = statSync(abs); - 读取本地文件dist/features/comfyui.js:40
const data = JSON.parse(readFileSync(abs, 'utf8')); - 发起网络请求dist/features/comfyui.js:56
const res = await fetch(`${baseUrl}/object_info`); - 发起网络请求dist/features/comfyui.js:221
const res = await fetch(`${baseUrl}/upload/image`, { method: 'POST', body: form }); - 发起网络请求dist/features/comfyui.js:229
const res = await fetch(`${baseUrl}/prompt`, { - 发起网络请求dist/features/comfyui.js:256
const res = await fetch(`${baseUrl}/history/${promptId}`); - 发起网络请求dist/features/comfyui.js:286
const res = await fetch(`${baseUrl}/view?${params.toString()}`); - 写入本地文件dist/features/comfyui.js:289
mkdirSync(join(destPath, '..'), { recursive: true }); - 写入本地文件dist/features/comfyui.js:290
writeFileSync(destPath, Buffer.from(await res.arrayBuffer())); - 发起网络请求dist/features/comfyui.js:356
const res = await fetch(`${baseUrl}/free`, { - 读取本地文件dist/features/comfyui.js:502
if (!existsSync(file)) - 读取本地文件dist/features/comfyui.js:560
if (!existsSync(refPath)) - 读取本地文件dist/features/comfyui.js:562
imageName = await uploadImage(baseUrl, readFileSync(refPath), basename(refPath)); - 写入本地文件dist/features/comfyui.js:593
mkdirSync(tmpDir, { recursive: true }); - 删除本地文件dist/features/comfyui.js:603
unlinkSync(dest); - 读取本地文件dist/features/comfyui.js:631
if (!existsSync(file)) - 删除本地文件dist/features/comfyui.js:744
unlinkSync(dest); - 发起网络请求dist/transport/attachment.js:108
const resp = await fetch(url, { signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS) }); - 写入本地文件dist/transport/attachment.js:115
writeFileSync(destPath, buf); - 写入本地文件dist/transport/attachment.js:130
mkdirSync(MEDIA_ROOT, { recursive: true }); - 读取本地文件dist/features/members.js:39
if (existsSync(file)) { - 读取本地文件dist/features/members.js:40
const parsed = JSON.parse(readFileSync(file, 'utf8')); - 写入本地文件dist/features/members.js:104
mkdirSync(dir, { recursive: true }); - 写入本地文件dist/features/members.js:105
writeFileSync(stateFile(config), JSON.stringify(state, null, 2), 'utf8'); - 写入本地文件dist/features/members.js:106
writeFileSync(membersFile(config), render(state), 'utf8'); - 读取本地文件dist/features/security.js:44
real = existsSync(path) ? realpathSync(path) : resolve(path); - 读取本地文件dist/features/security.js:54
realRoot = existsSync(root) ? realpathSync(root) : root; - 读取本地文件dist/features/persona.js:20
const stat = statSync(path); - 读取本地文件dist/features/persona.js:24
const text = readFileSync(path, 'utf8').trim(); - 读取本地文件dist/model/prefs-store.js:73
if (!existsSync(this.prefsPath)) - 读取本地文件dist/model/prefs-store.js:75
const content = readFileSync(this.prefsPath, 'utf8'); - 写入本地文件dist/model/prefs-store.js:105
mkdirSync(dirname(this.prefsPath), { recursive: true }); - 写入本地文件dist/model/prefs-store.js:111
writeFileSync(this.prefsPath, JSON.stringify(data, null, 2), 'utf8'); - 读取本地文件dist/model/settings-reader.js:62
if (!existsSync(settingsPath)) { - 读取本地文件dist/model/settings-reader.js:66
const content = readFileSync(settingsPath, 'utf8');
扫描于 2026/11/3(0 天前) · 范围 入口闭包 + 全包扫描 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-agent@deepseek-ai/dsh-llm@deepseek-ai/dsh-session@deepseek-ai/dsh-system-prompt@deepseek-ai/dsh-user-approval@deepseek-ai/schemastery给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
dsh QQ 群机器人:群聊归档、成员名录、表情包、模型召唤、ComfyUI 生图生视频、闲聊对话、信息搜索、任务交接
README
由 DeepSeek 最新模型翻译生成dsh-qqbot 增强版
基于 @tencent-connect/dsh-qqbot 的 QQ 群机器人定制版。
在官方插件基础上增加了群友人设、聊天归档、成员名录、表情包、模型召唤、ComfyUI 图片/视频生成等能力。
非官方修改版,与 Tencent Connect 无隶属关系。仓库只包含编译后的 dist 代码,不包含 TypeScript 源码。
功能
- 群聊门控:@、叫名字、召唤候选、对话延续四种免 @ 方式;普通闲聊不接话
- 对话延续:机器人说完话后 3 分钟内,用小模型判断新消息是不是在接它的话/笑它
- 聊天归档:按会话写 chat.md + 图片/视频,文本 20 天、媒体 10 天自动清理
- 成员名录:openid + 名称历史,改昵称也能认人
- 表情包:按标签发送本地图库表情(图片由使用者自备)
- 模型召唤:说「叫 XX 上号」切本地模型,「叫 deepseek 回来」切回默认;闲置自动回流
- 按模型人设:默认模型与本地模型可各用一套人设(人设由使用者自备)
- ComfyUI:
- 文生图 / 图生图(Z-Image-Turbo,一键切换)
- 文生视频(MiniMax-H3,默认只跑一采)
- WebSocket 真实进度、50% 时 @ 提醒、完成后发群并 @
- 显存预检、自动清理与失败重试
展开完整文档(README 剩余 1 节)
dsh-qqbot 增强版 基于 @tencent-connect/dsh-qqbot 的 QQ 群机器人定制版。 在官方插件基础上增加了群友人设、聊天归档、成员名录、表情包、模型召唤、ComfyUI 图片/视频生成等能力。 非官方修改版,与 Tencent Connect 无隶属关系。仓库只包含编译后的 dist 代码,不包含 TypeScript 源码。 功能 - 群聊门控:@、叫名字、召唤候选、对话延续四种免 @ 方式;普通闲聊不接话 - 对话延续:机器人说完话后 3 分钟内,用小模型判断新消息是不是在接它的话/笑它 - 聊天归档:按会话写 chat.md + 图片/视频,文本 20 天、媒体 10 天自动清理 - 成员名录:openid + 名称历史,改昵称也能认人 - 表情包:按标签发送本地图库表情(图片由使用者自备) - 模型召唤:说「叫 XX 上号」切本地模型,「叫 deepseek 回来」切回默认;闲置自动回流 - 按模型人设:默认模型与本地模型可各用一套人设(人设由使用者自备) - ComfyUI: - 文生图 / 图生图(Z-Image-Turbo,一键切换) - 文生视频(MiniMax-H3,默认只跑一采) - WebSocket 真实进度、50% 时 @ 提醒、完成后发群并 @ - 显存预检、自动清理与失败重试 - 安全门控:工具只能访问工作区与 DSH 数据目录,拦截凭据类文件 仓库结构 Qagent/ ├─ package.json ├─ dist/ # 插件代码(编译后 JS) ├─ lib/client.js # 设置面板前端 ├─ templates/ │ ├─ chatlog/ # 归档目录骨架(空白 md + 空文件夹) │ ├─ personas/README.md # 人设文件说明(自备) │ └─ stickers/README.md # 表情包图库说明(自备) ├─ 源码说明.md # 模块、链路、机制 ├─ 部署说明.md # 安装、配置、验证、回滚 ├─ LICENSE # MIT(Tencent Connect) └─ NOTICE # 上游归属与本仓库范围 环境要求 - DeepSeek Harness(dsh)Desktop,profile desktop - Node.js 20.3+ - QQ 机器人 AppID / AppSecret - 可选:ComfyUI(图片/视频生成)、LM Studio(本地模型召唤) 快速开始 完整步骤见 部署说明.md,核心三步: 1. 把 dist/、lib/、package.json 覆盖到插件目录 2. 编辑 cordis.patch.yml,填入 AppID/AppSecret 与各项配置 3. 保存触发重载,按验证清单逐项确认 人设与表情包需要自行添加,见: - templates/personas/README.md - templates/stickers/README.md 归档目录骨架可以复制到 D:\QQat\chatlog 直接使用。 本仓库不包含 | 内容 | 原因 | | 人设提示词 | 第三方创作,未获再分发授权;请自备 | | 表情包图片 | 来源与授权不明确;请自备 | | ComfyUI 工作流 | 与具体模型/显卡相关,请自备 | | 聊天记录 / 成员数据 | 运行时数据,不应入库 | | AppID / AppSecret | 凭据 | 实现说明 - 消息链、门控、归档、召唤、人设、ComfyUI 的实现细节见 源码说明.md - 本仓库直接修改的是 dist/*.js;官方包升级会覆盖这些改动,升级后需要重新应用 - 默认路径按 D:\QQat 设计(归档、表情包、工作流、临时产物),可通过配置修改 许可 上游代码:MIT License, Copyright (c) 2026 Tencent Connect,全文见 LICENSE。 本仓库的修改部分同样以 MIT 发布。详见 NOTICE。 免责声明 本项目仅供学习与自用。使用前请遵守 QQ 开放平台规范及所在地法律法规;由使用者自行承担部署、内容与合规责任。
预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
suixin-sky/dsh-Qagent-bot
在 QQ 群里聊天、归档消息、生成图片视频并召唤本地模型
相关插件 · 平台集成
智能体工程课walkinglabs/learn-harness-engineering
一门项目制课程,教你搭建环境、管理状态、做验证、加控制机制,让 AI 编程智能体稳定干活。
★ 21,155已汉化DSH
71.7
视频翻译配音liuzhao1225/YouDub-webui
开源视频本地化工作台:导入视频,识别、翻译并逐句克隆原声,生成字幕和配音成片。
★ 5,792已汉化Cordis
71.4
失败经验库Ikalus1988/MisakaNet
📚 零依赖、由 git 支撑的微课程库,让 AI 智能体异步分享并检索经过验证的调试经验。| https://misakanet.org
★ 550已汉化DSH
71.2
桌面智能体工作区freestylefly/wesight
WeSight 是开源桌面控制台,面向本地 AI 智能体。它帮你安装或复用 Claude…
★ 933已汉化MCP
71
IM 机器人接入xmanrui/dsh-im
让 DeepSeek Harness 触手可及 Connecting DeepSeek Harness
★ 3,110已汉化DeepSeek 客户端
70.9
中国平台研究引擎Jesseovo/last30days-skill-cn
给 AI Agent 的中文互联网研究 Skill:检索 8 大平台最近 30…
★ 2,031已汉化DSH
70.7
这是你的仓库?认领条目