8週間。これが、Autorの私たちのチームが「医療クリニック向けの音声AI受付を作るべきだ」というところから、24時間年中無休で実際の患者の電話を取り扱えるようになるまでに要した期間です。デモでも、PoC(概念実証)でもありません。現在、カナダ国内の歯科およびヘルスケアのクライアントに対して、月あたり数千件の自動化された通話を処理する本番システムになっています。ここまでのあらゆる技術的・ビジネス上の意思決定と、その裏付けとなる理由をすべてご紹介します。
出発点
オンタリオ州の歯科クリニックが、私たちが何度も聞いてきた問題を抱えて相談に来ました。営業時間外に電話に誰も出ないため、患者を失っているというのです。スタッフは、毎回同じ台本に沿った通話対応で、1日あたり3時間以上を費やしていました。予約確認、保険の質問への対応、緊急の電話の振り分けです。自動化は望んでいましたが、これまで試した市販のどの解決策も「ロボットと話している」ように聞こえ、患者が混乱してしまう内容でした。
私たちは、その時点ですでに40以上のAIプロダクトを構築していました。音声AIデモと、実際の患者からの実通話を扱える音声AIの間には大きなギャップがあることを理解していました。患者はときに不安になり、ときに怒り、ときに単に状況が分からないだけです。そこで8週間の計画を立て、作業に取りかかりました。
週1〜2:音声スタックの選定
最初の意思決定が最も難関でした。どの音声認識(STT)および音声合成(TTS)プロバイダを使うかです。2週間かけて、4つのSTT候補と3つのTTS候補をベンチマークしました。
音声認識:Deepgramが勝ちました。 Deepgram、Google Cloud Speech、AWS Transcribe、Whisper(セルフホスト)をテストしました。Deepgramは、多様なアクセントをもつカナダ英語に対して、遅延と精度の最良の組み合わせを提供してくれました。ベンチマークでは、Deepgramの平均「最初のバイト遅延」が180msで、Google Cloud Speechは320msでした。電話会話において、この140msの差は「自然」と「不自然」の境目です。Whisperは最も正確でしたが、リアルタイム用途では使い物になりませんでした。GPUインスタンス上でも、ストリーミング遅延は400ms超でした。
音声合成:ElevenLabs。 「ロボットに話しかけている」と反応されない声が必要でした。ElevenLabsのTurbo v2モデルは、150msの遅延でほぼ人間品質を実現します。ブラインドスタディで30人の実患者に試してみたところ、私たちがAIだと伝えるまでに22人がAIと気づきませんでした。
テレフォニー:Twilio。 これは難しい選択ではありませんでした。TwilioのMedia Streams APIは、WebSocket経由で双方向の音声ストリーミングを提供します。過去に使ったことがあり、エッジケースも理解していました。さらに、カナダの番号のプロビジョニングが堅牢であることも分かっていました。Vonageも一瞬検討しましたが、テストではWebSocketの実装に信頼性の問題がありました。
週3〜4:頭脳 — GPT-4よりAnthropic Claudeを選んだ理由
ここから面白くなります。患者の意図を理解すること、予約スケジューリングを管理すること、保険の質問に対応すること、そして人間へ転送すべきタイミングを判断すること――会話の中核ロジックを担える言語モデルが必要でした。
私たちは、GPT-4とAnthropic Claudeの両方を、200件の模擬患者会話で走らせました。その結果は私たちを驚かせました。
Claudeは「分かりません」と言うのがうまかった。 医療では、作り話をするよりも不確実性を認めるほうがずっと悪くありません。両モデルにエッジケースを投げてみたところ(稀な保険ケース、クリニックが提供していない特定の手技に関する質問など)、GPT-4のほうが「それっぽい答え」をでっち上げる傾向が強いことが分かりました。Claudeは、自信がないことを言い、患者をスタッフにつなぐ提案をする可能性がより高かったのです。ヘルスケア用途において、この振る舞いには金に換えられない価値があります。
Claudeの指示追従がより一貫していた。 モデルには受付係としての役割に厳密に留まってほしかったのです。医療アドバイスは一切なし。データベースを確認せずに料金について約束しないこと。両モデルを1週間、プロンプトエンジニアリングで調整した後、Claudeは1,000件以上のテスト会話において境界線をより確実に維持していました。
私たちは、構造化されたツール利用(tool use)でClaudeを会話エンジンとして構築しました。モデルは、予約の空き状況確認、患者レコードの照会、通話の振り分けといった関数を呼び出します。文字列の解析でつないだのではなく、きれいなツール利用インターフェースを通じて実行します。
週5:統合レイヤー
週5は配管(plumbing)のすべてでした。音声AIをクリニックの実際のシステムにつなぐための統合レイヤーを作りました。
アーキテクチャ:AWS ECS上のNestJSバックエンド。 NestJSを選んだのは、私たちのチームがTypeScriptで考えるからです。NestJSは、肥大化せずに依存性注入とモジュール構造を提供してくれます。サービスはECS Fargate上で動かします。サーバーの運用は避けたかったからです。そしてFargateのオートスケーリングが、すべての患者が同時に電話をかけてくる9時の通話急増にも対応してくれます。
データベース:Prisma ORMを使ったPostgreSQL。 すべての通話をログに残します。完全なトランスクリプト、意図分類、実行したアクション、通話時間、そして結果です。このデータこそが、システムを時間とともに良くしていく原動力になります。Prismaを選んだ理由は、TypeScriptコードとデータベースの型安全性により、過去に生SQLで構築したプロジェクトで悩まされていたバグの一種をまるごと排除できたからです。
CRM連携:HubSpotおよびSalesforce。 多くのクリニックは、どちらか一方を使っています。そこで両方に対応するアダプタを作成し、AI受付が患者の履歴を取得し、通話サマリーを反映できるようにしました。HubSpot連携は3日で完了。Salesforceは8日でした。Salesforce APIで作業したことがある方なら、理由は分かるはずです。
週6:レイテンシ最適化 — 背水の週
週6はほぼ崩れかけました。エンドツーエンドのレイテンシ――患者が話すのをやめてから、AIが応答し始めるまで――の平均が2.1秒でした。これは電話会話としては受け入れられません。1.2秒を超えると、発信者は「もしもし?」と言い直し始めます。
800ms未満にするためにやったことは以下です:
すべてをストリーミングする。 完成したSTTトランスクリプトを待つのをやめ、部分結果をストリーミングするように切り替えました。Deepgramが安定した部分トランスクリプトを返してくれた瞬間に、それをClaudeへ送信します。Claudeは応答をストリーミングで返し、その一方でClaudeが残りを生成している最中にも、最初の文からTTSを開始します。これにより往復で600msを削減できました。
プロンプトキャッシュ。 Claudeのプロンプトキャッシュ機能は大きな勝利でした。私たちのシステムプロンプトは約2,000トークンで、クリニック固有の情報、会話ルール、利用可能なツールなどが含まれています。プロンプトキャッシュを使うと、このシステムプロンプトは一度だけ処理され、ターンごとに再利用されます。これだけで、1ターンあたり200〜300msの削減になりました。
コネクションプーリングとキープアライブ。 Twilioには永続的なWebSocket接続、ClaudeのAPIには永続的なHTTP/2接続、そしてDeepgramにも永続的な接続を維持します。これらのいずれかをコールドスタートすると、100〜200msの追加遅延が発生します。
最適化を1週間行った後、応答時間の中央値は740msになりました。95パーセンタイルは1.1秒です。患者は遅延に気づかなくなりました。
週7:エッジケースと障害モード
私たちは週7を「うまくいかないときに何が起きるか」にすべて費やしました。デモとプロダクトを分けるのがこの週です。
患者がAIが扱えない言語を話したらどうなる? 最初の3秒で言語検知を組み込みました。フランス語、マンダリン語、広東語(オンタリオ州のクリニックで最も多い英語以外の3言語)だと検知した場合は、即座に人間へルーティングするか、その言語で事前収録したメッセージを再生します。
AIが混乱したらどうなる? 自信スコアリングの仕組みを作りました。Claudeの応答の確信度が、2ターン連続で私たちの閾値を下回った場合、システムは「担当チームにつなぎます」と言って通話を転送します。患者が混乱したAIとのループに閉じ込められることは、決してあってはなりません。
Deepgram や Claude がダウンしたらどうする? 外部依存関係ごとにサーキットブレーカーを設けます。STT が失敗したら、DTMF メニュー(「1 を押して予約」)へフォールバックします。LLM が失敗したら、スタッフへのテキスト通知つきでボイスメールにルーティングします。低トラフィックの時間帯に本番環境で実際にサービスを停止させることで、あらゆる失敗パターンをテストしました。
PIPEDA のコンプライアンスはどうなってる? ここはカナダです。HIPAA ではなく、PIPEDA のもとで患者データを取り扱う必要があります。すべての通話録音は、保存時および転送時に暗号化しています。書き起こしはカナダのデータセンターに保存します。クリニックが指定した保管期間が過ぎたら録音を自動削除するデータ保管ポリシーを構築しました。さらに、各通話開始時の同意フローが PIPEDA の要件を満たすことをプライバシーコンサルタントとともに確認しました。
第8週:ローンチと最初の1,000件の通話
私たちは木曜日の17時にローンチしました—ちょうどクリニックが閉まるタイミングです。AI レセプショニストは、ソフトローンチとして週末の営業時間外のすべての通話を対応します。
最初の週末:127件の通話。89件は完全にAIが対応。24件はオンコール番号へ転送(正しく—緊急または複雑なケースでした)。14件はAIが助ける前に通話を切りました。これは初日の70%が完全自動化という結果です。
最初の1か月以内に、実通話データに基づいてプロンプトを調整したことで自動化率は82%まで上がりました。クリニックは月あたり推定45スタッフ時間を節約できました。さらに重要なのは、電話に出てくれる競合に、営業時間外の患者を取りこぼすことがなくなったことです。
別のやり方をするなら
機能からではなく、レイテンシ予算から始める。 私たちは初日から 800ms のレイテンシ目標を設定し、その予算の範囲内で各コンポーネントを作るべきでした。ところが、先に機能を作ってから、第6週に慌てて最適化しました。レイテンシが最初から「最重要な制約」になっていれば、アーキテクチャはよりすっきりしていたはずです。
モニタリングダッシュボードはもっと早く作る。 第7週までリアルタイムの通話モニタリングがありませんでした。つまり、第5週と第6週は部分的に「見えない」状態でした。今は、Loquent の各デプロイで初日からモニタリングダッシュボードを提供します。
もっと早く実際の患者でテストする。 シミュレートした会話は、どれだけ良く作っていても、実際の患者が電話で話す様子は捉えられません。患者は文中で黙り込みます。別の誰かが同席している人と話をします。いったん電話を置いて、戻ってきます。こうしたパターンを第8週で見つけましたが、本来は第4週で見つけるべきでした。
重要な学び
レイテンシはプロダクトそのもの。 音声AIでは、応答時間が「役に立つ受付」なのか「うるさいロボット」なのかを決めます。初日からそれを予算に組み込むべきです。
モデルは“最高のケース”ではなく“失敗パターン”で選ぶ。 Claude は GPT-4 より賢かったから勝ったのではありません。より丁寧に失敗したからです。不確実であることをそれと認め、でたらめを作り話すことがありませんでした。
カナダにおけるヘルスケア向け音声AIは、今すでに現実的に導入可能。 PIPEDA のコンプライアンスは対応可能で、カナダ国内データ保管の選択肢は主要なクラウドプロバイダーすべてにあります。また、患者は多くの人が想像する以上に AI の受付に前向きです。
80/20 ルールはきっちり効く。 自動化 80% への到達には3週間かかりました。80% から 82% への引き上げは、プロンプト調整と例外ケース対応の追加でさらに4週間かかりました。スケジュールはそれに合わせて計画してください。
転送経路を先に作る。 人間へ引き継ぐタイミングをAIが理解できることは、あらゆるシナリオを処理できることより重要です。うまく転送できると信頼が生まれます。混乱したAIはそれを壊します。
これが、私たちが Loquent に作り替えたシステムです。つまり、私たちの本番環境向け音声AIプラットフォーム。現在はカナダ中の複数のヘルスケアおよび歯科クライアントに提供されており、月に何千件もの通話を処理しています。
もし同様のものを作っているなら、ぜひお話を聞かせてください。hello@autor.ca まで連絡するか、autor.ca をご覧ください。




