Star 历史趋势
数据来源: GitHub API · 生成自 Stargazers.cn
README.md
QQ Bot

基于 deepseek-harness (dsh) 的 QQ Bot 插件,将 DeepSeek AI 助手接入 QQ 私聊与群聊。

npm version License GitHub stars QQ Bot


English | 简体中文

扫码加入 QQ 群 / 频道

QQ 群二维码
QQ 开发者交流群
1群: 1032635674 · 2群: 1056948758
QQ 频道二维码
QQ 开发者社区频道
频道号: 20dnumts4z

架构

QQ 用户 → QQ WebSocket → dsh-qqbot → ctx.agents → dsh agent loop → LLM
                                 ↑                           │
                                 └── session/event ──────────┘
                                       (assistant reply → QQ sendMarkdown)

安装

方式一:桌面版安装(推荐)

无需命令行,全程在应用内完成:

  1. 安装:左侧栏点击「插件」→「添加插件」→ 输入 @tencent-connect/dsh-qqbot@latest → 安装并立即启动
端内添加插件
  1. 连接:左下角头像 → 设置 →「QQ 机器人」→ 手机 QQ 扫码连接
设置页扫码连接

扫码成功后凭据自动保存,后续启动无需再次扫码。

方式二:手动执行

# 安装到 profile
npx @deepseek-ai/dsh plugin --profile qqbot add @tencent-connect/dsh-qqbot

# 启动
npx @deepseek-ai/dsh --profile qqbot

首次启动时,插件检测到凭据未配置会自动进入扫码引导:终端输出二维码 → 手机 QQ 扫码绑定 → 凭据自动保存到 profile,后续启动无需再次扫码。

无端内绑定页的环境(如纯 CLI)可设置 QQBOT_BIND_OPEN_BROWSER=1,额外拉起系统浏览器扫码页作为降级通道。

二维码扫码示意图

提示:建议升级至 0.4.0 以上版本扫码,支持点击链接在浏览器打开,避免部分终端二维码渲染错位的问题。

方式三:本地路径安装

# 构建
cd /path/to/dsh-qqbot
pnpm install && pnpm build

# 安装到 profile(本地路径)
npx @deepseek-ai/dsh plugin --profile qqbot add /path/to/dsh-qqbot

# 启动
export QQBOT_APPID="你的AppID" QQBOT_SECRET="你的AppSecret"
npx @deepseek-ai/dsh --profile qqbot

方式四:--patch 开发模式

export QQBOT_APPID="你的AppID" QQBOT_SECRET="你的AppSecret"
npx @deepseek-ai/dsh web --patch /path/to/dsh-qqbot/cordis.dev.yml

配置项

配置类型默认值说明
appIdstring必填QQ Bot AppID(或通过 QQBOT_APPID 环境变量)
appSecretstring必填QQ Bot AppSecret(或通过 QQBOT_SECRET 环境变量)
providerstringdeepseek-officialLLM 提供商名称
modelstringdeepseek-chat模型名称
presetstring-Agent preset id
cwdstringprocess.cwd()Agent 工作目录
requireMentionbooleantrue群聊是否需要 @bot 才触发
groupPromptstring-群聊额外 system prompt
directPromptstring-私聊额外 system prompt
textChunkLimitnumber4500单条消息最大字符数
streamingbooleantrue是否启用流式输出(群聊始终不启用)
sessionIdleTimeoutnumber1800000会话闲置超时(ms),默认 30 分钟;<=0 表示不回收
processingTimeoutMsnumber1800000处理超时(ms),超时中断当前 LLM 调用
maxQueuenumber20并发队列最大长度
historyLimitnumber10群历史缓冲条数
askTimeoutMsnumber300000待答问题超时(ms),默认 5 分钟(ask_user_question)
showToolResultsbooleanfalse是否展示工具调用成功结果(错误始终展示)
debugbooleanfalse调试模式

访问控制(access)

配置类型默认值说明
access.c2cModeopen/allowlist/disabledopen私聊访问模式
access.c2cAllowstring[][]私聊白名单(user openid)
access.groupModeopen/allowlist/disabledopen群聊访问模式
access.groupAllowstring[][]群聊白名单(group openid)
access.commandModeopen/allowlist/disabledopenQQ 斜杠命令模式,白名单按发送者 OpenID 独立校验

QQ 斜杠命令与群聊、私聊共用“所有人/白名单/关闭”模式:先按接入规则进入对话,再按发送者身份校验命令;审批和提问按钮沿用各自鉴权。命令白名单保存在独立的身份文件中,切换模式不影响名单。

三类名单(私聊、群、命令)均支持三种添加方式:配对码、手动按 OpenID 批量添加、导出/复制。注意 OpenID 不是 QQ 号或群号;拿不到 OpenID 时用配对码添加。

  • 配对码:在账号设置中生成,让用户在对应对话里直接发给机器人即可加入名单。同一码可连续添加多人,错误场景(群码发到私聊等)不影响其有效性。
  • 撤销语义:移除身份后,移除前生成的同类配对码不能将其重新加回,重新授权需生成新码;其余人仍可继续认领。

配置接口的 GET 返回 config.accessRevision,更新 access 时应一并提交该值;名单或模式已变化时返回 409,不覆盖现有授权。

主动推送(proactiveDelivery)

QQ 入站触发的回合始终被动回复;定时任务等服务回合始终主动推送到 QQ。下表只控制「非 QQ 输入(如桌面续聊 QQ 会话)」的回合:

配置类型默认值说明
proactiveDelivery.externalTurnsoff/c2c/allc2coff 不推送;c2c 仅推送私聊;all 私聊和群聊都推送

富媒体理解(media)

配置类型默认值说明
media.enabledbooleantrue是否启用富媒体理解(图片/视频下载 + 工具分析)
media.maxMBnumber200富媒体下载大小上限(MB)
media.ttlHoursnumber24富媒体存活时长(小时),0=永不过期

视觉理解(vision)

配置类型默认值说明
vision.enabledbooleanfalse是否启用视觉理解(qqbot_describe_image 工具)
vision.providerstring-视觉模型 provider(如 pi-ai)
vision.modelstring-视觉模型 id(如 qwen-vl-max)
vision.maxBytesnumber10MB图片字节上限
vision.maxTokensnumber1024输出 token 上限
vision.timeoutMsnumber120000视觉调用超时(ms)

附件发送(sendFile)

配置类型默认值说明
sendFile.restrictPathsbooleantrue是否启用路径白名单(仅 media + cwd + extraRoots)
sendFile.extraRootsstring[][]额外允许访问的根目录

内置命令

命令说明
/new(别名 /reset /clear)开始新会话(清空上下文)
/compact压缩会话历史(摘要替换旧记录,保留上下文)
/model查看或切换模型
/preset查看或切换 agent preset(新会话生效)
/stop中止当前生成
/bot-ping网络延迟检测(返回传输与处理耗时)
/bot-version查看版本信息
/bot-status查看当前会话状态
/bot-help查看所有指令

核心模块

src/
├── index.ts                    # Cordis 插件入口(async apply)
├── config.ts                   # 配置 Schema
├── types.ts                    # 全局类型定义
├── setup/                      # 凭据绑定(扫码)
│   ├── index.ts                # 绑定编排(ensureCredentials)
│   ├── binding-service.ts      # 扫码状态机(宿主内唯一事实源)
│   ├── bind-routes.ts          # 端内绑定页路由(/qqbot/im-qqbot/bind)
│   ├── presenters.ts           # 呈现策略(终端/浏览器降级)
│   ├── qr-svg.ts               # 二维码 SVG 渲染(宿主侧)
│   └── persist.ts              # 凭据写入 cordis.patch.yml
├── client/                     # 浏览器半边(dsh.client Web Bundle)
│   ├── index.ts                # 侧栏 Tab 注册 + 待绑定自动引导
│   └── bind-page.ts             # 端内绑定页(二维码 + 状态轮询)
├── gateway/                    # 网关装配
│   ├── bootstrap.ts            # 启动装配(监听 session/event 等)
│   └── middleware-setup.ts     # 中间件链配置
├── transport/                  # 传输层
│   ├── inbound.ts              # QQ 入站消息 → agent.followup()
│   ├── outbound.ts             # session/event → QQ sendMarkdown
│   ├── outbound-buffer.ts      # 流式缓冲
│   ├── streaming-writer.ts     # 流式写入
│   ├── reply-target.ts         # 回复目标解析
│   ├── msgid-cache.ts          # 被动回复 msgid 缓存
│   ├── reply-limiter.ts        # 被动回复限流
│   ├── tool-presenter.ts       # 工具调用展示
│   └── chunker.ts              # Markdown 文本切分
├── session/                    # 会话管理层
│   ├── session-manager.ts      # QQ peer → Agent 映射
│   └── idle-evictor.ts         # 闲置回收
├── model/                      # 模型路由层
│   ├── model-resolver.ts       # 路由解析
│   ├── prefs-store.ts          # per-peer 偏好持久化
│   └── settings-reader.ts      # settings.yaml 只读
├── features/                   # 交互特性
│   ├── question-channel.ts     # ask_user_question 问答通道
│   ├── approval-channel.ts     # approval 审批确认通道
│   └── answer-parser.ts        # 答案解析
├── media/                      # 多媒体
│   ├── vision-tool.ts          # 图片视觉理解
│   ├── send-file-tool.ts       # 发送本地文件
│   └── media-cleaner.ts        # 媒体 TTL 清理
├── middleware/                 # 中间件
│   ├── question-answer.ts      # 问答答案处理
│   └── attachment.ts           # 附件处理
├── shared/                     # 共享工具
│   ├── utils.ts                # 通用函数
│   ├── scope.ts                # scope/peer 提取
│   └── send-helper.ts          # 分块发送
└── commands/                   # 斜杠命令

会话路由

sessionKey: qqbot:${appId}:${scope}:${peerId},新会话铸造 UUID 会话 id 并持久化到 model-prefs.json,重启后按持久化 id 恢复;0.5.x 老会话按原派生 id 沿用。

解析策略:进程内复用 → 持久化恢复 → 全新创建。

QQ 群聊和私聊的补充提示词按当前 Agent 作用域加载,恢复会话时继续使用对应场景的配置。

设计原则

  • 纯 Cordis 插件 — 遵循 dsh "Plugins, not loop changes" 原则
  • 声明式依赖 — inject = ['agents'],不直接耦合其他插件
  • 会话隔离 — 每个 QQ 私聊用户/群聊各一个独立 Agent
  • Preset 支持 — 可通过 agent-presets 服务挂载预设(工具集、prompt 等)
  • 闲置回收 — 超时自动 dispose Agent,防止内存泄漏(回收后仍可按会话映射主动推送)
  • Markdown 输出 — 回复以 Markdown 格式发送,支持代码块/表格感知切分
  • 图片理解 — 支持 qqbot_describe_image 视觉理解,可分析用户发送的图片
  • 附件发送 — 支持 qqbot_send_file 将本地文件发送给用户(默认启用路径白名单)
  • 问答互动 — 支持 ask_user_question,单选生成内联按钮(点一个其余变灰)、多选回复编号,逐题推进 + 问题级超时
  • 操作确认 — 支持 approval/request,关键操作通过「允许/拒绝」按钮请求用户确认

本地开发

# 安装依赖
pnpm install

# 构建
pnpm build

# 开发模式(watch)
pnpm dev

# 用 --patch 方式调试
export QQBOT_APPID="xxx" QQBOT_SECRET="xxx"
npx @deepseek-ai/dsh web --patch /path/to/dsh-qqbot/cordis.dev.yml

License

MIT

关于 About

让 QQ Bot 接入 DeepSeek Harness(dsh)的官方插件
dshdsh-pluginqqbot

语言 Languages

TypeScript99.5%
Shell0.4%
JavaScript0.1%

提交活跃度 Commit Activity

代码提交热力图
过去 52 周的开发活跃度
81
Total Commits
峰值: 27次/周
Less
More

核心贡献者 Contributors