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

QQ 机器人增强 lecheng2018/dsh-moyu

DeepSeek Harness
lecheng20182 天前有提交已提供中文文档扫描:含敏感能力

把 AI 助手接入 QQ 私聊群聊,并管理主动消息配额

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

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

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

状态速览

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

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

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

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件读取剪贴板或密钥环境变量发起外部网络请求
查看扫描证据(共 81 处,展示前 80 条)
  • 发起网络请求
    lib/client.js:209
    const res = await fetch(BIND_STATE_PATH, { cache: "no-store" });
  • 发起网络请求
    lib/client.js:261
    const res = await fetch(BIND_MANUAL_PATH, {
  • 发起网络请求
    lib/client.js:368
    fetch(BIND_UNBIND_PATH, { method: "POST" }).then(async (res) => {
  • 发起网络请求
    lib/client.js:418
    fetch(BIND_REFRESH_PATH, { method: "POST" }).catch(() => {});
  • 发起网络请求
    lib/client.js:740
    fetch(BIND_CONFIG_PATH, { cache: "no-store" }).then(async (res) => {
  • 发起网络请求
    lib/client.js:775
    fetch(BIND_CONFIG_PATH, {
  • 读取密钥环境变量
    lib/gateway/bootstrap.js:70
    tokenBaseUrl: process.env.QQBOT_TOKEN_BASE_URL?.replace(/ +$/, '') || 'https://api.bot.qq.com',
  • 读取本地文件
    lib/shared/utils.js:18
    const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
  • 读取本地文件
    lib/shared/utils.js:52
    const byPatch = findProfileAncestor(baseDir, (dir) => existsSync(resolve(dir, 'cordis.patch.yml')) ? dir : null);
  • 读取本地文件
    lib/shared/utils.js:55
    const byWorkspace = findProfileAncestor(baseDir, (dir) => existsSync(resolve(dir, 'pnpm-workspace.yaml')) ? dir : null);
  • 读取本地文件
    lib/shared/utils.js:77
    if (!existsSync(profilesRoot))
  • 读取本地文件
    lib/shared/utils.js:103
    entries = readdirSync(profilesRoot);
  • 读取密钥环境变量
    lib/setup/bind-routes.js:234
    delete process.env.QQBOT_SECRET;
  • 执行外部命令来自配置/变量
    lib/setup/presenters.js:74
    const child = spawn(command, args, { detached: true, stdio: 'ignore', windowsHide: true });
  • 写入本地文件
    lib/setup/persist.js:43
    mkdirSync(dir, { recursive: true });
  • 读取本地文件
    lib/setup/persist.js:46
    const before = existsSync(patchPath) ? readFileSync(patchPath, 'utf8') : '';
  • 读取本地文件
    lib/setup/persist.js:46
    const before = existsSync(patchPath) ? readFileSync(patchPath, 'utf8') : '';
  • 读取本地文件
    lib/setup/persist.js:55
    const current = existsSync(patchPath) ? readFileSync(patchPath, 'utf8') : '';
  • 读取本地文件
    lib/setup/persist.js:55
    const current = existsSync(patchPath) ? readFileSync(patchPath, 'utf8') : '';
  • 写入本地文件
    lib/setup/persist.js:65
    writeFileSync(tmpPath, next, 'utf8');
  • 写入本地文件
    lib/setup/persist.js:66
    renameSync(tmpPath, patchPath);
  • 删除本地文件
    lib/setup/persist.js:70
    unlinkSync(tmpPath);
  • 读取本地文件
    lib/setup/persist.js:77
    const writtenDoc = parseProfilePatch(readFileSync(patchPath, 'utf8'));
  • 写入本地文件
    lib/setup/persist.js:88
    writeFileSync(rollback, before, 'utf8');
  • 写入本地文件
    lib/setup/persist.js:89
    renameSync(rollback, patchPath);
  • 读取本地文件
    lib/features/meme-bridge.js:32
    if (!existsSync(file))
  • 读取本地文件
    lib/features/meme-bridge.js:35
    const parsed = JSON.parse(readFileSync(file, 'utf8'));
  • 读取本地文件
    lib/features/meme-bridge.js:56
    if (typeof dir === 'string' && dir.length > 0 && existsSync(dir) && !roots.includes(dir)) {
  • 写入本地文件
    lib/features/meme-bridge.js:90
    writeFileSync(dshExpressionFile(), JSON.stringify(patched, null, 2));
  • 读取本地文件
    lib/transport/proactive-budget.js:37
    if (!existsSync(this.file))
  • 读取本地文件
    lib/transport/proactive-budget.js:39
    const parsed = JSON.parse(readFileSync(this.file, 'utf8'));
  • 写入本地文件
    lib/transport/proactive-budget.js:56
    mkdirSync(dirname(this.file), { recursive: true });
  • 写入本地文件
    lib/transport/proactive-budget.js:57
    writeFileSync(this.file, JSON.stringify(this.state, null, 2));
  • 读取本地文件
    lib/transport/proactive-queue.js:32
    if (!existsSync(this.file))
  • 读取本地文件
    lib/transport/proactive-queue.js:34
    const parsed = JSON.parse(readFileSync(this.file, 'utf8'));
  • 写入本地文件
    lib/transport/proactive-queue.js:52
    mkdirSync(dirname(this.file), { recursive: true });
  • 写入本地文件
    lib/transport/proactive-queue.js:53
    writeFileSync(this.file, JSON.stringify(this.state, null, 2));
  • 读取本地文件
    lib/features/proactive-permission.js:29
    if (!existsSync(this.file))
  • 读取本地文件
    lib/features/proactive-permission.js:31
    const parsed = JSON.parse(readFileSync(this.file, 'utf8'));
  • 写入本地文件
    lib/features/proactive-permission.js:42
    mkdirSync(dirname(this.file), { recursive: true });
  • 写入本地文件
    lib/features/proactive-permission.js:43
    writeFileSync(this.file, JSON.stringify(this.state, null, 2));
  • 读取本地文件
    lib/features/closing.js:37
    if (!existsSync(this.file))
  • 读取本地文件
    lib/features/closing.js:39
    const parsed = JSON.parse(readFileSync(this.file, 'utf8'));
  • 写入本地文件
    lib/features/closing.js:57
    mkdirSync(dirname(this.file), { recursive: true });
  • 写入本地文件
    lib/features/closing.js:58
    writeFileSync(this.file, JSON.stringify(this.state, null, 2));
  • 读取本地文件
    lib/features/awake.js:122
    if (!existsSync(this.deps.storePath))
  • 读取本地文件
    lib/features/awake.js:124
    const parsed = JSON.parse(readFileSync(this.deps.storePath, 'utf8'));
  • 写入本地文件
    lib/features/awake.js:142
    mkdirSync(dirname(this.deps.storePath), { recursive: true });
  • 写入本地文件
    lib/features/awake.js:143
    writeFileSync(this.deps.storePath, JSON.stringify(this.state, null, 2));
  • 读取本地文件
    lib/media/media-cleaner.js:24
    if (!existsSync(MEDIA_ROOT))
  • 读取本地文件
    lib/media/media-cleaner.js:28
    const entries = await readdir(MEDIA_ROOT, { withFileTypes: true });
  • 读取本地文件
    lib/media/media-cleaner.js:33
    const info = await stat(filePath);
  • 删除本地文件
    lib/media/media-cleaner.js:36
    await rm(filePath, { force: true });
  • 发起网络请求
    lib/media/vision-tool.js:48
    const resp = await fetch(image, { signal, redirect: 'error' });
  • 读取本地文件
    lib/media/vision-tool.js:57
    const info = await stat(image).catch(() => null);
  • 读取本地文件
    lib/media/vision-tool.js:62
    data = new Uint8Array(await readFile(image));
  • 读取本地文件
    lib/media/vision-tool.js:150
    if (!existsSync(settingsPath))
  • 读取本地文件
    lib/media/vision-tool.js:153
    const before = readFileSync(settingsPath, 'utf8');
  • 读取本地文件
    lib/media/vision-tool.js:197
    if (readFileSync(settingsPath, 'utf8') !== before) {
  • 写入本地文件
    lib/media/vision-tool.js:204
    writeFileSync(tmpPath, next, 'utf8');
  • 写入本地文件
    lib/media/vision-tool.js:205
    renameSync(tmpPath, settingsPath);
  • 删除本地文件
    lib/media/vision-tool.js:209
    unlinkSync(tmpPath);
  • 读取本地文件
    lib/media/send-file-tool.js:97
    if (!existsSync(absPath)) {
  • 发起网络请求
    lib/transport/attachment.js:144
    const resp = await fetch(url, { signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS) });
  • 写入本地文件
    lib/transport/attachment.js:165
    mkdirSync(MEDIA_ROOT, { recursive: true });
  • 写入本地文件
    lib/transport/attachment.js:185
    writeFileSync(localPath, buf);
  • 写入本地文件
    lib/session/session-manager.js:612
    mkdirSync(dir, { recursive: true });
  • 读取本地文件
    lib/media/send-media.js:74
    const info = await stat(filePath);
  • 读取本地文件
    lib/model/prefs-store.js:92
    if (!existsSync(this.prefsPath))
  • 读取本地文件
    lib/model/prefs-store.js:94
    const content = readFileSync(this.prefsPath, 'utf8');
  • 读取本地文件
    lib/model/prefs-store.js:134
    if (!existsSync(this.prefsPath))
  • 读取本地文件
    lib/model/prefs-store.js:138
    raw = readFileSync(this.prefsPath, 'utf8');
  • 写入本地文件
    lib/model/prefs-store.js:162
    writeFileSync(backupPath, raw, 'utf8');
  • 写入本地文件
    lib/model/prefs-store.js:190
    mkdirSync(dirname(this.prefsPath), { recursive: true });
  • 写入本地文件
    lib/model/prefs-store.js:197
    writeFileSync(tmpPath, JSON.stringify(data, null, 2), 'utf8');
  • 写入本地文件
    lib/model/prefs-store.js:198
    renameSync(tmpPath, this.prefsPath);
  • 删除本地文件
    lib/model/prefs-store.js:202
    unlinkSync(tmpPath);
  • 读取本地文件
    lib/model/settings-reader.js:62
    if (!existsSync(settingsPath)) {
  • 读取本地文件
    lib/model/settings-reader.js:66
    const content = readFileSync(settingsPath, 'utf8');
  • 读取本地文件
    nas-memediag2.js:2
    const lines=fs.readFileSync('/tmp/qq-verify.jsonl','utf8').split('\n').filter(Boolean);
扫描于 2026/11/3(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 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
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

deepseek-harness 的 QQ 机器人 IM 频道插件——官方 dsh-qqbot 定制分支:字母问答卡、dsh-meme 零配置桥、主动消息配额加暂存箱、健康面板

README

由 DeepSeek 最新模型翻译生成
[!NOTE] 这是 dsh-moyu —— 腾讯官方 @tencent-connect/dsh-qqbot 的定制 fork(MIT)。 在官方版基础上的增强(自 0.5.5-moyu.1 起,原 zhoukai.1-11 全部功能延续): 1. 提问卡片增强 —— 选项带 A./B./C. 字母前缀(按钮+正文一致),回复字母或编号都认(全角字母、「选 1 3」、A,C 多选、混合标记均支持),多问时显示(第 N/M 问)进度; 2. dsh-meme 零配置对接 —— 自动探测表情包图库目录并放行 qqbot_send_file 路径白名单,自动为 dsh-meme 补「QQ 发图尺寸 300px」默认值(只补缺失键,从不覆盖用户配置); 3. 主动消息每日配额 —— 官方协议主动推送额度有限,新增客户端预算闸门(全局/单目标两个维度、跨进程持久化、每日 0 点重置),配额用尽自动拦截并计数,/bot-quota 随时查余额,剩余额度注入 system prompt 让模型自己掂量。 基于 deepseek-harness (dsh) 的 QQ Bot 插件,将 DeepSeek AI 助手接入 QQ 私聊与群聊。
展开完整文档(README 剩余 1 节)
[!NOTE]
这是 dsh-moyu —— 腾讯官方 @tencent-connect/dsh-qqbot 的定制 fork(MIT)。
在官方版基础上的增强(自 0.5.5-moyu.1 起,原 zhoukai.1-11 全部功能延续):
1. 提问卡片增强 —— 选项带 A./B./C. 字母前缀(按钮+正文一致),回复字母或编号都认(全角字母、「选 1 3」、A,C 多选、混合标记均支持),多问时显示(第 N/M 问)进度;
2. dsh-meme 零配置对接 —— 自动探测表情包图库目录并放行 qqbot_send_file 路径白名单,自动为 dsh-meme 补「QQ 发图尺寸 300px」默认值(只补缺失键,从不覆盖用户配置);
3. 主动消息每日配额 —— 官方协议主动推送额度有限,新增客户端预算闸门(全局/单目标两个维度、跨进程持久化、每日 0 点重置),配额用尽自动拦截并计数,/bot-quota 随时查余额,剩余额度注入 system prompt 让模型自己掂量。

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

扫码加入 QQ 群 / 频道

QQ 开发者交流群1群: 1032635674 · 2群: 1056948758 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 → 安装并立即启动

2. 连接:左下角头像 → 设置 →「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

配置项

| 配置 | 类型 | 默认值 | 说明 |
| appId | string | 必填 | QQ Bot AppID(或通过 QQBOT_APPID 环境变量) |
| appSecret | string | 必填 | QQ Bot AppSecret(或通过 QQBOT_SECRET 环境变量) |
| provider | string | deepseek-official | LLM 服务商名称 |
| model | string | deepseek-chat | 模型名称 |
| preset | string | - | 智能体 preset id |
| cwd | string | process.cwd() | 智能体工作目录 |
| requireMention | boolean | true | 群聊是否需要 @bot 才触发 |
| groupPrompt | string | - | 群聊额外 system prompt |
| directPrompt | string | - | 私聊额外 system prompt |
| textChunkLimit | number | 4500 | 单条消息最大字符数 |
| streaming | boolean | true | 是否启用流式输出(群聊始终不启用) |
| sessionIdleTimeout | number | 1800000 | 会话闲置超时(ms),默认 30 分钟 |
| processingTimeoutMs | number | 1800000 | 处理超时(ms),超时中断当前 LLM 调用 |
| maxQueue | number | 20 | 并发队列最大长度 |
| historyLimit | number | 10 | 群历史缓冲条数 |
| askTimeoutMs | number | 300000 | 待答问题超时(ms),默认 5 分钟(ask_user_question) |
| showToolResults | boolean | false | 是否展示工具调用成功结果(错误始终展示) |
| debug | boolean | false | 调试模式 |

访问控制(access)

| 配置 | 类型 | 默认值 | 说明 |
| access.c2cMode | open/allowlist/disabled | open | 私聊访问模式 |
| access.c2cAllow | string[] | [] | 私聊白名单(user openid) |
| access.groupMode | open/allowlist/disabled | open | 群聊访问模式 |
| access.groupAllow | string[] | [] | 群聊白名单(group openid) |

富媒体理解(media)

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

视觉理解(vision)

| 配置 | 类型 | 默认值 | 说明 |
| vision.enabled | boolean | false | 是否启用视觉理解(qqbot_describe_image 工具) |
| vision.provider | string | - | 视觉模型服务商(如 pi-ai) |
| vision.model | string | - | 视觉模型 id(如 qwen-vl-max) |
| vision.maxBytes | number | 10MB | 图片字节上限 |
| vision.maxTokens | number | 1024 | 输出 token 上限 |
| vision.timeoutMs | number | 120000 | 视觉调用超时(ms) |

附件发送(sendFile)

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

内置命令

| 命令 | 说明 |
| /new(别名 /reset /clear) | 开始新会话(清空上下文) |
| /compact | 压缩会话历史(摘要替换旧记录,保留上下文) |
| /model | 查看或切换模型 |
| /preset | 查看或切换智能体 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 沿用。

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

设计原则

- 纯 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,关键操作通过「允许/拒绝」按钮请求用户确认

本地开发

bash
安装依赖
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
许可证

MIT
预览分享卡片长什么样 ↓lecheng2018/dsh-moyu
分享 · DeepSeek Harness Hub
lecheng2018/dsh-moyu

把 AI 助手接入 QQ 私聊群聊,并管理主动消息配额

这是你的仓库?认领条目

回到顶部