问题出现得很突然,日志倒是留得挺全。Python 3.10 用 mistralai 1.2.3 调 mistral-large-latest,messages 由模板渲染后传入,接口回 400,原文是 Invalid request: messages must not be empty,打印出来列表长度是 1,但那条消息的 content 是空字符串。
刚开始盯着「SDK 要求 content 是字符串 传 None 被序列化掉」,折腾了半个多小时,排掉了。
排查方向其实有限,先把可能性排一排。模板里变量没替换 渲染成空串。少数情况下是过滤函数把 system 消息删了 剩下空列表。
另外,拼装时把 messages 放进 data 字段 外层传了空数组。
上来先打印实际发出的请求体
python -c "import json;print(json.dumps(json.load(open('req.json')),ensure_ascii=False)[:400])"
然后用 curl 发一条最小消息确认凭证与路径
curl https://api.mistral.ai/v1/chat/completions -H "Authorization: Bearer $MISTRAL_API_KEY" -H "Content-Type: application/json" -d '{"model":"mistral-large-latest","messages":[{"role":"user","content":"ping"}]}'
再往下在发送前断言每条消息 content 非空
python -c "ms=[{'role':'user','content':''}];assert all(m['content'].strip() for m in ms),'empty content'"
给模板加默认值 变量缺失时直接报错
python render.py --strict --template chat.j2 --vars vars.json
别只看报错消失,验证要多做一步。请求返回 200,choices 里有正常文本,日志里打印的消息条数与内容都不为空。
补一句。报错文案说的是 messages 为空,真正的原因常常是某条 content 为空,逐条校验比只看列表长度有效。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。
