这个坑值得记一笔。上传一段 40 分钟的会议录音后立刻引用,generateContent 返回 400,原文 file is not in ACTIVE state,隔一会儿手动重试又能过。
刚开始盯着「引用的 URI 用了上传响应里的 name 之外的字段」,折腾了半个多小时,排掉了。
真正麻烦的地方在于,几个原因的现象几乎一样。上传成功不等于解析完成,状态要先经过 PROCESSING;轮询间隔太短,反而触发额外限流;文件超过大小上限,永久停在 FAILED。
上传后先记下文件 name
curl -sS -X POST "https://generativelanguage.googleapis.com/upload/v1beta/files?key=$GEMINI_API_KEY" -H 'X-Goog-Upload-Protocol: raw' -H 'Content-Type: audio/mp3' --data-binary @meeting.mp3 | jq -r '.file.name'
然后按两秒间隔轮询直到 ACTIVE
curl -sS "https://generativelanguage.googleapis.com/v1beta/files/$FILE_NAME?key=$GEMINI_API_KEY" | jq -r '.state'
就绪后再发内容请求
curl -sS "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro:generateContent?key=$GEMINI_API_KEY" -H 'content-type: application/json' -d @audio_req.json
排查用的命令都是临时敲的,没有写成脚本,事后才整理。
手上没有现成的复现脚本,就照着线上请求手工拼了一个。
改完先别撤,确认这几项。文件状态返回 ACTIVE,随后 generateContent 返回 200 并给出对录音内容的摘要,轮询次数收敛在个位数。
大文件解析时间随长度线性增长,把轮询写进流程比手工等更可靠,超时要有明确的失败出口。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。
