チュートリアル
AI Agent State とは?2026 の状態管理、JSON State、Memory、Workflow とタスク実行 完全ガイド
チャット履歴は状態ではない。Agent が一時停止、再開、次ホップへ渡せるのは、検証できる JSON があるからだ。目標、手順、ツール回执、記憶ポインタ、タスク封筒。
2026 年に Agent を本番へ出すとき、詰まるのは「モデルが賢いか」ではない。停止、再試行、人手確認のあと、自分が何ホップ目にいたかを忘れないかだ。前回は Agent を観察→判断→ツール呼び出しのループに畳んだ。AI Agent とはを見よ。本稿はループの外側の層を足す。State。State は会話全文を文脈に詰めることでも、ベクトル庫の一節でもない。ランタイムの今の機位の構造化スナップショットであり、ほぼ常に JSON だ。JSON State、Memory、Workflow、タスク実行に分け、Stateless MCP、A2A、Structured Output、1M 文脈の記事へつなぐ。
Agent State とは:チャット履歴と Session との差
最小定義は一文。Agent State は、一度の run を一時停止・再開・再生できる構造化スナップショット。少なくとも四つに答える。目標は何か、今どのホップにいるか、確定した作業結果は何か、次を誰が止めているか(ツール、人、maxSteps)。行動はモデルが今の観察から選び、実行と機位の書き戻しはランタイムが担う。検証できる機位がなければ、ループは「チャット全文を再貼付」するしかない。それはチャットであり、状態管理ではない。
チャット履歴はモデルが見るメッセージ列だ。user / assistant / tool。Session(OpenAI Conversations、previous_response_id、旧 Assistants Thread)はベンダーが見る会話ハンドルだ。次リクエストが運ぶべきモデル側項目。State はあなたのランタイムが見る機位だ。請求書の突合が進んだ位置、確認待ち金額、現在のグラフノード、checkpoint id。共存はできる。成り代わりはできない。messages[] を唯一の真実にすると、再試行で二重課金や二重メールになる。Conversation id を業務状態にすると、ベンダーを替えた瞬間に機位が消える。Assistants から Responses へ移ったあと、会話の原語は変わった。業務スナップショットをプラットフォームオブジェクトに縛る理由はさらに薄い。Assistants → Responses 移行。
2026 年の典型事故は層の混線だ。ツール arguments を State に書く、State ごと次プロンプトに詰める、長期記憶を checkpoint として再生する。分けたあと、デバッグに取っ手ができる。モデルの読み違いは観察の問題、機位の書き違いは reducer / Schema、好みの取り違いは Memory。対照は次のとおり。
| 概念 | 誰が読むか | 失うとどうなるか |
|---|---|---|
| チャット / messages | モデル(このターンの文脈) | 的外れな回答。多くは checkpoint から再投影できる |
| Session / Conversation | モデルベンダー | 推論項目がずれる。業務機位は独立しているべき |
| Agent State / checkpoint | あなたのランタイムと編成器 | 安全に再開できない。再試行が下流へ二重書きする |
| Memory | run を跨ぐ检索と好み | 習慣を忘れる。現在ステップの真実にしてはならない |
JSON State:契約は checkpoint
State を JSON にするのは見栄えではない。検証、Diff、再生のためだ。LangGraph 系の編成器は super-step ごとに checkpoint を落とし、thread_id で一本の線にし、checkpoint_id で一枚を指す。本番はプロセス内 MemorySaver ではなく Postgres / SQLite saver。名前は変わる。形は変えてはならない。parse できるオブジェクトに schemaVersion、status 列挙、step、working、memoryRefs。シリアライザは JsonPlus や拡張 JSON でもよいが、ログ、公開、联调に出す層は普通の JSON object であるべきだ。でなければ Schema 検証もブラウザ Diff も使えない。
下のスナップショットは機位だけを書く。messages[] も下流 HTTP 原文も埋め込まない。業務フィールドは working。ツール呼び出しは name と callId。記憶はポインタ。完全な対話は checkpoint からモデル文脈へ再投影する。逆に文脈を State にしない。
{
"schemaVersion": "1.0",
"runId": "run_7c2a",
"threadId": "thr_invoice_42",
"goal": "Reconcile January 2026 paid invoices",
"status": "awaiting_tool",
"step": 3,
"maxSteps": 12,
"node": "call_tools",
"plan": ["searchInvoices", "sumTotals", "askConfirm"],
"working": {
"invoiceCount": 2,
"currency": "USD"
},
"pendingTool": {
"name": "searchInvoices",
"callId": "call_8f3a"
},
"memoryRefs": ["mem_user_prefs", "mem_last_reconcile"],
"checkpointId": "ckpt_3"
}
どちらも成立する。毎回の全量スナップショットか、JSON Patch / reducer。全量は Diff と再生がしやすい。パッチは容量を節約し、パッチ自体を検証できる必要がある。どちらでも Draft 2020-12 Schema を先に決める。status は列挙(running / awaiting_tool / awaiting_human / succeeded / failed / cancelled)、step は整数、working のキーは業務から、additionalProperties は禁止してツールのごみを入れない。ユーザや下流への最終答えは別の Structured Output ファイル。checkpoint と共用しない。AI Structured Output。
Memory:回想は機位ではない
Memory は「時間を跨いで何を覚えているべきか」、State は「この一枚がどこで止まったか」。2026 年の三層はこうだ。作業記憶(このターンのメッセージと直近の tool_result)、短期 / スレッド記憶(同一 thread_id の checkpoint 鎖。LangGraph の short-term memory)、長期記憶(スレッドを跨ぐ Store。好み、事実、手順)。三つを巨大 JSON に揉むと手早く見える。再生と忘却ポリシーが同時に壊れる。
内容でも分ける。情景(この突合で何が起きたか)、意味(ユーザはドル合計を好む)、手続(「先に請求書を探し、次に合計」)。現在の run が参照した記憶だけを State の memoryRefs に書く。文脈窓が百万 token になっても、このポインタ層は引退しない。窓は予算であり、真実ではない。1M Token 文脈。
| 層 | 典型的な担体 | 入れてならないもの |
|---|---|---|
| 作業記憶 | このターンの messages / tool_result | セッションを跨ぐ好みの全文 |
| 短期 / checkpoint | thread_id 上の State スナップショット | ベクトル庫の原文、未裁断ログ |
| 長期 Store | userId / namespace の条目 | 現在の step、pendingTool、冪等キー |
| モデル側 Session | Conversation / previous_response_id | 業務の working オブジェクト |
長期条目は封筒を固定する。id、kind、scope、text または data、source、updatedAt。source はユーザ明示、ツール回执、モデル要約のどれかを書く。後二者は破棄できなければならない。検索ヒットのあと、State には id だけを書き、本文は必要時に文脈へ注入する。例:
{
"id": "mem_user_prefs",
"kind": "semantic",
"scope": "user",
"userId": "u_1042",
"text": "Prefers USD totals and weekday email summaries",
"source": "explicit_setting",
"updatedAt": "2026-09-01T09:00:00Z"
}
Workflow と Agent:辺を引く者と State を書く者
古典ワークフロー(n8n、Temporal、自前の状態機械)の次ホップは人が予め配線する。State はワークフロー変数だ。注文 id、再試行回数、補償を出したか。Agent の次ホップはモデルが今の JSON 観察から選ぶ。State は plan、node、pendingTool も記す。2026 年の本番は純種が少ない。「グラフ + いくつかの Agent ノード」が普通だ。辺はワークフロー、ノード内部はツール循環。一つの JSON State が二人の読者に仕える。編成器は status / node を読み、モデルは投影した観察の部分集合だけを見る。
MCP はこの層を持たない。2026-07-28 前後のリモート MCP はステートレス JSON-RPC だ。毎回のリクエストがメタを持ち、Server は業務機位を覚えない。それは伝送の正しい選択であり、「Agent は状態を持てない」ではない。アプリ状態はなおあなたの checkpoint にある。詳細は Stateless MCP。ツール arguments の Schema と State Schema はファイルを分ける。前者はこのホップの入参、後者は機位。MCP と JSON Schema。
多 Agent の横委託は A2A。対端は不透明な Agent。タスクは独自のライフサイクル(submitted / working / completed / failed)と artifacts を持つ。それは別の状態機械だ。ローカル checkpoint とオブジェクトを共用しない。編成器は parentRunId で釘付けする。対照は A2A vs MCP。モデルゲートウェイ(ローカル /v1 など)は推論の供給だけを変え、State の形は変えない。契約が安定してこそ降級に意味がある。
タスク実行:run、step、冪等と再試行
実行層は State を「写真」から「回復できる機械」にする。ユーザ目標ごとに runId。ループ内の各ツール hop が step。下流への書き込み(課金、メール、チケット)には idempotencyKey が必須。クラッシュ後は最新 checkpoint から復帰し、成功済み step の副作用を再実行しない。pending writes(一部成功、一部失敗)はスナップショットに残す。運用の勘に頼らない。
人手確認は一等の状態であり、特殊分岐ではない。status=awaiting_human、確認対象は working、再開時は合法な遷移だけを許す(承認→続行、拒否→失敗または plan 変更)。「もう一度モデルに聞く」で状態遷移を代替しない。観察に書いていないクリックはモデルに見えない。maxSteps、ユーザ取消、Schema 失敗も停止条件だ。status に書き、ログだけにしない。
プラットフォームのセッションとあなたの実行記録のうち、履歴の主人は一人にする。OpenAI Responses は Conversation または previous_response_id で推論項目を続けられる。それはモデル側のテープであり、請求書突合の機位ではない。推奨:checkpoint とタスク封筒はあなたが持ち、プラットフォームは再生を要求する reasoning 項目だけを持つ(tool_calls があるとき reasoning_content の原状回放を求めるベンダーがある)。タスク封筒の例:
{
"taskId": "task_a2a_91",
"parentRunId": "run_7c2a",
"kind": "delegate",
"status": "working",
"idempotencyKey": "inv-jan-2026-reconcile",
"steps": [
{ "id": "s1", "name": "searchInvoices", "ok": true },
{ "id": "s2", "name": "sumTotals", "ok": null }
],
"artifacts": []
}
子 Agent へ委譲するときは、远端の taskId をローカルの working または steps に書く。相手の artifacts を同じ checkpoint に広げない。中間産物は新しい JSON 家族だ。最終 Structured Output とも MCP arguments ともファイルを共用しない。今から各ツールログに correlationId / runId を打て。後の突合が合う。DevDay 系の観測も同じキーで揃える。OpenAI DevDay 2026 予測。
現場の検証と JSONVue
checkpoint を落とす前は三步。parse → Schema → 業務規則。賢いモデルでもこの三步は代替できない。State の破損は arguments の破損より危ない。後者は一 hop、前者は run 全体の真実だ。
- checkpoint を JSON.parse。失敗なら書き込みを拒み、前の ckpt_id を残す。
- State Schema(Draft 2020-12)で status / step / working を検証。path と keyword を出す。
- 業務ゲート:step は単調、冪等キーは安定、memoryRefs はすべて存在、非法な status 遷移は失敗で閉じる。
联调では三つの JSON を並べる。ckpt_n、ckpt_n+1、モデルへ投影した観察。形の跳びはほぼ reducer。ブラウザではJSON フォーマッタでスナップショットの木を見、JSON Schema 検証で State と Memory 封筒を固定し、JSON Diffで隣接 checkpoint を比べる。valid / 欠 step / 非法 status を CI と手作業で共有する。
関連:AI Agent とは、Structured Output、Stateless MCP、A2A vs MCP、1M Token 文脈。
よくある質問
State と Memory は同じか?
違う。State は現在の run の機位(安全に再開できるか)。Memory は時間を跨ぐ回想(好み、事実、古いエピソード)。checkpoint 鎖は短期記憶になれる。長期 Store に step / pendingTool を書いてはならない。再生は State、検索は Memory。
文脈窓が 1M になった。checkpoint はまだ必要か?
必要だ。窓は「このターンにどれだけ観察を詰められるか」を決める。「クラッシュ後にどのホップから続けるか」と「再試行が二重書きするか」は決めない。履歴全文を State にすると、請求と故障面が同時に悪化する。1M は予算の道具、checkpoint は実行の道具。
OpenAI Conversation を使っている。自分で JSON State を持つ必要はあるか?
ある。Conversation / previous_response_id が続けるのはモデル側の項目であり、業務機位ではない。クォータ、リージョン、ゲートウェイが変わると、プラットフォームのセッションは揃わないことがある。working、冪等キー、人手確認の状態は、あなたが制御する JSON に置く。
Stateless MCP では有状態 Agent は作れないのか?
作れる。プロトコルが無状態なのは、毎回の tools/call が自分の引数を持つという意味だ。Server は突合の進捗を保存しない。アプリ状態はあなたの checkpoint。MCP は発見と伝送のまま。inputSchema と State Schema は二つのファイルにする。
まとめと次の一手
2026 年の Agent State は一文にできる。ランタイムは検証できる JSON スナップショットで機位を覚え、Memory は参照された回想だけを出し、Workflow は辺を引くかモデルに渡し、タスク実行は run / step / 冪等キーでスナップショットを回復できる機械にする。チャット履歴もプラットフォーム Session も、このスナップショットの代わりにはならない。
次は具体的だ。State Schema と valid な checkpoint を一つ書き、JSONVue で隣接スナップショットを Diff し、欠フィールドと非法 status の夹具を足す。ループ定義は Agent 記事、最終形は Structured Output、プロトコルは MCP / A2A。