共计 2226 个字符,预计需要花费 6 分钟才能阅读完成。
问题背景:为什么 API 调用会失败?
当 ChatGPT API 返回错误时,常见的失败模式可以归纳为以下几类(附典型错误码):

- HTTP 429:速率限制(默认 3,500 RPM/350K TPM),每个模型有独立配额
- HTTP 400:无效请求(如超出 max_tokens 限制,对话历史超过 16k 上下文)
- HTTP 503:服务不可用(OpenAI 服务器过载或维护)
- 内容截断:未正确处理 finish_reason 为 ”length” 的响应
技术方案实战
重试策略对比
- 指数退避(推荐)
- 首次失败后等待 1 秒,第二次 2 秒,第三次 4 秒 …
-
公式:
delay = min(base_delay * 2^attempt, max_delay) -
固定间隔
- 简单但可能加剧拥塞
- 适用于非瞬时错误(如配额重置)
# 带 Jitter 的重试装饰器实现
from functools import wraps
import random
import time
def retry_with_backoff(
max_retries: int = 3,
base_delay: float = 1.0,
max_delay: float = 10.0,
):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
attempt = 0
while attempt < max_retries:
try:
return func(*args, **kwargs)
except (RateLimitError, ServiceUnavailableError) as e:
attempt += 1
jitter = random.uniform(0, 0.1 * base_delay)
delay = min(base_delay * (2 ** attempt), max_delay) + jitter
time.sleep(delay)
except InvalidRequestError as e:
raise # 非瞬时错误直接抛出
raise MaxRetriesExceededError(f"Failed after {max_retries} attempts")
return wrapper
return decorator
内容分块处理
当响应被截断时(finish_reason=”length”),可采用以下分块策略:
- Token 计数分块
- 使用 tiktoken 库预估 token 消耗
-
保持每块低于 max_tokens 的 80%
-
语义分块
- 按段落 / 句子边界分割
- 用 NLTK/spaCy 检测语言边界
import tiktoken
def chunk_by_tokens(text: str, model: str, chunk_size: int = 2000) -> list[str]:
encoder = tiktoken.encoding_for_model(model)
tokens = encoder.encode(text)
return [encoder.decode(tokens[i : i + chunk_size])
for i in range(0, len(tokens), chunk_size)
]
生产级架构建议
监控指标设计
- 关键指标
- 请求成功率(按状态码分类)
- 平均重试次数(分位数统计)
-
Token 消耗速率(按模型分组)
-
Prometheus 示例
from prometheus_client import Counter, Histogram API_FAILURES = Counter('api_failures_total', 'Total API failures', ['status_code']) RETRY_HISTOGRAM = Histogram('request_retries', 'Retry attempts per request', buckets=[0, 1, 2, 3]) @retry_with_backoff() def call_api(): try: # API 调用逻辑 except APIError as e: API_FAILURES.labels(status_code=e.status_code).inc() raise
Kubernetes 优化
- HPA 配置
- 基于自定义指标(如请求排队时间)扩缩容
-
示例指标:
avg(rate(api_failures_total[5m])) by (pod)> 10 -
预热策略
- 启动时发送低优先级测试请求
- 使用 Readiness Probe 延迟流量接入
真实避坑案例
- Markdown 转义问题
- 问题:响应含未转义的 Markdown 符号导致 JSON 解析失败
-
修复:
json.dumps(text, ensure_ascii=False) -
长对话上下文丢失
- 问题:未正确处理对话历史导致逻辑断裂
-
修复:实现对话压缩算法(如提取关键实体)
-
代理服务器超时
- 问题:企业网络代理设置 1 分钟超时
- 修复:调整
requests会话超时参数
flowchart TD
A[发起请求] --> B{成功?}
B -->| 是 | C[返回结果]
B -->| 否 | D{错误类型?}
D -->|429/503| E[计算退避时间]
E --> F[等待 +Jitter]
F --> A
D -->|400| G[抛出业务异常]
总结建议
对于关键业务流,建议组合使用:
- 分层重试策略(客户端 + 服务端)
- 实时监控与告警(区分瞬时 / 持久错误)
- 定期更新 SDK 版本(OpenAI 频繁更新错误处理逻辑)
实际测试表明,采用指数退避 +Jitter 后,API 整体可用性可从 92% 提升至 99.5%。最重要的是理解失败模式背后的原因,而非简单增加重试次数。
正文完
发表至: 未分类
近两天内
