Dev KnowledgeV2.0
输入关键词开始搜索

    JSON Schema、Function Calling 与工具选择

    区分回答格式、工具参数和工具选择策略,理解结构化输出的兼容性与校验边界。

    类型
    原理解释
    适合读者
    接入模型 API 并希望理解结构化输出和工具调用差异的开发者
    最近核验

    JSON Schema 是描述数据结构的规范。模型接口可以用它描述回答正文,也可以用它描述工具参数。SDK 中的 jsonSchema 与 functionCalling 通常代表两种输出策略,不能理解成“前者有 Schema,后者没有”。

    本文使用 Chat Completions 风格字段;不同 Provider、接口和 SDK 的命名及默认值可能不同。LangChain 的接口将原生 Schema 输出、Function Calling 和 JSON Mode 分为不同方法。LangChain withStructuredOutput

    分清三个控制点

    字段 控制什么
    tools 有哪些工具、每个工具做什么、接受什么参数
    tool_choice 是否允许、要求或指定模型选择工具
    response_format 最终回答采用什么数据格式

    工具定义包括名称、描述及参数 Schema。模型根据用户问题和这些定义生成调用意图;应用收到调用后,才查找对应函数并执行。模型收到的是工具说明,不是自动获得本地函数的执行能力。工具参数与选择策略

    jsonSchema 约束回答正文

    以输出一个评价结果为例,下面定义字段结构:

    const resultSchema = {
      type: 'object',
      properties: {
        score: { type: 'number' },
        reason: { type: 'string' },
      },
      required: ['score', 'reason'],
      additionalProperties: false,
    };

    原生 Schema 输出把它放在回答格式中。下面是参数片段,省略模型、消息和客户端初始化;strict 的可用性须按服务端文档确认:

    response_format: {
      type: 'json_schema',
      json_schema: {
        name: 'result',
        schema: resultSchema,
        strict: true,
      },
    }

    结果通常位于回答正文 message.content,正文是一段 JSON 文本,例如 {"score":0.8,"reason":"基本满足要求"}。SDK 可以进一步解析成对象。此流程不需要虚构一个工具来承载结果。

    json_object(JSON Mode)与 json_schema 也不同:前者要求合法 JSON,但不等于约束到指定字段结构;后者提交了具体 Schema,严格遵守程度还与服务端支持及严格模式有关。结构化输出模式对比

    functionCalling 约束工具参数

    同一个 Schema 可以用于定义工具:

    tools: [{
      type: 'function',
      function: {
        name: 'submit_result',
        description: '提交评价结果',
        parameters: resultSchema,
      },
    }],
    tool_choice: {
      type: 'function',
      function: { name: 'submit_result' },
    }

    支持该选择方式的服务会要求模型输出指定工具调用。数据位于 tool_calls[].function.arguments,原始协议通常将 arguments 编码成 JSON 字符串。这里同样有 Schema,只是 Schema 作用于工具入参。

    Function Calling 有两种常见用途:

    • 实际工具执行:模型请求 get_weather({city: '上海'}),应用执行查询,再将结果作为工具消息交回模型,模型继续回答。
    • 结构化结果提取:把最终数据定义成 submit_result 的参数,程序直接解析参数作为结果,不必真的执行一个提交函数,也不必多请求一次模型。

    后一种用途解释了为什么某些结构化输出 SDK 会自动绑定一个工具并设置强制工具选择。工具结果回传是实际执行工具时的流程,不是所有结构化结果提取都必须进行的额外回合。Function Calling 执行流程

    没有 tool_choice,为什么仍能选择工具

    前提是请求已经提供 tools,并且该接口默认采用自动选择。省略可选字段时使用服务端默认策略,不等于禁用工具。

    策略 含义(具体支持范围按接口确认)
    省略或 auto 在默认值为 auto 的接口中,由模型决定直接回答或发出工具调用
    none 不选择工具
    required 要求至少调用一个工具,不指定具体工具
    指定工具对象 要求使用给定工具

    例如提供天气查询工具后,“上海现在下雨吗”可能产生天气查询调用;“你好”可能直接得到文字回复。判断依据来自工具描述、参数定义、用户输入和对话上下文,tool_choice 只改变选择规则。自动选择不保证选对工具,也不保证一定调用。

    例如千问兼容接口明确以 auto 为默认;其部分 thinking 模式限制强制选择。因此,自主调用成功不能证明 required 或指定工具也可用。默认值与模式限制

    为什么不能未经验证就统一使用 jsonSchema

    对于只需要最终数据对象的任务,若所有目标推理点都支持原生 Schema,统一这一路径可以简化实现。但“支持文本对话”“支持工具调用”“支持原生 Schema”“支持严格工具参数”是不同能力。

    还要检查实际 Schema 是否落在服务端支持的子集内:对象根类型、必填字段、额外字段、联合类型、引用和数值限制等都可能影响兼容性。服务商的模型名单和 Schema 限制应分别确认;同名模型通过不同网关访问,也不能直接推断能力一致。支持范围与关键字限制

    原生回答格式也不会代替真实外部查询或操作。Agent 需要工具时,仍需工具定义、调用分发和结果回传;如果接口支持,两种能力可以组合为“先使用工具,再生成结构化最终答案”。

    适配表记录现有策略,不是模型能力的完整证明。验证一个模型后可以收敛其策略,但不应因一个推理点报错而把所有模型改成提示词 JSON。协议兼容的更大边界见模型接入边界。

    原生约束与本地校验负责不同问题

    服务端严格模式在其支持范围内约束输出结构;本地解析器检查最终收到的数据,两者可以同时存在。只看 method: 'jsonSchema',不能推断 SDK 已显式发送 strict: true;须核对实际请求和服务端默认值。

    Zod 的 .strict() 用于本地对象未知字段校验,与请求中的 json_schema.strict 不是同一个开关。SDK 可以从 Zod 生成 Schema,但本地声明不能代替确认服务端的严格模式配置。

    结构符合 Schema 也不等于内容正确:合法的数字可以是错误评分,合法字符串可以包含错误事实。字段结构由解析和 Schema 校验负责,事实准确性、标识是否与本次输入对应、跨字段关系等仍需应用检查。处理响应时也要区分正常完成与截断、拒绝或请求失败。

    抽取遗漏不等于原文缺失

    模型省略字段、返回 null 或空字符串,只能证明这次抽取未给出有效值,不能证明原文没有该信息。若校验器只接收模型输出,就没有足够证据把缺字段直接解释为“原文没有”;反过来,模型填出一个合法字符串,也不能证明它来自原文。

    处理方式应区分格式错误、抽取遗漏、原文确实缺失与证据不足。可保留字段对应的原文片段或结构化来源,核对它是否支持提取值;不能核验时交给人工确认。结构正则也有边界:YYYY-MM-DD 的形状检查会接受 2026-99-99,实际日历有效性需另外校验。

    2026-10-19 的离线探针分别注入“原文有负责人但输出漏字段”和“输出编造负责人、日期为 2026-99-99”两种结果,复现仅检查输出形状的校验器将前者判为原文缺失、将后者判为可用。此实验说明校验能力边界,不估计真实模型产生这些错误的频率。

    本文示例用于说明协议形状,不宣称已对所有模型或网关执行验证。