博客 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

← 返回博客