はじめに
Azure Communication Service(以下、ACS)は、Azureサービスの中でも電話やTeamsなど、コミュニケーションサービスを管理することに特化していますが、Azure公式でもサンプルがある通り、生成AIに応対をさせることができます。
今回はそんなACSと、Azure OpenAI Serviceで選択可能な音声モデルであるgpt-realtimeを使って、電話応対のAI化を試してみます。
システム化に当たって、電話応対の文字起こしを行なってログ記録することは必須要件かと思うので、文字起こしも合わせて実装してみます。
文字起こしに関しては、gpt-realtimeにはwhisperモデルを利用してオーディオ音声の文字起こしを行う機能があります。
しかし、ユーザー音声の文字起こしは、あくまでgpt-realtime組み込みであるwhisperモデルが、ネットワークを通して劣化した音声を認識した文字起こしとなります。
従って、ユーザーが実際に発している音声の文字起こしとは、結果が少し異なる可能性があります。
実際、日本語の文字起こしの精度が結構悪く、高確率でハルシネーションを起こします。
さらに、AI音声に関しては、生成結果をgpt-realtimeが読み上げるという形を取っているので、実際にユーザーが聞いた音声とは異なる場合があります。
そこで、ユーザー音声の文字起こしには、Call Automation SDK v1.4.0からGAとなっている「ACSを用いた文字起こし」と、AI応答の文字起こしには「Azure AI Speechを用いた文字起こし」を試してみます。
※ 2025年12月現在、「ACSを用いた文字起こし」はAI応答の文字起こしに対応していないため、上記のようにAI応答は「Azure AI Speech」を用いて文字起こしをします
構築するシステムアーキテクチャ
今回はAzure公式サンプルを用いながら、AI応答を試していきます。
また、そこからカスタムしてユーザー音声とAI応答を文字起こししていきます。
登場人物は以下7人です。
- ユーザー
- Azure Communication Service
- Event Grid
- Call Automation SDK
- Web Socket
- gpt-realtime
- Azure AI Speech
Azure Communication Serviceについて
Azure Communication Serviceには以下のようにいくつかサービスの種類があります。
- Call Automation
- Chat
- Messages
- SMS
- Rooms
例えば、ChatやRoomsなどはTeamsでのチャットや通話の管理を行ったり、Emailサービスを利用してユーザーにメールを送ったりできます。
今回は電話サービスであるCall Automationサービスを利用します。
参考: Azure Communication Services とは | Microsoft Learn
また、ACSは基本的にはイベント駆動となるため、イベントを管理するためにEvent Gridを利用します。
架電イベントや録音データ保管イベントをEvent Gridに送信し、Event Gridが目的のアプリケーションのエンドポイントにイベントデータを送り、Call Automation SDKが通話を制御します。
Azure OpenAI Serviceについて
gpt-realtimeはOpenAIが提供する、生成AIの音声モデルです。
このモデルを利用することで、ユーザーは従来のチャットでのAI利用から音声によるコミュニケーションが可能になります。
さらに今までのTTSなどと比べて非常に自然な会話と音声を実現しています。
今回はAI応答として、Azure OpenAI Serviceの中で提供されているgpt-realtime-miniモデルを利用します。
Azure AI Speechについて
OpenAIが提供する生成AIモデルが強力すぎて、AIに関する話題は全部持って行かれてしまいましたが、Azureには昔からAzure Cognitive Servicesという名前でAIサービスが展開されており、その中でもSTTやTTSを担当しているのがAzure AI Speechです。
ACSではユーザーが発話した音声をAzure AI Speechに組み込みで連携する仕組みがあり、それを利用して文字起こし結果をリアルタイムで取得することができます。
生成AIの応答を受け取ってACSにWebSocketを通して返しつつ、それをリアルタイムでAzure AI Speechに文字起こしさせることで、AI音声の文字起こしを実現します。
また、ACSの組み込みである文字起こし機能も、実体はこのAzure AI Speechを使っています。
ACSが受け取ったユーザー音声をリアルタイムでAzure AI Speechに文字起こしさせて、その結果をWebSocketで受け取ることができます。
環境について
- Python 3.12.6
- Call Automation SDK 1.5.0
- Azure Cognitive Services 1.43.0
- MacOS
サンプルコードはこちらに格納しています。
準備
Azureサービスの作成
まずはAzure上で以下のサービスを作成していきます。
- Azure Communication Service
- Azure AI Services
- Azure OpenAI Service
基本的には全てデフォルトで大丈夫です。
ACSは一応Japanに作成します。
AI SservicesはJapan Eastに作成します。
また、システム割り当てIDはオンにしておきます。
Azure OpenAI ServiceもJapan Eastに作成します。
ACSの準備
ユーザー音声の文字起こしはACSの組み込みの仕組みであるAzure AI Speechで行うため、双方の紐付けを行います。
- ACSのOverviewを開き、左ペインの「設定」タブから「Cognitive Services」を開く
- Azure AI ServicesをデプロイしたSubscriptionを選び、「Enable Managed Identity」を押下
- 状態を「オン」にして保存(確認を求められるので、「はい」を選択)
- もう一度「設定」タブの「Cognitive Services」を開き、「Connect cognitive service」を押下
- 自動で情報が入るので、問題なければ「connect」を押下
問題なければ以下のような画面になります
続いて、ACSに架電するための電話番号を取得します。
- ACSのOverviewを開き、左ペインの「テレフォニーとSMS」から「Phone Numbers」を開く
- 「Get a number」を押下
- Country or regionで「US」を選択
- Typeは「Toll-free」を選択
- 適当なものを「Add to cart」する
- 「Buy now」を押下する
日本の電話番号も取得できますが、サポートリクエストでやり取りする必要があり、取得に3~5営業日かかります。
今回は手軽なUSのToll-free番号を購入しました。
電話番号はリース扱いとなり、月額$2.00かかりますので注意してください。
また、この電話番号に日本の番号から掛ける場合国際電話になりますので、ご注意ください。
さらにEventGridでのイベント作成を行う必要がありますが、アプリケーションのエンドポイントがわからないと構築できないので、アプリケーションのエンドポイントが判明した時に作成します。
AOAIの準備
AOAIではgpt-realtimeのデプロイを行なっていきます。
- AOAIのOverviewを開き、左上の「Go to Foundry Portal」を押下
- Azure AI Foundryが開くので、左ペインの「モデルカタログ」を押下
- モデルのうち「gpt-realtime-mini」を選択
- 「このモデルを使用する」を押下し、「作成」を押下
DevTunnelの準備
次にDevTunnelの準備をします。
アプリケーションを開発してApp ServiceやVMに載せてももちろんいいんですが、今回は簡略化するために動かすアプリケーションはローカルで完結させます。
公式ドキュメントにインストール方法が載っているので、インストールします。
インストールが成功したら以下コマンドでログインし、いつでもDevTunnelを開始できるようにしておきます。
devtunnel user login
ブラウザが自動で開きEntraIDなど認証するログイン画面になるので、適切なユーザーでログインします。
アプリケーション準備
次にアプリケーションの準備をしていきます。
私のサンプルコードをgit cloneして利用してください。
cloneできたら、仮想環境を作成し、パッケージをインストールしていきます。
# 仮想環境作成
python -m venv .venv
# 仮想環境起動 (コマンドはlinux,mac用)
source .venv/bin/activate
# パッケージインストール
pip install -r requirements.txt
完了したら、Azure DevTunnelのセットアップを行います。
# DevTunnelの作成
devtunnel create --allow-anonymous
# portの作成
devtunnel port create -p 8000
# ローカルウェブサービスをホスト
devtunnel host
ホストが完了した後のパブリックなURLは、後でEventGrid作成に利用するのでメモしておきます。
次にmain.pyを開き、以下の定数の値を書き換えます。
- ACS_CONNECTION_STRING: Azure Communication Serviceの接続文字列
- CALLBACK_URI_HOST: DevTunnelエンドポイント
- COGNITIVE_SERVICES_ENDPOINT: Azure AI Servicesのエンドポイント
また、azureOpenAIService.pyを開き、以下の定数の値を書き換えます
- AZURE_OPENAI_SERVICE_ENDPOINT: Azure OpenAI Serviceのエンドポイント
- AZURE_OPENAI_SERVICE_KEY: Azure OpenAI Serviceのキー
- AZURE_OPENAI_DEPLOYMENT_MODEL_NAME: Azure OpenAI デプロイ名
さらに、azureAISpeech.pyを開き、以下の定数の値を書き換えます
- COGNITIVE_SERVICES_ENDPOINT: Azure AI Servicesのエンドポイント
- COGNITIVE_SERVICES_KEY: Azure AI Servicesのキー
最後にアプリケーションを実行します。
python main.py
ブラウザで、https://DevTunnelエンドポイント/にアクセスすると、DevTunnelにアクセスして良いか聞かれるので、「続行」してください。
以下画面になれば起動成功です。
EventGridの準備
最後にEventGridの準備を行います。
- ACSのOverviewを開き、左ペインから「イベント」を開く
- 左上の「イベントサブスクリプション」を押下
- Event Gridの作成のうち、「イベントの種類のフィルター」は「Incoming Call」にチェックを入れる
- Event Gridの作成のうち、「エンドポイントの種類」は「Web hook」を選択
- 「エンドポイントの構成」を押下し、
https://DevTunnelエンドポイント/api/incomingCallを入力する - 「選択の確認」を押下する
- 「作成」を押下する (失敗する場合はサブスクリプションに「Microsoft.EventGrid」を登録する)
この時、正しくDevTunnelが起動している場合は、アプリケーションログに以下が記録されます。
[2025-12-02 07:31:10,537] INFO in main: incoming event data
[2025-12-02 07:31:10,560] INFO in main: incoming event data --> {'validationCode': 'xxx', 'validationUrl': 'https://rp-global.eventgrid.azure.net:553/eventsubscriptions/xxx/validate?id=xxx&t=2025-12-01T22:31:09.3170052Z&apiVersion=2025-04-01-preview&token=xxx'}
[2025-12-02 07:31:10,561] INFO in main: Validating subscription
[2025-12-02 07:31:10 +0900] [29864] [INFO] 127.0.0.1:65197 POST /api/incomingCall 1.1 200 62 33481
コールを試してみる
ACSの電話番号に対して電話を掛けてみます。
するとアプリログとして以下のように出力されます。
[2025-12-02 13:08:19,083] INFO in main: incoming event data
[2025-12-02 13:08:19,084] INFO in main: incoming event data --> {'to': {'kind': 'phoneNumber', 'rawId': '4:xxx', 'phoneNumber': {'value': 'xxx'}}, 'from': {'kind': 'phoneNumber', 'rawId': '4:xxx', 'phoneNumber': {'value': 'xxx'}}, 'serverCallId': 'xxx', 'callerDisplayName': '', 'incomingCallContext': 'xxx', 'correlationId': 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'}
[2025-12-02 13:08:19,084] INFO in main: Incoming call received: data={'to': {'kind': 'phoneNumber', 'rawId': '4:xxx', 'phoneNumber': {'value': 'xxx'}}, 'from': {'kind': 'phoneNumber', 'rawId': '4:xxx', 'phoneNumber': {'value': 'xxx'}}, 'serverCallId': 'xxx', 'callerDisplayName': '', 'incomingCallContext': 'xxx', 'correlationId': 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'}
[2025-12-02 13:08:19,084] INFO in main: incoming call handler caller id: xxx
[2025-12-02 13:08:19,084] INFO in main: callback url: https://DevTunnelエンドポイント/api/callbacks/cd25a59f-c2d2-4c01-8acf-cb69dac3ccaf?callerId=xxx
[2025-12-02 13:08:19,084] INFO in main: websocket url: wss://DevTunnelエンドポイント/ws
[2025-12-02 13:08:19,084] INFO in main: transcription websocket url: wss://DevTunnelエンドポイント/transcriptionws
speech_recognition_model_endpoint_id is not a known attribute of class <class 'azure.communication.callautomation._generated.models._models.WebSocketTranscriptionOptions'> and will be ignored
[2025-12-02 13:08:19,521] INFO in main: Answered call for connection id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
[2025-12-02 13:08:19 +0900] [9065] [INFO] 127.0.0.1:59036 POST /api/incomingCall 1.1 200 - 439132
[2025-12-02 13:08:23,367] INFO in main: Received Event:-> Microsoft.Communication.CallConnected, Correlation Id:-> xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, CallConnectionId:-> xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
[2025-12-02 13:08:23,528] INFO in main: MediaStreamingSubscription:--> <azure.communication.callautomation._models.MediaStreamingSubscription object at 0x1056bee70>
[2025-12-02 13:08:23,529] INFO in main: Received CallConnected event for connection id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
[2025-12-02 13:08:23,529] INFO in main: CORRELATION ID:--> xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
[2025-12-02 13:08:23,529] INFO in main: CALL CONNECTION ID:--> xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
speech_recognition_model_endpoint_id is not a known attribute of class <class 'azure.communication.callautomation._generated.models._models.StartTranscriptionRequest'> and will be ignored
[2025-12-02 13:08:23 +0900] [9065] [INFO] 127.0.0.1:59056 POST /api/callbacks/cd25a59f-c2d2-4c01-8acf-cb69dac3ccaf 1.1 200 - 487620
[2025-12-02 13:08:23,856] INFO in main: Received Event:-> Microsoft.Communication.ParticipantsUpdated, Correlation Id:-> xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, CallConnectionId:-> xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
[2025-12-02 13:08:23 +0900] [9065] [INFO] 127.0.0.1:59062 POST /api/callbacks/cd25a59f-c2d2-4c01-8acf-cb69dac3ccaf 1.1 200 - 1316
Client connected to WebSocket Transcription
[2025-12-02 13:08:24 +0900] [9065] [INFO] 127.0.0.1:59064 GET /transcriptionws 1.1 101 - 1829
Hello World
Client connected to WebSocket
[2025-12-02 13:08:24,846] INFO in main: Received Event:-> Microsoft.Communication.TranscriptionStarted, Correlation Id:-> xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, CallConnectionId:-> xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
[2025-12-02 13:08:24 +0900] [9065] [INFO] 127.0.0.1:59073 POST /api/callbacks/cd25a59f-c2d2-4c01-8acf-cb69dac3ccaf 1.1 200 - 3232
start audio recognition.
[2025-12-02 13:08:25 +0900] [9065] [INFO] 127.0.0.1:59066 GET /ws 1.1 101 - 987239
Session Created Message
Session Id: sess_CiBybY9cs1BqD0ApP41P4
[2025-12-02 13:08:25,913] INFO in main: Received Event:-> Microsoft.Communication.MediaStreamingStarted, Correlation Id:-> xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, CallConnectionId:-> xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
[2025-12-02 13:08:25,913] INFO in main: Media streaming content type:--> Audio
[2025-12-02 13:08:25,913] INFO in main: Media streaming status:--> mediaStreamingStarted
[2025-12-02 13:08:25,913] INFO in main: Media streaming status details:--> subscriptionStarted
[2025-12-02 13:08:25 +0900] [9065] [INFO] 127.0.0.1:59081 POST /api/callbacks/cd25a59f-c2d2-4c01-8acf-cb69dac3ccaf 1.1 200 - 1436
AI (ai speech):-- こんにちは。サムと申します。
AI (whisper):-- こんにちは、サムと申します。Contoso Servicesで働いておりまして、穏やかで陽気な対応を心がけております。どうぞよろしくお願いします。何かお手伝いできることがあれば、なんでもお知らせくださいね。
AI (ai speech):-- コントソースサービスで働いておりまして。
AI (ai speech):-- 穏やかで陽気な対応を心がけております。
AI (ai speech):-- どうぞ、よろしくお願いします。
AI (ai speech):-- 何かお手伝いできることがあれば、何でもお知らせくださいね。
User (ai speech):-- こんにちは。コントツサービスという会社について詳しく教えてください。
User (whisper):-- こんにちは。コントソサービスという会社について、 詳しく教えてください。
AI (ai speech):-- こんにちは。
AI (whisper):-- こんにちは!私の名前はサムと申しまして、Contoso Servicesで働いております。Contoso Servicesは、お客様に様々なITソリューションやサポートを提供している会社です。たとえば、ネットワーク構築やクラウドサービス、データベース管理など、幅広い分野でお手伝いしています。何か具体的にご興味のあるサービスや、もう少し詳しく知りたい内容があれば、教えてください!
AI (ai speech):-- 私の名前はサムと申しまして、コントソサービスで働いております。
AI (ai speech):-- コンテストサービスは、お客様にさまざまなITソリューションやサポートを提供している会社です。
AI (ai speech):-- 例えば、ネットワーク構築やクラウドサービス、データベース管理など幅広い分野でお手伝いしています。
AI (ai speech):-- 何か具体的にご興味のあるサービスや、もう少し詳しく知りたい内容があれば教えてください。
User (ai speech):-- 営業時間を教えてください。
User (whisper):-- 営業時間を教えてください。
AI (ai speech):-- はい。承知しました。
AI (whisper):-- はい、承知しました。Contoso Servicesの営業時間は、月曜日から金曜日の午前9時から午後6時までです。土日や祝日はお休みとなっております。何か他にご質問やご要望があれば、お気軽にどうぞ!
AI (ai speech):-- コントソースサービスの営業時間は?
AI (ai speech):-- 月曜日から金曜日の午前9時から午後6時までです。
AI (ai speech):-- 土日や祝日はお休みとなっております。
AI (ai speech):-- 何か他にご質問やご要望があればお気軽にどうぞ。
User (ai speech):-- 3.14から始まる円周率を20桁まで教えてください。
User (whisper):-- 3.14から始まる演習率を20桁まで教えてください。
AI (whisper):-- こんにちは!私の名前はサムで、Contoso Servicesに勤めております。では、円周率を3.14から20桁までご紹介しますね。
3.141592653589793238462643...です。
他にも何かお手伝いできることがあればいつでもおっしゃってくださいね。
AI (ai speech):-- こんにちは。
AI (ai speech):-- 私の名前はサムで、コントソーサービスに勤めております。
AI (ai speech):-- では、円周率を3.1 4から20桁までご紹介しますね。
AI (ai speech):-- 3.1445626535897。
AI (ai speech):-- 39323。
AI (ai speech):-- 4562643です。
AI (ai speech):-- 他にも何かお手伝いできることがあればいつでもおっしゃってくださいね。
stop audio recognition.
[2025-12-02 13:09:16,507] INFO in main: Received Event:-> Microsoft.Communication.MediaStreamingStopped, Correlation Id:-> xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, CallConnectionId:-> xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
[2025-12-02 13:09:16,507] INFO in main: Media streaming content type:--> Audio
[2025-12-02 13:09:16,507] INFO in main: Media streaming status:--> mediaStreamingStopped
[2025-12-02 13:09:16,507] INFO in main: Media streaming status details:--> streamConnectionInterrupted
[2025-12-02 13:09:16 +0900] [9065] [INFO] 127.0.0.1:59311 POST /api/callbacks/cd25a59f-c2d2-4c01-8acf-cb69dac3ccaf 1.1 200 - 2138
[2025-12-02 13:09:16,989] INFO in main: Received Event:-> Microsoft.Communication.CallDisconnected, Correlation Id:-> xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, CallConnectionId:-> xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
[2025-12-02 13:09:16 +0900] [9065] [INFO] 127.0.0.1:59311 POST /api/callbacks/cd25a59f-c2d2-4c01-8acf-cb69dac3ccaf 1.1 200 - 1181
サンプルアプリケーションはgptへのインストラクションとして、以下のように指示しています。
あなたの名前はサムです。あなたはContoso Servicesで働いでいます。あなたは穏やかで陽気なエージェントで、丁寧な日本語で応答します。常に元気な声で返事をしてください。
また、最初にgptへ以下のようにテキストを送信しているので、自分の名前とどこで働いているかを日本語で発言してきます。
こんにちは!あなたの名前と職業を教えてください。
発言が聞こえたら、正常にAIと会話ができています。
※ SSL関連のエラーが発生する場合は以下コマンドを実行してください。
export SSL_CERT_FILE=$(python -m certifi)
ログ解析
上記出力されたログを確認すると、会話の文字起こしは以下のように記録されています。
AI (ai speech):-- こんにちは。サムと申します。
AI (whisper):-- こんにちは、サムと申します。Contoso Servicesで働いておりまして、穏やかで陽気な対応を心がけております。どうぞよろしくお願いします。何かお手伝いできることがあれば、なんでもお知らせくださいね。
AI (ai speech):-- コントソースサービスで働いておりまして。
AI (ai speech):-- 穏やかで陽気な対応を心がけております。
AI (ai speech):-- どうぞ、よろしくお願いします。
AI (ai speech):-- 何かお手伝いできることがあれば、何でもお知らせくださいね。
User (ai speech):-- こんにちは。コントツサービスという会社について詳しく教えてください。
User (whisper):-- こんにちは。コントソサービスという会社について、 詳しく教えてください。
AI (ai speech):-- こんにちは。
AI (whisper):-- こんにちは!私の名前はサムと申しまして、Contoso Servicesで働いております。Contoso Servicesは、お客様に様々なITソリューションやサポートを提供している会社です。たとえば、ネットワーク構築やクラウドサービス、データベース管理など、幅広い分野でお手伝いしています。何か具体的にご興味のあるサービスや、もう少し詳しく知りたい内容があれば、教えてください!
AI (ai speech):-- 私の名前はサムと申しまして、コントソサービスで働いております。
AI (ai speech):-- コンテストサービスは、お客様にさまざまなITソリューションやサポートを提供している会社です。
AI (ai speech):-- 例えば、ネットワーク構築やクラウドサービス、データベース管理など幅広い分野でお手伝いしています。
AI (ai speech):-- 何か具体的にご興味のあるサービスや、もう少し詳しく知りたい内容があれば教えてください。
User (ai speech):-- 営業時間を教えてください。
User (whisper):-- 営業時間を教えてください。
AI (ai speech):-- はい。承知しました。
AI (whisper):-- はい、承知しました。Contoso Servicesの営業時間は、月曜日から金曜日の午前9時から午後6時までです。土日や祝日はお休みとなっております。何か他にご質問やご要望があれば、お気軽にどうぞ!
AI (ai speech):-- コントソースサービスの営業時間は?
AI (ai speech):-- 月曜日から金曜日の午前9時から午後6時までです。
AI (ai speech):-- 土日や祝日はお休みとなっております。
AI (ai speech):-- 何か他にご質問やご要望があればお気軽にどうぞ。
User (ai speech):-- 3.14から始まる円周率を20桁まで教えてください。
User (whisper):-- 3.14から始まる演習率を20桁まで教えてください。
AI (whisper):-- こんにちは!私の名前はサムで、Contoso Servicesに勤めております。では、円周率を3.14から20桁までご紹介しますね。
3.141592653589793238462643...です。
他にも何かお手伝いできることがあればいつでもおっしゃってくださいね。
AI (ai speech):-- こんにちは。
AI (ai speech):-- 私の名前はサムで、コントソーサービスに勤めております。
AI (ai speech):-- では、円周率を3.1 4から20桁までご紹介しますね。
AI (ai speech):-- 3.1445626535897。
AI (ai speech):-- 39323。
AI (ai speech):-- 4562643です。
AI (ai speech):-- 他にも何かお手伝いできることがあればいつでもおっしゃってくださいね。
今回は比較のためにwhisperの文字起こしも出力してみました。
ユーザー音声に関しては、AI Speechもwhisperも正直どっこいどっこいで、AI Speech側が「コントソサービス」を「コントツサービス」と文字起こししていたり、whisper側が「円周率」を「演習率」と文字起こししていたりでした。
しかし、「演習率」と起こしているにも関わらず、gptは円周率だと理解しているので、この辺りに文字起こしと認識との差が生まれていそうです。
問題があるのはAI音声の方で、whisperはカンペを出すので文字列上は非常に正確に文字起こし結果が出るのですが、音声自体はハルシネーションを起こしていたり、裏返った声で聞き取りづらかったり、実際にユーザーが認識する音とは異なることがしばしばありました。
例えば、営業時間を聞いている質問に対して、AI Speechが「コントソースサービスの営業時間は?」と疑問系で文字起こししている箇所がありますが、この部分は確かに音声としては声が裏返って尻上がりになっており、ユーザーからすると疑問系として聞こえていました。
また、円周率を20桁まで読み上げる部分では、whisperのカンペ上では正しい円周率を記載していますが、実際に聞こえてきた音声はAI Speechが文字起こしするようにでたらめなものでした。
whisper: 3.141592653589793238462643
ai speech: 3.1445626535897393234562643
まとめ
無事、電話をかけて生成AIと会話し、その文字起こしを取得することに成功しました。
今回生成モデルとしてはgpt-realtime-miniを利用しましたが、RAGを利用したりMCPサーバーを構築したりすれば、よりSpecificな自動応答が可能なエージェントを作ることができると思います。
文字起こしに関しては、一概にwhisperが悪い、gpt-realtimeの読み上げ精度が悪いとはいえず、プロンプトを改善したりモデルをチューニングすれば十分に改善できると思います。
しかし本番環境としてサービスを展開する場合は、whisperで文字起こしするより、ユーザーにより近い音声を文字起こしすることで、音声モデルのファインチューニングに活かしたりなど、サービスの品質向上につながると思います。
今回は非常に簡単な検証で、実際にgpt-realtimeモデルの読み上げ精度を上げたり、裏返らないように制御したりするような高度な検証まではできなかったので、今後はそういったよりハルシネーションを抑え、自然に近い応答ができるようなチューニングを試したり、企業情報や特定の分野に特化した応答が可能なAIモデルの実現について試していきたいと思います。
お世話になった記事
本番環境の音声エージェントに対応する gpt-realtime と Realtime API に更新が登場 | OpenAI
トンネルを作成してホストする - Microsoft dev tunnels | Microsoft Learn
リアルタイム文字起こし機能をアプリケーションに追加する - An Azure Communication Services how-to document | Microsoft Learn
クイックスタート - Azure Communication Services を使用して電話番号を取得して管理する | Microsoft Learn
Strange Error with Azure Speech Service TTS, suddenly stopped working - Microsoft Q&A





