アドベントカレンダー最終日なので、今日は技術詳細じゃなくて お気持ち表明 です。
この数週間、Rustで「SIP UAS + RTP + 録音 + ASR/LLM/TTS」の音声ボット基盤を作ってきて、思ったことをそのまま書きます。
まず、なにを作っているのか(超短く)
SIPフォン(Zoiperみたいなやつ)から電話をかけると、
- SIPで呼が確立して
- RTPで音声が流れてきて
- それを録音する
- ASR/LLM/TTSを活用する
…というところまでをMVPとして作りました。
“会話はこれからが本番だけど、まず土台ができた、という状態です。
このプロジェクトで一番やりたかったこと
やりたかったのは「電話でしゃべるボット」そのものもあるけど、実はそれ以上に、
- SIP/RTPみたいな「古くて強い世界」
- LLM/音声AIみたいな「新しくて雑に進化する世界」
この2つを ちゃんと繋げられる設計 にしたかった。
雑にやると、プロトコルの泥とAIの泥が混ざって、たぶん二度と触れないコードになるので、
最初に「責務の境界」をちゃんと引くことを一番大事にしました。
“設計” を先に作って良かった
- transport / sip / rtp / session / app / ai / media / http
- 依存方向は下向きだけ
- 逆向きはイベントで通知する
みたいな話を先に固定しておいたのは、結果的にかなり効きました。
正直、実装中は「この責務どこに置くべき?」が毎日出てくるけど、迷ったときに戻れる場所があると強い。
そしてコードを書かせる時も「この境界を守れ」が伝えやすい。
“神様がある”だけで、コード生成もレビューもブレにくくなりました。
逆に、難しかったのは「技術」より「現実」
SIP/RTPって「仕様を知る」だけじゃ足りなくて、
- 相手が何を許容するか(ソフトフォン差)
- NATやIP広告(ADVERTISED_IP問題)
- RTPが来ない/来てるけど無音/途切れる
- “無言” が一番つらい(AI失敗、RTP途絶)
みたいな、現実の地雷が多い。
だからこそ、MVPで “録音” を入れたのは正解だったと思っています。
録音が残ると、「音が来てるかどうか」が一瞬で分かる。
これは開発速度に直結しました。
MVPを「ここまで」と決めたのも正解だった
途中で何度も「LLMを繋ぎたい」「ずんだもんに喋らせたい」って気持ちが先行しそうになったけど、
一旦 “通話基盤” に集中して、
- INVITE/ACK/BYE が通る
- RTPを受信して録音できる
- 録音をHTTPで見られる
を先に固めたのは良かったです。
AIは後から差し替えられるけど、SIP/RTPが不安定だと全部崩れる。
土台を作ってから上を乗せるのが結局いちばん早い。
この連載で一番伝えたかったこと
SIP音声ボットって、派手なLLMの話に比べると地味で泥臭いんだけど、
- “境界を引く”
- “MVPを固定する”
- “観測(録音・ログ相関)を先に入れる”
- “無言回避のポリシーを決める”
みたいなソフトウェア設計の話が、めちゃくちゃ効く分野だと思っています。
結局、SIP/RTPもAIも「失敗する前提」なので、設計がないと壊れた時に戻れない。
次にやること(来年の自分へ)
この先のTODOは山ほどあります。
でも、MVPの基盤ができたので、これらは“積み上げ”として進められるはず。
おわりに
アドベントカレンダーで書くことで、
- 仕様が固定されて
- 実装の位置が整理されて
- 次に何をするかも見えた
という意味で、自分にとってかなり良い整理になりました。
もし同じことをやる人がいたら、
- まず録音を入れる
- まずMVPを固定する
- まず境界を引く
をおすすめします。
来年は、ずんだもんにちゃんと電話対応させます。