如何修复 Gemini JSON 截断:3 步让 json.loads 不再抛错
2026/8/24 8:58:39 网站建设 项目流程

如何修复 Gemini JSON 截断:3 步让 json.loads 不再抛错

【免费下载链接】generative-aiSample code and notebooks for Generative AI on Google Cloud, with Gemini Enterprise Agent Platform项目地址: https://gitcode.com/GitHub_Trending/ge/generative-ai

你在 generative-ai 项目里让 Gemini 输出 JSON,结果生成到一半就断了,解析器当场报错——这就是典型的 Gemini JSON 截断。这篇排查指南带你看清 3 种成因、吃下 3 种修法,读完你的解析链路就能稳定跑起来。

现场还原:json.loads 抛 JSONDecodeError 的那一刻

先还原一个很有代表性的场景:晚上十点多,你跑完一次模型调用,随手json.loads(response.text),终端立刻红了一片——JSONDecodeError: Expecting ',' delimiter。你按报错行号翻回去看,数组写到第 19 条就停了,最后一个右括号根本不存在。

你的第一反应通常是怀疑自己的解析代码。做个小实验就能排除:把response.text原样打印出来,肉眼确认结尾是不是完整的。不完整,就说明问题出在模型输出这一侧,进入下面的排查。

这种残缺 JSON 一旦流出去,下游全遭殃:前端拿不到数据,界面只剩一张"无结果"占位图;统计脚本少算一批记录;自动化流水线卡死在这次调用上,等你手动重启。

诊断 Gemini 输出不完整:三个常见症状

诊断一:每次都在差不多的长度处断开,重试切点还不一样。真凶是输出令牌上限。Gemini 单次回复有 token 预算,Flash 这类模型通常只有几千到八千。你的 JSON 超出预算,模型就写到哪截到哪。打个比方:这就像快递车装不下全部货,司机只好把后半截卸在路边,你收到的包裹永远缺斤少两。确认方法:多跑几次,看截断位置是否都卡在 token 预算附近。

诊断二:JSON 尾巴上多了"话"。比如结尾冒出"以上是查询结果",或者整段被包进 markdown 代码块。真凶是你没约束输出格式。自由文本模式下模型爱"唠叨",而json.loads对多余字符零容忍。确认方法:检查文本里是否出现 ``` 或中文说明。

诊断三:函数调用的参数缺字段、不闭合。当你把大嵌套对象或长数组塞进一个函数参数时,参数体积会撑爆输出空间,最后半段参数直接被吞。确认方法:对比function_call.args里的字段数是否比 schema 声明的少。gemini/function-calling/function_calling_data_structures.ipynb 里演示的正是这类复杂结构,可以对照着看。

三剂药方,由轻到重

💊 先看病情:JSON 只是略大,吃①;格式老跑偏,吃②;数据量大到一次装不下,吃③。

药方①:如何调高 Gemini 的输出上限

适合谁:JSON 只比默认输出多一截,差几百个字符就能完整。

from google import genai client = genai.Client() r = client.models.generate_content( model="gemini-2.0-flash", contents="生成 200 个产品的 JSON 数组", config=genai.types.GenerateContentConfig( max_output_tokens=8192, temperature=0), ) print(r.text)

temperature设 0 是为了让输出尽量确定,减少"差一点"的重试。不够用的时候:上限是模型自身的硬约束,参数设得再大也不会突破,数据太大时该截还是截。

药方②:结构化输出怎么开,让模型"闭嘴只交 JSON"

适合谁:要每次拿到稳定 schema,一个多余字符都不能忍。

from google import genai from google.genai import types client = genai.Client() schema = types.Schema(type=types.Type.OBJECT, properties={"products": {"type": types.Type.ARRAY, "items": {"type": types.Type.OBJECT}}}, required=["products"]) r = client.models.generate_content( model="gemini-2.0-flash", contents="生成 20 个产品数据", config=types.GenerateContentConfig( response_mime_type="application/json", response_schema=schema)) print(r.text)

你把 schema 画好,模型被锁死在里面,只能往里填数据,多一个字都出不来。偏好用强制函数调用达到同样效果的,可以看 gemini/function-calling/forced_function_calling.ipynb。不够用的时候:schema 保格式、不保数量,数据量太大时输出照样被截。

药方③:几千条数据怎么分片生成

适合谁:数组动辄上千条,单次调用物理上装不下。

import json from google import genai client = genai.Client() def build_big_json(total=5000, chunk=500): items = [] for i in range(0, total, chunk): r = client.models.generate_content( model="gemini-2.0-flash", contents=f"生成第 {i}~{i + chunk - 1} 条产品数据,只输出 JSON 数组", config=genai.types.GenerateContentConfig(max_output_tokens=8192)) items += json.loads(r.text) return {"total": len(items), "data": items}

把大数组拆成小块,逐片生成、逐片解析、再拼回。建议每个分片都套上药方②的 schema,结构更稳;拼接完成后再整体校验一次total是否等于预期条数。不够用的时候:调用次数和等待时间线性上涨,需要你的业务逻辑能接受"生成—校验—拼接"这个流程。

三个修复方案怎么选

药方适用场景改动成本局限
① 调高输出上限JSON 略大、偶发截断改一个参数顶不过模型硬上限
② 结构化输出schema 必须稳定、格式常跑偏加一段 config只保格式不保数量
③ 分片生成数千条的超大数据写循环和拼接调用变多、延迟变长

复诊:如何给 JSON 解析加一层兜底

⚠️ 上面手段全做完,也不能 100% 保证每次解析都成功。关键链路上,建议给解析加个容错:

import json def safe_parse(text): candidates = [text] if not text.rstrip().endswith(("}", "]")): candidates.append(text.rstrip() + "}") for t in candidates: try: return json.loads(t) except json.JSONDecodeError: continue return None

先直接解析,失败后再尝试补一个右括号,只救"少一个括号"这种轻症。拿到None说明这份输出已不可用,正确动作是把分片改小、重新调用,循环到成功为止。顺手把原始文本落一份日志,方便事后分析模型到底断在哪。

先上哪个方案:Gemini JSON 截断选型建议

✅ 一句话结论:默认先上药方②,它成本最低、从源头消灭格式问题;当数据量大到单次装不下,再叠加药方③分片生成。药方①更适合顺手加上,很少单独够用。更多基础用法参考项目里的 gemini/function-calling/intro_function_calling.ipynb 和 gemini/README.md。

【免费下载链接】generative-aiSample code and notebooks for Generative AI on Google Cloud, with Gemini Enterprise Agent Platform项目地址: https://gitcode.com/GitHub_Trending/ge/generative-ai

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询