コンテンツにスキップ

タイムアウト

このダイヤルは何か

タイムアウトは、エージェントが特定の操作の完了を待つ最大時間を制御するダイヤルです。AIエージェントシステムでは、ツール呼び出し・LLM推論・セッション全体というレイテンシ特性の異なる複数の操作が組み合わさるため、一律のタイムアウトでは機能しません。ツール呼び出しは数秒で終わるのに対し、LLM推論は数十秒から数分かかることがあり、セッション全体は数十分に及ぶこともあります。

従来のWebサービスではHTTPリクエストに対して30秒程度のタイムアウトを設ければ済むケースが大半でしたが、AIエージェントでは1リクエストが長い(F1)という本質的な特性があります。さらにレイテンシのばらつきが大きく(F12)、同じLLM呼び出しでも入力の長さやモデルの負荷によって応答時間が数倍異なります。加えてプロバイダ可用性が不安定(F7)であるため、タイムアウトが短すぎると一時的な遅延で正常な処理を殺してしまいますし、長すぎると障害を隠蔽してリソースを無駄に占有します。

このダイヤルを適切に調整するには、操作クラス(層)ごとにタイムアウトを分け、さらに観測データに基づいて動的に調整する仕組みが必要になります。特にストリーミング応答を使う場合は、全体のタイムアウトよりもトークン間タイムアウト(次のトークンが来るまでの最大待ち時間)の方が本質的な監視指標になります。

効かなすぎる害 ⇔ 効きすぎる害

効かなすぎる害(タイムアウトが短すぎる)

タイムアウトを短く設定しすぎると、正当な長時間処理を途中で打ち切ってしまいます。たとえば、複雑な推論タスクでLLMが80秒かけて高品質な回答を生成している途中で、60秒のタイムアウトにより処理が中断されるケースです。

具体的には以下のような問題が発生します。

  • 複雑な数学的推論やコード生成で、思考の連鎖(Chain of Thought)が深くなる正当なケースが失敗します
  • 大量のコンテキストを持つLLM呼び出しで、入力処理だけで時間がかかり応答が始まる前にタイムアウトします
  • ピーク時のプロバイダ遅延で、通常は問題ない呼び出しが断続的に失敗し、リトライの連鎖が始まります
  • 外部APIを呼び出すツールが、相手先のレスポンスが遅いだけで失敗扱いになり、ユーザーに無用なエラーを返します

効きすぎる害(タイムアウトが長すぎる)

タイムアウトを長く設定しすぎると、障害の検出が遅れ、リソースが不必要に占有されます。

  • プロバイダが応答しないまま数分間スレッドが占有され、同時実行数の上限に達して他のリクエストが詰まります
  • ハングしたツール呼び出しが放置され、ユーザーは何も表示されないまま数分間待たされます
  • 障害が隠蔽されます。本来サーキットブレーカが開くべき状況で、タイムアウトまで待ち続けるため障害検出が遅れます
  • UXが著しく悪化します。「いつ終わるか分からない」状態はユーザーにとって最も苦痛な体験のひとつです

決め方

タイムアウトの値は [latency_budget] を最も強く反映します。ユーザーや下流システムがどれだけ待てるかが出発点です。

操作クラスごとに分ける

タイムアウトは少なくとも以下の3層に分けて設定します。

  1. ツール呼び出し層 — 外部API・データベースクエリ・ファイル操作など。レイテンシ特性が操作ごとに大きく異なるため、ツール種別ごとにさらに細分化することもあります。たとえばデータベースクエリは3〜5秒、外部SaaS APIは10〜30秒、ファイルダウンロードはサイズに応じて10〜60秒など、ツールの性質に応じた設定が理想です。
  2. LLM推論層 — LLMプロバイダへの呼び出し。入力トークン数とモデルの負荷で大きく変動します。小型モデル(Haiku相当)と大型モデル(Opus相当)では応答時間が10倍近く異なることがあり、モデル層別にタイムアウトを設定することも検討します。
  3. セッション全体層 — エージェントセッションの全体的な制限時間。A7 予算カスケードのdeadlineとして伝播します。セッション全体のタイムアウトはUXの観点から設定するもので、「ユーザーがこのタスクに何分待てるか」から逆算します。

観測P99から導出する

各操作の応答時間のP99(99パーセンタイル)を観測し、安全係数(概ね1.5〜2.0倍)を掛けた値を出発点とします。[latency_budget] が短い環境ほど安全係数を小さくし、[failure_cost] が高い環境ほど安全係数を大きくします。

たとえば、あるLLM呼び出しのP99が45秒であれば、安全係数1.5を掛けた67.5秒(切り上げて70秒)が出発点です。しかし [latency_budget] がSLA上30秒しかない場合は、このタイムアウト値ではSLAを守れないため、モデルの軽量化、入力の縮小、またはストリーミングへの切り替えといった根本対策が必要になります。

P99の観測値がまだない立ち上げ初期は、目安値の表を出発点にし、1〜2週間の運用データを蓄積してから実測値ベースに切り替えます。

ストリーミングの場合はトークン間タイムアウト

ストリーミング応答を使う場合、全体タイムアウトに加えて「前のトークンから次のトークンまでの無応答時間」で監視します。これにより、応答が始まったが途中で詰まった状況を早期に検出できます。

ストリーミングのタイムアウトは3つに分解するのが理想的です。

  1. 接続タイムアウト — TCP接続が確立するまでの時間。概ね5〜10秒です。
  2. TTFT(Time to First Token) — 最初のトークンが返るまでの時間。入力が長いほど延びるため、入力トークン数に応じて動的に設定するのが理想です。概ね15〜30秒を出発点とします。
  3. トークン間タイムアウト — 連続するトークン間の無応答時間。これが最も有用な監視指標です。概ね5〜15秒を出発点とします。正常な推論では数百ミリ秒〜数秒間隔でトークンが返るため、15秒の無応答はプロバイダ側の異常を強く示唆します。

適応型タイムアウト

最も洗練されたアプローチは、過去の応答時間の統計を元にタイムアウトを自動調整する仕組みです。直近の応答時間のスライディングウィンドウ(概ね100〜1000リクエスト)からP99を計算し、安全係数を掛けた値を動的に適用します。プロバイダの負荷変動や季節性(業務時間帯のピーク)にも自動追従できます。ただし実装の複雑さが増すため、まずは静的なタイムアウトから始め、運用課題が顕在化してから適応型に移行するのが現実的です。

目安値(出発点)

以下は出発点であり、本番メトリクスに基づいて継続的に調整してください。

操作クラス 目安値 補足
ツール呼び出し(一般) 10〜30秒 外部APIの特性に応じて個別調整。DBクエリは5秒でも長い場合がある
LLM推論(全体) 60〜120秒 入力トークン数が多いほど長くなる。長文生成タスクは上限を引き上げる
LLM推論(トークン間) 5〜15秒 ストリーミング時のトークン間無応答監視。プロバイダ障害の早期検出に有効
LLM推論(TTFT) 15〜30秒 最初のトークンが返るまでの待ち時間。入力が長いほど延びる
セッション全体 数分〜数十分 タスク種別による。対話型は短く、調査・分析型は長く

[latency_budget] が厳しい(数秒以内)環境では、ツール呼び出しを3〜5秒、LLM推論を10〜30秒に絞り込むことも検討してください。ただし短くするほど失敗率が上がるため、リトライ戦略(A6)との整合を取る必要があります。

具体的なシナリオ

シナリオ1:対話型チャットアシスタント

ユーザーが数秒以内の応答を期待する対話型サービスです。[latency_budget] は厳しく、概ね5〜10秒が限界です。

  • ツール呼び出し:3〜5秒(検索APIやデータベースクエリ)
  • LLM推論(全体):15〜30秒(ただしストリーミングで即座にトークンを返し始める)
  • LLM推論(トークン間):3〜5秒
  • セッション全体:概ね60〜120秒

ストリーミングを活用して「応答が始まっている」ことをユーザーに見せることで、体感的な待ち時間を大幅に短縮できます。

シナリオ2:調査・分析エージェント

複数のデータソースを探索し、分析レポートを生成するエージェントです。[latency_budget] には余裕があり、数分の処理が許容されます。

  • ツール呼び出し:10〜60秒(複数のSaaS APIを順次呼び出し)
  • LLM推論(全体):60〜180秒(長文の分析・要約)
  • セッション全体:5〜30分

ここではタイムアウトよりも予算上限(コスト・ステップ数)が主要な制約になります。

シナリオ3:自動コードレビューエージェント

コードの差分を分析し、レビューコメントを生成するエージェントです。大きな差分では入力トークンが数万に達します。

  • ツール呼び出し:5〜15秒(git操作、ファイル読み込み)
  • LLM推論(全体):120〜300秒(大量の入力を処理)
  • LLM推論(TTFT):30〜60秒(入力が長いためPrefill時間が長い)
  • セッション全体:10〜30分

入力サイズが大きい場合はTTFTが延びるため、通常のタイムアウトでは早切りしてしまいます。入力トークン数に応じてTTFTタイムアウトを動的に調整する仕組みが有効です。

実践的なアドバイス

  • タイムアウトは「静的な定数」ではなく「動的な変数」として扱ってください。本番のP99レイテンシを定期的に計測し、閾値を自動調整する仕組みを入れるのが理想です。少なくとも月次で実績値と設定値の乖離をレビューしましょう。

  • 操作ごとにタイムアウトを分けないのは典型的なアンチパターンです。「全部30秒」のような一律設定は、ツール呼び出しには長すぎ、LLM推論には短すぎる中途半端な値になります。最初から層別設定を設計に組み込んでください。

  • タイムアウト発火後の振る舞いを必ず設計してください。タイムアウト例外を投げるだけでは不十分です。リトライ可能か、縮退応答を返すか、ユーザーに待ち状態を通知するかを事前に決めておきます。A6 のサーキットブレーカ機能と連携させることで、タイムアウト多発時にプロバイダへのリクエストを遮断できます。

  • ストリーミングを活用している場合、トークン間タイムアウトの方が全体タイムアウトより有用です。全体タイムアウトだけだと、応答が始まったが途中で止まった場合の検出が遅れます。トークン間5〜15秒を監視することで、プロバイダの部分的なハングを早期検出できます。

  • タイムアウト値の変更はリトライ戦略に直結します。タイムアウトを短くすればタイムアウト発火頻度が上がり、リトライが増えます。リトライ予算(A6)やセッション全体の予算(A7)と一体で調整する必要があります。

  • タイムアウトとキャンセルは異なります。タイムアウトはクライアント側で待つのを止めるだけで、プロバイダ側の処理は続行されている可能性があります。プロバイダ側のリソースを解放するためにキャンセルリクエストも送信することを推奨します(APIがサポートしている場合)。課金はプロバイダ側の処理量に基づくため、クライアント側のタイムアウトだけではコスト削減になりません。

  • テスト環境と本番環境でタイムアウト値を変えることを検討してください。テスト環境ではプロバイダの応答が遅い(リソースが限定されている)場合があり、本番より長いタイムアウトが必要になることがあります。逆に、本番環境のSLA要件はテスト環境には不要です。環境別の設定管理を設計に含めます。

関連パターン

  • A6 適応タイムアウト+予算律速リトライ — タイムアウト設計の中核パターンです。操作クラス別タイムアウトとエラー分類に基づくリトライ戦略を定義しています。
  • A7 期限・予算のカスケード伝播 — セッション全体のdeadlineを子タスクに伝播する仕組みです。セッション全体タイムアウトの上位概念として機能します。
  • A2 耐久非同期セッション — 長時間処理でタイムアウトが現実的でない場合の代替アプローチです。タイムアウトで切るのではなく、チェックポイントで状態を保存して再開可能にします。
  • G1 二層観測 — タイムアウト発火率やレイテンシ分布の観測基盤です。タイムアウト値のチューニングに不可欠なフィードバックループを構成します。