博客 AI / JSON Schema

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

你在接 LLM API 做 Agent,文档里同时出现tools[].function.parametersresponse_format.json_schema和 MCP 的inputSchema——它们看起来都是 JSON,但各自约束什么、保证什么?

JSON Schema是描述 JSON 数据结构的标准(当前主流版本2020-12)。在 AI Agent 开发里,它不是「可选的文档格式」,而是模型与外部世界之间的契约语言:Tool Calling 用它描述工具参数,Structured Output 用它约束最终回答,MCP 用它定义工具输入输出。

本文将说明:

先记住这一点:模型「输出 JSON」和「输出符合 schema 的 JSON」是两回事。JSON Schema 定义的是后者——字段名、类型、必填项、枚举值。下面按「为什么需要 → Tool Calling → Structured Output → MCP → 怎么写 → 怎么校验」拆开。

Agent 为什么离不开 JSON Schema

Agent 的核心循环是:模型推理 → 决定调用工具或给出结构化回答 → 执行 → 把结果回填 → 继续推理。这个循环里每一步的 I/O 都应该是机器可解析、可校验、可审计的。

纯自然语言输出有两个致命问题:

JSON Schema 解决的是「格式契约」问题:在模型生成之前,你就声明了「输出必须有哪些字段、什么类型、哪些必填」。这让 Agent 从 demo 变成生产系统的关键基础设施。

2026 年的 Agent 栈已经高度对齐:OpenAI Function CallingAnthropic Tool UseDeepSeek Function CallingMCP Tools——全部用 JSON Schema 描述工具参数。

Schema 出现在 Agent 栈的哪几层

一张表看清 JSON Schema 在 Agent 开发中的位置:

层级 Schema 字段 约束什么 谁负责校验
LLM API — Tool Calling tools[].function.parameters 模型生成的tool_calls[].function.arguments 模型(软约束)+ 你的代码(硬校验)
LLM API — Structured Output response_format.json_schema 模型最终回答的 JSON 结构 模型(Strict 模式硬约束)+ 你的代码
MCP Server inputSchema / outputSchema 工具调用参数 / Server 返回的 structuredContent Client SDK + 你的代码
业务层 自定义 schema 文件 入库前、API 响应前的最终 gate ajv / jsonschema / 你的 validate 函数

关键洞察:API 层的 schema 是「引导模型生成」,业务层的 schema 是「拒绝不合格数据」。两层都需要,不能互相替代。

Tool Calling:parameters 就是 JSON Schema

以 OpenAI 兼容 API 为例,你在请求里声明tools数组,每个工具的function.parameters就是 JSON Schema object:

Function Calling 工具定义(parameters = JSON Schema)
{
  "model": "deepseek-v4-pro",
  "messages": [
    { "role": "user", "content": "查一下北京今天天气" }
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "Get current weather for a city",
        "parameters": {
          "type": "object",
          "properties": {
            "city": {
              "type": "string",
              "description": "City name, e.g. Beijing"
            },
            "unit": {
              "type": "string",
              "enum": ["celsius", "fahrenheit"],
              "default": "celsius"
            }
          },
          "required": ["city"],
          "additionalProperties": false
        }
      }
    }
  ]
}

模型返回的tool_calls里,function.arguments是一个 JSON字符串,不是已解析的对象:

模型返回的 tool_call(arguments 是字符串)
{
  "tool_calls": [
    {
      "id": "call_abc123",
      "type": "function",
      "function": {
        "name": "get_weather",
        "arguments": "{\"city\": \"Beijing\", \"unit\": \"celsius\"}"
      }
    }
  ]
}

这意味着你必须在业务层做两件事:

  1. 1
    JSON.parse + try/except

    arguments可能语法损坏(缺引号、尾随逗号),先保证是合法 JSON。

  2. 2
    JSON Schema validate

    用你声明的parametersschema 校验解析后的对象——字段是否齐全、类型是否正确、enum 是否合法。

完整的工具循环:请求带 schema → 模型选工具并生成 arguments → 你解析并校验 → 执行工具 → 把结果作为 tool message 回填 → 模型继续推理。schema 质量直接影响模型能不能一次生成正确的 arguments。

Structured Output 三条路径对比

除了 Tool Calling,你还可以让模型直接输出结构化 JSON 作为最终回答。三条常见路径:

路径 API 配置 保证什么 适用场景
JSON Mode response_format: { "type": "json_object" } 输出是合法 JSON 对象 自由格式提取、简单分类、字段结构简单
Function Calling tools+ 模型返回 tool_calls arguments 尽量符合 parameters schema Agent 工具调用、与 MCP 组合
Strict Schema response_format.json_schema + strict: true 输出严格 conform 到给定 schema 生产环境、schema 复杂、字段类型严格

Strict Schema 示例(OpenAI / DeepSeek 兼容格式):

Strict Structured Output 请求
{
  "model": "deepseek-v4-pro",
  "messages": [
    { "role": "user", "content": "分析这段用户反馈的情感和关键问题" }
  ],
  "response_format": {
    "type": "json_schema",
    "json_schema": {
      "name": "sentiment_analysis",
      "strict": true,
      "schema": {
        "type": "object",
        "properties": {
          "sentiment": {
            "type": "string",
            "enum": ["positive", "neutral", "negative"]
          },
          "issues": {
            "type": "array",
            "items": { "type": "string" }
          },
          "confidence": {
            "type": "number",
            "minimum": 0,
            "maximum": 1
          }
        },
        "required": ["sentiment", "issues", "confidence"],
        "additionalProperties": false
      }
    }
  }
}

最佳实践是多层防御:API 层选 Strict 或 Function Calling → 业务层用 JSON Schema validate → 调试层用 JSONNote 本地 format / diff / schema check。详见DeepSeek V4-Pro 完整解析中的 JSON 输出章节。

MCP 与 JSON Schema 2020-12

Model Context Protocol (MCP)是 Agent 与外部服务之间的标准协议。2026-07-28 规范把工具的inputSchemaoutputSchema升级到完整 JSON Schema 2020-12,支持oneOfanyOf$ref等组合特性。

MCP 工具定义(inputSchema + outputSchema)
{
  "name": "search_docs",
  "description": "Search documentation by keyword",
  "inputSchema": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "object",
    "properties": {
      "query": { "type": "string", "minLength": 1 },
      "limit": { "type": "integer", "minimum": 1, "maximum": 50, "default": 10 }
    },
    "required": ["query"]
  },
  "outputSchema": {
    "type": "object",
    "properties": {
      "results": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "title": { "type": "string" },
            "url": { "type": "string", "format": "uri" }
          },
          "required": ["title", "url"]
        }
      }
    },
    "required": ["results"]
  }
}

Server 返回的structuredContent必须 conform 到outputSchema(如果定义了)。这和 LLM API 里 parsetool_calls.arguments是同一类工程问题——只是数据来源从模型变成了 MCP Server。更多 MCP 背景见AI Conference 2026 热点梳理

怎么写一份好用的 tool schema

schema 质量直接影响模型 tool calling 的成功率。以下是经过生产验证的写法要点:

  1. 1
    每个 property 都写 description

    模型读 description 决定怎么填值。city写成「City name, e.g. Beijing, Shanghai」比裸字段名准确率高很多。

  2. 2
    用 enum 限制选项,不要靠 description 暗示

    "enum": ["low", "medium", "high"]比 description 里写「可选 low/medium/high」可靠。

  3. 3
    设 additionalProperties: false

    防止模型「创造性」添加未声明字段。Strict Schema 模式通常强制此选项。

  4. 4
    复杂参数用 oneOf / $ref,不要扁平化所有组合

    例如「按 ID 查」和「按名称查」是两种参数结构,用 oneOf 分开比一个大 object 更清晰。

  5. 5
    工具 description 写清楚「什么时候该调、什么时候不该调」

    模型靠 description 做 tool selection。写「Only call when user explicitly asks about weather」能减少误触发。

校验工作流:从 API 到业务层

推荐的 Agent JSON 校验流水线:

Python 校验示例(parse + validate)
import json
from jsonschema import validate, ValidationError

TOOL_SCHEMA = {
    "type": "object",
    "properties": {
        "city": {"type": "string"},
        "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
    },
    "required": ["city"],
    "additionalProperties": False
}

def parse_tool_arguments(raw: str) -> dict:
    try:
        data = json.loads(raw)
    except json.JSONDecodeError as e:
        raise ValueError(f"Invalid JSON in arguments: {e}") from e
    try:
        validate(instance=data, schema=TOOL_SCHEMA)
    except ValidationError as e:
        raise ValueError(f"Schema validation failed: {e.message}") from e
    return data

# 用法
args = parse_tool_arguments(tool_call["function"]["arguments"])
weather = get_weather(args["city"], args.get("unit", "celsius"))

无论数据来自模型arguments还是 MCPstructuredContent,都走同一套 parse → validate → 业务逻辑。开发阶段把 schema 和实际输出贴进 JSONNote 做可视化校验,比 print 调试快得多。

用 JSONNote 调试 schema 与模型输出

Agent 开发里最耗时的往往不是写 prompt,而是 debug 模型返回的 JSON。JSONNote 在浏览器本地运行,适合处理 API 响应和 MCP 消息:

  1. 1
    格式化模型输出

    tool_calls[].function.arguments贴进JSON 格式化,立刻看到语法错误和缩进问题。

  2. 2
    校验 tool schema

    把 tool 定义和模型返回的 arguments 贴进JSON Schema页面做 validate。

  3. 3
    对比两次调用

    JSON Diff对比 prompt 迭代前后的 structured output 差异,做回归检查。

  4. 4
    分享调试现场

    URL Hash 分享把某次 tool call 的 JSON 写进链接,同事打开即可复现——数据不经过服务器。

常见问题

JSON Schema 和 Function Calling 是什么关系?

Function Calling 的tools[].function.parameters就是 JSON Schema。模型根据 schema 生成 arguments JSON 字符串;你的代码负责解析并校验是否符合 schema。两者不是并列概念,而是「调用机制」与「参数契约」的关系。

JSON Mode 和 Strict Schema 有什么区别?

JSON Mode 只保证输出是合法 JSON 对象,不保证字段和类型符合你的 schema。Strict Schema 在推理阶段约束 token 生成,使输出严格 conform 到给定 schema。简单提取用 JSON Mode;生产环境复杂结构用 Strict Schema。

MCP 工具的 inputSchema 用什么版本?

MCP 2026-07-28 规范要求 inputSchema 和 outputSchema 使用 JSON Schema 2020-12,支持 oneOf、anyOf、$ref 等完整特性。outputSchema 描述 Server 返回的 structuredContent 结构。

模型已经返回 JSON 了,还需要手动校验吗?

需要。即使开了 Strict Schema,生产环境仍建议 try/except 解析 + JSON Schema validate。tool_calls.arguments 可能缺字段、类型错误或语法损坏——校验是业务层的责任,不是模型的保证。

JSON Schema 和 OpenAPI 有什么区别?

OpenAPI 是 REST API 的完整描述规范(路径、方法、认证、响应码等),其 request/response body 部分用 JSON Schema 描述。Agent Tool Calling 只需要「单个函数的参数 schema」,直接用 JSON Schema 即可,不必套整个 OpenAPI 文档。

总结

AI Agent 开发的核心信号可以概括为:

Agent I/O JSON 化、工具契约 Schema 化、校验多层化。

JSON Schema 贯穿 Tool Calling 的 parameters、Structured Output 的 response_format、MCP 的 inputSchema/outputSchema——它是模型与外部世界之间的通用契约语言。写好 schema、加上业务层 validate、用 JSONNote 本地调试,是从 demo 到生产的必经之路。

← 返回博客