F-14: インコンテキスト状態 vs 外部ステートストア¶
この相反は何か¶
AI エージェントが処理の途中経過や会話履歴などの「状態」を保持する際、「LLM のコンテキストウィンドウ内に保持するか(インコンテキスト)、それとも外部のデータストア(データベース、KVストア、オブジェクトストレージなど)に永続化するか」という二択が F-14 の相反です。
この選択が排他的になる理由は、状態の生存期間と可用性が根本的に異なるためです。インコンテキスト状態は LLM の推論リクエストが終了した時点で消滅します(次のリクエストで再度渡さなければなりません)。外部ステートストアに保存された状態は、プロセスの停止・再起動を跨いで永続します。ある状態情報をどちらに置くかは、混合ではなく選択の問題です。
AI エージェントの文脈でこの相反が重要な理由は二つあります。第一に、エージェント処理は数分から数十分に及ぶことがあり、その間にプロセスの再起動やプロバイダ障害が発生しうるため、状態の永続性が可用性に直結します。第二に、LLM のコンテキストウィンドウには容量制限があり、すべての状態をコンテキストに保持し続けると、本来の推論に使えるトークンが圧迫されます。
選択肢A:インコンテキスト状態¶
インコンテキスト状態とは、LLM に渡すプロンプト(システムプロンプト、会話履歴、中間結果)の中に状態を埋め込む方式です。状態は LLM のコンテキストウィンドウ内にのみ存在し、外部ストアへの書き込みは行いません。
この方式の最大の強みは実装のシンプルさと低レイテンシです。外部ストアへの読み書きが不要なため、追加のネットワークラウンドトリップが発生しません。データベースのスキーマ設計、接続管理、トランザクション処理といったインフラ上の関心事を排除できます。プロトタイピングや PoC の段階では、このシンプルさが開発速度を大きく向上させます。
また、LLM が状態の全体を「見ている」ため、状態に基づく推論が自然に行えます。外部ストアから取得した状態を LLM に渡す場合、何をどの粒度で渡すかの設計が必要ですが、インコンテキストであればすべてが自然に参照可能です。
弱点は容量制限と耐障害性の欠如です。コンテキストウィンドウには上限があり(モデルによって 8K~200K トークン程度)、状態が増えると推論に使えるトークンが減少します。長い会話履歴や多数の中間結果を保持する必要がある場合、容量が不足します。さらに、プロセスが停止した場合、コンテキスト内の状態はすべて失われます。再開するにはゼロからやり直す必要があります。
選択肢B:外部ステートストア¶
外部ステートストアとは、エージェントの状態をデータベース(RDB、KVストア)、オブジェクトストレージ、ファイルシステムなどの永続化層に保存する方式です。各ステップの完了時に状態をチェックポイントし、必要に応じて読み出します。
この方式の最大の強みは耐障害性と再開可能性です。プロセスが停止しても、最後のチェックポイントから処理を再開できます。これは長時間処理(数十分以上)において決定的な利点です。また、複数のエージェントインスタンスやワーカーが同じ状態を参照・更新できるため、スケールアウトや負荷分散が可能になります。
さらに、コンテキストウィンドウの制約から解放されます。必要な状態だけを選択的に LLM に渡し、残りは外部ストアに保持しておくことで、コンテキストの有効活用が可能です。履歴が長くなっても、直近の N ターンだけをコンテキストに含め、それ以前は要約してストアに保存する、といった戦略が取れます。
弱点は実装の複雑さとレイテンシの追加です。ステート管理のためのスキーマ設計、チェックポイントのタイミング設計、一貫性の保証、障害時のリカバリロジックなど、考慮すべき点が多くなります。各ステップで外部ストアへの読み書きが発生するため、ネットワークレイテンシが上乗せされます。また、「何を保存し、何を保存しないか」の判断が設計上の新たな課題になります。
選定基準¶
この相反の選定は主に [reversibility] で決まります。
外部ステートストアを選ぶべき条件:
[reversibility]が低い場合。処理の途中で障害が発生したとき、最初からやり直すコストが大きい(時間・トークン・副作用の重複実行)なら、チェックポイントによる再開可能性が不可欠です。- 処理時間が長い場合(目安として数分以上)。長時間処理ではプロバイダ障害やプロセス再起動の確率が無視できなくなります。
- 人間の承認待ちが処理中に発生する場合。承認待ちの間、状態をメモリに保持し続けるのはリソースの浪費であり、外部化して待機する方が効率的です。
- 複数のエージェントやワーカーが同じタスクの状態を共有する場合。マルチエージェント構成やワーカープール構成では外部ステートストアが必須です。
インコンテキスト状態で十分な条件:
- 処理が短時間で完了する場合(目安として数十秒以内)。障害確率が低く、やり直しコストも小さいため、永続化の恩恵が薄いです。
- 単一のリクエスト-レスポンスで完結する場合。会話の継続や多段処理がなければ、状態の永続化は不要です。
- プロトタイピング段階で、耐障害性よりも開発速度を優先する場合。
デフォルトとハイブリッド¶
デフォルト:長時間処理・承認待ち・複数ワーカー共有のいずれかに該当すれば外部ステートストアを選びます。短時間の単発処理はインコンテキストで十分です。
ハイブリッド:作業中はインコンテキスト、節目で外部に永続化という二層構成が実用的です。LLM の推論ステップ間ではコンテキスト内に状態を保持し、ステップ完了時(特に副作用が発生した境界)でチェックポイントとして外部ストアに保存します。これにより、通常時は外部ストアへの読み書きを最小限に抑えつつ、障害時にはチェックポイントから再開できます。A2 Durable Async Agent がこの構成を体系化しています。
判断を誤ったときの症状¶
インコンテキストを選んだが外部ステートストアが必要だった場合の症状:
- プロセス再起動やプロバイダ障害の後、処理全体を最初からやり直すことが頻繁に発生し、トークンコストと処理時間が膨張しています。
- コンテキストウィンドウが状態で埋まり、推論品質が劣化しています。要約や古い履歴の圧縮を場当たり的に行っていますが、情報の欠落が問題になっています。
- 人間の承認待ちの間、プロセスがメモリとコネクションを占有し続け、同時処理数がスケールしません。
- エージェントのデバッグが困難です。障害発生時の状態が揮発しており、再現ができません。
外部ステートストアを選んだがインコンテキストで十分だった場合の症状:
- ステート管理のためのインフラ(データベース、スキーマ、マイグレーション)の運用コストが、本来の機能開発を圧迫しています。
- チェックポイントの書き込み頻度が高く、外部ストアへのレイテンシが体感に影響しています。
- 実際には障害による再開が発生しておらず、チェックポイント機能が使われていません。
- ステートのシリアライズ/デシリアライズの不整合でバグが発生しています。
関連パターン¶
- A2 Durable Async Agent --- 外部ステートストアを用いたチェックポイント・再開の具体的な設計を扱います。
- F1 Short DB Transaction, Long Agent Session --- 外部ステートストア使用時のトランザクション設計。LLM 推論中はトランザクションを開かない原則を扱います。
- D2 Context Budget Allocator --- インコンテキスト状態を使う場合のコンテキストウィンドウ予算配分を扱います。
- A3 Sync Facade over Async Core --- 非同期処理への切り替え時に外部ステートストアが必要になる場面を扱います。