先給結論:Agents API 把迴圈託管了,沒有把合約託管。2026 年 9 月 10 日,OpenAI 把驅動 Codex 的 Agent Harness 以 public beta 交給開發者。模型排程、上下文壓縮、子 Agent、沙箱生命週期,都從你的程式挪到了 beta.agents.sessions。你還握在手裡的,幾乎全是 JSON:function 工具的 JSON Schema、arguments、tool_result 的字串、MCP 的 inputSchema、session 事件流。Harness 替你跑 loop,不等於替你校驗欄位。合約鬆了,託管迴圈只會把壞參數跑得更勤。
這篇按 2026 年 9 月 18 日寫。本站已有《Agent 為什麼離不開 JSON》《Tool Calling 為什麼依賴 JSON Schema》《JSON Schema 會成為標準 Contract 嗎》《MCP / Skills / Tools / Subagents》《MCP 是什麼》。本文只回答:Agents API 發布之後,JSON 為什麼更重要,而不是更不重要。
9 月 10 日到底發布了什麼
OpenAI 的原話是:用驅動 Codex 的同一套 harness 和基礎設施,給開發者一個託管的雲端 Agent。公開文件把它放在 beta.agents 名稱空間,請求要帶 OpenAI-Beta: agents=v1。Harness 本身不另收費,你付的是模型 token、工具和沙箱時間。
一次 session 建立裡,你提交的是一份 JSON:模型、指令、工具列表、環境、輸入。官方示例用 gpt-6-astra,工具可以是 MCP、自定義 function、內建檢索。環境可以是 none、openai_hosted,或接到 Blaxel、Cloudflare、Daytona、E2B、Modal、Vercel 這類自建 / 合作沙箱。多 Agent 用 multi_agent.enabled 和 max_concurrent_subagents 開啟。
它不是又一個「請輸出 JSON」的聊天介面。Responses API 還在;Agents SDK 還在。Agents API 收走的是迴圈本身:誰決定下一跳、何時壓縮上下文、何時派子 Agent。公測期欄位名仍可能改,但分層已經清楚:OpenAI 跑 harness,你提供工具合約和業務結果。
三套入口:Responses、Agents SDK、Agents API
2026 年 9 月,OpenAI 並排放著三條做 Agent 的路。混用之前先分清「迴圈跑在哪」:
| 入口 | 迴圈跑在哪 | 狀態存在哪 | 你還寫什麼 |
|---|---|---|---|
| Responses API | 你的應用 | 你自己拼 history / Conversations | 模型呼叫、工具回灌、整段 loop |
| Agents SDK | 你的程式 | SDK session + 你的儲存 | 審批、部署、仍可改 loop |
| Agents API | OpenAI 託管的 Codex harness | 服務端 session / turn / item | 工具定義、function 結果、環境選擇;改不了 loop |
單次補全繼續用 Responses。要自己握審批和落盤,用 SDK。要把「跑幾天的任務、壓縮、子 Agent、沙箱」交給對方,用 Agents API。三條路的工具參數都還是 JSON Schema。差別是:前兩條你還能在 loop 里加補丁;第三條補丁只能加在合約和回灌上。
Agent Harness 是什麼,它不替你簽什麼
Harness 是夾在模型和副作用之間的執行時:讀事件、選工具、喂結果、壓縮上下文、在超長任務裡保住進度。Codex 那一套現在開源可見,Agents API 則由 OpenAI 運維同一套邏輯,並隨模型版本升級。公告裡點名的能力包括自動 compaction、Tool search、Programmatic Tool Calling、並行 subagents。
它不簽這幾樣東西:
- 某個
customer_id該不該存在、該不該是 UUID; - 你的函式該不該接受多餘鍵;
- MCP Server 的
inputSchema松還是緊; - 回灌給模型的
output是物件、字串,還是一段聊天。
這些仍然是 JSON Schema 和你自己的二次校驗。託管 harness 提高的是「迴圈能跑多久、能並行多少」;它不提高「這一跳參數是否合法」。把兩者當成一回事,是這篇要拆開的第一層誤會。
為什麼託管之後 JSON 跳數反而更多
自己寫 loop 時,壞 JSON 往往死在你這一側:parse 失敗、欄位對不上,你就停。迴圈託管之後,失敗被推遲、被複製、被送進更多通道:
| 跳 | 載體 | 誰生成 | 誰必須校驗 |
|---|---|---|---|
| 建立 session | agent / tools / environment JSON | 你的應用 | 你:提交前 |
| function 定義 | JSON Schema(parameters) | 你的應用 | 你:收緊 required / additionalProperties |
| 模型發起呼叫 | arguments 物件 | 託管 harness + 模型 | 你:執行前再驗一遍 |
| 回灌結果 | tool_result.output 字串 | 你的應用 | 你:先 stringify 合法值 |
| MCP | JSON-RPC + inputSchema | Server / harness | Server 與你的允許列表 |
| 事件流 | agent.session.* JSON 事件 | 託管服務 | 你:按 type 分支,不要當聊天正文 parse |
再加上 Tool search 按需載入定義、Programmatic Tool Calling 在程式碼裡串並行呼叫、subagent 各自帶一份上下文——一次使用者任務裡的 JSON 往返,比「單次 Function Calling」多一截。託管讓這些跳對你不可見,不可見不等於可以不校驗。資料流的逐跳拆解見《從 Tool Calling 到 MCP》。
Tool Calling:function 工具仍是 JSON Schema
Agents API 的 function 工具和 Responses API 用同一套定義。你交給 agent.tools 的不是一段自然語言,而是名字、說明、一份 JSON Schema:
{
"type": "function",
"name": "get_customer",
"description": "Look up a customer by ID.",
"parameters": {
"type": "object",
"properties": { "customer_id": { "type": "string" } },
"required": ["customer_id"],
"additionalProperties": false
}
}
官方示例把 required 寫滿,並把 additionalProperties 設為 false。這不是排版習慣。Agent 一旦被允許多寫一個鍵,那個鍵就可能變成路徑、SQL 片段或「順便刪除」。Schema 是模型在解碼時看到的合約,也是你在執行前應再跑一遍的合約。嚴格模式、ajv、二次校驗的流水線見《Tool Calling 為什麼依賴 JSON Schema》。
描述欄位仍然有用,它幫模型選工具;它不能代替型別、列舉和必填。Harness 越聰明,越會在一堆工具裡挑一個「差不多」的——差不多的呼叫,只能靠 Schema 擋下來。
requires_action 與 tool_result:回灌也是 JSON
模型要跑你的函式時,session 停在 agent.session.requires_action。待處理項在 required_actions 裡,而不是「歷史裡有一條 function_call」就算數。一條典型的 pending 呼叫是:
{
"type": "function_call",
"turn_id": "turn_123",
"call_id": "call_123",
"name": "get_customer",
"arguments": { "customer_id": "123" }
}
檔案把 arguments 寫成物件。不要把它再包進聊天回覆裡用 JSON.parse 摳——那是上一篇《JSON.parse 為什麼失敗》的通道錯誤。你要做的是:用同一份 Schema 校驗這個物件,執行函式,然後往 session 事件介面回 agent.session.input.tool_result,帶上原來的 turn_id / call_id。
成功時 success: true,output 是字串或受支援的內容陣列。物件要先 JSON.stringify。失敗時 success: false,給模型一段能讀的 error。不要把堆疊、金鑰、整份資料庫行回灌回去。程式若在執行後、回灌前崩潰,應按 session / turn / call 做冪等:重啟後先讀 pending,再決定是否重跑。
Function 始終在你的應用裡跑,即使 session 帶了沙箱。Harness 不會替你執行 get_customer。你不線上,這一跳就掛起。這是託管迴圈裡,少數仍然完全屬於你的同步點——也是你必須把 JSON 做對的那一跳。
Tool search 與 Programmatic Tool Calling
工具一多,把全部 Schema 塞進上下文會燒 token、打快取。Agents API 預設急切載入 function;不常用的可以 defer_loading: true,並在 agent.tools 裡放 {"type": "tool_search"}。模型先搜到相關定義,再呼叫。於是多出一跳「定義本身也是 JSON」:搜到的 Schema 必須和你真正實現的函式一致,不能搜到一份寬合約、執行一份窄實現。
Programmatic Tool Calling 讓受支援的模型寫一小段程式碼,並行或串聯合格工具,再只把過濾後的結果帶回上下文。這降低了「每一跳都佔滿視窗」的成本,提高了「中間 JSON 必須合法」的要求。中間結果若型別漂移,後面的過濾和合並會在你看不見的 harness 裡靜默錯下去。SDK 一側已經出現「把結構化錯誤編碼成 JSON」的修補,說明這條路徑吃的就是 Schema,不是散文。
MCP 與 Subagents:更多 Schema,更多 JSON
把 MCP Server 寫進 agent.tools,harness 負責發現工具、發起呼叫、把結果喂回模型。和 function 不同:這些呼叫不經過你的應用。HTTP 預設由 OpenAI 連;也可以指定從環境連,或在沙箱裡用 stdio 拉起程式。你在這一層能做的,是 allowed_tools、初始化失敗是否讓 turn 失敗(required: true),以及 Server 自己的 inputSchema 有多緊。
MCP 的報文仍是 JSON-RPC。Schema 鬆,託管 harness 會替模型打出更多你看不到的請求。這不是「協議幫你安全了」,是「迴圈離你更遠了」。協議分層見《MCP 是什麼》;和 Skills、Subagents 的邊界見《2026 Agent 棧》。
Subagents 各自一份上下文,主 Agent 彙總。並行能降延遲,也會並行打出多份 arguments。主 Agent 拿到的彙總若仍是無 Schema 的長文字,你只是把「解析聊天」推遲到了最後一跳。要程式序的結論,最終答覆仍應走 Structured Output 或一份你定義的結果 Schema,而不是再從散文裡摳。見《Structured Output 是什麼》。
你還要在本機校驗的四件事
Harness 託管之後,清單不是變短,是變窄:
- 工具 Schema。
required寫滿,additionalProperties: false,列舉收緊。不要靠描述詞攔副作用。 - 執行前的 arguments。廠商說過 Schema,仍要在你的程式裡用同一份再驗。型別錯、缺欄位、多出來的鍵,這一層攔。
- 回灌的 output。先做成合法 JSON 再
stringify。錯誤走success: false,不要把內部異常原文丟給模型。 - 事件與聊天正文分通道。讀
event.type,不要把整段 SSE 當 JSON 值。最終對使用者的結構化答覆,用 Structured Output,不要JSON.parse助手句子。
安全一側還要記得:arguments 裡的字串可能是注入,不是「型別對了就執行」。見《惡意 JSON 與 Prompt Injection》。JSON Schema 會不會成為跨廠商合約,見《標準 Contract》——Agents API 沒有削弱這個判斷,它把它推到了你唯一還能改的那一層。
用本機 JSON 工具看合約
接到託管 session 之前,先在瀏覽器裡看三份文字:工具 Schema、一條樣本 arguments、你準備回灌的 output。
- JSON 校驗 — 文法是否合法;有 Schema 就一起核欄位、必填、多餘鍵。
- JSON 格式化 — 把壓成一行的
tool_result展開,看你是不是把整行資料庫序列化回去了。 - JSON Diff — 對比「模型傳來的 arguments」和「Schema 允許的最小物件」。
資料不離開瀏覽器。適合把一份失敗的 required_actions、一份 parameters、一次 stringify 後的結果放在一起看。合約穩定了,再交給 hosted harness 去跑幾天。
常見問題 FAQ
Agents API 是不是讓我不用再寫 JSON Schema 了?
正好相反。迴圈被託管之後,Schema 是你還握著的主合約。function 的 parameters、MCP 的 inputSchema、回灌的 output,都還是 JSON。
Agents API、Agents SDK、Responses API 該怎麼選?
單次呼叫用 Responses。要自己握 loop、審批和儲存,用 SDK。要把長任務、壓縮、子 Agent、沙箱交給 OpenAI,用 Agents API。三條路的工具參數都是 JSON Schema。
arguments 已經是物件,還要不要 JSON.parse?
不要把整段聊天再 parse 一遍。按檔案把它當物件,用同一份 JSON Schema 校驗。從散文裡摳 arguments,是通道用錯了。
tool_result 為什麼必須 stringify?
檔案要求 output 是字串或受支援的內容陣列。物件先做成合法 JSON 再 stringify,避免二次編碼和「看起來像物件、其實是字串」混用。
MCP 工具會經過我的應用嗎?
預設不會。harness 直連 Server。你要收緊的是 Server 自己的 inputSchema、allowed_tools,以及不可逆操作在 Server 內的審批。
公測期欄位會不會改?
會。這篇按 2026 年 9 月 18 日的公開文件寫。分層不會改:harness 跑迴圈,你提供 JSON 合約。欄位名變了,校驗責任還在你這邊。
總結
Agents API 降低的是「如何跑完一個 Agent」的工程量,提高的是「每一跳 JSON 必須正確」的權重。9 月 10 日交出的是 Codex harness:session、壓縮、工具搜尋、程式化呼叫、子 Agent、沙箱。它不檢查你的 customer_id 該長什麼樣,也不替你把 tool_result 編成合法字串。
2026 年把 Agent 接到程式,順序沒有變:工具走 JSON Schema,結果走 Structured Output,聊天正文不要當 API。變的是,loop 一旦託管,你能打補丁的地方只剩合約。先在本機校驗工具裡看 Schema、arguments 和回灌結果,再交給 hosted session 去跑。模型會換,harness 會改版本;你的欄位合約不應跟著一起松。