博客 AI / Agent

AI Coding Agent 如何工作?Claude Code、Codex、Xcode 27 Agent、Tool Calling 与 JSON 数据详解

打开 Claude Code、Codex 或 Xcode 27,界面都像在聊天。真正让它们改仓库、跑测试、点模拟器的,不是那段自然语言回复。

AI Coding Agent 的工作方式是:模型推理下一步,发出 Tool Calling;本地或 IDE 里的 harness 执行工具,把结果写成结构化数据再喂回去。参数和结果几乎都是 JSON。

本文将介绍:

先记住这一点:界面像聊天,真正干活的是 Tool Calling。模型选工具、填 JSON 参数;能不能改文件、跑测试、连模拟器,取决于 harness 给了哪些工具、权限和校验。下面按循环 → 工具调用 → 三家产品 → JSON 契约拆开。

不是聊天框,是循环

补全解决「下一行写什么」。Coding Agent 解决「这个目标怎么在真实工程里做完」:读上下文、选工具、改代码、跑命令、看结果、再决策。

官方文档里的说法会换词,形状是同一套。Claude Code 把它写成收集上下文 → 采取行动 → 验证结果;Xcode 27 则是先计划、再改文件、再用构建 / 测试 / Preview / 模拟器自我校验。底层都是:

  1. 1
    观察

    读文件、搜符号、看 git 状态、拉测试失败日志。没有这一步,后面的补丁是猜的。

  2. 2
    决策

    模型在上下文里选下一步:再读、再搜、改一处、跑一条命令,或问你一句。

  3. 3
    执行

    harness 接到 tool call,按权限和沙箱真正去跑。模型此时不碰磁盘。

  4. 4
    回写

    工具结果变成文本或 JSON,塞回上下文。模型根据新证据继续,或宣布做完。

你也在这个循环里:打断、改方向、批准高风险动作。模型负责推理;harness 负责工具、权限、会话和「怎样算做完」。四家产品怎么抢控制权,见

AI Coding Agent 已经不只是补全代码:四家正在竞争什么?

本文只拆「循环怎么转、JSON 在哪一跳出现」。技术栈分层可对照

2026 AI Agent 技术栈:LLM、MCP、Function Calling、JSON Schema

Tool Calling:参数就是 JSON

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",
      "properties": {
        "suite": { "type": "string", "enum": ["unit", "integration", "e2e"] },
        "path": { "type": "string", "minLength": 1 }
      },
      "required": ["suite"],
      "additionalProperties": false
    }
  }
}

模型返回时,arguments 经常是字符串,不是已经 parse 好的对象:

模型返回的 tool_call(arguments 是字符串)
{
  "id": "call_8f21",
  "type": "function",
  "function": {
    "name": "run_tests",
    "arguments": "{\"suite\":\"unit\",\"path\":\"src/auth\"}"
  }
}

所以业务层至少做两件事:先把字符串解析成合法 JSON,再按你声明的 schema 校验字段、类型和枚举。缺引号、多逗号、多写未声明键,都发生在这一跳,不发生在「模型看起来很聪明」那一层。

完整一圈是:请求带上 schema → 模型选工具并生成 arguments → 你解析并校验 → 执行工具 → 把结果当 tool message 喂回去 → 模型继续。schema 写得好,第一次参数就对;写得含糊,循环会空转。

契约怎么写、JSON Mode 和 Strict Schema 差在哪,见

AI Agent 为什么需要 JSON Schema?从 Tool Calling 到 Structured Output

Claude Code:内置工具 + 扩展层

Claude Code 的官方说明把 Agent 拆成两块:负责推理的模型,和负责行动的工具。没有工具,Claude 只能回文字;有了工具,它才能读仓库、改文件、跑命令、搜网页。

内置工具大致五类:文件操作(Read / Edit / Write)、搜索(Grep / Glob)、执行(Bash)、Web(WebSearch / WebFetch),以及需要插件的代码智能(跳转到定义、看类型错误)。子 Agent、向你提问,也是工具,只是编排用的。

一次「把失败测试修掉」在循环里可能是:

  1. 1
    Bash 跑测试

    先看哪条断言炸了,而不是先改代码。

  2. 2
    Grep / Read 定位源文件

    用错误栈和符号把上下文读进窗口。

  3. 3
    Edit 做精确替换

    官方要求先读再改:old_string → new_string,避免盲写。

  4. 4
    再跑测试验证

    结果回到上下文。失败就再循环,而不是口头说「应该好了」。

扩展层叠在这个循环上面,不替换它:

Claude Code 的工程妥协很清楚:概率性 Agent + 确定性钩子。会话本身也会落成 JSONL,方便恢复和分叉——你调试的往往不是「一段聊天」,而是一串 tool 事件。

Codex:沙箱、审批与 JSONL

Codex 同样走 Agent loop,但它把「模型生成的命令如何落地」当成产品中心。终端里跑

Codex CLI时,你先选沙箱和审批,再让模型行动。

开关 常见取值 它限制什么
sandbox read-only / workspace-write / danger-full-access 命令能写哪里、能不能出网
approval-policy untrusted / on-request / never 升级权限或高风险动作要不要人点头

自动化场景用codex exec --json。标准输出变成 JSONL:thread / turn 起止、命令执行、文件变更、MCP 调用、计划更新。CI 脚本消费的是事件流,不是一段散文。

codex exec --json 事件(示意)
{"type":"item.completed","item":{"id":"item_12","type":"command_execution","command":"npm test -- src/auth","exit_code":1,"aggregated_output":"FAIL src/auth/session.test.ts"}}
{"type":"item.completed","item":{"id":"item_13","type":"file_change","path":"src/auth/session.ts","kind":"update"}}
{"type":"turn.completed","usage":{"input_tokens":18420,"output_tokens":966}}

需要稳定字段给下游时,用--output-schema让最终答复符合 JSON Schema。这和 Tool Calling 的 parameters 是同一类契约,只是约束的是「任务结束时的那份 JSON」,不是每一步命令。

默认codex exec是只读沙箱。要改文件,显式加--sandbox workspace-write。需要更多目录时优先--add-dir,而不是一上来danger-full-access

Xcode 27 Agent:计划、校验、编辑器工具

Apple 在 WWDC 2026 把 Xcode 27 定位成「在 Apple 平台上和 Agent 一起写代码的地方」。和终端 Agent 不同,它的工具箱长在 IDE 里。

Apple 新闻稿

Xcode, agents, and you

What’s new in Xcode 27说清楚了几件事:

WWDC 实验室把 Chat 和 Agent 说成能力差,不是文案差:Chat 只有一小套固定工具;Agent 模式加上命令行和 Xcode 内部工具(构建、测试、Preview、模拟器)。默认安全模式是权限提示——Agent 能拿到任务需要的东西,但不能在磁盘上随便逛。

对 JSON 开发者,Xcode 这一跳的要点是:校验结果也是结构化回写。构建失败、测试摘要、Preview 产物,都会变成 Agent 下一步的输入。你在后端看到的,往往仍是自己 API 的 JSON;在 IDE 里,同一循环消费的是 Xcode 工具的输出。

系统级 Siri AI 走的是 App Intents,不是这套编辑器 Agent。别把两条线混成「Apple 只有一种 Agent」,见

Siri AI 会成为 AI Agent 吗?

三家对照:同一循环,不同工具箱

功能清单会越来越像。差别在默认工具、执行边界、以及结果怎么变成下一轮上下文。

Claude Code Codex Xcode 27 Agent
循环 观察 → 行动 → 验证 同一 loop + 事件流 计划 → 改代码 → IDE 校验
默认工具 Read / Edit / Bash / Grep shell + MCP + plan 构建 / 测试 / Preview / 模拟器
扩展 Skills、MCP、Hooks MCP、Agents SDK、output-schema MCP 插件、ACP 外部 Agent
边界 权限模式 + Hooks sandbox + approval-policy 工程权限提示 + 工作目录
机器可读出口 会话 JSONL、tool 结果 exec --json、--output-schema diff、产物、构建/测试输出

选型可以很短:通用多语言仓库和可复用 Skills,走 Claude Code;要在真实机器上跑、又要把权限写进 CI,走 Codex;目标是 Apple 平台、校验必须经过 Xcode 工具链,走 Xcode 27。Xcode 的 ACP 让后一种不必排斥前两种——外部 Agent 可以进编辑器,但构建和 Preview 仍是 Xcode 的工具。

JSON 数据在哪一层、谁校验

三家产品 UI 不同,JSON 出现的位置很稳:

位置 典型字段 谁硬校验
工具声明 parameters / inputSchema 你的 schema + SDK
模型出参 tool_calls.arguments 先 parse,再 schema
工具回写 structuredContent / 日志 JSON outputSchema 或你自己的校验
最终答复 response_format / output-schema Strict Schema + 业务层

关键一句:API 层 schema 引导模型生成;业务层 schema 拒绝脏数据。两层不能互相替代。为什么 AI 输出必须先有 schema,见

AI 为什么需要 JSON Schema?

一份给 Coding Agent 用的工具 schema,描述要写清「何时调用、何时不要调用」,枚举写进 enum,而不是埋在 description 里:

Coding Agent 工具 schema(可粘贴校验)
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["action", "path"],
  "properties": {
    "action": { "type": "string", "enum": ["read", "edit", "test"] },
    "path": { "type": "string", "minLength": 1 },
    "suite": { "type": "string", "enum": ["unit", "integration"] },
    "old_string": { "type": "string" },
    "new_string": { "type": "string" }
  },
  "additionalProperties": false,
  "allOf": [
    {
      "if": { "properties": { "action": { "const": "edit" } } },
      "then": { "required": ["old_string", "new_string"] }
    },
    {
      "if": { "properties": { "action": { "const": "test" } } },
      "then": { "required": ["suite"] }
    }
  ]
}

模型若返回{"action":"edit","path":"src/a.ts"}却没有 old_string,schema 会在执行层拦住。这比事后看 diff 便宜。

用 JSONNote 调试 tool 参数

Agent 开发最慢的往往不是写提示词,而是对一次失败的 tool call。JSONNote 在浏览器本地跑,密钥和仓库内容不用上传。

  1. 1
    先看 arguments 能不能 parse

    把模型返回的字符串丢进JSON 格式化。缺引号、尾逗号、被聊天软件截断的 hash,这一步就现形。

  2. 2
    再按 schema 校验

    工具定义和实际 arguments 一起放进JSON Schema。enum 写错、少 required、多 extra 字段,比读模型「抱歉」有用。

  3. 3
    对比两次调用

    改完 description 或加了 additionalProperties: false 之后,用JSON Diff看参数回归。

  4. 4
    分享调试现场

    URL Hash 分享把一份 tool JSON 嵌进链接。同事打开即可复现,数据不经过服务器。

常见问题

AI Coding Agent 和代码补全有什么本质区别?

补全只建议下一行。Coding Agent 能读仓库、改文件、跑命令、调外部工具,并在循环里根据工具结果继续决策。差别不在文笔,而在它能不能行动。

模型会直接改我的磁盘文件吗?

不会。模型只生成 tool call,通常是一段 JSON。真正写文件、跑 shell、点模拟器的是本地 harness。没有工具、权限被拒或参数校验失败,磁盘上什么都不会发生。

Claude Code、Codex 和 Xcode 27 Agent 谁更好?

没有统一冠军。要通用仓库与 Skills / MCP 选 Claude Code;要沙箱、审批和 CI 里的 JSONL 事件选 Codex;要做 Apple 平台、需要构建 / Preview / 模拟器校验选 Xcode 27 Agent。Xcode 还可用 ACP 接入外部 Agent。

为什么还要自己校验 JSON?模型不是已经按 schema 填了吗?

模型填参是软约束。arguments 经常是字符串,可能缺字段、类型错、或多写未声明键。生产路径仍要 parse + JSON Schema 校验,再交给业务层。Codex 的 --output-schema 也只约束最终答复,不替代你对每一步 tool 结果的检查。

Xcode 27 的 Agent 是不是只能用 Apple 自己的模型?

不是。Xcode 27 把 Anthropic、Google、OpenAI 的模型与 Agent 接到同一套编辑器工作流,也支持本地模型,并可用 ACP 接入外部 Agent、用 MCP 接入外部工具。变的是工具箱和校验手段,不是循环本身。

小结

三家产品的界面会继续长得像聊天。底下那句话没有变:

Coding Agent = 模型决策 × Tool Calling × harness 执行。JSON 是工具参数和回写结果的共同形状。

先把循环看清楚,再选工具箱:Claude Code 强化通用 Agent,Codex 管沙箱与事件,Xcode 27 把构建和 Preview 变成校验工具。schema 写在声明里,校验写在执行层,调试可以留在浏览器本地。

下一步:把一次失败的 tool call 粘进 JSONNote

← 返回博客