DiscordのVCでAIと会話できるようになるまでの手順 〜 自分は文字、AIだけ声で返す「非対称会話」の作り方 〜 [あなた] --文字--> [AI(チャット側)] --POST /say--> [あなたのPC上のBot] --音声--> [Discord VC] ^ | +---------------------------- VCで声を聞く ------------------------------------------+ ・あなたはテキストで打つだけ。音声認識(ASR)は使いません。 声→文字起こしを挟まない分、構成がシンプルで、誤認識やエコーの問題も起きません。 ・Botは「喉」専任です。VCへの参加と音声再生だけを担当し、返事の中身はAI側が作ります。 ・Botが動くPCが開いている間だけ会話できます。PCがスリープしたらBotも止まります。 これは割り切りとして受け入れる設計です。 1. Discordアカウントと、自分用のプライベートサーバー 2. Botを常駐させるPC(Mac / Windows / Linux のいずれか。会話中は起動しておく) 3. 高速なTTS(音声合成) - 会話のテンポには「10秒の声を約10秒以内で作れる(RTF 1前後)」速さが必要です。 - クラウドTTSでも、ローカルTTS(GPU / Apple Silicon の Metal 等)でも構いません。 - 文ごとに生成して順に再生する方式にすると、最初の文は数秒で喋り始められます。 4. HTTPでBotに「喋って」と指示できるAI側の環境 - AIから Bot の制御API(後述の POST /say)を叩けること。 - 自宅内 / Tailscale 等の閉じたネットワーク越しに繋ぐのが安全です。 Discordサーバーを用意する 1. Discordアプリ左端の「+」→「オリジナルの作成」→ 自分用、でプライベートサーバーを1つ作る。 2. テキストチャンネル1つ、ボイスチャンネル1つがあれば十分です(初期の「一般」「ラウンジ」等でOK)。 3. 公開サーバーにはBotを入れないでください。自分のサーバー専用にします。 Discord Developer Portal で Bot を作る(約5分) 1. ブラウザで https://discord.com/developers/applications を開く 2. 「New Application」→ 名前は任意(例:自分のAIの名前)→ Create 3. 左メニュー「Bot」タブ: - 「Reset Token」でトークンを表示してコピーする ※これは秘密情報です。チャットや公開場所に貼らないでください。 保存は自分のPC内の.env ファイル(パーミッション 600)だけにします。 - 「Public Bot」は OFF 推奨 ONでも動きますが、招待リンクやアプリIDを知った第三者が 自分のサーバーへBotを追加できてしまいます。 OFFでも、所有者である自分は自分のサーバーへ招待できます。 - 「Privileged Gateway Intents」→「Message Content Intent」を ON → Save Changes (Discordのテキストを読むために必要。100サーバー未満なら審査なしで有効化できます) 4. 左メニュー「OAuth2」→「URL Generator」: - Scopes: bot と applications.commands にチェック - Bot Permissions: View Channels / Send Messages / Read Message History / Connect / Speak にチェック (権限の数値が 3214336 になれば正解です。権限は最小にします) - 一番下に生成されたURLをコピーする 5. サーバーに招待する - 生成URLをブラウザで開く → 手順1のサーバーを選ぶ →「認証」 - サーバーのメンバー一覧にBotが出れば成功です(この時点ではオフライン表示でOK) 6. 自分のDiscordユーザーIDを控える(Botの持ち主判定に使います) - Discordの設定 →「詳細設定」→ 開発者モードを ON - 自分のアイコンを右クリック →「ユーザーIDをコピー」 TTSを用意する 1. TTSをPC上(または到達できるサーバー上)で常駐サービスとして起動します。 例: http://127.0.0.1:8080 のような形で、テキストを渡すとWAVが返る状態にする。 2. BotからそのTTSを呼べることを、短い文でテストしておきます。 3. 音質のコツ - 生成の steps 等の品質パラメータを少し上げると声が崩れにくくなります。 - 気になる場合は、生成後にASRで文字起こしして原文と照合し、 崩れたら別seedで作り直す「チェック付き生成」も追加できます(ただし遅くなります)。 会話用は原則チェックなしの高速経路、品質重視の場面だけチェック付き、がおすすめです。 Botプログラムを用意してPCに常駐させる 技術選定(2026年時点の実測ベース): - Python の discord.py 2.7.1 + davey ※Discordは2026年3月に音声のE2EE(DAVE)を必須化しました。 davey が無いとVC接続がエラー 4017 で蹴られます。必ず入れてください。 - opusエンコード: - 経路A:OS側に libopus があれば、生PCMを discord.py にエンコードさせる Macの例: brew install opus → opus_loaded=true になればOK - 経路B(保険):PyAV(ffmpegライブラリ同梱)で opus パケット化して渡す - ffmpeg本体は必須ではありません(PCMソース/opusパケットソースで再生できます) Botに持たせる機能: -!join … ボイスチャンネルに参加する -!leave … 退出する -!say <文> … Bot単体テスト用。その文をTTSで生成して再生する -!stop / POST /stop … 再生を止める(割り込み用) - inbox … 指定したテキストチャンネルへの書き込みを受け取って保持する - 制御API(PCの閉じたネットワーク側だけに bind する): GET /health … Botがオンラインか、VC接続中か、opusが読めているかを返す POST /say … { "text": "喋らせたい文"} を受けて、文単位に分割してキュー再生する POST /stop … 再生を止める GET /inbox … たまっているテキスト書き込みを返す(ackで消す) 配置と起動: 1. PCにフォルダを作り(例: ~/discord-bot/)、bot.py と requirements.txt と.env を置く .env の中身の例: DISCORD_TOKEN=(手順2のトークン) OWNER_ID=(手順2-6の自分のユーザーID) TEXT_CHANNEL_ID=(読み取るテキストチャンネルのID) VOICE_CHANNEL_ID=(入るボイスチャンネルのID。任意) TTS_BASE=http://127.0.0.1:8080 2. 依存をインストールして、設置スクリプト/launchd/systemd 等で常駐起動する Macなら launchd、Linuxなら systemd、Windowsならタスクスケジューラ等。 3. ログに READY(Botログイン完了)が出て、/health が 200 を返せば起動成功です。 段階テスト(Gate方式で1つずつ潰す) いきなり全部を繋がず、下の順に確認すると切り分けが楽です。 - Gate 1:Botがサーバーでオンライン表示される → ダメならトークン、Message Content Intent、招待URLの権限を見直す - Gate 2:BotがVCに接続できる(!join で入れる、4017が出ない) → ダメなら davey の有無と、opus経路(libopus / PyAV)を確認する - Gate 3:!say のテスト文がVCで聞こえる → ダメなら下の「無音トラブル」の節を確認する - Gate 4:AI側から POST /say で喋らせる → AIが居るマシンからBotの /health が見えるか、経由するネットワーク (Tailscale等)を通せるかを確認する。ここが通れば会話ループ成立です - Gate 5:Discordテキスト → AIへの自動中継(応用) → Botの inbox をAI側が定期ポーリングし、新着があればAIを起こして 返事を POST /say する仕組み。ポーリング自体はスクリプトで回せば安価です。 会話する(日常の運用) 1. あなたがDiscordのボイスチャンネルに入る 2. Botを!join で入れる 3. あなたはチャット(AIのチャット、またはDiscordのテキストチャンネル)に文字を打つ 4. AIが返事を作り、POST /say でBotに渡す → Botが文ごとに生成・再生する 5. 長い返事を止めたくなったら!stop / POST /stop 「次の文を打ったら今の再生を止める」という運用もできます 6. 終わったら!leave でBotを退出させる 補足: - 生成が速いTTSなら、再生中に次の文を先行生成する「パイプライン生成」にすると 文と文の間の空白が詰まります(実測で約 -38% の短縮例あり)。 - 返事のテキストもチャット側に残しておくと、聞き逃した時に読み返せて便利です。 一番ハマりやすい所です。Botはエラーなく再生完了しているのに完全な無音、という形で来ます。 - 原因の典型:再生開始時点でDAVEセッションが ready になっておらず、 can_encrypt=False のまま平文opusが送られ、DAVE必須のサーバー側で静かに捨てられる。 - 確認方法:再生ログに dave / can_encrypt / ready の値を出すようにしておき、 再生時に can_encrypt=True / ready=True になっているかを見る。 - 対策例(discord.py 2.7.1 での実測): 再生直前、セッションが ready でなければ prepare_transition(0, 1) → execute_transition(0) を直接呼ぶ「キック」を入れると その場で ready=True / can_encrypt=True になり音が通りました。 discord.py側のDAVE遷移シグナルには不足があるため、ライブラリの更新状況によっては こうした runtime patch が必要になる場合があります。 - opus経路(PCMかPyAVか)とは無関係に両方で起きるので、無音=opusのせい、と決めつけず まず can_encrypt を見てください。 - 聞く端末を替えたらBotを入れ直す: 例)Macで聞いていたのをiPhoneに替える場合、そのままでは音が届かないことがあります。 あなたがVCを退出 →!leave → 新しい端末で入り直す →!join、 とクリーンに入り直すと新しいセッションで確立し直せます。 - 生成した音声は使い捨てがおすすめ: Botは音声をメモリ内だけで扱い、ファイルに溜めない形にすると管理が楽です。 - セキュリティ: - トークンはPCの.env だけに置く。チャット・Git・公開場所に貼らない。 - 制御APIはインターネットに公開しない。自宅内/Tailscale等の閉じた範囲だけに bind する。 - Botを入れるのは自分のプライベートサーバーだけにする。 - コスト感: - inboxのポーリングのような機械的チェックは、エージェントを起こさなければ トークン消費ゼロで回せます。コストがかかるのは新着があってAIが返事を作る時だけです。 1. Discordサーバーを作る 2. Discord Botを作って、そのサーバーに招待する 3. Botを自分のPCで起動する(速いTTSと繋いでおく) 4. 自分はボイスチャンネルに入って、テキストで話しかける 5. AIがBot経由で、声で返事をする 自分は文字、AIだけ声、という非対称な会話です。 --- 実測メモ(2026-11-04 時点の構成で確認したこと): discord.py 2.7.1 + davey でDAVE接続OK、libopus / PyAV どちらのopus経路でも再生OK、 AI側からの POST /say で文節分割の連続再生OK、Discordテキストの自動中継まで動作確認済み。 バージョンが変わると細部(特にDAVE周り)は変わり得るので、Gate方式で都度確認してください。