このページの目次

本番化チェックリスト

これまでの全章を「評価セットの構築」から「グレープリリース」、そして「オンラインでの失敗ごとに回帰テストを追加する」までのリリースライフサイクルとして一本の糸に織りなす。これはAIセクションの最終ページであり、いつでも参照できるチェックリストだ。

概要

これまでの十数本の記事では、モデル、コンテキスト、エージェント、アプリケーションパターンについて個別に解説してきました。この記事ではその逆で、LLM/エージェントアプリケーションのリリース順序に従ってそれらを時系列でつなぎ合わせ⁠、総括的なまとめとしつつ、チェック可能なリストとして機能させます。

一貫して貫かれる2つの核心信念があります。

  • 評価なしに改善はない。 プロンプトを変更し、モデルを交換し、ツールを追加したとして、なぜ「良くなった」と言えるのか?——それは勘ではなく、評価(eval)によるものだ(評価と観測可能性参照)。
  • まず「リリースするべきか」を確認し、次に「どのようにリリースするか」を議論する。 ワークフローで記述できるものはエージェントにせず、単一エージェントで済むものはマルチエージェントにしない——最も安定したシステムとは、最も単純なものである。

リリースライフサイクル

flowchart TD
    A["① レベルの選択<br/>ワークフロー?エージェント?マルチエージェント?"] --> B["② 評価セットの構築<br/>小さく現実的、境界ケースを含む"]
    B --> C["③ プロンプト/モデル/エフォートを調整<br/>評価セットに対して調整"]
    C --> D["④ 防護策の実装<br/>サンドボックス/権限/インジェクション/シークレット"]
    D --> E["⑤ 観測可能性の接続<br/>トレース + 使用量 + 停止理由"]
    E --> F["⑥ グレープリリース<br/>少量トラフィック、ロールバック可能"]
    F --> G["⑦ オンラインでの失敗<br/>回帰評価として固定"]
    G --> C

以下、各段階ごとにチェック項目を示し、それぞれの詳細な解説記事へのリンクを記載します。

① レベルの選択:安易にエージェントを使わない

エージェントを導入する前に、4つの関門を通す(いずれかでも「No」であれば、より単純なレベルに退く)。

  • 複雑さ⁠: タスクが複数ステップに分かれており、事前に完全に規定できないか?(フローをハードコードできるなら → ワークフローを使用)
  • 価値⁠: 結果が、より高いコストとレイテンシに見合う価値があるか?
  • 実現可能性⁠: モデルは実際にこの種の問題を得意としているか?
  • エラーのコスト⁠: 失敗した場合に検知およびロールバックできるか?(テスト/レビュー/フォールバックがあるか)

マルチエージェントの場合、さらに1問追加する:⁠単一エージェント + 優れたツールでは解決できない場合にのみ、マルチエージェントを採用する⁠(マルチエージェントオーケストレーション参照)——マルチエージェントは調整オーバーヘッド、コンテキスト同期、デバッグの複雑さを導入する。

② まず評価セットを、調整より先に

最も重要なプラクティス:手を動かす前に、小さく現実的な評価セット(evalセット)を持つこと。 20件程度の代表性のあるタスク(既知の失敗ケースや境界ケースを含み、ハッピーパスだけでなく)があっても、単一のケースに頼った勘に勝る(評価と観測可能性参照)。

  • 評価セットには失敗/境界用例を含める。順調なケースだけでなく。
  • 採点は信頼性の高い順に:⁠プログラム可能な検証 > LLM-as-judge > 結果スコアリング。assert で検証できる場合は審判を呼ばない——構造化出力により、此类の検証を安定して実行可能にする。
  • LLM審判は被験体と分離する⁠(自己採点を避ける)、⁠独立して判定可能なルーブリックを与える。

③ 評価セットに対して調整し、勘に頼らない

  • プロンプト⁠: 「必須」を羅列するのではなく、「いつ/境界」を記述し、正例を反例より優先する(プロンプトエンジニアリング参照)。
  • エフォート⁠: 最初は high で始め、評価セット上で medium/high/xhigh をスキャンして決定する——関係性は単調ではない(推論と思考参照)。
  • サンプリングパラメータ⁠: 新しいモデルでは既に削除されている。古いコードの temperature は削除し、プロンプト + エフォートに置き換える。
  • 出力形状⁠: 下流に渡す場合は output_config.format / strict を使用し、「JSONを返してください」というお任せにしない。
  • 知識⁠: プライベート/リアルタイム知識は RAG を経由し、生成を調整する前にまず recall@k を最大化する。
  • コンテキスト予算⁠: 安定するまでプレフィックスを固定して キャッシュ を確保し、動的なコンテンツは後置し、長文の会話には compaction / context editing を使用する。

④ 防護策の実装:モデルの出力はすべて信頼できない

リリース前に、セキュリティと防護のゲートをすべて設置する。

  • bash/ツール⁠: 隔離環境 + 白リスト + タイムアウト + ログ;コマンドは信頼できない出力である。
  • パス⁠: 正規化 + 境界検証、../シンボリックリンク/URLエンコードされたトラバーサルを拒否。
  • 危険な操作⁠: 不可逆な操作は human-in-the-loop、可逆性に応じて分级、最小権限。
  • インジェクション⁠: ツールの出力をデータとして扱い、指示として扱わない;オペレータの指示は role:system の信頼できるチャネル経由。
  • シークレット/PII: コンテキスト/メモリ/プロンプトに決して入れない;資格情報はプロキシ注入;マルチテナント分離。
  • 出力側⁠: content を読む前に stop_reason を確認する(拒否処理);SQL/HTML/shell に出力する前にパラメータ化してエスケープ。

⑤ 観測可能性の接続:「どのステップで問題が発生したか」に答えられるようにする

リリース時に観測不能なのは=災害である。評価と観測可能性を接続する。

  • trace/span: 各 tool_use/tool_result/モデル呼び出しごとに1つのspanを作成し、レイテンシとコストを段階的に帰属可能にする(本サイト構築時にOTelを初期化済み)。
  • usage: input/output_tokenscache_read_input_tokens(長期間0の場合=キャッシュが静かに無効化されている)、cache_creation_input_tokens を監視する——合計 = 三者の和、1つのフィールドだけを見ないこと。
  • stop_reason 分布⁠: max_tokens が高い = 出力が切り捨てられる;refusal が異常に増加 = プロンプトが拒否をトリガー;pause_turn が多い = サーバーサイドのツールループが継続中。
  • コスト/レートリミット⁠: キャッシュヒット率、429の頻度をダッシュボードに表示(コスト、パフォーマンスと信頼性参照)。

⑥ グレープリリース:制御可能、ロールバック可能

  • ストリーミング⁠: 長入力/長出力はすべてストリーミング、非ストリーミングHTTPタイムアウトを回避。
  • リトライ/冪等性⁠: 429/5xx のみをリトライ;副作用のあるアクションには冪等キー + 手動確認を付与。
  • 帰属⁠: 並列/Batches の結果は custom_id/trace id で対応付け、順序に頼らない。
  • 少量トラフィックから開始⁠: 新しいプロンプト/モデルはまず少量でグレープリリースし、評価セットとオンライン指標を比較してから拡大;ロールバック経路を確保。
  • モデル変更時のキャッシュ注意⁠: モデルを変更するとキャッシュ全体が無効化され、トークンのベースラインを再計算する必要がある——メインループ内で中途半端に切り替えない(マルチエージェントオーケストレーション参照)。

⑦ 回帰:失敗ごとに1つ、防御線を追加

  • オンラインで失敗を1つ発見するたびに、⁠評価ケースとして固定する⁠——これにより、評価セットは時間とともに強化される(評価と観測可能性参照)。
  • ③に戻って再調整し、全量評価を実行して劣化がないことを確認してからリリース。

ベストプラクティス(全セクションの凝縮)

  • まず評価、その後イテレーション。 小さく現実的な評価セットは、すべての変更の審判である;それなしでは、すべての「最適化」は賭け事である。
  • シンプルに保つ。 ワークフロー > 単一エージェント > マルチエージェント;レベルを上げるごとに発生する調整コストが、リターンに見合う必要がある。
  • ウィンドウを予算として管理する。 キャッシュはプレフィックスで固定、検索は強引な挿入より優先、エフォートで深さを調整——この3つでコストと品質を管理。
  • モデルの出力はすべて信頼できない。 セキュリティ境界はホスト実行側にある:サンドボックス、パス検証、危険な操作の承認、シークレットをコンテキストに入れない。
  • 各ステップを定量化する。 trace + usage + stop_reason で「どこが間違えたか」を可視化;観測可能性がなければ、盲目の変更である。
  • 作成とレビューは別のレーンで行う。 実行するエージェントは自身を審査しない、別の reviewer/verifier を独立したコンテキストで評価させる(マルチエージェントオーケストレーション参照)。
  • オンラインでの失敗 → オフライン回帰。 各インシデントが1つのevalとなり、防御線は増えるだけで減らない。

トレードオフと失敗パターン

  • 評価なしで調整⁠: 勘で変更し、「良くなった」のか「別の間違い方に変えただけ」なのか区別できない → まず20件の現実的なevalを構築。
  • 反射的にエージェント/マルチエージェントを採用⁠: 調整オーバーヘッド > リターン、さらにデバッグが困難 → 4つの関門を通り、ワークフローで済むならエージェントにするな。
  • リリース時に観測可能性なし⁠: 問題発生時にどのステップか不明、トークンをどれくらい消費したか不明 → trace + usage + stop_reason を先に接続。
  • キャッシュヒット率を監視しない⁠: コストが何倍にもなってから気づく → cache_read_input_tokens をダッシュボードに追加。
  • ハッピーパスのみテスト⁠: オンラインで境界ケースに遭遇すると即座に崩壊 → 評価セットに境界を含め、インシデントに応じて成長させる。
  • 実行エージェントが自己評価⁠: 自己推薦 → レビューは別の独立したレーンで行う。
  • プロンプト/モデルをいきなり全量リリース⁠: 回帰の比較ができず、問題発生時にロールバック困難 → グレープリリース + ロールバック経路確保 + 全量評価の実行。

参考

Keywords: 本番化, production checklist, リリースライフサイクル, eval-first, ワークフロー vs エージェント, グレープリリース, canary, ロールバック, rollback, 回帰, regression, 観測可能性, observability, trace, span, OTel, usage, stop_reason 分布, プロンプトキャッシュ, RAG, 構造化出力, 防護, サンドボックス, シークレット, human-in-the-loop, 冪等, authoring vs review lane, チェックリスト