一个凌晨3点的报警
凌晨3点,你被PagerDuty叫醒。数据处理管道崩溃了。日志显示:“JSONDecodeError: Expecting value: line 1 column 1 (char 0)"。AI生成的JSON格式不对——它在外层包裹了一个Markdown代码块。
你揉着眼睛修改Prompt,加了更强硬的措辞:“严格输出纯JSON,不要加任何其他内容!!!!“然后重新部署。第二天凌晨3点,同样的报警再次响起。
格式问题不是靠"更强烈的语气"能解决的。 你需要理解结构化输出的底层机制。
技巧一:用JSON Schema定义输出格式
不要只是说"输出JSON格式”,而是提供完整的JSON Schema:
请严格按以下JSON Schema输出:
{
"type": "object",
"properties": {
"name": {"type": "string", "description": "用户姓名"},
"age": {"type": "integer", "minimum": 0, "maximum": 150}
},
"required": ["name", "age"]
}
JSON Schema不仅定义了结构,还定义了每个字段的类型、约束和含义。这是最精确的格式指定方式。
技巧二:在System Prompt和User Prompt中双重强调
在System Prompt中定义一次格式,在User Prompt中再简要重申一次。双重强调能将格式遵循率从85%提升到95%以上。 原因:模型在长对话中可能"遗忘"早期的System Prompt指令,在User Prompt中重申相当于"刷新"了模型的"记忆”。
技巧三:使用"输出示例"而非"格式描述”
与其说"输出一个包含name和age的JSON对象",不如直接给一个完整的输出示例:
期望输出格式(请严格遵循):
{"name": "张三", "age": 28}
示例比描述更有效。 模型在模仿示例时,出错概率远低于按照描述生成格式。
技巧四:在末尾加上"格式检查"指令
在Prompt末尾加上:“在输出前,请确认你的输出:1)是纯JSON,没有Markdown包裹;2)所有必填字段都存在;3)字段类型正确。如果不符合,请修正后再输出。”
这个简单的技巧能减少约60%的格式错误。
技巧五:使用API的JSON Mode
GPT-5和Claude 4 Opus都提供了原生JSON Mode。在API调用中设置response_format={"type": "json_object"},模型会强制输出合法JSON。这比Prompt中的格式约束更可靠,但需要注意:JSON Mode可能影响回答质量,因为模型被约束在"JSON思维"中。
技巧六:处理嵌套结构
对于嵌套JSON,使用"分层定义"策略:先定义外层结构,再定义内层结构。不要在Prompt中一上来就展示完整的嵌套JSON——那会让模型"迷失"在复杂的结构中。
技巧七:处理数组输出
对于数组输出,始终指定"最少元素数量"和"最多元素数量"。否则模型可能输出0个元素或100个元素,导致下游处理出错。
技巧八:用CoT生成内容,再格式化为JSON
将任务分为两步:第一步让模型用自然语言生成内容(可以自由思考),第二步将内容格式化为JSON。两步法比一步法效果好得多,因为模型在第一步可以自由推理,在第二步只需专注格式化。
技巧九:增加输出验证层
不要完全信任模型的输出。在代码中增加一层验证:检查JSON是否合法、必填字段是否存在、字段类型是否正确。如果验证失败,自动重试(带上错误信息)。
技巧十:使用不同的模型做"格式检查"
用一个便宜的模型(如DeepSeek V3)来检查另一个模型输出的格式是否正确。DeepSeek V3做格式检查的能力很强,但成本只有GPT-5的七分之一。
结构化输出的核心原则:不要期望模型"完美遵守"你的格式要求——而是设计一个"容错系统",让格式错误在造成破坏之前被捕获和修复。