底解决大模型 JSON 报错:提示词 + 硬约束 + 兜底的全链路修复方案
Markdown 标签包裹带有json标签导致无法直接解析。非法格式用单引号替代双引号、转义字符使用错误等。语法漏洞尾部缺失反括号、字段后多添逗号等。显然这种不合规的 JSON 输出无法正常被json.load()正确解析直接导致业务代码报错。为了解决这个问题我们需要在调用大模型的前、中、后三个阶段分别采取一些处理措施事前引导、事中约束、事后补救全方位确保大模型能够输出稳定、纯净的 JSON。下面我们以『判断用户输入的内容是否违规违规类型是什么违规词是什么』这个需求为例详细介绍下具体处理手段。一、事前引导提示词优化提示词优化是最基础、最通用的解决方案核心是通过明确严谨的指令引导大模型输出符合要求的 JSON。这种方式属于『软约束』依赖模型对指令的理解和执行能力无法从源头强制合规但胜在简单易用、适配所有大模型。常见的优化方式为明确字段要求详细说明每个字段的输出类型、取值范围而非简单要求输出 JSON提供 Few-Shot 示例借助大模型的上下文学习能力给出输入输出配对示例让模型直观掌握格式添加校验指令要求大模型输出前自动校验 JSON 语法及内容合规性确保无冗余、无错误。 提示词模板示例如下# 角色你是一个严格的用户输入违规判断助手负责对用户输入内容进行违规判定并严格按预设规则输出合规JSON结果。# 技能- **核心违规类型**用户输入含「色情」「暴力」「辱骂」类词汇或违法、广告推广等其他明确违规内容 → 违规否则不违规。- **违规词提取**仅提取用户输入中明确出现的核心违规词汇不新增、不推断。# 输出格式**严格按以下格式生成JSON**{is_illegal: boolean,illegal_type: string,illegal_words: list}# 限制- **输出唯一**仅输出符合规则的JSON禁止任何非JSON内容并且 JSON 中的 key 名不可修改禁止新增/遗漏key。- **输出内容**- is_illegal小写true/false。- illegal_type仅允许色情/暴力/辱骂/其他/。- illegal_words无违规词则为[]否则为原始输入词汇列表。- **边界规则**仅提取用户明确输入的核心违规词不拆分/扩展/推断词汇。# 核心要求- 严格遵循上述规则输出前自动校验JSON语法及内容合规性确保无冗余、无错误。# 示例## 示例1输入今天天气不错适合去公园散步。## 示例1输出{is_illegal: false,illegal_type: ,illegal_words: []}## 示例2输入你这个蠢货滚远点”## 示例2输出{is_illegal: true,illegal_type: 辱骂,illegal_words: [蠢货, 滚远点]}## 示例3输入本产品能治百病点击链接购买享8折## 示例3输出{is_illegal: true,illegal_type: 其他,illegal_words: [本产品能治百病, 点击链接购买]}二、事中约束编码管控提示词优化是一种『软约束』手段存在局限性即使指令再明确大模型仍然可能因为幻觉、随机性出现格式偏差。为此主流大模型厂商推出了原生『硬约束』能力可在模型生成结果过程中强制输出合规 JSON。其核心原理简单来说系统会将 JSON 规则转换为状态机在模型生成每个 Token 前过滤非法内容仅允许合法Token 参与概率计算从底层确保输出完全符合 JSON 规范和字段要求例如生成冒号后下一个 Token 绝不可能是逗号。⚠️ 注意并非所有大模型都支持这类硬约束功能多数轻量模型、小众模型暂不支持仅适配OpenAI系列、Anthropic Claude 等主流模型。1. JSON Mode基础格式硬约束JSON Mode是基础硬约束功能通过 API 参数约束模型输出编码逻辑强制生成符合 JSON 语法规范的文本从源头杜绝冗余话术、代码块包裹等问题。核心操作调用接口时新增response_format{type: json_object}参数且提示词中需明确提及“JSON”否则模型报错。⚠️ 注意JSON Mode 仅保证输出格式为合规 JSON不支持在 response_format 中输入具体 schema无法锁定字段规则仍可能出现字段遗漏key 名写错问题 代码示例如下以 OpenAI SDK 为例import jsonfrom openai import OpenAIclient OpenAI(api_keyyour_api_key,base_urlhttps://api.openai.com/v1)MODEL gpt-4o-miniif __name__ __main__:system_prompt # 角色你是一个...user_prompt 真是一头猪messages [{role: system, content: system_prompt}, {role: user, content: user_prompt}]response client.chat.completions.create(modelMODEL, messages messages, response_format{type: json_object})result json.loads(response.choices[0].message.content)print(result)2. Structured Outputs格式字段双维度强制JSON Mode 仅能保证输出的格式为 JSON但并不能保证字段是否准确、是否完整等。为了解决这个问题诞生了Structured Outputs结构化输出功能可通过定义完整的 JSON Schema强制模型输出指定字段及类型彻底杜绝 key 名错误和字段遗漏问题。核心操作调用接口时在 response_format 中传入具体 JSON Schema实现格式与字段的双重硬约束确保模型输出完全匹配预设的字段规则合规率 100%这也是官方主推的结构化输出方案。 代码示例如下以 OpenAI SDK 为例import jsonfrom openai import OpenAIclient OpenAI(api_keyyour_api_key,base_urlhttps://api.openai.com/v1)MODEL gpt-4o-miniif __name__ __main__:system_prompt # 角色你是一个...user_prompt 真是一头猪messages [{role: system, content: system_prompt}, {role: user, content: user_prompt}]response client.chat.completions.create(modelMODEL, messages messages, response_format {type: json_schema,json_schema: {name: illegal_judge_result,strict: True, # 严格遵循schema杜绝字段遗漏、类型错误schema: {type: object,properties: {is_illegal: {type: boolean,description: 是否违规仅true/false小写},illegal_type: {type: string,description: 违规类型仅允许色情/暴力/辱骂/其他/},illegal_words: {type: array,description: 违规词列表无违规则为[]仅含用户输入的核心词汇}},required: [is_illegal, illegal_type, illegal_words],additionalProperties: False # 禁止新增额外字段}}})result json.loads(response.choices[0].message.content)print(result)3. Function Calling 工具调用Function Calling工具调用同样能间接实现稳定 JSON 输出并且支持格式与字段的双约束。我们在调用大模型接口时通过tools参数定义完整的工具 JSON Schema明确字段名、类型、必填项等规则并要求模型调用该工具。模型为确保工具正常调用会严格按照预设 Schema 输出合规的函数参数而这些参数本身就是一段合规 JSON。核心操作调用接口时用tools定义 Schema 规则通过tool_choice强制模型调用函数直接提取参数即可获得合规 JSON无需额外处理。 代码示例如下以 OpenAI SDK 为例import jsonfrom openai import OpenAIclient OpenAI(api_keyyour_api_key,base_urlhttps://api.openai.com/v1)MODEL gpt-4o-miniif __name__ __main__:system_prompt # 角色你是一个...user_prompt 真是一头猪tools [{type: function,function: {name: process_illegal_judge,strict: True, # 开启严格模式必须返回JSON格式description: 对用户输入进行违规判定返回结构化JSON结果,parameters: {type: object,properties: {is_illegal: {type: boolean,description: 是否违规仅true/false小写},illegal_type: {type: string,description: 违规类型仅允许色情/暴力/辱骂/其他/},illegal_words: {type: array,description: 违规词列表无违规则为[]仅含用户输入的核心词汇}},required: [is_illegal, illegal_type, illegal_words],additionalProperties: False # 禁止新增任何额外字段}}}]messages [{role: system, content: system_prompt}, {role: user, content: f判定用户输入是否违规{user_prompt}}]response client.chat.completions.create(modelMODEL,messages messages,tools tools,tool_choice{ # 强制调用锁死输出格式type: function,function: {name: process_illegal_judge}})if response.choices[0].message.tool_calls:result json.loads(response.choices[0].message.tool_calls[0].function.arguments)print(result)else:raise ValueError(模型未调用工具)三、事后补救JSON 修复当软约束偶尔失效且模型不支持硬约束时事后补救就是保障业务不挂的最后一道防线。核心是通过轻量技术修复 JSON 异常、应对 API 问题适配所有大模型弥补软约束偏差和硬约束适配局限即便 JSON 格式有误也能尽力修复、重试保障服务可用。1. 正则提取清除冗余内容核心功能剔除json包裹、前后冗余话术提取纯 JSON 文本。优势成本极低、速度极快实现简单是后处理的基础步骤。局限性仅提取文本无法修复 JSON 本身的语法错误如括号缺失、逗号多余。import redef extract_json_from_text(text: str):从大模型输出文本中提取纯JSON内容# 优先匹配markdown json代码块json_pattern1 rjson\s*(\{[\s\S]*?\})\s*match1 re.search(json_pattern1, text, re.DOTALL)if match1:return match1.group(1).strip()# 兜底匹配最外层的{}应对所有前后带废话的场景json_pattern2 r(\{[\s\S]*\})match2 re.search(json_pattern2, text, re.DOTALL)return match2.group(1).strip() if match2 else text2. json_repair修复语法错误核心功能自动修复 JSON 轻微语法错误如末尾多逗号、引号未闭合、缺少括号等。优势本地修复无需重新调用模型速度快有效弥补正则提取的不足。局限性仅修复语法错误无法解决字段缺失、key 名错误等字段相关问题。import json_repairimport jsondef repair_invalid_json(invalid_json_str: str):修复JSON语法错误如括号缺失、逗号多余等try:json_str json_repair.repair_json(invalid_json_str)return json.loads(json_str)except Exception as e:print(fJSON修复失败{e}大模型原始输出{invalid_json_str})return None3. pydantic字段规则校验核心功能通过 Python 类定义 JSON 字段规则格式、类型、取值范围等全量校验 JSON 合规性。优势可发现所有合规问题语法、字段、类型避免因数据不合规导致的线上崩溃。局限性需编写校验模型增加少量代码复杂度。from pydantic import BaseModel, Field, ValidationErrorfrom typing import Literalclass IllegalJudgeResult(BaseModel, extraforbid):is_illegal: bool Field(description是否违规仅true/false小写)illegal_type: Literal[色情, 暴力, 辱骂, 其他, ] Field(description违规类型仅允许色情/暴力/辱骂/其他/)illegal_words: list Field(description违规词列表无违规则为[])def validate_json(raw_json: str):全量校验JSON贴合违规判断需求try:data json.loads(raw_json)return IllegalJudgeResult(**data).model_dump()except (json.JSONDecodeError, ValidationError) as e:print(fJSON校验失败{e})return None4. 重试机制保障服务可用性核心功能API 调用失败后按 1s/2s/4s 指数退避重试。优势对超时、限流、格式错误等异常大幅提升服务可用性。局限性增加代码复杂度重试会延长接口调用耗时四、总结大模型 JSON 输出异常本质是模型幻觉与业务确定性需求的矛盾。通过「事前引导→事中约束→事后补救」的全链路解决方案可实现 JSON 输出稳定合规适配不同场景、不同类型大模型。事前引导通过明确字段规则、提供 Few-Shot 示例、添加校验指令低成本引导模型输出合规 JSON事中约束借助JSON Mode、Structured Outputs、Function Calling实现硬约束从源头杜绝异常