前言¶
在 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 變成「全接」或「全死」。目錄與文檔: