Gladia、Deepgram、AssemblyAI、Speechmatics、Soniox、ElevenLabsをbot単位で選択できます。自分のAPI key、自分のリージョンを使い、プロバイダー固有のオプションはすべてそのまま渡せます。

音声認識(speech-to-text)プロバイダーの選定は、一度決めれば終わりという判断ではありません。自社ドメインでの精度、1時間あたりの価格、必要な言語、データをEU内にとどめたままDPAを締結してくれるかどうか、3人が同時に話したときに話者分離がどこまで持ちこたえるか。そのいずれもが変化しますし、すべてのお客様にとって同じ答えになるものは1つもありません。
そこで私たちは、選ぶのをやめました。プロバイダーはbot単位で選択でき、すでに手元にある録音についても後から選び直せます。
選べるプロバイダー
| プロバイダー | バッチ | ライブ |
|---|---|---|
gladia | ✅ | ✅ |
deepgram | ✅ | ✅ |
assemblyai | ✅ | ✅ |
speechmatics | ✅ | ✅ |
soniox | ✅ | ✅ |
elevenlabs | — | ✅ |
ElevenLabsはストリーミング専用です。他の5つは両方に対応しています。
ほとんどの方が求めるのはバッチでしょう。ミーティングが終わると音声が送信され、話者ラベルと単語単位のタイムスタンプが付いた文字起こしがwebhookで返ってきます。ライブは、ミーティングの進行中にWebSocketで文字起こしのセグメントが届く方式で、その場で反応する必要がある用途向けです。
この2つは独立して設定でき、同じbotで別々のプロバイダーを使って両方を動かすこともできます。速いライブのフィードと、より精度の高い最終的な文字起こしを両立したい場合に有効です。
バッチ
{
"meeting_url": "https://meet.google.com/abc-defg-hij",
"bot_name": "Recording Bot",
"transcription_enabled": true,
"transcription_config": {
"provider": "speechmatics",
"region": "eu2",
"api_key": null,
"custom_params": null
}
}フィールドは4つです。providerを省略した場合のデフォルトは"gladia"です。region、api_key、custom_paramsはいずれもデフォルトがnullで、詳細は後述します。
transcription_configはtranscription_enabledがtrueのときは必須で、falseのときは無視されます。

botが終了すると、transcription_providerとtranscription_idsがbotのレコードとwebhookのpayloadに返されます。またGET /v2/bots/:bot_id/statusは、プロバイダー自体をポーリングして取得した最新のtranscription_statusを返します。値はnot-applicable、not-started、queued、processing、done、errorのいずれかです。
リージョンの固定
これらのプロバイダーの多くは複数のリージョンで稼働しており、多くのお客様にとってはこの点がすべてです。
| プロバイダー | バッチのリージョン | ライブのリージョン |
|---|---|---|
gladia | グローバルendpointのみ | us-west、eu-west |
deepgram | global、eu | global、eu |
assemblyai | us、eu | us、eu |
speechmatics | eu1、eu2、us1、us2、au1 | バッチと同じ |
soniox | us、eu、jp | バッチと同じ |
elevenlabs | — | global、us、eu、in |
プロバイダーが持たないリージョンを指定すると、bot作成の時点で許可されている値の一覧とともに400が返ります。後から不意に発覚することはありません。GladiaのバッチAPIはグローバルのみのため、バッチの設定でprovider: "gladia"とともにregionを渡すと拒否されます。ライブAPIにはリージョンがあります。
regionをnullのままにすると、妥当なデフォルトを選びます。DeepgramとAssemblyAIはeu、Speechmaticsはeu1、Sonioxはusです。
音声を特定の法域から一切出したくない場合は、Bring Your Own Storageと組み合わせてください。プロバイダーはバケット上の署名付きURLから音声を取得するため、バケットの所在地とプロバイダーのリージョンの組み合わせが、音声が実際にどこへ行くかを決定します。
自分のAPI keyを持ち込む
api_keyを渡すと、私たちのアカウントではなく、そのプロバイダーにおけるあなたのアカウントを使用します。
{
"transcription_config": {
"provider": "deepgram",
"region": "eu",
"api_key": "your-deepgram-key"
}
}keyは保存前にAES-256-GCMで暗号化され、botへ渡る間も暗号化されたままで、使用する時点でbotが復号します。botのデータを削除すると、保存されているkeyは上書きされます。
使う理由は2つあります。1つ目はコストです。私たちのkeyでの文字起こしは1時間あたり0.25 token、あなたのkeyなら0.05 tokenで課金されます。2つ目は、自分でトレーニングしたカスタム語彙や、私たちが持っていない条件の契約など、自分のアカウントでしか実現できないことがあるためです。
BYOKはProプラン以上でご利用いただけます。対象外の場合はFST_ERR_BYOK_TRANSCRIPTION_NOT_ENABLED_ON_PLANが返ります。
プロバイダーのオプションは、そのまま素通しする
正規化されたオプション層は意図的に作りませんでした。どのプロバイダーにも他にはない機能があり、それを最大公約数にならしてしまうと、そのプロバイダーを選んだ理由そのものを捨てることになるからです。
custom_paramsは、ほぼ書いたままの形でプロバイダーに渡ります。
{
"transcription_config": {
"provider": "speechmatics",
"region": "eu2",
"custom_params": {
"transcription_config": {
"language": "en",
"diarization": "speaker",
"operating_point": "enhanced"
}
}
}
}組み立てやすければ、ドット記法も使えます。
{ "custom_params": { "diarization_config.min_speakers": 2 } }ライブの設定では、validationの前にフラット化が解除されるため、プロバイダーが実際に受け取る形でvalidationされます。バッチの設定では、フラットなキーは書かれたままvalidationされ、展開されるのは送信時です。
ライブの設定では、4つのフィールドがpipeline側で設定されるため、送信すると拒否されます。encoding、sample_rate、bit_depth、channelsです。特にサンプルレートは、ミーティングの音声からプロバイダーごとにネゴシエートされるため、上書きするとストリームが壊れます。代わりにstreaming_config.audio_frequencyを使ってください。
話者分離はデフォルトで有効です。無効にすると話者ラベルのない文章の塊が返ってくるうえ、少なくとも1つのプロバイダーは明示的に指定しない限り発話を1つも返しません。custom_paramsで明示した値が優先されます。
落とし穴:バッチとライブは形が違う
これは半日を溶かしかねない点なので、はっきり書いておきます。同じプロバイダーであっても、ライブAPIとバッチAPIは同じ形のパラメータを受け付けません。
Gladiaが最も分かりやすい例です。バッチは翻訳の設定をトップレベルで受け取ります。ライブではrealtime_processingの下にネストする必要があります。
{
"streaming_config": {
"mode": "transcription",
"output_url": "wss://your-app.example.com/transcripts",
"audio_frequency": 24000,
"transcription": {
"provider": "gladia",
"region": "eu-west",
"api_key": "your-gladia-key",
"custom_params": {
"language_config": { "languages": ["ru"] },
"realtime_processing": {
"translation": true,
"translation_config": { "target_languages": ["en"] }
}
}
}
}
}ライブのパラメータはstrictモードでvalidationされます。ライブセッションのAPIは未知のキーを問答無用で拒否するため、ミーティングを失敗させるくらいならbotの作成を失敗させたい、という判断です。1階層下に属するキーを送った場合は、エラーが正しい場所を教えてくれます。
'translation' is not a top-level field of the gladia live API —
did you mean 'realtime_processing.translation'?
(the live API shape differs from batch)バッチとライブのどちらのパラメータも、bot作成時に各プロバイダー自身のschemaと突き合わせて検証されます。そのため、入力ミスは1時間後の文字起こし失敗ではなく、1秒後の400として返ってきます。その厳密さについて、注意点が2つあります。バッチのパースは寛容なので、未知のバッチのキーはvalidationを通過し、そのまま転送されてプロバイダーの処理に委ねられます。未知のキーを拒否するのはライブだけです。またElevenLabsのライブのパラメータは、突き合わせるべき公開schemaが存在しないため、validationなしでそのまま渡されます。
ライブの出力
mode: "transcription"を指定すると、プロバイダーのセッションを開き、ミーティングの音声を流し込み、イベントをJSONとしてあなたのoutput_urlに転送します。
{
"event": "transcript.segment",
"bot_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"data": {
"text": "so the migration lands Thursday",
"isFinal": true,
"utteranceStart": 12.44,
"utteranceEnd": 14.91,
"confidence": 0.97,
"speaker": { "name": "Alice", "id": 1 },
"words": []
}
}このほか、使用されたプロバイダーを含むsession.started、翻訳を要求した場合のtranslation、そしてerrorがあります。中間のネットワーク機器がアイドル状態のソケットを閉じないよう、30秒ごとにpingを送ります。
制約が1つあります。私たちのプラットフォームのkeyで動作するライブセッションは、管理下のプロバイダー(現時点ではGladia)に限られます。それ以外のプロバイダーでライブの文字起こしを行うにはBYOKのkeyが必要で、ミーティング開始時に発覚するのではなく、bot作成の時点でFST_ERR_STREAMING_TRANSCRIPTION_KEY_UNAVAILABLEとして拒否します。
後から選び直す
POST /v2/bots/:bot_id/retranscribe{
"transcription": {
"provider": "assemblyai",
"region": "eu",
"api_key": "your-assemblyai-key"
}
}保存された音声が別のプロバイダーに再送信され、botの設定が更新されます。これが、ベンダーのデモ音声ではなく自社のミーティングで2社をA/Bテストする方法であり、失敗した文字起こしを復旧する方法でもあります。
botのデータを削除すると、?delete_from_provider=true(デフォルト)によってプロバイダー側からも文字起こしが削除されます。自分のkeyを指定していた場合は、そのkeyが使われます。
プロバイダーの調子が悪い日に何が起きるか
送信に失敗した場合、5秒後と15秒後に2回再試行し、合計3回試みます。対象となるのは、再試行で成功する見込みがあるエラーだけです。rate limit、5xx、接続およびポーリングのタイムアウト、ネットワークレベルの障害、そしてプロバイダーが2xxを返したもののbodyにジョブIDが含まれていなかった場合です。認証エラー、不正な入力、サポートされていない操作は決して再試行しません。2回目もまったく同じように失敗するからです。
再試行のたびに、再送信の前にcallbackのシークレットをローテーションします。これは実際に起こりうる競合を塞ぐためです。私たち側でresponseがタイムアウトしたジョブを、実際にはプロバイダーが受理していた場合、そのcallbackはすでに存在しないシークレットに対して届くため拒否されます。再試行したジョブと競合して、1つのチャンクから2つの文字起こしができてしまうことはありません。
別のプロバイダーへの自動フェイルオーバーはありません。 障害の最中に気づいていただくより、はっきり書いておきたいと考えています。選択したプロバイダーが再試行後も失敗した場合、botはTRANSCRIPTION_FAILEDとともにfailedで終了しますが、録画も音声のアーティファクトもすべて残っています。復旧手段はretranscribeの呼び出しで、必要であれば別のプロバイダーを指定できます。黙ってベンダーを切り替えれば、同意していない法域で、同意していない価格で文字起こしが行われることになります。そのため、この判断はお客様に委ねています。
関連記事
- Bring Your Own Storage — プロバイダーが読み取る音声の実際の保存先を管理する
- Meeting BaaS APIリファレンス