报错是这么冒出来的。claude-3-5-sonnet 在 system 里写明只输出 JSON,实际返回「好的,以下是结果:
{"ok":true}」,json.loads 直接抛 JSONDecodeError: Expecting value。

中间走过弯路,把「JSON 后面还跟了一段解释文字」当成主因,改完现象没变。

原因不止一个,得分开看。模型习惯性加一句自然语言前缀。另一种情况是JSON 被 markdown 代码围栏包住。

另外,temperature 0.7 让格式遵循变得不稳定。

先把原始返回完整打印出来看前后缀

python -c "print(repr(open('raw.txt').read()[:200]))"

再往下用正则剥掉围栏和前缀再解析

python -c "import re,json;s=open('raw.txt').read();m=re.search(r'\{.*\}',s,re.S);print(json.loads(m.group(0)))"

随后加 assistant 预填充强制从花括号开始

curl https://api.anthropic.com/v1/messages -H "x-api-key: $ANTHROPIC_KEY" -H 'anthropic-version: 2023-06-01' -H 'Content-Type: application/json' -d @req_prefill.json

等前面都确认过,再把 temperature 降到 0 再跑 100 条看失败率

python -c "import json;print(json.load(open('cfg.json')).get('temperature'))"

这类问题以前遇到过,但这次的触发条件和上次不一样。

恢复的判定其实很直接。100 条请求里 99 条能直接 json.loads 成功,剩下一条是模型返回了截断的 JSON,加长长尾限制后也通过。

补一句。要求纯 JSON 只是提示,真正的保证要靠预填充和解析兜底,客户端永远要假设返回值里可能夹着解释。同一份配置在测试环境跑通,不代表线上没事,两边的默认值经常不一样。

作者 9823189