1. はじめに
近年、Retell AI や Vapi といったリアルタイム音声AIプラットフォーム(Voice AI Agent)の進化が目覚ましく、自然なスピードでの日本語対話や外部API連携(Function Calling)が容易に実装できるようになりました。
しかし、これらの海外製音声AIサービスを「実際のビジネスの現場(電話)」で利用しようとすると、日本国内の固有の壁にぶつかります。それは、**「日本の電話番号(050や03)を海外の音声AIプラットフォームにどうやって接続するか」**という電話インフラの問題です。
本記事では、国内で広く利用されている Brastel My 050 を中継PBXである Asterisk に収容し、海外の最先端音声AIである Retell AI との間を相互接続(SIPブリッジ)した構成と、その過程で得られた技術的知見・ハマりどころの解決策を余すことなく紹介します。
2. なぜ直接接続できないのか?
Retell AI等のサービスでは、電話回線を接続する方法として Elastic SIP Trunk(固定IP間での相互通信)または特定の SIP URIへのダイレクトコール を求めてきます。
一方で、国内の個人・中小企業向け050事業者(Brastel My 050など)の多くは、端末のSIPクライアント(IP電話機やソフトフォン)がキャリアのサーバーに対して定期的にレジストレーションを行う SIP REGISTER方式 を採用しています。
両者の接続仕様には以下のような根本的な乖離があります:
| 項目 | Brastel My 050 等の国内回線 | Retell AI 等の海外音声AI |
|---|---|---|
| 接続方式 | SIP REGISTER方式 (動的レジスト) | SIP Trunk方式 (静的IP/ドメイン接続) |
| 主なプロトコル | UDP (5060) | TCP (5060/5061) 推奨 |
| 認証 | ユーザー名 & パスワードによる常時登録 | IP制限 or SIP Trunk情報による識別 |
| 転送先仕様 | レジストされたContact URI宛に着信を送る | 指定のSIP URIに直接INVITEを投げる |
この仕様のズレを吸収するため、中継サーバーとして「Asterisk」を置き、両側のSIPプロトコルを仲介する必要があります。
3. 全体システム構成
今回構築したシステム構成とシグナリング(INVITE)の流れは以下の通りです。
4. 技術スタック・検証環境
- 中継サーバー: AWS EC2 (t3.micro)
- OS: Ubuntu 24.04 LTS
- PBX: Asterisk 22.x (PJSIP チャネルドライバー)
- 電話番号: Brastel My 050 (050-XXXX-XXXX)
- 音声AIプラットフォーム: Retell AI
- 音声コーデック: PCMU (μ-law, 8kHz)
5. Asterisk pjsip.conf の設定例
Asteriskの最新SIPチャネルドライバーである chan_pjsip を使用した設定です。
Brastel側は UDP、Retell AI側はパケット制限防止のために TCP をトランスポートとして構成します。
また、AWS EC2などのNAT環境で必須となる external_signaling_address および external_media_address の設定を含めています。
; ===========================================================================
; /etc/asterisk/pjsip.conf
; ===========================================================================
[global]
type=global
user_agent=SIPBridge-Gateway
; --- Transport 設定 ---
[transport-udp]
type=transport
protocol=udp
bind=0.0.0.0:5060
external_signaling_address=YOUR_EC2_PUBLIC_IP
external_media_address=YOUR_EC2_PUBLIC_IP
local_net=172.31.0.0/16 ; AWS VPCのCIDR
[transport-tcp]
type=transport
protocol=tcp
bind=0.0.0.0:5060
external_signaling_address=YOUR_EC2_PUBLIC_IP
external_media_address=YOUR_EC2_PUBLIC_IP
local_net=172.31.0.0/16
; --- Brastel Trunk 設定 (REGISTER 方式) ---
[brastel-auth]
type=auth
auth_type=userpass
username=BRASTEL_USER_ID
password=BRASTEL_SIP_PASSWORD
[brastel-aor]
type=aor
contact=sip:softphone.spc.brastel.ne.jp
[brastel]
type=endpoint
transport=transport-udp
context=from-brastel
disallow=all
allow=ulaw
timers=no
100rel=no
outbound_auth=brastel-auth
aors=brastel-aor
from_user=BRASTEL_USER_ID
from_domain=softphone.spc.brastel.ne.jp
direct_media=no
rtp_symmetric=yes
force_rport=yes
rewrite_contact=yes
[brastel-identify]
type=identify
endpoint=brastel
match=softphone.spc.brastel.ne.jp
[brastel-registration]
type=registration
transport=transport-udp
outbound_auth=brastel-auth
server_uri=sip:softphone.spc.brastel.ne.jp
client_uri=sip:BRASTEL_USER_ID@softphone.spc.brastel.ne.jp
contact_user=BRASTEL_USER_ID ; 着信時にextenがこの文字列になる
retry_interval=60
forbidden_retry_interval=600
expiration=300
; --- Retell AI 設定 (Elastic SIP Trunking / TCP接続) ---
[retell-aor]
type=aor
contact=sip:sip.retellai.com:5060
[retell]
type=endpoint
transport=transport-tcp
context=from-retell
disallow=all
allow=ulaw
allow=alaw
allow=g722
aors=retell-aor
direct_media=no
rtp_symmetric=yes
force_rport=yes
from_domain=sip.retellai.com
outbound_proxy=sip:sip.retellai.com\;lr\;transport=tcp
[retell-identify]
type=identify
endpoint=retell
; Retell AIのSIP Trunk送信元IPアドレス帯域
match=18.98.16.120/30,3.42.144.0/23,143.223.88.0/21,161.115.160.0/19
6. Dialplan extensions.conf の設定例
ダイアプランでは、着信・発信時のルーティングおよび、電話番号フォーマットの変換を行います。
Retell AIは通常、発着信時にE.164フォーマット(例: +815012345678)を期待しますが、国内キャリアへの発信は国内フォーマット(例: 05012345678)にする必要があります。
; ===========================================================================
; /etc/asterisk/extensions.conf
; ===========================================================================
[from-brastel]
; 1. Brastelからの着信を受け付け、Retell AIへ中継
exten => _X.,1,NoOp(=== Inbound from Brastel: ${CALLERID(num)} -> ${EXTEN} ===)
same => n,Answer()
same => n,Wait(1)
; Retell AI宛にE.164形式でダイヤル (例: +8150XXXXXXXX)
same => n,Dial(PJSIP/retell/sip:+8150XXXXXXXX@sip.retellai.com,120)
same => n,NoOp(Dial Status: ${DIALSTATUS})
same => n,Hangup()
; REGISTER時のcontact_userに合わせた予備ルート
exten => BRASTEL_USER_ID,1,NoOp(=== Inbound from Brastel (contact_user matching) ===)
same => n,Answer()
same => n,Wait(1)
same => n,Dial(PJSIP/retell/sip:+8150XXXXXXXX@sip.retellai.com,120)
same => n,Hangup()
[from-retell]
; 2. Retell AIからの発信を受け付け、国内フォーマットに整形してBrastelへ架電
; +81XXXXXXXXX から始まる国際表記を国内表記 (0XXXXXXXX) に変換
exten => _+81.,1,NoOp(=== Outbound from Retell (intl format converted): 0${EXTEN:3} ===)
same => n,Set(CALLERID(num)=BRASTEL_USER_ID)
same => n,Dial(PJSIP/brastel/sip:0${EXTEN:3}@softphone.spc.brastel.ne.jp,60)
same => n,Hangup()
; すでに0から始まっている場合の発信ルート
exten => _0.,1,NoOp(=== Outbound from Retell: ${EXTEN} ===)
same => n,Set(CALLERID(num)=BRASTEL_USER_ID)
same => n,Dial(PJSIP/brastel/sip:${EXTEN}@softphone.spc.brastel.ne.jp,60)
same => n,Hangup()
; その他の汎用ルート
exten => _X.,1,NoOp(=== Outbound from Retell raw: ${EXTEN} ===)
same => n,Set(CALLERID(num)=BRASTEL_USER_ID)
same => n,Dial(PJSIP/brastel/sip:${EXTEN}@softphone.spc.brastel.ne.jp,60)
same => n,Hangup()
7. ハマったポイントと解決策
実際に検証・構築するうえで解決した、代表的な障害ポイント4点です。
① REGISTERは成功するのに着信が拒否される
pjsip show registrations で登録ステータスが Registered になっているにもかかわらず、着信がAsteriskまで届かない、あるいは届いた瞬間に 503 Service Unavailable や 401 Unauthorized で切断されるパターンです。
-
原因: Asteriskの
identifyセクションで、キャリアサーバーのIPアドレス(Brastelのドメイン名)とエンドポイントが紐づいておらず、Asterisk側が「認証外のアクセス」と判断していました。 -
解決策: ドメイン名またはIPで識別できるように
pjsip.conf内に[brastel-identify]を明示的に設定し、match=softphone.spc.brastel.ne.jpを追加しました。
② 通話はつながるが「無音」または「片通話」になる
制御信号(SIPシグナリング)は正常に通って電話が応答したものの、音声が一切聞こえない、または一方の音声しか届かない現象です。
-
原因: AsteriskがAWS EC2などのプライベートサブネット内に配置されている場合、相手に送るSDP(セッション記述プロトコル)の接続先IPアドレスに、EC2のローカルIP(
172.31.X.X等)が記述されてしまい、RTP(音声実データ)の宛先迷子が発生していました。 -
解決策: PJSIPのトランスポート設定において
external_signaling_addressとexternal_media_addressにEC2のElastic IPを設定し、NAT越えを明示します。さらに、RTPの対称ルーティングを有効にするためエンドポイント側にrtp_symmetric=yes、force_rport=yes、direct_media=noを設定しました。 -
ファイアウォール: AWSのSecurity Groupにおいて、SIP制御(
5060/UDP,TCP)のほか、RTP音声データ用のポート(/etc/asterisk/rtp.confで設定される10000-20000/UDP)をフルオープンにする必要があります。
③ Retell AI ➔ Asterisk 接続で SIP/2.0 513 Message Too Large が発生する
Retell AIから着信をAsteriskへ送信(Dial-to-SIP)した際、接続エラーが発生する問題です。
-
原因: Retell AI側でサポートされる音声コーデック候補や追加のSIPヘッダーが多量に含まれると、INVITEパケット全体のサイズがUDPの一般的なMTUサイズ(通常1500バイト、安全限界はより低い)を上回ります。これにより、ルーターやキャリア側でパケットがフラグメンテーション(断片化)され、UDP経由で正しく組み立てられず
513 Message Too Largeとして拒否されます。 - 解決策: AsteriskとRetell AIの接続トランスポートに TCP を使用します。TCPであればバッファサイズ制限やフラグメンテーションのペナルティを受けず、大きなパケットサイズでも安全に通信できます。
④ 発信者番号(Caller ID)の偽装制限
Retell AIからAsterisk経由で発信する際、任意のCaller IDヘッダーを送信しても、キャリア側で拒否されたり、通知圏外になります。
- 原因: 当然ながら、日本の通信キャリアは契約番号以外の発信元番号(なりすまし)を厳格に拒否します。
-
解決策:
extensions.confの[from-retell]において、発信ダイヤルを投げる前にSet(CALLERID(num)=BRASTEL_USER_ID)で強制的に自社の契約番号・IDに上書きする処理を入れることで解決しました。
8. 疎通確認テスト項目
検証時に実施したテストマトリクスです。これらを1つずつクリアすることで、商用利用に耐えうる接続品質を担保しました。
| テストNo | テスト項目 | 確認ポイント |
|---|---|---|
| 1 | キャリアレジストレーション |
pjsip show registrations で Registered であること |
| 2 | インバウンド着信 | 050へ発信した際、AsteriskのCLIログにINVITEが出ること |
| 3 | AIエージェント接続 | 着信から1秒以内にRetell AIエージェントが日本語で応答すること |
| 4 | 双方向クリア音声 | 音声遅延が許容値(通常150ms以内)で、双方向の音声がはっきり聞こえること |
| 5 | 切断制御 | ユーザー側、AI側のどちらから電話を切っても即時切断されること |
| 6 | アウトバウンド発信 | Retell AIからAPI経由で発信した際、日本の携帯電話に着信すること |
9. まとめ
音声AI(Retell AIなど)は非常に賢く、プログラミングだけでエージェントを作成できます。しかし、それを 「日本の一般電話網」 に組み込もうとすると、SIPやRTP、トランスポートレイヤー(UDP/TCP)、NATといった電話通信インフラ特有の知識が不可欠になります。
今回の構成により、以下のような高度なAI電話が実現可能になりました:
- 営業時間外の自動予約・FAQ受付
- 問い合わせに対するAI自動応答 ➔ 必要に応じて人間のスマホへ転送
- 不動産反響への即時自動架電(自動アプローチ)
10. 技術的なサポート・構築代行について
今回紹介した「Brastel - Asterisk - Retell AI」の接続は検証用構成ですが、実際の商用導入においては、「本番運用のための冗長化」「同時通話数のスケール対策」「セキュリティ制限」 など、さらにシビアなインフラ設計が必要になります。
「自社で保有している050/03回線を音声AIと接続したい」
「着信はできたが、無音や片通話が発生して困っている」
「APIと連携した自動予約AI電話をゼロから構築してほしい」
といった課題をお持ちの企業・開発者様向けに、接続・構築の専門代行サービスを提供しています。
お持ちの回線が接続可能かの「無料診断」も実施しておりますので、詳細やご相談は下記ページからお気軽にお問い合わせください。
👉 [SIPBridge 日本番号対応AI電話構築代行] (https://www.sipbridge.dev/agency)