OpenAI Realtime API の unknown_parameter で設定が全部消える
OpenAI の Realtime API で、日本語で実況するキャラクターを動かしています。昨日まで日本語で喋っていた AI が、今日は突然こう言って登場しました。
Hey there! What would you like to talk about?英語で、声も違い、人格の指示もすべて消えた素のアシスタントです。コードの差分は、設定にフィールドを一つ足しただけでした。
実測: 未知のパラメータ 1 つで session.update が丸ごと拒否される
画面のデバッグログに、こんなエラーイベントが出ていました。
type: invalid_request_error
code: unknown_parameter
param: session.max_response_output_tokensmax_response_output_tokens は、ベータ時代の Realtime API で応答のトークン数を制限するフィールドの名前です。当時の情報を元にそのまま足したのですが、GA の session オブジェクトではこの名前は受理されませんでした。
問題は、拒否のされ方でした。このフィールドだけが無視されるのではなく、`session.update` が丸ごと拒否されるのです。同じ session.update に入れていた人格の指示、声、VAD の設定、転写言語が全部適用されず、セッションは初期状態のまま始まります。だから英語の素のアシスタントが出てきました。
さらに、このエラーは画面のログにしか出ていませんでした。永続化していたログは会話の内容と音声の状態だけで、API のエラーイベントは書き出していなかった。何が起きたかを追うのに、まず「エラーが出ていたこと」に気づくまで時間がかかりました。
機構: 「部分的に効かない」ではなく「全部効かない」
設定が効かないとき、私は「そのフィールドだけが無視されている」と思い込んでいました。実際には、session.update は一つでも受理できないフィールドがあると全体が拒否されます。失敗の様式が「部分」ではなく「全部」です。
この様式だと、症状から原因にたどり着けません。人格が消えた、声が違う、言語が違う — どれも「足したフィールド」とは無関係に見えるからです。
どう直したか
- 適用を待ってから始める。
session.updateを送ったら、サーバーからのsession.updatedイベントで設定が反映されたことを確認してから会話を開始する。session.updatedが来ずにエラーが来たら、接続自体を失敗させる。素の状態で始まるよりも、始まらない方がましです - API のエラーイベントは必ず永続ログに書く。 画面のログは見ていないと消えます
- 新しいフィールドはデプロイ前に実キーで受理を確認する。 名前が合っているかどうかは、送ってみないと分かりません
どこで止まるか
session.update全体が拒否されるというのは、私の構成での観察です。API の仕様として保証されている挙動かどうかは確認できていません。ただ、受理されたかどうかをsession.updatedで確認する設計にしておけば、どちらであっても安全側に倒れます- この事故でテスト 2 回分のデータが無効になりました。その 2 回は「人格が消えた状態」で走っていたからです。計測の前に、どのビルド(コミット SHA)と、どの設定で走ったかを記録しておくべきでした。記録がなかったので、どこまでのデータが有効かを遡って判定することもできませんでした
この構成で気をつけること
- 設定の適用は「送った」ではなく「
session.updatedが返った」で判定する。返らなければ接続を失敗させる - API のエラーイベントは画面ではなく永続ログへ。特に接続直後のイベントは、見ている人がいない時間帯に出る
- 「部分的に効かない」と「全部効かない」の両方を疑う。後者は症状が設定内容と無関係に見える
- 計測データには、ビルドの SHA と設定内容を一緒に記録する
設定を一行足しただけで人格が消えたのは、その一行が悪かったのではなく、拒否を確認せずに始めていた設計の問題でした。「送った」と「適用された」は別の状態です。