Python 如何让 AI 返回稳定的 JSON:结构化输出与结果校验实战

Python 如何让 AI 返回稳定的 JSON:结构化输出与结果校验实战 在 AI 工具、自动化脚本和数据处理项目中最麻烦的问题之一不是模型不会回答而是返回内容格式不稳定。本文介绍一种更可靠的处理方式明确输出结构再在 Python 中校验结果。为什么不能直接把模型返回当作 JSON很多项目一开始会直接这样处理resultresponse.choices[0].message.content然后默认result一定是 JSON。实际运行时模型可能返回JSON 前后带说明文字字段名称不一致某个字段缺失数字变成字符串多出 Markdown 代码围栏只要后续代码依赖固定字段程序就可能直接报错。更稳的做法是在提示词中明确格式对返回结果做解析校验必要字段失败时给出可处理的错误一、先明确输出结构假设我们要让模型提取一段文本中的任务信息可以先定义目标结构{title:任务标题,priority:high,tags:[python,api]}然后在提示词中明确要求prompt 请从下面内容中提取任务信息。 只返回合法 JSON不要添加 Markdown 标记或解释文字。 字段必须包含title、priority、tags。 内容 用户需要整理 Python API 接入文档并优先处理错误排查。 输出要求越清楚后续解析越容易。二、使用 Python 解析 JSON可以先使用标准库jsonimportjson text{title: API 文档, priority: high, tags: [python, api]}datajson.loads(text)print(data[title])print(data[tags])但是真实返回内容可能不符合要求所以不能只写json.loads()还要处理异常。importjsondefparse_json(text:str)-dict:try:valuejson.loads(text)exceptjson.JSONDecodeErrorasexc:raiseValueError(f返回内容不是合法 JSON{exc})fromexcifnotisinstance(value,dict):raiseValueError(返回结果必须是 JSON 对象)returnvalue三、校验必需字段解析成功不代表数据完整。可以继续校验字段defvalidate_task(data:dict)-dict:required[title,priority,tags]forkeyinrequired:ifkeynotindata:raiseValueError(f缺少字段{key})ifnotisinstance(data[title],str):raiseValueError(title 必须是字符串)ifdata[priority]notin{low,medium,high}:raiseValueError(priority 不是有效值)ifnotisinstance(data[tags],list):raiseValueError(tags 必须是数组)returndata这样可以把格式问题尽早暴露出来而不是让错误一路传到业务层。四、组合成一个完整函数importjsondefparse_and_validate(text:str)-dict:try:datajson.loads(text)exceptjson.JSONDecodeErrorasexc:raiseValueError(模型返回的内容无法解析为 JSON)fromexcifnotisinstance(data,dict):raiseValueError(模型返回结果必须是对象)required{title,priority,tags}missingrequired-data.keys()ifmissing:raiseValueError(f缺少字段{, .join(sorted(missing))})ifdata[priority]notin{low,medium,high}:raiseValueError(priority 值不合法)ifnotisinstance(data[tags],list):raiseValueError(tags 必须是列表)returndata调用时contentresponse.choices[0].message.contenttry:taskparse_and_validate(content)exceptValueErrorasexc:print(f结果校验失败{exc})else:print(task[title])五、用 Pydantic 管理复杂结构当字段变多时手动校验会越来越长可以使用 PydanticpipinstallpydanticfrompydanticimportBaseModel,FieldclassTask(BaseModel):title:strpriority:strField(pattern^(low|medium|high)$)tags:list[str]解析数据importjson rawresponse.choices[0].message.content taskTask.model_validate(json.loads(raw))print(task.title)如果字段缺失或类型错误Pydantic 会抛出明确的校验异常。六、常见问题和处理方式1. 返回内容带 Markdown 围栏可以在提示词中明确要求只返回 JSON。不要优先用复杂字符串替换因为可能误删正文内容。2. 字段偶尔缺失把必需字段写进提示词并在代码中再次校验。3. 枚举值不统一例如模型返回高、high、High可以在业务层建立映射但要记录转换过程。4. JSON 结构嵌套太深先减少不必要的层级。结构越简单模型越容易稳定返回。七、适合使用结构化输出的场景这种方式适合文本信息提取自动分类标签生成内容审核结果整理表单字段生成Agent 工具参数准备批量数据清洗只要后续程序需要读取模型结果就应该考虑结构化输出和校验。八、结语让 AI 返回 JSON 只是第一步真正可靠的流程还包括明确字段结构解析返回内容校验字段类型处理异常结果记录失败原因对于 Python AI 项目来说结构化输出可以让模型调用更容易接入后续业务也能减少因为格式变化带来的异常。建议先从一个简单的数据结构开始确认解析和校验稳定后再逐步扩展字段。免责声明本文内容仅用于技术交流与经验分享具体实现请结合项目实际情况调整。