很多团队第一次接入大模型 API 时,最关心的往往是“能不能跑通”:拿到 API Key,把 messages 拼好,接口返回一段文本,Demo 看起来就算成功了。
但真到了生产环境,情况就完全不一样了。线上会遇到的东西要复杂得多,比如 429 限流、接口超时、流式响应突然断掉、JSON 解析失败、上下文超长、token 成本飙升、API Key 泄露,甚至模型输出质量波动带来的业务风险。
所以,大模型 API 的生产化,绝不是简单地调一个接口。更准确地说,它是一整套围绕稳定性、性能、成本、安全和可观测性搭起来的工程体系。本文不绑定某一家厂商,主要从通用的大模型 API 报错处理和性能优化角度,整理一些更适合线上系统的实践经验。
为什么大模型 API 到生产环境会比 Demo 难很多?
Demo 阶段通常很简单:一个用户、一个请求、一段固定 prompt,最多再加一点参数调试。但线上系统不是这样。生产环境里会有高并发、多租户、长上下文、流式输出、批处理任务、模型切换、费用结算、合规审计等一堆现实问题。
比较常见的事故有这些:
- 高峰期请求突然打满,触发大量 429,用户端一直转圈;
- 模型只返回了一半内容,前端流式输出卡住,不知道该结束还是继续等;
- 结构化输出偶尔不是合法 JSON,后面的业务流程直接失败;
- 历史对话越拼越长,最后超过上下文限制;
- 重试逻辑没控制好,一次失败被放大成多次计费请求;
- API Key 被写进前端代码或日志里,引发安全和成本风险。
所以线上系统的目标不是保证“每次调用都成功”。这不现实。更重要的是:失败能分类、能重试、能降级、能观测,而且局部故障不会拖垮整个系统。
大模型 API 常见报错分类:哪些能重试,哪些别重试?
处理大模型 API 报错时,第一件事就是别把所有错误都扔给同一个 retry 逻辑。不同错误背后的原因完全不同,处理方式也不一样。
| 类型 | 常见状态码 / 表现 | 常见原因 | 是否重试 | 处理建议 |
|---|---|---|---|---|
| 参数错误 | 400 / 422 | messages 格式不对、模型名写错、参数范围非法 | 否 | 提前做参数校验,记录请求摘要 |
| 认证错误 | 401 / 403 | API Key 错误、权限不足、Key 被禁用 | 否 | 立即告警,检查密钥和权限配置 |
| 资源不存在 | 404 | 模型不可用、endpoint 写错 | 通常否 | 检查模型名、区域和接口路径 |
| 上下文超限 | context length exceeded | prompt 太长、RAG 内容过多、历史未裁剪 | 否 | 裁剪上下文、做摘要压缩,动态计算 max_tokens |
| 限流 | 429 | RPM、TPM、RPS 或并发超限 | 是 | 指数退避、客户端限流、队列削峰 |
| 服务端错误 | 500 / 502 / 503 / 504 | 供应商服务波动、网关超时、模型负载高 | 是 | 有限重试,超过阈值后熔断或切换模型 |
| 网络错误 | timeout、connection reset | 网络出口问题、连接池异常、读取超时 | 是 | 设置 timeout、复用连接、检查出口网络 |
| 流式中断 | SSE 断开、输出半截 | 网络抖动、网关超时、客户端断开 | 视情况 | 记录 partial output,前端做超时兜底 |
| 输出格式错误 | JSON parse error、字段缺失 | 模型输出不稳定、约束不够强 | 可重试一次 | 使用 JSON mode、schema 校验和修复逻辑 |
| 内容安全拦截 | 内容为空、finish_reason 为 safety | 输入或输出触发安全策略 | 否 | 返回合规提示,优化输入审核 |
| 成本异常 | token 激增、账单异常 | 上下文失控、死循环重试、Key 泄露 | 否 | 预算告警、频控、Key 轮换、日志审计 |
大体结论很清楚:像 400、401、403、404、422 这类错误,通常不要重试;而 408、429、500、502、503、504 可以做有限重试。盲目重试不仅解决不了问题,还会让延迟和成本一起上升。
生产级重试策略:指数退避、jitter、幂等和熔断
一个真正能在线上用的重试策略,至少要回答几个问题:哪些错误可以重试?最多重试几次?每次间隔多久?一直失败之后怎么办?
最基础的分类可以这样写:
retryable_status={408,429,500,502,503,504}non_retryable_status={400,401,403,404,422}实际生产里,更推荐使用“指数退避 + 随机抖动”。比如第一次等 500ms,第二次等 1s,第三次等 2s,同时再叠加一点随机 jitter。这样可以避免大量请求在同一时间重新打到供应商接口,造成二次拥堵。重试次数一般控制在 2 到 3 次,具体要看业务 SLA、供应商限流规则和成本预算。
这里还有一个经常被忽略的问题:幂等性。
如果只是普通文本生成,失败后再试一次,风险通常还算可控。但如果大模型 API 触发了 function calling 或 tool calling,比如创建订单、扣减库存、发送消息,那就必须给外部动作加幂等键。否则一次模型调用失败,可能会变成多次真实业务写入,后果就比较麻烦了。
另外,当某个 provider 或某个模型连续出现大量 5xx、超时、流式中断时,不应该继续把流量往上打。更合理的做法是进入熔断状态。熔断后可以短时间切换到备用模型,也可以直接返回降级结果。等到半开恢复时,只放少量请求进去探测,确认稳定后再逐步恢复全部流量。
每一次重试都应该记录 attempt、error_type、status_code、latency、request_id、provider、model 和 token 用量。没有日志的重试,出了问题基本只能靠猜,线上排查会非常被动。
限流与并发控制:不要等 429 出来了才补救
不少团队会把大模型 API 性能优化理解成“把并发调高”。其实这很容易踩坑。并发太高不仅会触发 429,还可能让失败率升高,最后整体吞吐反而下降。
限流时至少要区分几个概念:
- RPM:每分钟请求数;
- RPS:每秒请求数;
- TPM:每分钟 token 数;
- 并发数:同一时间正在处理的请求数量。
只控制请求数远远不够。两个请求的成本可能差很多:一个可能只是 200 token 的分类任务,另一个可能是 10 万字长文总结。后者更容易触发 TPM 或上下文长度限制。
更稳妥的方式,是在客户端主动做限流:同时控制请求数、并发数、输入 token 和预计输出 token。在线聊天类请求优先保证低延迟,可以设置更短的超时,并使用流式输出;批量总结、批量改写这类任务,则更适合进入异步队列,由 worker 按配额慢慢消费;低优先级任务在高峰期可以延后处理。
如果是多租户系统,还要做租户级限流,避免某个用户或某个客户把全部额度打满。企业应用里,高优先级任务和低优先级任务最好分队列,不然很容易互相影响。
性能优化先看指标:TTFT、P95、token/s、缓存命中率
优化大模型 API,不能只盯着平均响应时间。平均值经常会掩盖问题,尤其是线上长尾请求。更值得关注的是 P95、P99 和错误率。
下面这些指标建议长期监控:
| 指标 | 含义 | 优化方向 |
|---|---|---|
| TTFT | 首 token 延迟 | 使用流式输出、缩短 prompt、减少排队时间 |
| Total Latency | 总响应时间 | 控制输入和输出 token,选择合适模型 |
| token/s | 生成速度 | 观察模型能力、供应商负载和网络状况 |
| P95 / P99 | 慢请求体验 | 发现高峰期问题、长尾任务和供应商波动 |
| 429 Rate | 限流比例 | 调整客户端限流、队列和配额 |
| 5xx Rate | 服务端错误比例 | 重试、熔断、启用备用模型 |
| Cache Hit Rate | 缓存命中率 | 优化缓存 key 和适用场景 |
| Cost per Request | 单次请求成本 | 控制 token、减少重试、做模型分层路由 |
首 token 延迟对聊天类产品尤其关键。即使总耗时没有明显变化,流式响应也能让用户更早看到结果,体感会好很多。不过流式输出并不代表性能问题就消失了,后端仍然要监控 TTFT、完整输出耗时,以及 stream_interrupted 这类中断情况。
降低延迟的 8 个实用方法
第一,用流式响应。聊天、写作、问答这类场景,用 SSE 或 stream 可以让用户更早看到内容,明显降低等待感。
第二,缩短 prompt。把无效背景、重复规则、过长示例删掉,很多时候比单纯提高并发更有效。
第三,控制 max_tokens。不要所有任务都给一个很大的输出上限。分类、抽取、标签生成这类任务,本来就应该限制输出长度。
第四,把历史对话摘要化。多轮对话不要无限拼接历史。通常可以保留最近几轮,再用摘要承载长期上下文。
第五,RAG 要控制 top_k 和 chunk 长度。检索结果不是越多越好。塞太多上下文,不仅会增加 TTFT 和成本,还可能提高幻觉风险。
第六,简单任务交给小模型。比如意图识别、分类、短文本改写等,可以优先用低成本、低延迟模型。真正需要复杂推理时,再升级到更强的模型。
第七,复用连接池。服务端调用大模型 API 时,要配置 HTTP 连接池,并设置合理的 connect timeout、read timeout 和 total timeout,避免每次都重新建连。
第八,缓存高频请求。FAQ、固定知识库问答、分类标签、模板化改写等场景,都很适合做缓存。
降低成本的 7 个关键动作
成本优化的第一步,其实不是马上换更便宜的模型,而是先把 token 记录清楚。每次调用都应该记录 input_tokens、output_tokens、total_tokens、retry_count 和 cost_estimate。没有 token 日志,就很难判断钱到底花在哪里。
具体可以从这几件事入手:
第一,限制用户输入长度,避免恶意文本或异常长文本直接进入模型。
第二,对重复请求做缓存,减少相同 prompt 的重复调用。
第三,使用模型分层路由。简单任务走小模型,复杂任务再走强模型。
第四,避免无效重试,尤其是 400、401、403、上下文超限这类本来就不该重试的错误。
第五,管理 prompt 模板版本,避免一次模板变更导致 token 用量突然暴涨。
第六,长文本任务做分块、摘要和合并,不要一次性把内容全部塞进上下文。
第七,设置预算告警、单用户频控和异常用量监控。
需要注意的是,多 key、多线路、多供应商路由确实能提升可用性,但不能把它理解成“可以无限调用”。不同平台都有自己的配额、风控和使用政策,具体规则还是要以各平台最新说明为准。如果使用 ClaudeAPI 这类第三方 Claude API 兼容接入服务,也要明确它不是 Anthropic 官方服务;可以关注它在兼容接入、多线路选择、中文支持、企业充值、开票和基础技术协助等方面的能力,具体价格、额度和政策仍以官网最新说明为准。
缓存策略:缓存什么,怎么缓存,风险在哪里?
缓存不是把所有大模型 API 响应都存起来。比较适合缓存的场景包括 FAQ 问答、分类标签、固定 prompt 的文本改写、结构化抽取、固定知识库问答,以及批处理任务。
但也有很多场景不适合缓存,比如强实时问题、强个性化对话、包含敏感隐私的数据,以及随机性很高的创作类任务。
缓存 key 也不能只用用户输入文本。一个相对完整的 key,通常要包含这些信息:
- provider 和 model;
- prompt_template_version;
- 用户输入 hash;
- temperature、top_p、max_tokens;
- 工具版本;
- 知识库版本;
- 业务租户或权限范围。
缓存也会带来风险。比如旧答案可能已经不准确,权限隔离没做好可能造成数据泄露,模型升级后结果也可能和之前不一致。所以缓存需要 TTL、版本号、权限隔离和失效机制,不能只图省钱省时间。
输出不稳定怎么办:JSON、函数调用和结构化结果处理
很多生产流程都依赖结构化输出,比如分类、抽取、审核、表单填充和工具调用。这种情况下,不能直接相信模型返回的内容。
更稳妥的做法是:
- 优先使用供应商支持的 JSON mode、response_format 或 function calling;
- 明确 schema,限制字段名、字段类型和枚举值;
- 把 temperature 设低一些,提高输出稳定性;
- 对返回结果做 schema 校验;
- JSON 解析失败时,可以做一次自动修复或有限重试;
- 对外部工具调用参数再次校验,不要让模型直接决定高风险动作。
像“markdown 包着 JSON”“字段缺失”“最后多输出一段解释”这类问题,不能只靠 prompt 里写一句“请严格输出 JSON”。prompt 约束当然有用,但到了生产环境,还需要解析、校验、修复和兜底机制配合。
监控与日志:上线后必须记录哪些字段?
大模型 API 的线上问题,通常很难靠用户截图定位。真正出了事故,还是要靠提前设计好的结构化日志。
建议记录这些字段:
| 字段 | 用途 |
|---|---|
| request_id | 串联一次完整调用 |
| user_id / tenant_id | 定位用户和租户级异常 |
| provider / model / endpoint | 区分供应商和模型问题 |
| prompt_template_version | 追踪 prompt 变更带来的影响 |
| input_tokens / output_tokens / total_tokens | 分析成本和上下文问题 |
| latency_ttft / latency_total | 分析首 token 和总耗时 |
| status_code / error_code | 做错误分类 |
| retry_count | 判断重试是否放大了问题 |
| finish_reason | 判断截断、安全拦截等情况 |
| cache_hit | 评估缓存效果 |
| stream_interrupted | 监控流式中断 |
| json_parse_success | 监控结构化输出稳定性 |
| cost_estimate | 粗略估算调用成本 |
告警可以先从这些指标做起:5xx 错误率、429 错误率、P95 / P99 延迟、TTFT 异常升高、token 用量异常、单用户调用异常、JSON 解析失败率、缓存命中率下降、备用模型切换次数。
另外,日志里不要记录完整的敏感 prompt。必要时做脱敏、截断或 hash,尤其是涉及用户隐私、商业数据、密钥等内容时,更要谨慎。
安全与成本避坑
API Key 绝对不能写在前端,也不要提交到 Git 仓库。生产环境里,应该使用环境变量、密钥管理服务或配置中心,并且尽量设置最小权限。对外提供能力时,最好在后端做代理层,不要让用户直接拿到真实 Key。
还需要做几类保护:
- 设置单用户、单租户、单 IP 的调用频率限制;
- 限制输入长度和文件大小;
- 对异常调用做风控;
- 定期轮换 API Key;
- 设置预算上限和费用告警;
- 对日志里的敏感信息做脱敏;
- 确认供应商的数据保留和合规策略。
很多安全问题并不是模型能力不够,而是工程边界没守住。一旦 Key 泄露,或者频控缺失,成本风险会被迅速放大。
上线前 Checklist:大模型 API 生产环境检查清单
- API Key 没有暴露在前端;
- API Key 没有提交到 Git;
- 已设置 connect timeout、read timeout 和 total timeout;
- 已区分可重试错误和不可重试错误;
- 已配置指数退避和 jitter;
- 已限制最大重试次数;
- 已配置客户端限流和并发控制;
- 在线请求和离线批处理已分队列;
- 已记录 input_tokens、output_tokens 和 total_tokens;
- 已配置 P95、P99 和 TTFT 监控;
- 已配置 429、5xx、timeout 告警;
- 已设置预算告警和异常用量监控;
- JSON 输出已有 schema 校验;
- 流式响应有中断检测和前端兜底;
- 已准备备用模型或降级策略;
- 模型和 prompt 变更有灰度机制;
- 日志已脱敏,不记录完整敏感输入。
总结:生产环境优化优先级
大模型 API 生产化可以按这个顺序推进:
第一,先做好 timeout、错误分类和有限重试,避免系统被单次调用卡死。
第二,再补上限流、队列和熔断,防止高峰期出现雪崩。
第三,建立性能指标体系,重点关注 TTFT、P95、P99、错误率和 token 用量。
第四,继续优化 prompt、上下文裁剪、缓存和模型分层路由。
第五,再完善成本治理、多供应商容灾、安全审计和灰度发布。
真正可靠的大模型 API 系统,不是永远不报错,而是每一种错误都有清楚的处理路径;也不是一味追求更高并发,而是在延迟、吞吐、稳定性和成本之间,做出可观测、可调整的工程取舍。