AI 開発

OpenAI Agents API は長時間の AI Agent をどう扱うか。Context、Tools、Subagents、JSON 状態管理(2026)

約 16 分

9 月 10 日の公開ベータは「もう一つの chat」ではない。Codex を何日も回していた harness を渡した:Session は続き、文脈は compact され、subagent は自分の文脈を持つ。長い仕事がどう生きるかだけを書く。どの JSON を保存し、何が圧縮され、切断後にどの items を読むか。

読む前の一覧

対象 何をするか 何を持つか
Session 時間と窓をまたぐ継続可能な実体 session_id
Turn 一つの入力で始まる非同期作業 turn_id / 終了イベント
Items 保存されたメッセージとツール呼び出し 切断後の再生
Compact 上限近くで自動圧縮 要点は自分で持つ
Subagent 独立した文脈で並列作業 同時実行の上限

アイドルの session は成功ではない。turn のイベントと items を見る。最後の一文ではない。

長い仕事は Session に住む。より長い prompt ではない

Agents API の答えは具体的だ。durable な session を作り、後続の入力は同じ session_id に送る。文脈上限に近づくと harness が先行内容を自動 compact する。独立した下位作業は subagent に出せる。チャット全文を自分で組む必要はない。

  • 継続:session_id を業務の会話に結ぶ。同じ案件で二つ目の session を開かない。
  • 切断:ストリームは再送しない。session と items を取り直す。クライアントが前の跳躍を覚えていると思わない。
  • 金額と番号:compact は細部を落とす。注文番号、金額、承認は自分の JSON に書く。

Session とツール JSON のつなぎは OpenAI Agents API 完全解説。ループを預けるかは Agents API vs Responses API。Agent と Function Calling がまだ一つの語なら AI Agent 完全ガイド。

Session は続き、Turn は非同期で走る

作成時にモデル、ツール、環境、multi_agent を一度宣言する。公式の作成は POST /v1/agents/sessions、ヘッダは OpenAI-Beta: agents=v1。ホストされたサンドボックスは openai_hosted:

{
  "agent": {
    "model": "gpt-6-astra",
    "instructions": "Look up orders. Confirm before any refund. Delegate independent lookups to subagents.",
    "tools": [
      {
        "type": "function",
        "name": "lookup_order",
        "parameters": {
          "type": "object",
          "properties": {
            "order_id": { "type": "string", "pattern": "^[A-Z]-\\d{4}$" }
          },
          "required": ["order_id"],
          "additionalProperties": false
        }
      },
      { "type": "web_search" }
    ],
    "multi_agent": { "enabled": true, "max_concurrent_subagents": 3 }
  },
  "environment": { "type": "openai_hosted", "workspace_directory": "/workspace" },
  "input": [
    {
      "role": "user",
      "content": [{ "type": "input_text", "text": "Look up A-1042 and keep the case open." }]
    }
  ]
}

同じ session に agent.session.input.message を送る。アイドルなら新しい turn。稼働中なら現 turn を操舵する。取消は agent.session.input.cancel。session と保存済み作業は残る:

{
  "events": [
    {
      "type": "agent.session.input.message",
      "input": [
        {
          "role": "user",
          "content": [
            { "type": "input_text", "text": "Warehouse marked A-1042 packed. Continue." }
          ]
        }
      ]
    }
  ]
}

結末を見る。「今アイドルか」ではない。公式イベントは agent.session.turn.completed、failed、cancelled。turn 完了は全ツール成功を意味しない。関数結果が必要なら required_actions を読む。

ツール連鎖は時間をまたぐ。書き戻しは JSON のまま

長い仕事でもモデルは引数だけ埋める。関数の番が来ると harness は止まり、turn_id / call_id で結果を返す。四時間後も形は同じ:

{
  "type": "tool_result",
  "turn_id": "turn_4",
  "call_id": "call_3c91",
  "success": true,
  "output": "{\"order_id\":\"A-1042\",\"status\":\"packed\"}"
}

function はあなたが実行する。MCP と web_search は harness が走らせてよい。subagent は MCP とウェブ検索を継ぐ。function ツールは継がない。自社注文の副作用は主 Agent に残す。

門は依然 Schema。広い object は長い仕事でより危うい。compact 後、モデルは番号を誤りやすい。MCP の行は別のツール表。境界は MCP Tool Schema vs Function Calling。

Compact が縮めるのは窓であり、台帳ではない

公式はこう書く。上限に近づくと Agents API が先行文脈を自動 compact し、仕事が複数の窓をまたげる。圧縮器を自分で書く必要はない。Responses の context_management / /responses/compact とは別層。

  • Agents API:session が自分で圧縮する。items を取り、注文番号が残るか確かめる。
  • Responses:compact を自分で付けるか、compact 端点を呼ぶ。暗号化された compaction item を次窓の入力にし、手で切らない。
  • 両方:圧縮は細部を落とす。金額、確認、解放はホストが書く。

order_id を会話にだけ置くのは、台帳を要約に渡すことだ。門としての Schema は AI に JSON Schema が必要な理由。

Subagent:並列だが文脈は分かれる

multi_agent.enabled を付けると、harness が作成、伝言、待機、中断を用意する。これらのツールを自分で宣言しない。items に協調動作が出る:

{
  "data": [
    {
      "type": "function_call",
      "turn_id": "turn_4",
      "call_id": "call_3c91",
      "name": "lookup_order",
      "arguments": "{\"order_id\":\"A-1042\"}"
    },
    {
      "type": "create_subagent_call",
      "agent_id": "agent_main",
      "task": "Compare A-1042 packing notes with the invoice."
    }
  ]
}
  • 独立した文脈:subagent ごとに一つ。主 Agent は create / message / wait / interrupt で閉じる。
  • 同時実行に上限:既定は 6(調整役を除く)。本番ではより小さい数を固定する。
  • 完了した項目 ≠ 下位作業の終了:create_subagent_call の完了は派遣されたことだけ。agent.session.subagent.created とその subagent の items を見る。

handoff は監査できる JSON であるべきだ。「経理へ渡して」という一文ではない。Schema への収め方は JSON Schema と Agent ワークフロー。

状態は自分で持つ。compact に記憶させない

OpenAI は session 設定、会話、保存済み作業を持つ。切断後に再建できる業務オブジェクトは、まだあなたが持つ:

{
  "session_id": "sess_8f21",
  "order_id": "A-1042",
  "last_turn_id": "turn_4",
  "last_call_id": "call_3c91",
  "awaiting": "tool_result",
  "compact_checkpoint": "after_turn_3"
}

このオブジェクトは Session でも、SDK session でも、Responses conversation でも、sandbox でもない。一つを消しても他は残る。データ所在は当面アメリカのみ。自己ホストのサンドボックスでも ZDR にはならない。

窓をまたぐ仕事を終える五手順

デモ動画から逆算しない。対象を歩く:

  1. session を一度作る。session_id を会話に書く。ツール表と Schema は一度締める。
  2. 購読してから後続入力を送る。流れを先に開き、それから agent.session.input.message。早いイベントを落とさない。
  3. required_actions で止まったら書き戻す。同じ turn_id / call_id を使う。新しい session で再試行しない。
  4. 切断したら items を取る。流れは再送しない。order=asc で並べ、番号と未完了の呼び出しを合わせる。
  5. compact のあと台帳を再確認する。要約に A-1042 が無ければ、次の跳躍は番号を作る。

五手順はすべて対象の上にある。一つ欠けると、窓がまだ空いていると賭けることになる。

長い仕事を見直すなら、二つの JSON を広げる

失敗の多くは、モデルが愚かになったことではない。対象が食い違うことだ。

  • session items と手元の状態を 整形 し、session_id / call_id が揃うか見る。
  • JSONPath 抽出 で order_id、turn_id、subagent の agent_id を抜く。
  • compact 前後の items を JSON Diff。番号が漂ったら、まず圧縮を見る。
  • 主 Agent の items とある subagent の items は分けて列挙する。一頁に混ぜると、協調が別人に付く。
  • 注文、session、社内 MCP を公開フォーマッタに貼らない。JSONSort はブラウザ内で動く。

二つの軌跡が再建できて初めて、仕事は続いたと言える。そうでなければ再び推測しただけだ。

よくある落とし穴

  • アイドルを成功だと思う。turn.completed / failed / cancelled を見てから、ツール結果を見る。
  • 切断後に流れの再送を待つ。公式は再送しないと書く。session と items を取る。
  • 注文番号を会話にだけ置く。compact 後、要約は A-1042 を落とすことがある。
  • multi_agent を開き、上限を付けない。既定の 6 でも token と副作用は扇状に広がる。
  • subagent に function を走らせる。下位エージェントは function ツールを持たない。照会は主 Agent に残す。
  • Session と Conversation を同一資源だと思う。一つを消しても他は残る。

FAQ

長時間実行は、より長い prompt のことか?

違う。durable な session、自動 compact、自分で持つ業務 JSON だ。長いシステムプロンプトでは窓の上限は上がらない。

Agents の compact と Responses の compact を混ぜてよいか?

混ぜない。Agents session は自分で圧縮する。Responses は context_management か /responses/compact。資源は二つ、次窓の入力も二つ。

切断後はどう復旧するか?

保存した session_id で session と items を取る。流れは逃したイベントを再送しない。last_turn_id と未完了の call_id を揃えてから、書き戻すか次のメッセージを送る。

subagent は lookup_order を呼べるか?

呼べない。公式は function ツール非対応と書く。MCP、ウェブ検索、環境のファイル / コマンドは継ぐ。自社注文の照会は主 Agent に残す。

自己ホストのサンドボックスで Zero Data Retention になるか?

ならない。公式は当面アメリカ所在のみ、ZDR 非対応と書く。self-hosted を選んでも ZDR にはならない。

結論

長時間実行は、より賢いモデルではない。継続できる Session、自動 compact、自分で握る JSON 状態だ。ツール引数、turn イベント、subagent の items は、その鎖の上の対象でしかない。

切断後に A-1042 を再建できるかを先に書く。できるなら仕事は生きている。モデルは変わる。session_id と Schema を先に安定させる。

続きを読む

更新記録: 初回公開