dsh-air-sense:QQ 群 AI 的「读空气」闸门

前言

在 QQ 群里挂 AI,常见痛点不是模型不会答,而是每句都接:随口吐槽被分析、@ 别人时它插嘴、深夜它比谁都精神。DSH(DeepSeek Harness)侧已有对话与工具链,但「要不要开口」往往仍由 AstrBot 原逻辑或全量转发决定,token 和群氛围都扛不住。

dsh-air-sense 是维护者 yingchaoyi 发布的 DSH 工作流类插件:在 AstrBot 群消息进入正常回复流程之前,先问 DSH 一次——这条消息现在值不值得接;不值得则客户端侧直接停事件,群里看不到任何回复,也不消耗回复 token。判断失败或插件不可用时会退回 AstrBot 原逻辑,避免把群聊憋死。

这是什么

  • 名称:dsh-air-sense(读空气)
  • 分类:工作流(社区目录 SkillHub 插件页)
  • 源码:github.com/yingchaoyi/dsh-air-sense(MIT,package 版本 0.1.16,需 Node.js >= 22)
  • 定位:DSH 插件 + AstrBot astrbot_plugin_dsh 配合使用;群消息流先 POST 到 DSH 的 /api/air-sense/decide,通过才走原回复流程,并在正文前按配置插入时间戳。

社区插件目录为独立站点,与 DeepSeek / 幻方无官方从属关系;安装前请自行审阅源码与许可证。插件在 当前 DSH 进程权限 下运行,数据与 token 落在本机 ~/.dsh/air-sense/。

核心功能

消息漏斗:接不接,再接回什么

判断目标不是「回什么」,而是要不要开口。README 描述的闸门顺序大致为:

总开关 → 群黑/白名单 → 发送者黑名单 → 闭麦 → 指令前缀 → 戳一戳 → 关键词 → 静默时段 → @ 机器人(硬过)→ @ 别人(硬拦)→ 刷屏氛围 → 活跃度 → 每日/每小时额度 → 同人冷却 → 概率(基础 × 回复加成 × 注意力 × 戳戳增值 × 表情衰减 × 密度衰减 × 自适应分数)→ 掷骰子 → 可选:判断模型只答 yes/no。

任一步不过即「不接」。面板里关闭「AI 判断 → 启用 AI 判断」后,不再调判断模型;掷骰子或关键词过了可直接开口,日志记为 judgeOff。

与 AstrBot 的协作方式

QQ ── AstrBot(dsh 插件 + 补丁) ──POST /api/air-sense/decide──> DSH(dsh-air-sense)
                                      │
                          不接 ────────┴──────── 接:走原来的回复流程,正文前插时间戳
                            │
                            └─ stop_event(),群里什么都看不到

AstrBot 侧需在 astrbot_plugin_dsh/main.py 中拼请求体(含 groupId、senderId、text、atBot、recent 等)、读 ~/.dsh/air-sense/token、默认请求 http://127.0.0.1:3080(超时 20 秒)。非 200、异常或 ok=false 时 _air_decide 返回 None,自动退回原逻辑。

出口清理与发图等补丁单独维护在 dsh-astrbot-patches;patch_astrbot_export.py 已包含 DSML 清理,打补丁后需重载 AstrBot 插件。

Web 面板与数据

设置 → 读空气,四个 tab:概览(统计、每群分数与闭麦、总开关)、规则(九组折叠共 49 项说明)、日志(未接理由可搜)、设置(时间戳格式、并发、数据目录等)。右上角总开关关闭后插件完全不插手。

数据目录 ~/.dsh/air-sense/:store.json(设置与日志等)、token(0600)、air-sense.log(超 512KB 自动截断)。整目录拷贝即可备份或迁移。

图片参与判断

AstrBot 可将消息内图片本地路径(images,最多两张)一并传入;DSH 对图片内容 sha256 缓存,未命中时用模型生成一句描述写入判断提示词,同图不再重复调用;模型不支持时记 unsupported,不反复试(描述超时 8 秒,失败当无图)。

设计上的硬规矩

插件不注册任何工具(避免 schema 投影导致会话 400);apply 内异常只写日志不抛出;判定失败按「不接」处理,而非默认接所有人。

安装与启用

这是 DSH profile 内安装的 bundle,不是凭仓库名拼接的 dsh plugin add。官方 README 步骤如下。

先把插件目录拷进 profile(在仓库根目录执行):

# 1) 拷进 profile
cp -R . ~/.dsh/profiles/web/node_modules/dsh-air-sense

# 2) 让 profile 认识它(bundles 管加载,dependencies 管插件页显示)
python3 - <<'PY'
import json, os
p = os.path.expanduser('~/.dsh/profiles/web/package.json')
d = json.load(open(p))
d.setdefault('dependencies', {})['dsh-air-sense'] = 'file:' + os.getcwd()
b = d.setdefault('dsh', {}).setdefault('profile', {}).setdefault('bundles', [])
if 'dsh-air-sense' not in b:
    b.append('dsh-air-sense')
json.dump(d, open(p, 'w'), ensure_ascii=False, indent=2)
PY

# 3) 重启 dsh web(新 bundle 不会热加载)

AstrBot 侧按 README 修改 astrbot_plugin_dsh/main.py 四处(_air_body / _air_base / _air_token、_air_decide、on_message 开头、_forward 时间戳),并视需要运行 patches 仓库中的脚本,例如:

git clone https://github.com/yingchaoyi/dsh-astrbot-patches
python3 dsh-astrbot-patches/patch_astrbot_export.py ~/data/plugins/astrbot_plugin_dsh/main.py

改完重载 AstrBot 插件;DSH web 重启后才能在面板看到「读空气」。

典型用法与参数直觉

日常主要在 DSH Web 读空气面板调规则:例如初始读空气概率默认 0.02(约 50 条普通消息看 1 条)、回复后概率 0.2 且提升持续 120s、每日/每小时上限 80/10、自适应分数与饥饿加成等。静默时段默认 23:30–07:30 但默认关闭;判定超时 15s,超时按不接处理。

开发者在插件仓库可跑自测:

node test/smoke.mjs          # 40 项:假 ctx 假 req/res,跑完整漏斗与 HTTP
node test/client-smoke.mjs   # 14 项:假 React 把四个 tab 真渲染一遍
npm test                     # 两个一起跑

适用场景与注意

适合:已在 QQ 群通过 AstrBot + DSH 跑 AI,希望用可开关、可日志追溯的规则控制接话频率,并可选地用轻量 yes/no 模型做最后一道闸。

注意:

  • 必须同时维护 DSH 插件与 AstrBot 侧改动(及可选 patches);只装一半不会形成完整链路。
  • 群昵称由 AstrBot 拼进时间戳发送者格式,DSH 侧拿不到原始群名片。
  • 已知限制见 README:单条最多两张图描述、描述计入判断耗时等。
  • 安装与运行前请检查源码;插件不以沙箱隔离,token 与 store.json 含群聊相关数据,权限与备份需自行规划。

结尾

dsh-air-sense 把「读空气」做成 DSH 内可配置的工作流:先决定接不接,再接才走原有对话;故障时退回 AstrBot,避免 silent failure 变成「全接」或「全死」。目录与文档:

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye