{
  "issue": "2026-09-03",
  "generated_at": "2026-09-03T07:00:00+09:00",
  "theme": {
    "title": "長時間稼働エージェントの状態管理 — 「会話の保存」から「プロセスの永続化」へ",
    "category": "agent-durability",
    "lede": "エージェントが数分の対話ではなく数時間・数日単位のバックグラウンドタスクをこなすようになったことで、コンテナ再起動やタイムアウトはもはや例外ではなく前提になった。これまでチャットボットが会話履歴だけを保存してきたのに対し、いま各社が取り組んでいるのは「どのステップまで完了したか」という実行状態そのものをチェックポイントとして永続化する設計だ。何を保存し、何を保存しないかという粒度の判断も含め、具体例を追う。",
    "tldr": [
      "Google ADKやMastraは、ツール呼び出しなどステップの境界ごとに実行状態をシリアライズして外部ストレージに書き込み、コンテナが落ちても直前のステップから再開できる設計に収束している。",
      "LangGraphのinterrupt()は人間の承認待ちを例外処理ではなくグラフの一時停止として扱い、待機時間の長さに関係なく同じチェックポイント/再開の仕組みに乗せる。",
      "スナップショットには大きなデータそのものではなく参照(ID)だけを持たせるclaim checkパターンが標準になりつつあり、Temporal上の実装ではイベント履歴の上限を超えないための必須設計になっている。"
    ],
    "sections": [
      {
        "heading": "チェックポイントは「会話履歴の保存」ではなく「プロセス状態の永続化」",
        "body_html": "<p>長時間稼働エージェントの標準構成は、ツール呼び出しなど各ステップの境界でエージェントの実行状態（変数・実行位置・保留中のタスク）をシリアライズし、外部ストレージへ書き込むというものだ。会話ログとは別に、<code>ToolContext.state</code>のような実行状態そのものを永続化することで、プロセスが落ちても直前のステップから再開できるようにする。</p><p>バックグラウンドで数時間から数日動くエージェントが増え、コンテナのタイムアウトやスケールゼロは例外ではなく前提になった。インメモリの会話履歴だけを保持していると、再起動のたびに文脈は残っても「どこまで進んだか」という実行位置が失われる。この2つを分けて管理しないと、副作用のあるツール呼び出しまで巻き戻って再実行してしまう、というのが各社が同じ設計に落ち着いた理由だ。</p>",
        "examples": [
          {
            "product": "Google ADK（Agent Development Kit）",
            "approach": "ツール呼び出しごとに自動でチェックポイントし、DatabaseSessionServiceでToolContext.stateをSQLite/Cloud SQLへ永続化",
            "detail": "コンテナがスケールゼロしても、Webhook到達時にセッションをストレージから復元し推論チェーンを中断箇所から再開する設計を公式ブログで解説している",
            "source_url": "https://developers.googleblog.com/build-long-running-ai-agents-that-pause-resume-and-never-lose-context-with-adk/"
          },
          {
            "product": "Mastra",
            "approach": "1回のrunをJSONにチェックポイントし、別マシンでも同じスナップショットから再開できる設計",
            "detail": "起動時にstatusがrunningのまま止まっている全runを検出し、最後のスナップショットから自動的に再実行する仕組みを公式ブログで公開している",
            "source_url": "https://mastra.ai/blog/what-are-durable-ai-agents"
          }
        ],
        "takeaway": "長時間動くエージェントを設計するなら、会話履歴の永続化とは別に「どのステップまで完了したか」を表す実行状態を明示的にモデル化し、ステップ境界ごとに書き込む仕組みを最初から組み込むべき。"
      },
      {
        "heading": "人間の承認待ちを「例外処理」ではなく「グラフの一時停止」として設計する",
        "body_html": "<p>LangGraphの<code>interrupt()</code>は、承認が必要な地点でグラフの状態をチェックポインタに保存し、再開の合図が来るまで無期限に待つ。呼び出し側は<code>thread_id</code>で「どの中断中の実行を再開するか」を指定し、人間の判断は<code>Command(resume=...)</code>というJSONシリアライズ可能なペイロードとして<code>interrupt()</code>の戻り値になる。</p><p>承認待ちを個別のポーリングAPIやtry/exceptで実装すると、承認までの待ち時間が数分でも数日でも同じコードパスで扱うのが難しい。グラフの一時停止として扱えば、待機時間の長さに関係なく同じチェックポイント/再開の仕組みに乗る。これが「割り込みは例外ではなく状態遷移の一種」という設計に各フレームワークが収束した理由だ。</p>",
        "examples": [
          {
            "product": "LangGraph",
            "approach": "interrupt()でグラフ状態を保存し、Command(resume=...)で再開する一時停止パターン",
            "detail": "checkpointerとthread_idを必須要件とし、中断中の実行を人間の判断が届くまで待たせる設計を公式ドキュメントが規定している",
            "source_url": "https://docs.langchain.com/oss/python/langgraph/interrupts"
          }
        ],
        "takeaway": "承認待ちやレビュー待ちのような不定長の待機は、専用のポーリング機構を自作せず、チェックポイント可能なグラフの一時停止として設計に組み込むと後から待機時間の制約に振り回されにくい。"
      },
      {
        "heading": "スナップショットの粒度設計 — 保存するのは本文ではなく参照",
        "body_html": "<p>実行状態のスナップショットには、大きなデータそのものではなく参照（ID）だけを持たせ、必要になった時点で再取得する「claim check」パターンが標準になりつつある。Temporal上でエージェントを組む場合、イベント履歴には50MB・51,200イベントという上限があり、数KBを超えるペイロードは履歴に直接書かず外部ストレージへ逃がすことが推奨されている。</p><p>これはストレージ節約の話ではなく再開速度の話だ。スナップショットが肥大化するとシリアライズ・デシリアライズのコストが増え、再開のたびに大きなペイロードを読み込むことになる。ステップの状態を小さく保つことが、復元を高速かつどこでも安全に行うための前提条件だという認識に、各社のドキュメントが揃ってきている。</p>",
        "examples": [
          {
            "product": "Mastra",
            "approach": "ステップ状態に大きなドキュメント本文を持たせず、IDだけを保持して必要時に再取得",
            "detail": "スナップショットを小さく・速く・どこでも安全に読み込めるものに保つためのベストプラクティスとして公式ブログが明記している",
            "source_url": "https://mastra.ai/blog/what-are-durable-ai-agents"
          },
          {
            "product": "Ably（Temporal上のAIエージェントチャット実装）",
            "approach": "50MB・51,200イベントの上限を超える前にclaim checkパターンで大きなペイロードを外部ストレージへ逃がす",
            "detail": "イベント履歴に会話全文を置くと実行がContinue-As-Newで分断され、単一クエリで全文を取得できなくなる問題を実例付きで解説している",
            "source_url": "https://ably.com/temporal/managing-conversation-history-in-a-temporal-ai-agent-chat"
          }
        ],
        "takeaway": "エージェントの状態設計では、まず「再開に絶対必要な最小の情報は何か」を先に決め、それ以外は参照だけを持たせる。スナップショットのサイズは後から効いてくるコストなので最初から意識しておく。"
      }
    ]
  },
  "editorial": "会話の続きを保存するのと、プロセスの続きを保存するのは別の設計課題だ。会話履歴だけを永続化してきたチャットボット時代の発想のままバックグラウンドエージェントを作ると、再起動のたびに「どこまでやったか」を失う。2026年に各社が収束したのは、実行位置そのものを一級市民として永続化するという、地味だが本質的な転換だった。",
  "quick_picks": [
    {
      "title": "Long-running Agents（AddyOsmani.com）",
      "summary": "長時間稼働エージェントを実務で構築する際の実装パターンをまとめた記事。ディスクへの中間状態の書き込みとNユニットごとのチェックポイントを推奨しており、本文の「チェックポイント境界の設計」と直接つながる。",
      "url": "https://addyosmani.com/blog/long-running-agents/"
    },
    {
      "title": "Introducing Durable Agents（Mastra Blog）",
      "summary": "MastraがDurableAgentという実行時プリミティブを発表した際の一次情報。本文で紹介したチェックポイント機構の元になった製品発表で、設計思想の背景を補足する。",
      "url": "https://mastra.ai/blog/introducing-durable-agents"
    },
    {
      "title": "Build Resilient AI Agents with Restate and Google ADK（Restate Blog）",
      "summary": "Restateのdurable execution基盤をGoogle ADKと組み合わせてエージェントを堅牢化する実装例。本文のチェックポイント/再開設計を、別のランタイムでどう実現するかの比較対象になる。",
      "url": "https://www.restate.dev/blog/build-resilient-ai-agents-with-restate-and-google-adk"
    }
  ]
}
