dwgx@blog:~$dwgx
> cd ../posts

YuKiKo:セルフホストの AI QQ ボット

// created

YuKiKo はセルフホストの AI QQ ボットで、チャット、曲のリクエスト、動画リンクの解析ができる。ベースは NoneBot2 + OneBot V11 で、QQ 側には NapCat を置き、リバース WS で接続してくる。

QQ プロトコルには一切触れず、そこは NapCat に任せて、YuKiKo は OneBot V11 しか相手にしない。NapCat はリバース WS で ws://<アドレス>:<ポート>/onebot/v11/ws に報告するよう設定し、両側の access token が一致すれば繋がる。プロトコル層とロジック層は完全に分離してあるので、NapCat が実装を変えようが、ある日落ちようが、こちら側は一行も変えない。

モデルは一社に縛らず、OpenAI、Claude、DeepSeek、Gemini、通义、Moonshot のどれでも繋げて、安くてオンラインなものを使う。手を掛けたのはルーティングで、メッセージが入ってきたらまず応答すべきかどうか、どのモデルで答えるかを判断し、信頼度の閾値で絞る。グループで適当な一言が飛ぶたびに高い推論が走らないようにするためだ。

Agent システムが核心で、数十個のツールを内蔵し、モデル自身が複数ステップの推論をしながらツールを連続で呼ぶ。一問一答ではない。音楽のリクエストが一番ハマりどころが多く、マルチプラットフォーム検索、VIP アンロック、アーティストの取り違え防止、どうしても見つからなければ B站 の音声にフォールバックする。動画解析は B站/抖音/快手/AcFun に対応し、ダウンロードしたついでに内容の分析までできる。

設定は三層に分けてある。.env にはポートやキーといった機微なものを置き、config/config.yml はボットの挙動とモデルのパラメータを管理し、プラグインはそれぞれ独自の yml を持つ。キーは暗号化して保存し、権限は三段階に分け、さらに self-check を入れてボットが自分の発言をユーザー入力と勘違いして延々と自答するのを防いでいる。この落とし穴の解消には長くかかった。

管理パネルは React で書いた。設定のオンラインホットリロード、ログのリアルタイム閲覧、データベースのインポート/エクスポート、そしてブラウザ内で直接ボットと会話してテストできる。プラグインはホットスワップ対応で、plugins/ に放り込んで独自の yml を用意すれば使え、パネルで視覚的に切り替えられる。NewAPI、Wayback、ConnectCLI がいくつか内蔵されている。デプロイには bootstrap スクリプトがあり、一コマンドで済む:

bash <(curl -fsSL https://raw.githubusercontent.com/dwgx/YuKiKo/main/bootstrap.sh)

システム依存、Python 仮想環境、WebUI ビルド、systemd 登録まで一気通貫で、入れ終わると yukiko CLI が手に入る。status/logs/doctor/backup/update といった運用コマンドはすべてこの中にあり、自分でも毎日叩いている。