ConversationRelayとPythonを使用してGoogle GeminiとTwilio Voiceを連携
Time to read:
- FastAPIサーバーを構築し、ConversationRelayを活用してGoogle GeminiとTwilio Voiceを連携させます。
- 安全なコミュニケーションを行うために、必要な環境変数と依存関係を設定します。
- Twilioに発信し、AIとのリアルタイムな会話を通じて連携をテストします。
この要約は、AIにより生成されました。
電話越しに、AIモデルとリアルタイムで自然な会話ができる場面を想像してみてください。Twilio Conversation Relayを使用すれば、そんな体験を実現できます。高速なイベント駆動型WebSocketを介して、音声通話と各種LLMを連携させ、シームレスなコミュニケーションを実現します。
この記事では、ConversationRelayを使用してTwilio VoiceでGoogle Geminiを設定する方法について説明します。最終的には、シンプルなPythonサーバーが稼働し、Twilioの電話番号にかけるだけでGeminiと会話できるようになります。ここから、さらにインタラクティブで高機能な音声アプリケーションへと拡張していくことができます。
前提条件
このチュートリアルを進めるには、以下が必要です。
- Python 3.10以降がインストールされていること
- Twilioの電話番号(Twilioのサインアップはこちら)
- 任意のIDE(Visual Studio Codeなど)
- Ngrokなどのトンネリングサービス
- Google AI StudioアカウントとAPIキー
- Twilioへの発信に使用する電話
プロジェクトのセットアップ
まず、プロジェクトの新しいディレクトリを作成します。
次に、仮想環境を作成し、有効化します。
その後、pipを使用して必要な依存関係をインストールします。
FastAPIをフレームワークとして使用し、WebSocketとTwilioのルートの両方を備えたサーバーをすばやく構築します。
環境変数の設定
Google GeminiのAPIキーは、安全な場所に保存してください。プロジェクトフォルダで.envファイルを作成し、以下を追加します。
プレースホルダー部分を、実際のAPIキーとNgrokの転送URLに差し替えます(手順については、後ほど説明します)。
サーバーの作成
次に、「main.py」という名前で新しいPythonファイルを作成します。このファイルに、アプリケーションのメインのロジックを記述します。
1. 必要なライブラリをインポートし、環境をセットアップする
サーバー構築の最初のステップとして、必要なライブラリをインポートします。これらのライブラリは、サーバーの構築、WebSocket接続の処理、Google Geminiとの連携、環境変数の読み込みに使用します。
- FastAPI: サーバーの構築に使用するメインのWebフレームワーク。簡単にルートを簡単に定義して、HTTPリクエストを処理できるほか、サーバーとTwilio ConversationRelay間のWebSocket通信にも対応しています。
- uvicorn: FastAPIアプリケーションを実行する高速ASGIサーバー。
- genai: GoogleのGen AI SDK。GoogleのGeminiモデルと連携して応答を生成するために使用します。
- dotenv: .envファイルから環境変数(Google APIキーやNgrok URLなど)を読み込むためのモジュール。
ライブラリをインポートした後、以下の行を追加して.envファイルから環境変数を読み込みます。
- PORT: サーバーが接続を待ち受けるポート番号(環境変数から取得するか、デフォルト値の
8080を使用) - DOMAIN: TwilioとのWebSocket通信の確立に使用されるNgrok URL。このコードは設定値を即座に検証し、未設定の場合はエラーを発生させます。
- WS_URL: Twilioの接続先であるエンドポイントの完全なWebSocket URL。
- WELCOME_GREETING: 通話接続時に流れる挨拶メッセージ。
- SYSTEM_PROMPT: Geminiモデルに動作の指示を与える特殊なメッセージ。AIの応答のトーンやフォーマット(例:数字を文字で表記する、絵文字を使用しないなど)を定義する重要な役割を果たします。今回は音声会話であるため、これらのルールを設定することで、クリアで聞き取りやすい音声応答を出力できるようになります。
- sessions: 各通話のアクティブなチャットセッションオブジェクトを保持する辞書(キーとして
callSidを使用)。注記: この実装では、正常な切断時のみクリーンアップ処理が行われます。本番環境で運用する場合は、セッションのタイムアウト処理の追加を検討してください。
3. FastAPIとGeminiクライアントの初期化
FastAPIアプリケーションを初期化し、.envファイルに保存されているAPIキーを使用してGeminiクライアントを設定します。
- GOOGLE_API_KEY: 環境変数からAPIキーを読み込み、処理を実行する前にAPIキーが正しく設定されているか検証するコード。
- client:
genai.Client()を使用して、GoogleのGen AIクライアントを初期化します。これは新しいSDKのパターンです。以前のgoogle-generativeaiパッケージを使用していた場合、これは新しいgoogle-genaiSDKであること注意してください。 - FastAPIアプリ: HTTPリクエストとWebSocket接続の両方を処理するWebサーバーが生成されます。
4. AI応答関数
次に、Gemini APIと連携して、AIからの応答を取得する関数を作成します。
- gemini_response(): Geminiのチャットセッションオブジェクトとユーザーのプロンプトを取り、メッセージを送信してテキストの応答を返す関数。チャットセッションオブジェクトが会話履歴を自動的に維持するため、Geminiはメッセージごとに文脈を把握した上で応答できます。
5. TwilioのTwiML応答
/twimlエンドポイントは、着信した音声通話をWebSocketアプリケーションへ接続するようTwilioに指示します。Twilioは、TwiML(Twilio Markup Language)を使って、音声対話の処理方法を判断します。
- TwiMLの応答によって、Twilioは指定されたWebSocketサーバー(
WS_URL)に接続し、発信者に対してWELCOME_GREETINGの挨拶メッセージを発信します。 - この例では、音声合成プロバイダーとしてElevenLabsを使用し、特定の音声ID(
FGY2WhTYpPnrIDTdsKH5)を設定しています。これはサンプル音声IDです。実際に利用する際は、ご自身の音声IDに置き換えてください。このカスタマイズはオプションです。ttsProvider属性とvoice属性を完全に削除し、TwilioのデフォルトのTTSを使用するか、「ElevenLabs」を「Amazon」や「Google」に置き換えることができます。 - 言語、ttsProvider、音声など、サポートされている属性の詳細については、ConversationRelayドキュメントを参照してください。
- 注記: このエンドポイントは、Twilioリクエスト署名を検証しません。本番運用については、Twilioのリクエスト検証ドキュメントを参照してください。
6. WebSocket接続処理
/ws WebSocketエンドポイントは、Twilioとサーバー間のリアルタイム通信を処理します。Twilioからメッセージを受信し、処理し、返信します。
- whileループは、Twilioからの着信メッセージを待ち受けます。サーバーはさまざまなメッセージタイプを処理します。
- setup: この通話用の新しいGeminiチャットセッションを初期化します。このコードは、
client.chats.create()を使用し、gemini-2.5-flashモデルを設定して、configパラメータでシステムプロンプトを渡します。この処理により、会話の履歴を自動的に保持するステートフルなチャットオブジェクトが生成されます。 - prompt: Twilioでテキスト化されたユーザーの音声入力を処理し、
gemini_response()関数でGeminiに送信します。応答テキストはTwilioに送信され、音声に変換されます。 - interrupt: 会話中の割り込みに対応します(例えば、AIの応答中に発信者が話し始めた場合など)。
- Unknown message: 認識されていないメッセージタイプを記録します。
- sessions: アクティブなGeminiチャットセッションは、
call_sidでインデックス化されてsessions辞書に保存されます。WebSocket接続が切断されると、セッションはクリーンアップされます。
7. FastAPIサーバーの実行
最後に、Uvicornを使用してFastAPIサーバーを実行します。
uvicorn.run(): サーバーが起動し、指定されたポート(デフォルトは8080)で待ち受けます。これでサーバーはHTTPリクエスト(TwiML用)とWebSocket接続(リアルタイムの会話用)の両方を処理できるようになります。
サーバーの実行
サーバーを実行するには、まずターミナルを開き、Ngrokトンネルを起動します。
まず、ngrokの接続ソケットを開いておいてください。ngrokのURLは、Twilio Consoleと.envファイルの2か所で必要になります。
Ngrok URL(例: https://1234abcd.ngrok.app)を書き留め、ドメイン部分を.envファイルに追加します。
これで、以下のコマンドでサーバーを起動できるようになりました。
Twilioの設定
Twilio Consoleにアクセスし、自分のTwilio電話番号を選択します。[Configure(設定)]タブの[Voice Configuration](音声設定)で、[Webhook URL]を自分のNgrok URL(/twimlを含む)に設定します。
連携のテスト
設定がすべて完了したら、携帯電話からTwilio電話番号に発信します。挨拶メッセージが流れると、AIへの質問を始めることができます。
次のステップ
このPythonアプリは、Twilioの音声機能をConversationRelayに接続するFastAPIサーバーを構築し、Google Geminiを搭載したAIアシスタントとのリアルタイムな対話を可能にします。サーバーはHTTPリクエスト(Twilioへの応答指示)とWebSocket接続(AIとのライブ通信)の両方を処理します。ConversationRelayは、着信時に音声の文字起こし、LLMとの通信、LLMの応答に基づく音声合成を一連の流れとして制御し、Geminiを搭載したAIアシスタントとのスムーズな会話を実現します。
リアルタイム音声アシスタントが動作するようになったので、TTSプロバイダーの変更、通話中にGeminiが天気予報を確認したり予約を入れたりできる機能呼び出しの追加、さまざまなGeminiモデルの検証など、さらなるカスタマイズを試すことができます。
その他のConversationRelayの事例やデモをお探しの場合は、Twilionのブログ記事をご覧ください。
- Integrate OpenAI with Twilio Voice Using ConversationRelay and Python(ConversationRelayとPythonを使用して、OpenAIとTwilio Voiceを連携)
- Integrate OpenAI with Twilio Voice Using ConversationRelay in NodeJS(NodeJSでConversationRelayを使用して、OpenAIとTwilio Voiceを連携)
動画もあります。TwilioとGemini Flashの統合を解説した動画をご覧ください。
Rishab Kumar は、Twilioのデベロッパーエバンジェリストであり、熱心なクラウド愛好家です。Rishabへのご連絡は、X(@rishabincloud)にお願いします。また、クラウド、DevOps、DevRelなどについては、youtube.com/@rishabincloudで個人ブログをフォローいただけます。