2023 年的 ChatGPT 插件让人第一次看到「模型会调 API」;2024 年 Function Calling 成为各厂商标配;2025 年 Anthropic 发布 MCP,Cursor、Claude Desktop 等 IDE 纷纷接入——同一条演进线上,JSON 从数据交换格式变成了 Agent 的「类型系统」与「握手协议」。
如果你正在搭建 RAG、自动化工作流或 Copilot 类产品,迟早会遇到三个名词:JSON Schema(约束结构)、Function Calling(模型选工具、填参数)、MCP(Model Context Protocol,标准化工具连接)。本文面向后端、平台与 AI 应用开发者,按时间线解释它们为何出现、各自解决什么问题、如何组合使用,并给出可落地的选型建议。
为什么 Agent 需要结构化接口
早期 LLM 应用的核心模式是:用户提问 → 模型生成自然语言 → 人工复制结果去执行。这在聊天场景够用,但无法可靠地驱动数据库写入、发邮件、查库存等可重复、可审计的自动化任务。
纯 Prompt 工程下的 ReAct(Reason + Act)模式让模型在文本里写「Action: search(query=...)」,宿主程序用正则解析——能跑,但脆弱:括号嵌套、引号转义、多语言混写都会导致解析失败。生产环境需要的是机器可读、可校验、可版本化的契约,而不是靠运气解析 Markdown。
JSON 恰好满足三点:LLM 训练数据中大量存在、人类与程序都能读、有成熟的 Schema 校验生态。于是 JSON Schema 成为描述「模型该输出什么形状的数据」的事实标准;Function Calling 则把「调用哪个函数、传什么参数」也纳入同一套 JSON 结构。
技术演进时间线
| 阶段 | 代表能力 | 核心痛点 | 解决方式 |
|---|---|---|---|
| 2022–2023 初 | 纯文本 + Prompt 模板 | 输出不可解析、幻觉参数 | Few-shot 示例约束格式 |
| 2023 中 | ReAct / Toolformer 思路 | 正则解析 Action 不稳定 | 约定 JSON 块,仍靠 Prompt |
| 2023 末–2024 | OpenAI Function Calling | 各厂商格式不统一 | API 级 tools 参数,JSON Schema 描述 |
| 2024 | Structured Outputs | 模型仍可能漏字段 | 服务端约束解码,强制符合 Schema |
| 2024 末–2025 | MCP(Anthropic 等推动) | N×M 集成:每个 IDE × 每个工具 | 统一 Host ↔ Server 协议,工具可插拔 |
| 2025–2026 | Agent SDK + MCP 生态 | 权限、审计、多租户 | OAuth、stdio/SSE 传输、工具发现 |
这条线的本质变化是:把「模型想干什么」从自然语言翻译成带类型的结构化消息,再由宿主程序或 MCP Server 安全执行。
JSON Schema:Agent 的「类型系统」
JSON Schema 最初用于 API 文档与配置校验(OpenAPI、Kubernetes CRD 等)。在 Agent 场景里,它承担两类职责:
- 工具入参:描述
search_products需要query(string)和limit(integer,默认 10) - 模型输出:例如抽取实体、分类标签、审批结论等,必须返回固定字段供下游消费
典型工具参数 Schema
{
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名,如北京、上海"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "温度单位"
}
},
"required": ["city"]
}description 字段尤其重要:它进入模型的上下文,帮助模型理解何时调用、各参数语义是什么——Schema 同时服务于校验器与Prompt。
Structured Outputs 与 Schema
仅把 Schema 写进 Prompt,模型仍可能多写字段或类型错误。OpenAI、Google 等提供的 Structured Outputs / JSON mode 会在解码阶段约束 token,使输出严格符合 Schema。这对「发票 OCR → 结构化 JSON → 入账系统」类流水线是刚需。
开发阶段建议:先用 JSON 工具箱等工具本地校验 Schema 语法,再用样例 payload 验证 required、enum 是否按预期拦截非法输入。
Function Calling:模型与工具的握手
Function Calling(各厂商也称 Tool Use、Tools API)定义了模型与宿主之间的一轮握手:
- 宿主把工具列表(name、description、parameters Schema)随 messages 发给模型
- 模型不直接执行代码,而是返回
tool_calls:选中的工具名 + JSON 参数字符串 - 宿主执行真实函数(查 DB、调 HTTP),把结果以
tool角色消息塞回对话 - 模型基于结果生成最终用户可见的回答
与 ReAct 文本模式的对比
| 维度 | ReAct 文本 | Function Calling |
|---|---|---|
| 参数格式 | 自由文本,需解析 | JSON,API 原生字段 |
| 多工具并行 | 难 | 支持单次多个 tool_calls |
| 模型微调对齐 | 弱 | 厂商针对 tool 格式训练 |
| 可观测性 | 需自建日志 | 标准 message 结构,易追踪 |
Function Calling 并没有消灭 Agent 框架(LangChain、AutoGen、Cursor Agent 等),而是成为框架与模型之间的薄协议层——框架负责编排、重试、记忆;模型 API 负责「决策调用哪个工具」。
MCP:可插拔的工具生态
Function Calling 解决的是「模型这一侧怎么声明调用」。但当工具数量增长、来源分散(GitHub、Slack、 Postgres、浏览器、文件系统)时,新问题出现:
- 每个 Host(IDE、Chat 客户端、自建 Agent)都要为每种工具写一遍适配
- 权限、凭证、stdio/HTTP 传输方式各自为政
- 用户无法「装一个 MCP Server,处处可用」
Model Context Protocol(MCP) 由 Anthropic 2024 年末开源,定位是 Host 与 Tool Provider 之间的标准协议。类比关系大致是:
| 类比 | Web 时代 | Agent 时代 |
|---|---|---|
| 能力描述 | OpenAPI / JSON Schema | MCP Tool 定义(含 inputSchema) |
| 运行时连接 | HTTP REST | stdio / SSE 等 MCP 传输 |
| 客户端 | 浏览器、SDK | MCP Host(Cursor、Claude Desktop…) |
| 插件市场 | npm、Chrome 扩展 | MCP Server registry |
MCP 核心概念
- Host:发起连接的应用(如 Cursor IDE)
- Client:Host 内的 MCP 客户端,维护与 Server 的会话
- Server:暴露 tools、resources、prompts 的进程(如 filesystem-mcp、github-mcp)
- Capabilities:工具列表动态发现,而非写死在 Prompt 里
MCP Tool 的 inputSchema 本身就是 JSON Schema。因此 MCP 不是替代 Function Calling,而是把「工具实现」标准化;Host 仍可能把 MCP 工具映射为模型 API 的 Function Calling 格式。
三者如何协同
用一张逻辑分层理解三者关系:
┌─────────────────────────────────────────────┐
│ 用户 / 业务系统 │
└─────────────────────┬───────────────────────┘
▼
┌─────────────────────────────────────────────┐
│ Agent Host(编排、权限、记忆) │
│ ┌─────────────┐ ┌─────────────────────┐ │
│ │ LLM API │◄──►│ Function Calling │ │
│ │ (推理) │ │ (tool_calls 消息) │ │
│ └─────────────┘ └─────────────────────┘ │
│ ▲ │ │
│ │ JSON Schema ▼ │
│ ┌────────┴────────┐ ┌──────────────────┐ │
│ │ 输出 Schema │ │ MCP Client │ │
│ │ (Structured │ │ ──stdio/SSE──► │ │
│ │ Outputs) │ │ MCP Server(s) │ │
│ └─────────────────┘ └──────────────────┘ │
└─────────────────────────────────────────────┘- JSON Schema:横切各层——工具参数、MCP inputSchema、模型结构化输出
- Function Calling:模型 ↔ Host 的调用语法
- MCP:Host ↔ 外部世界的工具总线
小型脚本可能只有 Function Calling + 几个本地函数;企业级 Agent 平台则常见 MCP 集群 + 统一 Schema registry + 审计日志。
完整调用链路示例
用户问:「上海今天多少度,顺便查我 GitHub 上 json-schema 相关仓库。」
- Host 向 MCP 拉取可用工具:
get_weather、github_search_repos - 转换为模型 API 的 tools 数组,每项带 JSON Schema parameters
- 模型 返回两个 tool_calls,参数均为合法 JSON
- Host 经 MCP 调用 weather Server 与 github Server,收集 JSON 结果
- 结果作为 tool messages 回传;模型合成自然语言答复
- 若需写入工单系统,再用输出 Schema 约束最终 JSON:
{ "summary", "temperature", "repo_count" }
任一步参数不符合 Schema,宿主可在执行前拒绝并请求模型重试——这是文本 ReAct 难以做到的fail-fast。
选型对比与最佳实践
| 场景 | 建议 |
|---|---|
| 单一后端 + 3 个以内工具 | Function Calling + 手写 Schema 即可 |
| IDE / 桌面 Copilot,工具持续增加 | 优先 MCP Server,减少 Host 定制集成 |
| 下游系统只要 JSON、不要自然语言 | Structured Outputs + 严格 Schema |
| 多模型厂商(OpenAI + Claude + 开源) | Schema 与工具定义与厂商 API 解耦,中间层转换 |
| 合规与审计 | 记录每次 tool_calls 与 Schema 版本,禁止未定义工具 |
Schema 设计要点
- 字段
description写清业务语义,比typealone 更能减少误调用 required宁严勿松;可选字段用default或明确 nullable- 大枚举改用 string + description,避免
enum列表过长占上下文 - Schema 纳入 Git 版本管理,与 API 变更一样做 Code Review
常见问题 FAQ
JSON Schema 和 Function Calling 是什么关系?
Function Calling 定义模型如何声明并调用工具;JSON Schema 描述工具参数与模型输出的结构约束。多数 API 直接用 JSON Schema 子集作为 tools 的 parameters 定义。
有了 Function Calling 还需要 MCP 吗?
Function Calling 解决单次模型与宿主程序的调用协议;MCP 解决工具如何被发现、授权、跨进程连接与复用。复杂 Agent 通常两者叠加:MCP 提供工具生态,Function Calling 是模型侧的调用语法。
MCP 会取代 OpenAPI 吗?
不会完全取代。OpenAPI 描述 HTTP API 契约;MCP 面向 Agent 运行时与 IDE 的工具连接。REST 服务仍可用 OpenAPI,Agent 侧可通过 MCP Server 包装后接入。
为什么 Agent 输出也要 JSON Schema 约束?
结构化输出便于程序解析、校验与下游流水线消费,减少模型「自由发挥」导致的字段缺失或类型错误,提高自动化任务的可靠性。
开发 Agent 时应该先学哪一层?
建议顺序:JSON Schema 基础 → 单工具 Function Calling → 多步 Agent 编排 → 按需引入 MCP 连接外部系统。每层解决不同粒度的问题。
如何本地验证 Agent 用的 JSON Schema?
可用 JSON 工具箱的校验功能在浏览器本地验证 Schema 语法与样例数据是否匹配,数据不上传服务器。
总结与下一步
AI Agent 从「会聊天」到「能办事」,靠的是一层层把不确定性关进结构化边界:JSON Schema 定义形状,Function Calling 定义模型如何伸手,MCP 定义工具如何接入生态。三者不是互相替代,而是同一条栈上的不同层。
下一步建议:拿一个真实业务工具(查订单、发通知),为其写 JSON Schema → 接入 Function Calling 跑通单轮 → 再评估是否值得封装为 MCP Server 供多个 Host 复用。Schema 与样例数据可在 JSON 工具箱本地校验后再上线。