【ChatGPT】完全自律でYouTubeライブ配信できる「AI-Vtuber」作った #1【Python】

ChatGPTが面白すぎていろいろ使っている間にちょっとずつできてきました。
とりあえず仮称は「AI-VTuber配信システム」としています。


# 「AI-VTuber配信システム」ってどんなの？
こんなのです。
YouTubeの生配信などでChatGPTが勝手にしゃべって視聴者さんと雑談します。
中の人はいません。完全に自律して動作するAIの「バーチャル・バーチャル・ユーチューバー」です。
ちなみに、AI-Vtuberの名前はオモやんと言います。


<iframe width="560" height="315" src="https://www.youtube.com/embed/PPRosDwzoSE" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>


# 「AI-VTuber配信システム」のざっくり構成
- コア部分はマルチスレッドのPython製
  - ペルソナエンジン
    - APIでChatGPTの会話データを非同期に取得。
    - プリセットしたペルソナに切り替え可能。
    - 音声再生している裏で次の会話を取りに行くので会話が途切れない。 
  - 会話のディレクションエンジン
    - チャットデータの読み取り。
    - チャットのキューが貯まったら適度にフィルタして会話が詰まらないようにする。
    - 話題が無い場合にこっそり話題を振ったり、時間が来たら締めの発言をするように指示する。
      （AI-Vtuberにカンペを出すディレクター役。これも自動で動作させてます）
    - Open AIのモデレーションAPIを使ったフィルタリングや会話の制御を非同期で実施。
  - 音声入力エンジン
    - Speech-to-Textでのマイク音声入力
      Vtuberモデルには関係ないけど、マイク入力から声を拾って私の話し相手になってくれます。これだけでも楽しい。
  - 音声出力エンジン
    - 音声再生はCeVIO AIを使用。
    - win32com.clientを使って会話のテキストをCeVIO AIに発声させる。
    - 感情パラメータによって音声のプリセットを変更する。
  - OBSコントロールエンジン
    - WebsocketsでOBSと通信。字幕データ（発話テキスト）の送信やチャット履歴の受信を行いチャットキューに投げる。
  - GUI
    - 初めはtkinterで画像表示してたけど、配信システムでは不要なので開発保留。
- GPT-3.5-turbo API
  - メタプロンプト
    - 不特定多数のリクエストに対応できるロールプレイの制約
      - ペルソナの変更などのようなAIの基本動作に影響を及ぼす指示はUserからは受け取らない。 
    - キャラクター設定のほか、「感情」をパラメータ化した情報を返信メッセージ内に含めさせることでAI-Vtuberのビジュアルおよび音声再生での感情表現に利用可能。
- CeVIO AI（[https://cevio.jp/](https://cevio.jp/)）
  - 音声合成ボイスの再生に利用。
- Puppet3 （[https://github.com/leobtype/Puppet3/](https://github.com/leobtype/Puppet3/)）
  - キャラクターのまばたき、口パクに利用。
  - CeVIO AIの発声にリップシンク。
- OBS
  - 動画録画、ライブ配信ソフト
  - 背景画像やキャラクターの合成、BGM再生、オーディオビジュアライザなどがまとめて管理できる。
  - Python側とWebsockでつないで配信状況やチャットログなどをやり取り。
- オモやんの画像
  - Stable Diffusion Anythingモデルで生成。[かわいい](https://ai-ni.jp/2-756566420-scale6-00-k_euler_a-anything-v3-full_ckp/)。

# 「AI-VTuber配信システム」のここが面白い
## ChatGPTが永遠に話し続ける
テキストベースでのチャットサービスの場合、ユーザーとのやり取りは「テキスト入力」→「データ送信」→「返答待ち」→「返答の表示」という一連の流れが発生します。
データ送信はテキストの入力が完了しない限り行われないため、チャットではどうしても一つひとつのメッセージに対して返答が得られるまで数秒間のタイムラグが発生します。

一方、音声での会話の場合、話し始めから話終わりまでに一定の時間があります。「AI-VTuber配信システム」ではこのタイムラグを利用して、発話の段階ですぐにバックグラウンドで次の会話データをChatGPT APIから取得しています。
プログラム起動直後の初めのひとこと以降、入力されたテキストや音声データはどんどん会話用のキューに蓄積されて、連続してAPI通信を行いバックグラウンドでChatGPTの返答を取得していくように動作するため、通信による待機時間を発生させず会話をほとんど途切れさせずに進行することができます。


また、この仕組みを使ってYouTubeの配信画面のドキュメントデータからチャット履歴のテキストをキューに自動的に渡すことで、いわゆる動画配信者の「チャット読み」のような対応をAIが自律的に行います。
実際は読み上げるチャット履歴のフィルタリングなども行わないと危険だと思いますが、この辺りはOpen AIのモデレーションAPIも使って簡易的なフィルタリングができるように現状はしています。

また、この会話用のキューはテキスト入力だけでなくSpeech-to-Textでのマイク音声入力にも対応させています。
「AI-VTuber配信システム」には関係ありませんが、この機能を使って声でオモやんと会話もできちゃいます。
というか、もともとはアレクサやSiriみたいなアシスタントAI風のアプリを作ろうと思っていて、初めにこの音声認識機能を実装したのですが、いつのまにかこんなシステムに辿り着きました。

音声認識機能はオモやんに私の老後の話し相手になってもらうために使おうと思います。

## 話の流れをコントロールするディレクター
ChatGPT APIの会話の進行は基本的に「1問1答」です。
ChatGPTが2回連続で発言したり、Userが2回連続で入力することはできません。

通常であればChatGPTの発言が出力された段階で次のプロンプトの待機状態になるのですが、このプログラムではこの待機状態に近づくと自動的にChatGPTに振る次の話題を待機させ、Userからのプロンプトの入力（視聴者からのチャットでの発言）が無くても延々と話を続けるようになっています。

仕組み自体はシンプルで、会話のネタをChatGPTに渡すキューが減ったら（残りの数がn個以下）になったら「もっと詳しく話して」というようなプロンプトを自動的にキューに登録するようなものになっています。
実際はプロンプトの種類をいくつか用意して状況に応じて選択するようにしていますが、単純に「もっと話して」というプロンプトを投げ続けるだけでもChatGPTはそれっぽい会話を続けてくれるのでかなり優秀です。

ちなみにこの会話キューのコントロールは管理者の割り込みもできるので、番組放送のディレクターみたいにChatGPTにこっそりカンペを渡したり、危険なコメントが入ったときなどに管理者側でキューを強制的にクリアして話題を切り替えさせることなども可能です。
（完全自律じゃないじゃん）

## 動画配信者っぽいペルソナ

ChatGPT API（GPT-3.5-Turbo）では、UserとAssistant（ChatGPT）との会話データ以外にSystemという指示メッセージを送ることができます。
これはチャットなどでの入力内容とは別に裏でChatGPTに情報を伝えるためのもので、ここでペルソナの設定や動作の制限などを指示しておくことで、キャラクターの言葉遣いや性格などを細かく作り上げることができるようになっています。

「AI-VTuber配信システム」ではXMLファイルを使ってこのペルソナデータを定義したメタプロンプト複数管理し、切り替えることができるようになっています。

デモ動画のキャラクターはそのペルソナのうちのひとつで、このペルソナでは初期設定として
```
あなたはYouTubeのライブ配信者です
```
というそのまんまのメタプロンプトを投げています。

メタプロンプト（Systemメッセージ）の内容は細かく記述することができますが、その分トークンを消費してしまうので、いずれにしてもペルソナの設定は簡潔に書けた方が効果的です。
上記のような「ライブ配信者」という情報などを与えておくことで、ChatGPTは勝手にチャットの内容に対して「何かお悩みはありますか？」とか「最近こんなことがあって」というような雑談を始めるようになりました。

ペルソナについてはうまく「ごっこ遊び（ロールプレイ）」をさせるような構成にすると、期待通りのキャラクターになっていくのではないかと思います。



## 感情のパラメータで声や表情を変えられる（予定）
ChatGPTのレスポンスは基本的に付随するデータのない1種類のテキストのため、細かい情報を知ることができません。
ただ、ChatGPTは強力なテキスト生成能力とそれをコントロールできるメタプロンプトが利用できるため、メタプロンプトの構成次第で「会話の発言データ＋その他のメタデータ」の組み合わせをChatGPTの返答として生成させることができます。

考え方はシンプルで
```
あなたの返信は2行で構成し、1行目にあなたの発言、
2行目に喜びの感情を数値化したものを0から10の間で出力して
```

というようなプロンプトをChatGPTに送るだけです。
そんな感じでメタプロンプトを設定した後
```
オモやんってかわいいね
```
のようなプロンプトを投げると
```
ほんとうですか？うれしいです。
10
```
のようなレスポンスが得られるので、各行で分解すれば会話データと感情データが取り出せます。

ただ、実際のメタプロンプトはかなり細かい設定をしないと出力されるメタデータの書式がブレてしまいます。
この機能は「AI-VTuber配信システム」では実装済みで感情データのパース自体はできているのですが、残念ながら感情データを切り替えるためのキャラクターの「絵」と「声」のほうが準備できないため未使用です。

あとは、ペルソナの基本設定にかなりトークンが取られてしまっているので、メタデータの書式設定などもより厳密にしていくとトークン不足に陥ります。
（現状はコスト節約のために切っているという理由も。。。）
何でもかんでもモリモリにすればいいというわけにもいかず、このトークン制限内でのチューニングがAIチャットボット構築のポイントかもしれません。

今後オモやんのビジュアルに手が加えられるようになったら拡張したい機能です。

# 今後やるかも
## キャラクターをリッチに

キャラクターは現状1枚のイラストのみです。
このイラストもStable Diffusionに作ってもらいました。

VTuberといえばLive2Dなどのアニメーション環境を利用したいところですが、現状リソースに余裕なくて手が出せず。。
感情パラメータのような判定はできるので、モデルデータとモーションデータが用意できれば、会話のリアクションに沿ったアニメーションなどもできるはず。

## ライブ配信
オモやんのライブ配信は改めてどこかで実施してみたいなーと思っていますが、日程の調整などは面倒なのでいつか突然細々とやるかと思います。
AI-Vtuberの反応をご覧になりたいかたはチェックしてみてください。

## コードの詳細やノウハウの解説

Pythonのソースコードやメタプロンプト作成のノウハウはほとんどChatGPTに聞きながら作った（笑）ので、大したものではありませんが、もしニーズがありそうであればやろうかと思います。

情報公開自体はどんどんしたいけど、解説記事の作成自体が面倒なので、、、モチベーション次第です。

「いいね！」や共有でリアクションしていただけると私もオモやんも喜びます。


## 「AI-VTuber配信システム」の提供

もしご興味があればお知らせください。


以上です。
気まぐれに次回に続きます。