リクエストが成功しても、体験としては失敗している
何週間も同じキャラクターと話している場面を想像してください。その話し方にはなじみがあり、使う言語は一貫し、返事には知性と生気が感じられます。
ところが、キャラクターもモデルも変えていないのに、突然何かがおかしくなります。
次の返事が始まるまで10秒かかる。構造化出力に依存する機能が急に壊れる。キャラクターが支離滅裂になり、別の言語を混ぜ始め、まるでずっと弱いモデルに切り替わったかのような口調になる。
サーバーから見れば、何も失敗していません。APIは 200 OK を返し、tokenも届き、料金も発生しています。
しかしユーザーから見れば、モデルは明らかに悪くなっています。
この隔たりを埋めるために、私たちはReverieへプロバイダー用カナリアプローブとルーティング隔離システムを導入しました。
1つのモデル名、その裏にある複数の推論環境
OpenRouterは、Reverieが主に利用しているモデルゲートウェイです。大きな利点の1つは、同じモデルを複数の独立した推論プロバイダーが提供できることです。1社が利用できなくても、別のプロバイダーがリクエストを処理できます。単一のendpointだけに依存するより、容量、価格競争力、耐障害性を高められます。
一方で、ユーザーから見えない変数も生まれます。
モデル名は同じでも、実際に推論を行うインフラはリクエストごとに変わり得ます。プロバイダーごとに、推論エンジン、ハードウェア構成、量子化精度、parser、チャットテンプレート、キュー、追加のポリシー層が異なる可能性があります。
OpenRouterのプロバイダールーティングに関するドキュメントでは、デフォルトのルーティングが直近の可用性と価格を考慮し、ほかのプロバイダーをfallbackとして用意すると説明されています。どちらも重要な指標です。しかし、endpointが稼働中で安価であっても、特定の製品にとって許容できない結果を返すことはあります。
OpenRouter自身も、同じモデルを提供するプロバイダー間に測定可能な差があることを公に説明しています。理論上、同じ重みを同じ精度で動かせば似た挙動になるはずです。実際の本番環境で大規模モデルを運用するのは複雑であり、そこで差が生まれます。
私たちが「モデル劣化」と呼ぶもの
「モデル劣化」は、原因が1つに決まった標準診断名ではありません。また、プロバイダーが意図的に小さなモデルへ差し替えたことを自動的に意味するものでもありません。
Reverieでは、運用上の定義として次のように捉えています。代表的なpromptに対して、要求したモデルに期待される挙動、能力、対話性能を推論endpointが維持できなくなったなら、技術的にはリクエストが成功していても、そのendpointは劣化している。
特に明確なのは、次のような状態です。
- 遅延の劣化:接続には成功しているものの、最初のtokenまでの時間が長く、リアルタイム会話の感覚を壊してしまう。
- 能力の劣化:構造化出力に対応するはずのendpointが不正なテキストを返したり、schemaを満たせなくなったりする。
- 挙動の劣化:返答が壊れる、支離滅裂になる、異常に反復する、または明らかに別の言語へ逸脱する。
- ポリシーの不一致:上流ホストが独自のフィルターを追加し、Reverieでは対応している場面を拒否、空の応答、途中で切れた返答に変えてしまう。
原因はさまざまです。低精度の量子化が難しいpromptの性能を損なう可能性は、OpenRouterのドキュメントと公開された量子化研究の両方で指摘されています。しかし、量子化ですべてを説明できるわけではありません。推論エンジンやツールparserの不具合、tokenizerやチャットテンプレートの設定ミス、過負荷のキュー、プロバイダー側のmiddlewareも同じくらい重要です。OpenRouterは、ツール呼び出しでは精度そのものよりparser実装が差の原因になることが多いとも報告しています。
大切なのは「どの原因が一番怪しく聞こえるか」ではなく、「そのendpointだけに固定して、障害を再現できるか」です。
問題を現実のものにした2つの事例
これは机上の懸念ではありませんでした。
プロバイダーを固定した比較では、あるプロバイダーが 20回中19回、返答の先頭に句読点や無関係なtokenの断片を挿入しました。同じモデルを提供するほかの14ホストでは、合計 49回中0回 でした。ロールプレイでは最初の文字がMarkdownの強調記号であることも多く、余計な1 byteによって返答全体の書式まで壊れていました。
別のテストでは、あるendpointが 3回中3回、ポルトガル語とスペイン語を激しく混在させました。同じpromptは、モデルの公式ホストと、同じ精度クラスのほかのテスト対象ホストではポルトガル語のままでした。「モデルにはもともとばらつきがある」という説明では不十分で、問題はendpointに追随していました。
この種の障害が厄介なのは、必ずしも例外を発生させないからです。従来の稼働監視には健全なAPIに見えても、ユーザーにはキャラクターが突然まともに話せなくなったように見えます。
私たちの答え:モデルだけでなく、すべてのルートをテストする
30分ごとに、カナリアシステムがReverieのデフォルトチャットモデルを提供中のプロバイダーを取得します。そのうえで、fallbackを無効にし、1社だけに固定した小さな合成リクエスト群を各プロバイダーへ送ります。
固定することが重要です。プローブがfallbackできると、2番目の健全なプロバイダーが最初の障害を隠してしまいます。どの推論環境が結果を生成したのか、正確に特定する必要があります。
システムは、コードで判定できる4つの限定的な契約を検査します。
1. 最初のtokenまでの時間
ストリーミング会話では、throughputは体験の半分にすぎません。最初のtokenが現れるまでの時間が、ユーザーがローディング表示を見続ける時間を決めます。
私たちはstreamから直接計測します。10秒以内にテキストを出さないプロバイダーは遅延プローブで失敗します。しきい値は意図的に余裕を持たせており、1回遅かっただけでホストを外すことはありません。短時間のキュー混雑は起こり得るためです。
2. フィルタリングと無言の拒否
Reverieが対応する実際のトラフィックを代表する、固定のロールプレイ継続リクエストを送ります。プローブは終了理由、高確度の拒否パターン、空の出力を検査します。
また、追加フィルターがあると分かっているホストを陽性対照としてテストします。対照が予想外に合格した場合、ほかの全プロバイダーを健全だとは判断せず、プローブ自体が弱くなったと記録します。既知の障害を検知できないテストは、健全性の証拠になりません。
3. 構造化出力
固定schemaを持つ小さなオブジェクトを要求し、結果を検証します。通信エラーと不正な出力は区別されます。接続失敗はプロバイダーに到達できなかったことを示しますが、生成が完了したのにschemaを満たせない場合は能力の後退を示します。
「endpointがそのparameterへの対応を掲げていること」と「endpointがそれを安定して守ること」は、同じ約束ではありません。
4. 言語の完全性
Reverieは17のインターフェース言語に対応しています。英語だけのsmoke testでは、ユーザーが実際に遭遇する障害の一部を見逃します。
カナリアは合成ロールプレイpromptを使い、対応言語を順番にテストします。ローカルで動作する決定論的な言語検出器が、返答全体の明確な言語切り替え、継続的な言語混在、明らかな文字化けを探します。実際の会話は使わず、別のモデルに主観的な採点を依頼することもありません。
曖昧または短すぎる出力は失敗ではなく「判定不能」です。言語異常が検出されると、すぐに2回の確認を追加し、3回の多数決を求めます。次のラウンドでも同じ言語を再検査するため、ローテーションが進んだだけで連続失敗ルールを回避することはできません。
自分自身の結論を疑うように設計する
推論容量を自動で外すことは有用ですが、偽陽性は元の不具合より大きな停止を引き起こしかねません。そのため、カナリアには複数の安全装置があります。
- 通信エラーは品質失敗として数えません。 timeout、rate limit、5xx応答ではスコアを凍結し、隔離に必要な連続失敗を進めません。
- 1回の不合格だけでは足りません。 同じプロバイダーが、30分ごとに実行される2ラウンドで連続して失敗する必要があります。
- 観察と実行を分離しています。 まず観察モードで全システムを動かし、どのホストが隔離対象になるかを記録し、管理者へ通知し、偽陽性率を確認してから自動処理を有効にできます。
- 容量には下限があります。 隔離後に本番ホストが2つ未満になる場合、カナリアは自動隔離せず、管理者に対応を求めます。
- 復旧もテストします。 隔離中のプロバイダーにもプローブを送り続け、2ラウンド連続で完全に合格すれば早期復帰できます。
- 再発時は段階的に延長します。 初回は1日、次回は3日、それ以降は7日です。新たな隔離なしに14日が経過すると履歴は薄れ、再び1日から始まります。
目的はプロバイダーを罰することではありません。再現可能な不健全ルートからユーザートラフィックを外し、問題が修正されたときには明確な復帰経路を残すことです。
3層の保護
最終的なルーティング判断では、3種類の除外を組み合わせます。
- レビュー済みの組み込み除外:測定済みの不具合やポリシー不一致を誤って再導入しないためのもの。
- 実行時の障害対応除外:デプロイを待たず、管理者がすぐに追加できるもの。
- カナリアによる期限付き隔離:自動失敗しきい値を超えたプロバイダーに適用するもの。
Reverieがリクエストを組み立てる際、これらのリストはOpenRouterの provider.ignore 設定へ統合されます。ユーザーが、偶然より良いプロバイダーに当たるまで再試行する必要はありません。不健全なルートは候補から外れます。
自動判断はすべて記録され、重要な状態変化は管理者へ通知されます。必要であれば手動で隔離を解除することもできます。
このシステムが保証すること、しないこと
カナリアの判断範囲は意図的に限定しています。遅延、schemaの妥当性、高確度のフィルタリング、言語と文字エンコーディングの完全性はコードで判定できます。しかし、キャラクターが十分に面白いか、感情を深く理解しているか、複雑な人格に忠実かを採点するふりはしません。
こうした広い品質評価には、代表的なprompt、人によるレビュー、本番telemetry、そして何よりユーザーからの報告が引き続き必要です。
また、奇妙な返答がすべてモデル劣化の証拠になるわけでもありません。生成モデルには確率性があります。長い会話には矛盾する文脈が蓄積することがあり、キャラクター定義に競合する指示が含まれる場合もあります。単に一度だけ奇妙な返答が出ることもあります。
変わったのは、「同じモデルだから」で調査を終えなくなったことです。具体的なルートを隔離し、客観的な障害を再現し、その後のトラフィックを遠ざけられるようになりました。
信頼性とは、体験を守ること
複数プロバイダーへのルーティングには今も大きな価値があります。個別のendpointが停止しても会話を提供し続けるための容量と耐障害性を、Reverieにもたらします。
しかし、HTTP応答を受け取ることだけが耐障害性ではありません。開始が遅すぎる、必要な構造を失う、対応している内容を拒否する、突然言語が変わる——そのような返答は、請求上「成功」と記録されても健全ではありません。
AIキャラクター製品における信頼性は、もっと人間的な意味を持ちます。どのマシンが代わりに話しても、そのキャラクターはそのキャラクターらしくあり続けるべきです。
Reverieの新しいルーティング保護は、この基準を守るために作られています。
返答の品質や言語が突然変わったと感じたら、モデル名とおおよその時刻を添えてご報告ください。その情報が、皆さんの見た体験と実際に応答したルートを結び付ける助けになります。

