2026-09-03 発行(読了 5 分)
実プロダクトのアーキテクチャ・使用例から AI 開発の現在地を週 3 回・1 号 1 テーマで深掘り
エージェントが数分の対話ではなく数時間・数日単位のバックグラウンドタスクをこなすようになったことで、コンテナ再起動やタイムアウトはもはや例外ではなく前提になった。これまでチャットボットが会話履歴だけを保存してきたのに対し、いま各社が取り組んでいるのは「どのステップまで完了したか」という実行状態そのものをチェックポイントとして永続化する設計だ。何を保存し、何を保存しないかという粒度の判断も含め、具体例を追う。
長時間稼働エージェントの標準構成は、ツール呼び出しなど各ステップの境界でエージェントの実行状態(変数・実行位置・保留中のタスク)をシリアライズし、外部ストレージへ書き込むというものだ。会話ログとは別に、ToolContext.stateのような実行状態そのものを永続化することで、プロセスが落ちても直前のステップから再開できるようにする。
バックグラウンドで数時間から数日動くエージェントが増え、コンテナのタイムアウトやスケールゼロは例外ではなく前提になった。インメモリの会話履歴だけを保持していると、再起動のたびに文脈は残っても「どこまで進んだか」という実行位置が失われる。この2つを分けて管理しないと、副作用のあるツール呼び出しまで巻き戻って再実行してしまう、というのが各社が同じ設計に落ち着いた理由だ。
LangGraphのinterrupt()は、承認が必要な地点でグラフの状態をチェックポインタに保存し、再開の合図が来るまで無期限に待つ。呼び出し側はthread_idで「どの中断中の実行を再開するか」を指定し、人間の判断はCommand(resume=...)というJSONシリアライズ可能なペイロードとしてinterrupt()の戻り値になる。
承認待ちを個別のポーリングAPIやtry/exceptで実装すると、承認までの待ち時間が数分でも数日でも同じコードパスで扱うのが難しい。グラフの一時停止として扱えば、待機時間の長さに関係なく同じチェックポイント/再開の仕組みに乗る。これが「割り込みは例外ではなく状態遷移の一種」という設計に各フレームワークが収束した理由だ。
実行状態のスナップショットには、大きなデータそのものではなく参照(ID)だけを持たせ、必要になった時点で再取得する「claim check」パターンが標準になりつつある。Temporal上でエージェントを組む場合、イベント履歴には50MB・51,200イベントという上限があり、数KBを超えるペイロードは履歴に直接書かず外部ストレージへ逃がすことが推奨されている。
これはストレージ節約の話ではなく再開速度の話だ。スナップショットが肥大化するとシリアライズ・デシリアライズのコストが増え、再開のたびに大きなペイロードを読み込むことになる。ステップの状態を小さく保つことが、復元を高速かつどこでも安全に行うための前提条件だという認識に、各社のドキュメントが揃ってきている。