这类问题我又碰上了一次。把聊天记录按角色分组后发给 gemini-1.5-pro,返回 400,原文 contents is not specified,可代码里明明拼了一个 list,日志打印出来是 []。
第一反应是「parts 里只有空字符串,被服务端视为空内容」,验证下来不成立。
原因不止一个,得分开看。过滤逻辑把所有轮次都判成空消息,列表被清空;role 用了 system,而 system 要走独立的字段;并发改写同一个 list,读取时已被别的线程清掉。
上来先把拼装结果先打印长度和角色
python -c "import json;d=json.load(open('req.json'));print(len(d['contents']),[c.get('role') for c in d['contents']])"
系统提示搬到 systemInstruction 字段
python -c "import json;d=json.load(open('req.json'));d['systemInstruction']={'parts':[{'text':'你是客服'}]};json.dump(d,open('req2.json','w'))"
剩下的就是用最小请求确认链路
curl -sS "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro:generateContent?key=$GEMINI_API_KEY" -H 'content-type: application/json' -d '{"contents":[{"role":"user","parts":[{"text":"ping"}]}]}'
这类改动我都写进变更记录,过两周再出问题时能对上号。
我习惯把每一步的执行时间和结果记在一边,后面复盘省事。
改完先别撤,确认这几项。请求返回 200,contents 长度大于零且最后一条角色为 user,日志里不再打印空数组。
这里还有个坑。Gemini 的角色只有 user 和 model,system 提示要单独放,把它塞进 contents 是空列表报错的常见来源。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。
