LLM APIからHTTP 200が返っても、処理成功とは限りません。文章が途中で切れている、拒否が返っている、形式は合っているが内容が誤っている、といった状態が残ります。
LLM APIは、アプリケーションからLLMへ入力を送り、生成結果を受け取るためのInterfaceです。
HTTP Requestを送り、Responseを受け取る点は一般的なWeb APIと同じ。ただし、ネットワークとSchemaに加えて、生成結果の品質まで扱います。
Requestには入力以外の実行条件も含まれる
Model APIによってField名は異なりますが、Requestには主に次の情報が入ります。
- Model ID
- System Instruction
- User Messageと会話履歴
- 画像・音声・文書などの入力
- Tool定義
- 出力Tokenの上限
- Structured OutputのSchema
- Streamingの有無
- Provider固有の生成設定
Claude Messages APIは、system、messages、model、max_tokensなどを受け取り、Content blockとUsageを返します。会話履歴はClient側で組み立てて送るStatelessな形式です。
Gemini APIのText Generationも、入力ContentとModelを指定し、通常ResponseまたはStreaming Responseを受け取ります。対応するRole、生成設定、終了理由はProviderとModel世代によって変わります。
Response本文だけを見ない
生成されたText以外にも、処理判断に必要な情報があります。
| 情報 | 確認する理由 |
|---|---|
| Response ID / Request ID | 問い合わせとTraceを結び付ける |
| Model / Model Version | 回帰調査の条件を残す |
| Finish reason | 正常終了、上限到達、Tool呼び出し、拒否を分ける |
| Usage | 入力・出力Tokenと費用を追う |
| Tool call | 実行前にSchemaと権限を検証する |
| Refusal / Safety result | 空文字や通常エラーと区別する |
HTTP 200でも、出力Token上限で途中終了している場合があります。本文があるから成功、と判定しないようにします。
Streamingは完了を保証しない
Streamingは、生成途中のChunkを順次受け取り、画面へ早く表示するために使えます。最初のTokenが早く見える一方で、途中切断、重複、順序、Cancel、最終Usageの扱いが増えます。
Browserの生成要求はApplicationを介してModel APIへ送られ、途中のStream eventsをPartial outputとして返します。Completedまたはerrorを受けたApplicationが最終状態を検証し、完了または回復処理をBrowserへ通知します。
- BrowserがApplicationへ生成要求を送ります。
- ApplicationがModel APIへRequestを送り、Stream eventsをBrowserへ中継します。
- Model APIのCompletedまたはerrorを受けてApplicationが最終状態を検証します。
- ApplicationがCompleteまたはRecoverの結果をBrowserへ返します。
画面へ表示した途中Textを、確定済みの業務データとして保存しないようにします。Tool callやStructured Outputでは、必要なEventがそろうまで実行を待ちます。
Rate Limitと費用は利用者単位でも制御する
Claude APIのRate Limitsは、Request数、入力Token、出力Tokenなど複数の軸で制限を定義しています。Providerの組織上限だけでは、自社サービスの一利用者が予算を使い切ることを防げません。
- 利用者・Tenant・機能単位の上限
- 一Requestの最大入力・出力Token
- 同時実行数
- 月次費用Budget
- 長時間処理の総Step数
- Cache利用条件
利用量の急増を障害として扱うのか、Queueへ逃がすのか、低コストModelへ切り替えるのかを決めます。
Timeoutと再試行には副作用を持たせない
一時的な429や5xxは再試行候補です。ただし、同じRequestを再送すると別の出力になる可能性があります。
Model API呼び出しだけなら再生成で済んでも、その前後でToolを実行している場合は重複更新が起こり得ます。Model呼び出しのRetryと、Tool実行のRetryを分け、Idempotencyを設計します。
指数Backoff、Jitter、最大試行回数、全体Deadlineを決めます。Retryを無制限にすると、Rate Limit中に負荷と費用を増やします。
Provider差分を隠しすぎない
複数Providerを同じInterfaceで呼べるSDKは便利です。ただし、Role、Tool call、Structured Output、Safety response、Token計測、Streaming Eventの差まで完全に同じにはなりません。
共通化するのは、自社が必要とする最小の契約に絞ります。Provider固有機能を使う箇所はAdapterの内側へ閉じ、元のResponse IDと終了理由を失わないようにします。
よくある誤解
LLM APIはChat UIを提供するAPIである
APIはモデルへの入出力を提供します。会話履歴、UI、Memory、検索、認可はアプリケーション側の責任になる場合があります。
Temperatureを0にすれば常に同じ結果になる
設定仕様はModelごとに異なり、低い値でも完全な決定性は保証されません。決定的であるべき処理はコードへ残します。
HTTP 200なら処理成功である
途中終了、Refusal、空のContent、期待形式からの逸脱を確認します。業務上の成功は別の判定です。
Providerを切り替えてもPromptはそのまま使える
Instructionの優先度、Role、Model特性、対応Schemaが異なります。同じ評価セットで移行前後を比較します。
EastBraver Labsの判断基準
EastBraver Labsでは、LLM APIを確率的な出力を返す外部依存として扱います。
Request ID、Model ID、Prompt Version、Token Usage、Finish reasonをTraceへ残します。本文だけを保存して、後から条件を再現できない構成にはしません。
Timeout・Rate Limit・費用上限は通常のAPI運用として設計し、出力品質は評価セットで確認します。
この二つを一緒に扱う。そこが本番運用の起点です。