智能工具库

LLM 输出结构化数据的可靠方法

LLM 输出结构化数据的可靠方法

本文分享从 LLM 获取可靠结构化数据的实战经验,涵盖输出约束、Schema 优先设计、验证与重试机制等核心技巧,帮助开发者避免常见解析陷阱。

2026-08-28 0来源:freeCodeCamp

从“能跑”到“可靠”:LLM 结构化输出的进阶指南

很多 LLM 教程在 JSON.parse(response.content) 这一步就戛然而止。这个看似简单的操作,在最初十几个测试用例里确实没问题,但一旦上线,问题就会接踵而至:模型可能编造一个不存在的日期、返回超出 schema 限制的数组项,或者给出一个字段缺失但语法完全合法的 JSON。

笔者在开发 Temploracraft(一个将简历文档转换为可编辑结构化数据的工具)时,对此深有体会。输入文档格式千奇百怪——双栏 PDF、伪表格、十几种日期写法——而输出必须严格符合预期,因为每个字段最终都会展示在用户面前。模型一旦弄错日期,用户几秒钟内就会察觉。

本文要讨论的,正是介于“模型返回文本”和“应用获得可信数据”之间的那层关键逻辑。

为什么仅靠 Prompt 不够

最初的想法很自然:在提示词里礼貌地要求“返回合法 JSON,不要包含其他内容”,再附上示例。开发阶段一切正常,演示也很顺利。但问题是,LLM 是逐 token 概率生成的,你的指令只是众多影响因素之一,它还要与模型训练数据、输入文档特征以及前文上下文竞争。大多数时候指令能赢,但偶尔会输。

以下是从生产环境提取管线中收集的真实失败案例,模型都明确收到了返回严格 JSON 的指令:

  • 响应被包裹在 Markdown 代码块中,尽管明确告知不要这样做。
  • 返回 "2019 - Present" 字符串,而 schema 要求分开的 startDateendDate 字段。
  • 为文档明确标注为“至今”的职位,编造了一个 2024-12-31 的结束日期。
  • 返回字符串 "null" 而非真正的 null
  • 为最多允许五项的职位输出了七个要点。
  • 因超出输出 token 限制而中途截断。

注意,这些失败并非同一性质。代码块和截断属于语法问题,通常可以在本地修复,无需重新调用模型;而日期合并、多余要点则是 schema 问题——JSON 解析没问题,但不符合预定义结构。

约束输出的三种机制

要解决上述问题,不能只靠提示词,而应该利用平台提供的结构化输出能力:

  1. JSON Schema 约束:许多主流 API(如 OpenAI、Anthropic)支持在请求中直接指定 JSON Schema,模型会尽力生成符合该结构的响应。
  2. 函数调用(Function Calling):将结构化输出定义为函数参数,模型会以参数形式返回数据。
  3. 工具使用(Tool Use):类似函数调用,但更强调模型“选择工具”的过程,适合多步骤任务。

这三种机制各有适用场景,但核心思想一致:把约束从“提示词的软性要求”变为“API 的硬性保证”

先设计 Schema,再写 Prompt

一个常见误区是先写长篇提示词,再考虑数据结构。正确的顺序应该反过来:先用 Zod 或 JSON Schema 定义好严格的输出结构,再基于此设计提示词

例如,在简历提取场景中,日期字段不应是自由字符串,而应定义为 startDate: stringendDate: string | null,并配合正则或格式验证。这样即使模型返回了“2019 - Present”,验证层也能立刻捕获错误,而不是让错误数据流入下游。

验证是两道工序

验证不是一次性的,而是两层:

  • 语法验证:检查 JSON 是否能解析,字段类型是否正确。
  • 语义验证:检查值是否合理,比如结束日期是否早于开始日期、数组长度是否在限制内。

用 Zod 这类库可以轻松实现两层校验。第一层 safeParse 捕获类型错误,第二层 refinesuperRefine 处理业务规则。两层都通过,数据才能进入应用。

构建不烧钱的重试循环

重试是必需的,但必须聪明地设计:

  • 区分失败类型:语法错误(如代码块包裹)可以本地修复后直接重试;schema 错误(如字段缺失)则需要带着错误信息重新调用模型。
  • 限制重试次数:一般 2-3 次足够,超过即放弃并走人工处理流程。
  • 利用错误信息:把 Zod 的校验错误反馈给模型,让它知道哪里不对,而不是盲目重试。
const result = schema.safeParse(raw);
if (!result.success) {
  // 将错误信息拼入新的 prompt,重新调用
}

流式输出与不可重试的失败

流式输出可以提升用户体验,但要注意:结构化输出的流式解析比普通文本复杂,需要逐块拼接并延迟验证,直到收到完整对象。

另外,有些失败是重试无法解决的:模型对模糊输入(如扫描质量极差的 PDF)的解读偏差、源文档本身信息缺失、或者语义歧义(例如“2024”到底指入学年份还是毕业年份)。这类情况应设计为人工审核队列,而不是无休止地消耗 token。

成本与适用边界

结构化输出通常比普通生成消耗更多 token(因为需要遵守严格格式),且部分 API 对结构化模式有额外计费。因此,并非所有场景都需要这套机制:如果只是给用户看一段总结,普通文本生成就够了;但如果是关键业务数据,投资结构化输出是值得的。

总结

可靠的 LLM 结构化输出不是靠运气,而是靠系统设计:

  1. 用 API 原生约束机制替代提示词软要求。
  2. 先定义 Schema,再设计 Prompt。
  3. 双层验证(语法 + 语义)确保数据质量。
  4. 智能重试,区分可修复与不可修复的错误。
  5. 为不可重试的失败预留人工处理通道。

这套方法论不限于简历提取,凡是需要 LLM 输出稳定数据的场景——表单填充、数据迁移、内容分类——都适用。核心思想是:把不确定性隔离在模型层,让应用层只处理可信数据

本文基于 freeCodeCamp 的公开内容,由 AI 辅助整理改写后发布。

原标题:How to Get Reliable Structured Data Out of an LLM

阅读原文