博客 AI / Agent

AI Coding Agent 大戰 2026:Claude Code、Codex、OpenCode、DeepSeek Agent 到底在競爭什麼?從 JSON Tool Calling 看 Agent Harness 架構

排行榜還在比誰分更高。打開終端,真正改文件、跑測試、連 MCP 的,不是那段自然語言回覆。

Claude Code、Codex、OpenCode、DeepSeek Agent 表面都在賣「能幹活的 Coding Agent」。真正拉開差距的,是 Agent Harness:誰擁有一次 JSON Tool Calling 從參數到副作用的控制權。

本文將介紹:

先記住這一點:2026 年的大戰不是「誰補全下一行更準」。模型發出 tool call,參數是 JSON;harness 決定能不能 parse、要不要批准、在哪種沙箱裏執行、結果怎麼回寫。Claude Code 把鉤子釘在每次調用前後;Codex 把沙箱和審批做成默認邊界;OpenCode 把模型和權限做成可換配置;DeepSeek Agent 把整條管道拆成插件。

真正在競爭的不是補全

補全解決「下一行寫什麼」。Coding Agent 解決「這個目標怎麼在真實倉庫裏做完」:讀上下文、選工具、改代碼、跑命令、看結果、再決策。

四家產品的界面都像聊天。底下的循環幾乎同一套:

四家共用的 Agent 循環
User goal
  → Agent loop
  → LLM emits tool_call (JSON arguments)
  → Harness parses / validates / gates / executes
  → Tool result returns to context
  → Agent decides again

模型負責推理和「下一步調誰」。harness 負責模型能看見哪些工具、參數算不算合法、高風險動作要不要問人、工具真正做什麼、會話怎麼記、怎樣算做完。

功能清單會越來越像。Skills、MCP、子 Agent、權限開關,大家都有。差別在控制權落在哪一層。產品定位怎麼分,見AI Coding Agent 已經不只是補全代碼:四家正在競爭什麼?。循環怎麼轉,見AI Coding Agent 如何工作?。本文只拆一件事:JSON Tool Calling 離開模型之後,harness 怎麼接管。

Agent Harness 是什麼

2026 年,這件事已經有了學科名字。一篇源碼解剖十一套生產 Coding Agent 的論文把它叫成 Harness Engineering:Agent 等於模型加 harness——把 LLM 接到真實世界的運行時,包括循環、工具、上下文、安全控制、編排和擴展面。

另一篇對照實驗問得更直:換 harness 會不會讓同一模型多解題?平均分往往差不多,倉庫任務和競賽任務會朝相反方向走,成本和取消率也會變。結論不是「原生 harness 一定更強」,而是「你買的是完成路徑,不是排行榜上的一個點」。

所以四家不是在比誰多一個按鈕。他們在比:誰把工具契約、執行邊界和人的否決權組織得更清楚。

負責什麼 不負責什麼
模型 選工具、填 JSON 參數、讀結果再決策 寫磁盤、跑 shell、連網、鑑權
JSON 契約 參數和結果長什麼樣 這次調用該不該發生
Agent Harness 可見工具、校驗、批准、沙箱、回寫、會話 替你想出業務目標

技術棧怎麼分層,可對照2026 AI Agent 技術棧:LLM、MCP、Function Calling、JSON Schema

共用電線:JSON Tool Calling

Tool Calling(也叫 Function Calling)不是「模型會寫代碼」的別名。它是一次結構化調用:模型從你聲明的工具列表裏選一個名字,再生成符合參數契約的 JSON。

OpenAI 兼容接口裏,工具定義的parameters字段本身就是 JSON Schema:

工具定義(parameters = JSON Schema)
{
  "type": "function",
  "function": {
    "name": "run_tests",
    "description": "Run the project test suite and return a structured summary.",
    "parameters": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "suite": { "type": "string", "enum": ["unit", "integration", "e2e"] },
        "path": { "type": "string", "minLength": 1 }
      },
      "required": ["suite"]
    }
  }
}

模型返回時,arguments經常是字符串,不是已經 parse 好的對象:

模型返回的 tool_call(arguments 是字符串)
{
  "id": "call_7f21",
  "type": "function",
  "function": {
    "name": "run_tests",
    "arguments": "{\"suite\":\"e2e\",\"path\":\"tests/checkout.spec.ts\"}"
  }
}

所以 harness 至少做兩件事:先把字符串解析成合法 JSON,再按你聲明的 schema 校驗字段、類型和枚舉。缺引號、多逗號、多寫未聲明鍵,都發生在這一跳。

MCP 把同一根電線接到外部 Server:inputSchema / outputSchema仍然是 JSON Schema,tools/call仍然是一次結構化調用。Server 越多,模型看見的 description 和 schema 越多,harness 要守的門也越多。安全責任怎麼拆,見MCP 安全漏洞全面解析

戰場:一次 tool call 的七跳

把四家產品攤開,功能名不同,管道形狀一樣。競爭發生在每一跳誰說了算:

  1. 1
    呈現

    哪些工具、哪一段 schema 被寫進這次請求。看不見的工具,模型調不到。

  2. 2
    發出

    模型選出名字,生成 arguments 字符串。這一跳只表示打算調用。

  3. 3
    解析

    字符串變成對象。非法 JSON 必須在進執行層之前失敗。

  4. 4
    校驗

    按 JSON Schema 檢查必填、類型、枚舉、additionalProperties。

  5. 5
    門禁

    allow / deny / ask。形狀合法不等於被授權。

  6. 6
    執行

    在沙箱、工作區或完整主機權限裏真正跑。副作用從這裏開始。

  7. 7
    回寫

    結果變成文本或 JSON,記入會話,喂回下一輪。失敗也要有結構,不能只丟一句「出錯了」。

四家都走這七跳。差別是:鉤子插在哪、默認沙箱有多緊、模型能不能換、管道本身能不能被替換。

Claude Code:鉤子釘在調用前後

Claude Code 把主 Agent 做強:Skills、MCP、子 Agent、CLAUDE.md 都圍繞同一個 Claude Agent。真正和 JSON Tool Calling 咬合的,是每次調用前後的確定性鉤子。

官方生命週期裏,循環中的每一次工具調用都會經過PreToolUsePostToolUse。還可以攔在權限提示出現時(PermissionRequest),或在失敗後決定能不能重試(PermissionDenied / PostToolUseFailure)。

鉤子讀到的是事件 JSON,不是一段散文。它可以改輸入、拒絕調用、要求確認,或在成功後補日誌、跑格式化、把新上下文塞回去。它不能撤銷已經發生的副作用——PostToolUse來晚了。

權限規則按 deny → ask → allow 匹配,deny 優先。鉤子返回 allow 只跳過交互提示,擋不住企業託管的 deny 名單。即使開了bypassPermissions,返回 deny 的PreToolUse仍能擋住調用。

工程含義很清楚:概率性的 Agent,加上確定性的門。測完再提交、擋住危險命令、保護路徑要批准——這些不該靠模型「每次都想起」。

適合:工作流穩定,要在主循環上釘 Skills / 子 Agent / 鉤子,把經驗做成可複用包。

Codex:沙箱和審批先於執行

Codex(含 Codex CLI)把問題推到執行層。Agent 一旦改文件、跑 shell、裝依賴、碰網絡和憑據,就必須同時回答兩件不同的事:能力邊界,和這次許不許可。

機制 回答的問題 典型旋鈕
Sandbox 技術上碰得到、改得到什麼? read-only / workspace-write / danger-full-access
Approval 這個動作現在允不允許? untrusted / on-request / never

默認敘事是最小權限:先把環境收緊,需要時再打開。未信任目錄從 read-only 起步;信任工作區後,常見預設是workspace-writeon-request——工作區內讀寫和常規命令自動跑,出工作區或碰網絡要批准。網絡默認關,要顯式打開。

新版本開始用 permission profile 描述文件系統和網絡,和舊的sandbox_mode不要混用。名字在變,拆法沒變:一邊是「碰得到什麼」,一邊是「現在能不能做」。

適合:副作用大、要可審計執行軌跡、把隔離和批准當成一等公民。開源倉庫:openai/codex

OpenCode:模型可換,權限是配置

OpenCode 的差異不在「再發明一套 Skills 語法」。默認立場是:模型可換。MIT 開源,終端優先,接多家供應商和本地模型。靈活性主要在配置——provider、model、permission、agent——而不是把 harness 內核拆成插件總線。

權限已經從早期的布爾tools收進permission:每個動作是 allow、ask 或 deny。可以按工具名、命令模式、是否出工作區(external_directory)來寫規則;最後一條匹配生效。子 Agent 可以比主 Agent 更嚴,比如 review 角色直接 deny 掉 edit。

OpenCode 把門禁寫成 JSON 配置
{
  "$schema": "https://opencode.ai/config.json",
  "permission": {
    "bash": {
      "*": "ask",
      "git *": "allow",
      "git push *": "deny"
    },
    "edit": "allow",
    "external_directory": "deny"
  }
}

它通常贏在:多模型是默認能力,而不是廠商附贈;開源許可和社區生態;「換模型」是一等操作。代價也清楚:執行邊界和插件深度未必是賣點第一名。你買的是可換模型的 harness,不是最重的沙箱產品,也不是「Everything is a plugin」的平臺內核。

適合:不信任單一供應商,或要在同一套循環裏換模型、走本地權重。

DeepSeek Agent:管道本身是插件

DeepSeek 把這個問題再往下推一層。公開預覽裏的產品是 DeepSeek Harness(dsh);對外合同是Agent接口,默認實現是可替換的 agent-loop。口號是 Everything is a plugin——模型、工具、Skills、會話、沙箱、存儲、loop、調度和 UI 都可以換。

和 Tool Calling 對齊的是工具管道,不是又一個聊天框。註冊表裏的ToolDefinition帶類型參數和輸出;投影給模型的只有 name、description、parameters。execute、超時、併發標記、UI 展示不能漏進請求。

每一次調用走固定瀑布:

DeepSeek Harness 的工具管道
tools/pre-execute   → allow / deny / ask
monotonic guards    → 只收紧,不能再放行
tools/execute       → 真正派发(可包超时 / 重试)
tools/post-execute  → 检查或替换结果
finalizeContent     → 定义自己的收尾
tools/result        → 冻结后的权威结果

它可以走原生 Function Calling,也可以走 PTC(用保留的run_code當傳輸,子調用仍進同一條管道)。併發按調用分類:獨佔的當屏障,可並行的進有界池;事件仍按模型順序寫入會話。

適合:要把運行時本身當平臺,而不是隻買一個更強的助手。模型層怎麼走,見DeepSeek V4 Pro 指南

對照:同一條 JSON,四套門

同一條 tool call JSON,四家把門鎖在不同的位置:

這一跳 Claude Code Codex OpenCode DeepSeek Agent
呈現給模型的工具面 內置工具 + Skills + MCP;schema 可延遲加載 會話工具箱 + 項目說明(AGENTS.md) 內置 + MCP + 按 agent 裁剪 作用域註冊表按 allowlist 投影 ToolSchema
參數進執行層之前 鉤子可讀完整 tool 事件 JSON 先過沙箱能力,再過審批策略 permission 規則匹配工具名和輸入 parse 後進 pre-execute 瀑布和單調守衛
人怎麼否決 PermissionRequest;deny 優先於鉤子 allow on-request / untrusted;可交給 reviewer ask;子 Agent 可更嚴 ask 決策是管道里的一等結果
副作用發生在哪 本機工具 + 鉤子後置處理 OS 級沙箱,默認無網、工作區可寫 本機執行,git 快照可 undo 可替換 sandbox 插件
結果怎麼回寫 PostToolUse / 失敗鉤子補上下文 JSONL 事件,便於 CI 審計 LSP 診斷可喂回循環 tools/result 凍結後寫入會話日誌

最後一行不是排名。你買的是「更好用的主 Agent」,「更可控的執行環境」,「可換模型的配置層」,還是「可組裝的運行時」。

控制權地圖的產品視角,仍可對照四家架構中心對照。MCP 把工具面撐大之後誰負責安全,見AI Agent 開始「自己攻擊互聯網」:JSON 如何成爲安全邊界

爲什麼還要自己看 JSON Schema

四家 harness 再強,髒參數進執行層都會變成事故。模型填參是軟約束:arguments 可能是壞 JSON,可能缺字段,可能多寫未聲明鍵。

Schema 合法也不等於被授權。下面兩段都能通過「有 sql 字段」的松 schema;只有右邊把操作收成枚舉,並把標識寫成 pattern:

松契約 vs 緊契約
{
  "loose": {
    "type": "object",
    "properties": { "sql": { "type": "string" } },
    "required": ["sql"]
  },
  "tight": {
    "type": "object",
    "additionalProperties": false,
    "properties": {
      "op": { "type": "string", "enum": ["get_user_by_id"] },
      "user_id": { "type": "string", "pattern": "^[a-z0-9-]{8,36}$" }
    },
    "required": ["op", "user_id"]
  }
}

契約怎麼寫、JSON Mode 和 Strict Schema 差在哪,見AI Agent 爲什麼需要 JSON Schema?從 Tool Calling 到 Structured Output,以及AI Agent 與 JSON Schema 完整解析

用 JSONNote 拆開一次 tool call

調試 harness,最有用的材料往往是一截 JSON:工具定義、模型 arguments、鉤子事件、拒絕原因。這些都可以在瀏覽器本地拆開,不必上傳倉庫。

  1. 1
    先看 arguments 是不是合法 JSON

    把字符串裏的轉義拆開,丟進JSON 格式化。缺逗號、多尾逗號、單引號,這一步就會爆。

  2. 2
    用聲明的 schema 校驗

    把工具的 parameters / inputSchema 和解析後的對象放進JSON Schema。看是缺字段、類型錯,還是多寫了不該存在的鍵。

  3. 3
    對比「批准時」和「現在」

    把上週保存的工具清單和今天的清單丟進JSON Diff,專門找 description 和 schema 的靜默改動。

  4. 4
    需要給同事看時用 Hash 分享

    數據留在 URL fragment,不經過服務器。見用 URL Hash 分享 JSON

常見問題

Claude Code、Codex、OpenCode、DeepSeek Agent 到底在競爭什麼?

不是功能清單,也不是誰補全下一行更準。競爭的是 Agent Harness:誰擁有一次 JSON Tool Calling 從參數解析、契約校驗、批准、沙箱執行到結果回寫的控制權。

Agent Harness 和模型哪個更重要?

模型負責推理和下一步;harness 負責工具可見範圍、參數是否合法、高風險動作要不要問人、副作用發生在哪。換 harness 並不保證平均分更高,但完成路徑、成本和取消率會變。選產品是在選控制權,不是隻選分數。

四家裏該選哪一家?

沒有統一冠軍。要在主 Agent 上釘確定性鉤子和權限,選 Claude Code;要把沙箱和審批當默認執行邊界,選 Codex;要換模型和防鎖定,選 OpenCode;要把 loop、工具管道和沙箱都做成可替換插件,選 DeepSeek Agent(DeepSeek Harness)。

JSON Tool Calling 本身有沒有權限控制?

沒有。模型選出工具名、填好 arguments,這一跳只表示打算調用。攔不攔、在哪種沙箱裏跑、結果回不回給模型,都是 harness 的事。沒有工具、權限被拒或 JSON 校驗失敗,磁盤上什麼都不會發生。

爲什麼還要自己校驗 JSON Schema?

模型填參是軟約束。arguments 經常是字符串,可能缺字段、類型錯、或多寫未聲明鍵。Schema 合法也不等於被授權。生產路徑仍要 parse 加校驗,再交給權限和沙箱。四家 harness 再強,髒參數進執行層都會變成事故。

小結

2026 年的 Coding Agent 大戰,看起來像模型戰爭。落到倉庫裏,它是 harness 戰爭。

模型發出 JSON。Harness 決定這段 JSON 能不能變成副作用。四家競爭的是同一條管道上的控制權:Claude Code 釘鉤子,Codex 收執行邊界,OpenCode 解開模型鎖定,DeepSeek Agent 把運行時本身做成插件。

功能會繼續趨同。你真正要看的,是一次 tool call 離開模型之後,誰說了算。

下一步:把一次 tool call 的 arguments 粘進 JSONNote

← 返回博客