先看现象。把 timeout 从默认 600 秒改成 30 秒后,长文总结请求开始报 anthropic.APIConnectionError,底层写着 httpx.ReadTimeout,可同一请求用 60 秒就能跑完,端口抓包显示服务端一直在推流。
把日志和配置对完,能解释这个现象的基本就这几处。超时是整条请求的读超时,长输出必然超过 30 秒。还有一种是SDK 默认会对超时做一次自动重试,重试叠加重放把时间翻倍。
还有一种情况,流式请求的每块间隔很短,但总时长被误当成单块超时。
另外,公司代理对大响应做了缓冲,首字节延迟被算进读超时。
先用 curl 观察首字节和总耗时分别多少
curl -sS -o /dev/null -w 'dns=%{time_namelookup} first=%{time_starttransfer} total=%{time_total}\n' https://api.anthropic.com/v1/messages -H "x-api-key: $ANTHROPIC_API_KEY" -H "anthropic-version: 2023-06-01" -d @long.json
随后把客户端超时拆成连接与读取两段
python -c "import anthropic,httpx;c=anthropic.Anthropic(timeout=httpx.Timeout(600.0,connect=10.0));print('ok')"
末了关掉自动重试,避免超时被放大
python -c "import anthropic;c=anthropic.Anthropic(max_retries=0);print('no retry')"
改完先别撤,确认这几项。长文请求在 30 秒以上也能正常返回 200,日志里没有 ReadTimeout,重试次数记录为 0 或 1 且总耗时可控。
这里还有个坑。把超时当成保护是好事,但读取超时要按最慢的合法输出给,不能按平均值,否则稳定误杀长回答。这类问题最好一次改到位,反复小改反而容易把原因搅混。
