News Hacker|极客洞察

128 182 天前 claude.com
🤦Claude API 正式支持结构化输出(JSON Schema 支持但有局限)
现在才搞结构化?之前的稳定性去哪儿了?

🎯 讨论背景

Anthropic 在 Claude 开发者平台的 API 中新增了 Structured Outputs(结构化输出)功能,社区把它与 OpenAI、Google Gemini 等已有实现比较。讨论围绕实现方式(如将 grammar 编译进推理以做 token 过滤、llama.cpp 与 LLGuidance 的先例)、工程实践(注入起始字符、双次调用、用 pydantic 校验并重试)以及 JSON Schema 在表达力和兼容性上的局限性。不少开发者在生产环境(例如使用 Bedrock 的部署或本地 llama.cpp)已有相关经验,因而既欢迎官方支持,也提出了对 EBNF/BNF 等更灵活语法支持的需求和对严格模式/截断 JSON 等行为的担忧。

📌 讨论焦点

结构化输出为 LLM 自动化核心

很多评论认为结构化输出对构建多步骤自动化流水线(agentic steps)至关重要:用户将每一步的输出以 JSON 传给下一步,减少对重试和随机文本解析的依赖,从而简化系统设计并提高可靠性。有人举例说在生产环境(例如在 Bedrock 上运行 Claude)用半年到一年并运行良好,官方支持被视为长期缺失的关键功能。支持者还指出,缺乏官方结构化支持曾把一些团队推向其他平台或用工具调用作为替代方案,因此原生支持能降低工程复杂度。总体论点集中在:除非只是做聊天机器人,否则结构化输出几乎是构建可组合自动化流程的基本设施。

[来源1] [来源2] [来源3] [来源4] [来源5]

语法编译与 token 过滤的实现与权衡

多人讨论了实现手段:Anthropic 和 OpenAI 等通过把 grammar 编译到推理阶段,在 token 采样时只允许符合语法的 token,从而保证输出语法正确,这在 llama.cpp 和 LLGuidance 中已有先例。评论里指出这种约束在高度受限场景(例如布尔字段或极短候选集)可能牺牲语义准确性或让模型显得“随机”,且 field 顺序、prompt 质量会显著影响结果。有人建议的折中方案包括先让模型在“思考”阶段生成自由文本再用约束生成最终 JSON,或通过改进 prompt 让模型本身更倾向于正确答案,从而与语法过滤协同工作。

[来源1] [来源2] [来源3] [来源4] [来源5]

API 限制、错误与常见绕行策略

许多评论列举了当前 structured outputs 的实用限制,并分享工程化绕行:官方对 JSON Schema 的实现对 union/discriminated union 等高级特性支持不足,导致必须将 schema 平坦化或拆成多个工具定义(tool)。业界常见的替代做法包括在 prompt 中注入起始左花括号 '{' 以“引导”模型生成 JSON、用双次调用检测工具使用、以及在服务端用 pydantic 等库做复杂校验并把校验错误反馈给模型重试。还有人抱怨在 OpenAI/Anthropic 的实现中会遇到语法不完整的 JSON(例如被截断的数组),以及 strict 模式参数在不同 SDK/用法中的兼容性问题,需要额外的解析和重试逻辑来保证健壮性。

[来源1] [来源2] [来源3] [来源4] [来源5] [来源6] [来源7]

对更灵活语法(EBNF/BNF 等)的需求

多位评论者表达了对比 JSON Schema 更灵活的语法表达的需求,举例希望能提供 EBNF/BNF 风格的 grammar(像 llama.cpp 那样)以覆盖更多用例和复杂结构。有人指出 JSON Schema 在某些应用场景表达力不足,而基于 grammar 的约束能直接描述更复杂的语言或数据格式,因此更适合某些生成任务。社区也提到现有开源工具(如 guidance/LLGuidance)和语言生态(例如 TS 的 Zod -> toJSONSchema)在解决这类问题上已有进展,但希望平台层面原生支持更通用的 grammar。

[来源1] [来源2] [来源3] [来源4] [来源5]

并非人人都迫切需要/已有可行替代

也有评论认为许多项目在没有官方结构化输出的情况下运作良好:有用户从 OpenAI 的 structured outputs 切换回 Claude(非结构化)仍未遇到问题,另一些人觉得结构化输出较慢、更适合离线场景。部分意见认为把 tool calling 当作变通方法并非不可接受,虽然看起来像“hack”,但在实际工程中常被采用。总体上这是功能改进而非颠覆性变革:官方支持受欢迎,但是否必须取决于具体产品和性能/延迟需求。

[来源1] [来源2] [来源3] [来源4]

📚 术语解释

JSON Schema: 用于描述和校验 JSON 数据结构的标准规范,在 structured outputs 中常被用来约束模型输出字段与类型,但对 union、discriminated union 等高级类型支持在实践中存在局限。

LLGuidance: guidance-ai 的开源库(GitHub: guidance-ai/llguidance),可用于把 schema/grammar 编译到推理阶段以强制模型在 token 级别遵守语法,OpenAI 与社区实现有关联。

pydantic: Python 的数据建模与校验库,用于将 JSON 输出解析为强类型模型并进行复杂验证,常被用在服务端对 LLM 输出做二次校验并把错误反馈给模型重试。

Constrained generation(约束生成 / token 过滤): 在推理时把语法或 schema 编译为允许的下一个 token 集合,模型只能从该集合中选择,从而保证语法正确性,但在概率接近时可能影响语义或答案多样性。

EBNF/BNF 语法(grammar): 用于描述语言或数据格式语法的形式化方式(例如 EBNF),像 llama.cpp 等实现支持基于 EBNF 的生成约束,适合表达比 JSON Schema 更复杂或更灵活的格式。

tool calling: 一种让模型输出映射为调用外部工具或 API 的机制,早期常被用作实现结构化输出的变通方法,但在复杂 schema 与可维护性上会有局限。