OpenAI Voice
Squid agent を背後に持つ OpenAI realtime model で、電話通話とブラウザ通話に応答します
OpenAI Voice connector の機能
OpenAI Voice connector は、OpenAI Realtime speech-to-speech model を通話に接続します。
- 自然な会話。 realtime model は中間の transcription ステップなしに直接聞いて話します。挨拶、雑談、確認を自ら処理でき、割り込みにも対応します。
- 頭脳としての Squid agent。 発信者が情報を求めたり、何かの実行を望んだりすると、model は
ask_agenttool を通じて agent を呼び出します。agent は knowledge base、connector、AI function を用いて応答し、model は自身の声でその回答を伝えます。 - 電話通話。 Twilio 電話回線の voice engine として利用できます。
- ブラウザ通話。
squid.ai().voice().startWebCall()を通じて、電話番号なしで WebRTC を使用し、Web ページから直接通話できます。 - 言語。 通話は回線の言語で開始され、発信者に合わせて選択した言語または任意の言語へ切り替えられます。
- Transcripts。 通話の両者は、ほかの engine と同様に transcription および記録されます。
音声は発信者と OpenAI の間を流れます。Squid は通話を制御するのみです。agent の instructions とともに通話を設定し、model から要求された際に agent を実行し、model が通話を終了した際に切断します。
始める前に
- Realtime API へのアクセス権を持つ OpenAI organization。
- 通話を実行するproject とその id(
proj_…)。project の settings に表示されます。電話通話は project の SIP endpoint、sip:<projectId>@sip.api.openai.comを通じて OpenAI に到達します。 - その project で作成した API key。
- 電話通話の場合は、project に登録した webhook endpoint。以下で説明します。ブラウザ通話には webhook は不要です。
Squid application への OpenAI Voice connector の追加
-
Squid Console の Connectors タブに移動します。
-
Available Connectors をクリックします。
-
OpenAI Voice connector を見つけ、Add Connector を選択します。
-
以下の設定詳細を指定します。
Connector ID: コード内で connector を一意に識別する文字列です。例: openai_voice。
API Key: OpenAI project の API key。secret として保存されます。
Project ID: OpenAI project id(proj_…)。
Webhook Secret: 任意ですが推奨されます。project に登録する webhook endpoint の signing secret(whsec_…)です。これを使用すると、Squid は着信通話 webhook が OpenAI からのものであることを検証します。これがない場合、webhook URL へのすべての request が信頼されます。
Default Model: 任意です。model を選択していない agent に使用する realtime model です。デフォルトは最新の realtime model、gpt-realtime-2.1 です。
Default Voice: 任意です。voice を選択していない agent に使用する voice です。デフォルトは marin です。
Advanced セクションには、OpenAI がこの application に到達するための public base URL である Webhook Base URL(proxy、tunnel、または custom domain の背後にある場合にのみ必要)と、OpenAI の API base URL である API Base URL(デフォルト: https://api.openai.com)があります。
connector は agent ごとの設定を行いません。どの agent が、どの model と voice でこれを使用して応答するかは、各 agent の電話回線で決定されます。
電話回線での OpenAI Voice の使用
-
まだ追加していない場合は、application に Twilio connector を追加します。
-
Agent Studio で agent に Twilio ability を追加する(または開く)し、Phone number を選択します。
-
Voice engine を OpenAI voice に設定し、使用する OpenAI Voice connector を選択します。
-
OpenAI model(account の realtime model。新しい順)と OpenAI voice を選択します。
marinとcedarは最新の voice です。alloy、ash、ballad、coral、echo、sage、shimmer、verseも利用できます。 -
通話を開始するLanguage を設定し、Languages で、発信者が選択した言語または任意の言語に切り替えられるかを設定します。
-
Greeting を記述し、Opening line を選択します。記述どおりの greeting、または通話接続時に agent が作成する line を選択できます。後者では、既知の発信者を名前で迎えられます。
-
保存します。status line に、この番号がこの agent に着信することと、OpenAI project に登録する webhook URL が表示されます。次に説明するように、connector ごとに一度登録してください。
コードから設定する allowInterruptions および interruptionSensitivity を含む全オプションの一覧は、Twilio connector の phone line settings にあります。
着信通話 webhook の登録
OpenAI は、project の SIP endpoint に到達するすべての通話を、project の webhook に realtime.call.incoming event を POST して通知します。Squid は webhook からその通話に応答するため、webhook は application を指している必要があります。
-
webhook URL を取得します。保存後に Twilio ability の status line に表示され、agent の電話回線では
provisioning.openAi.webhookUrlにあります。形式はhttps://[APP_ID].[REGION].squid.cloud/webhooks/openAiVoiceIncoming?integrationId=openai_voiceです。コードからは、client のsipTarget()が SIP URI とともにこれを返します。 -
OpenAI platform で project の Settings > Webhooks を開き、その URL で endpoint を作成して、
realtime.call.incomingevent を subscribe します。 -
endpoint の signing secret をコピーし、connector の Webhook Secret として保存します。
1 つの endpoint は connector を使用するすべての agent に対応します。通話の SIP headers が agent を指定します。project は登録されている endpoint にのみ通話を通知できるため、同じ project を使用する 2 つ目の application には独自の endpoint が必要です。また、1 つの project を使用する development application と production application には、それぞれ endpoint が必要です。
squid start で開始した backend の webhook URL には developer id が含まれ、public です。そのため development endpoint はこれを指せます。project のすべての endpoint はすべての通話を受信する点に注意してください。development application に存在しない agent 宛ての通話はその application によって拒否され、その agent を持つ application が応答します。
電話通話のフロー
- Twilio は agent の番号で通話を受信し、その処理方法を application に問い合わせます。Twilio connector は、agent、Twilio call、Twilio connector を指定する SIP headers とともに、通話を OpenAI project の SIP endpoint に bridge します。
- OpenAI は登録済み webhook に
realtime.call.incomingを POST します。OpenAI Voice connector は signature を検証し、headers から agent を読み取り、その agent の電話回線がこの connector を使用していることを確認します。認識できない通話は拒否されます。 - Squid は、回線の model、voice、言語ルール、Squid agent を説明する instructions、および
ask_agentとend_callの 2 つの tool を使用して通話を受け入れます。greeting を話すか、agent に opening line を作成させます。 - 通話中、各
ask_agentcall は、通話の context と memory を伴う Squid agent の 1 turn を実行し、回答を model に返して話させます。発信者と agent の turn は transcription に合わせて記録されます。 - 発信者が別れを告げると、model は短い farewell とともに
end_callを呼び出します。Squid は farewell の再生完了を待ち、その後 OpenAI と Twilio の両方の leg を切断します。
placeCall による outbound call は、着信者が応答すると step 1 から同じ経路をたどります。通話の目的が model の instructions に追加されます。
realtime model が行うことと agent が行うこと
model には、挨拶、雑談、確認には自ら応答し、自身では知り得ないすべてのことについては ask_agent を呼び出し、発信者の request をすべての詳細とともに渡すよう指示されます。これにより、agent を唯一の信頼できる情報源として保ちつつ、会話を円滑にします。知っておくべき影響は次のとおりです。
- 事実、ルール、tool は電話回線ではなく Squid agent に配置してください。model が knowledge base を直接見ることはなく、問い合わせを行います。
- agent の instructions は回答内容に適用されます。model の話し方は、Squid の組み込み phone instructions と回線の言語設定によって管理されます。
- 長時間かかる tool を使用すると、model は先に「少々お待ちください」と言います。通話で使用する AI function は高速に保ってください。
ブラウザ通話
同じ connector は Web ページからの通話にも対応します。Twilio や電話番号は必要ありません。ブラウザが microphone を開き、Squid が OpenAI との WebRTC session を broker して背後で agent を実行し、agent の voice がページで再生されます。
const call = await squid.ai().voice().startWebCall({ agentId: 'front-desk' });
call.onTurn((turn) => console.log(`${turn.role}: ${turn.text}`));
call.onEnd(() => console.log('The call ended'));
user は、agent と chat する場合とまったく同様に、agent の security rules のもとで通話を開始できます。その後、agent はその user として実行されます。browser call の voice、language、greeting までのすべての設定は、agent に OpenAI engine を使用する電話回線がある場合はその回線から、そうでない場合はこの connector からデフォルト設定を取得します。設定は call ごとに override できます。完全な API については Voice agents を参照してください。
コードからの OpenAI Voice connector の使用
npm install @squidcloud/openai-voice-client
import { SquidOpenAiVoiceClient } from '@squidcloud/openai-voice-client';
const openAiVoice = new SquidOpenAiVoiceClient(this.squid, 'openai_voice'); // your connector id
// Where phone calls go, and the webhook URL to register in the OpenAI project.
const { sipUri, webhookUrl } = await openAiVoice.sipTarget();
// The realtime models the account can put on a call, newest first, and the voices.
const { models } = await openAiVoice.listModels();
const { voices } = await openAiVoice.listVoices();
| Method | Executable name | 説明 |
|---|---|---|
sipTarget() | openAiVoiceSipTarget | 通話の送信先 SIP URI と、登録する webhook URL。API key が必要です。 |
listModels() | openAiVoiceListModels | account の realtime model。新しい順です。 |
listVoices() | openAiVoiceListVoices | realtime model の voice。 |
電話回線は Twilio connector を通じて設定され、通話には Squid 自身が応答します。これらの method は、Twilio connector と console が使用する構成要素です。
トラブルシューティング
| 症状 | 原因と対処方法 |
|---|---|
| 電話は鳴るが、応答されない | project に realtime.call.incoming 用の webhook endpoint がないか、別の場所を指しています。ability の status line にある URL を登録してください。webhook の登録を参照してください。 |
application log に INVALID_OPENAI_WEBHOOK_SIGNATURE が表示される | connector の Webhook Secret が、通話を送信した endpoint の signing secret ではありません。endpoint ごとに独自の secret があります。endpoint の作成または rotation 後に、もう一度コピーしてください。 |
| log に「Call … names no agent of this integration; rejecting it」と表示される | 通話の SIP headers は、この connector を使用していない電話回線の agent を指定しています。たとえば別の OpenAI Voice connector id で保存された回線、または project を共有する別 application からの通話です。 |
| ability に「Agent … is not wired up for OpenAI yet」と表示される | OpenAI connector を選択する前に回線が保存されました。ability を再度保存してください。 |
ブラウザ通話で OPENAI_VOICE_INTEGRATION_REQUIRED が発生する | agent に OpenAI engine を使用する電話回線がなく、application には複数の OpenAI Voice connector があります。integrationId を startWebCall() に渡してください。 |
| model が確認すると言った後、error または何もない回答を返す | ask_agent が失敗しました。agent の turn で error が発生しています。壊れた AI function や model provider error など、agent の失敗について application log を確認してください。 |
| farewell の直後に通話が切断される | 想定どおりです。farewell の再生完了後に通話は切断されます(または、OpenAI が再生なしを報告した場合は 15 秒後)。 |