先看现象。老项目把 openai 从 0.28 升到 1.40,启动就报 ModuleNotFoundError: No module named ‘openai.error’,代码里十几处 except openai.error.RateLimitError 全部失效,限流重试逻辑等于被删掉。

把日志和配置对完,能解释这个现象的基本就这几处。1.x 把异常类挪到了包顶层,不再有 error 子模块。还有一种是类名也改了,Timeout 变成 APITimeoutError。

还有一种情况,0.28 的全局 api_key 赋值方式被移除,必须实例化客户端。

另外,旧代码还引用 ChatCompletion 这类已被替换的类。

全局找出所有旧引用位置

findstr /s /n "openai.error" *.py

接着确认新版本里异常类的实际名字

python -c "import openai;print(openai.RateLimitError, openai.APITimeoutError)"

再往下改成实例化客户端并显式传 key

python -c "from openai import OpenAI;c=OpenAI(api_key='sk-x',timeout=30);print(c.base_url)"

等前面都确认过,再跑一次冒烟确认调用链正常

python -c "from openai import OpenAI;print([m.id for m in OpenAI().models.list().data][:3])"

中间停过一次,把已经改的东西回滚干净,再重新来一遍。

恢复的判定其实很直接。启动不再报 ModuleNotFoundError,触发 429 时能进入 RateLimitError 的重试分支,冒烟请求能列出模型。

1.x 的异常都继承自 OpenAIError,捕获得太宽会把参数错误一起吞掉,按具体类型分层更安全。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。

作者 9823189