DEBUG.WIKI
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →

升级 openai 后 ChatCompletion.create 不能用了,调用和取值要一起改

OpenAI Python 1.0 迁移改变了 ChatCompletion 调用入口和响应类型。同步、异步请求与字典取值要一起检查,再分别验证客户端调用和结果读取。

升级 openai 后 ChatCompletion.create 不能用了,调用和取值要一起改

安装完依赖后,原本能跑的聊天代码突然停在 openai.ChatCompletion.create(...),提示:

You tried to access openai.ChatCompletion, but this is no longer supported in openai>=1.0.0

这是旧调用入口遇到了新版 SDK。故障定位到 Python 接口层时,不必先换模型、改提示词,也不用怀疑账号突然失效。

OpenAI Python 在 1.0 迁移中改用了显式客户端,并将响应改为模型对象。迁移不能只做一次字符串替换,还要检查异步调用和响应读取。官方 1.0 迁移指南

第一件事:确认运行的到底是哪份包

python -c 'import sys,openai; print(sys.executable); print(openai.__version__); print(openai.__file__)'

在日志对应的容器、虚拟环境或 Notebook 内执行。若终端里查到的版本与服务不同,先调整启动路径。项目中若有同名 openai.py 文件,也要检查是否遮蔽了安装包。后者通常会产生别的属性错误,不能仅凭名字相同就认定它是本次故障。

同步代码的最小迁移

下面是独立的待执行验收脚本。先给环境配置有效的 OPENAI_API_KEY 和账户可用的 OPENAI_MODEL;运行会发送请求并可能计费。

import os
from openai import OpenAI

with OpenAI(api_key=os.environ["OPENAI_API_KEY"]) as client:
    response = client.chat.completions.create(
        model=os.environ["OPENAI_MODEL"],
        messages=[{"role": "user", "content": "只回复 OK"}],
    )
    message = response.choices[0].message
    if message.content is not None:
        print(message.content)
    else:
        print("没有文本,请检查工具调用或拒绝分支")

这里有两处连着变:请求从客户端进入;返回值使用属性读取。如果请求已经成功,下一行才报对象不能下标访问,应接着改旧的 response["choices"],无需回退请求端点。

异步项目还要改掉 acreate

异步客户端使用 AsyncOpenAI,同名的 create() 是需要等待的异步方法。可以把上面的请求包在以下生命周期里:

import os
from openai import AsyncOpenAI

async def ask_once():
    async with AsyncOpenAI(
        api_key=os.environ["OPENAI_API_KEY"]
    ) as client:
        response = await client.chat.completions.create(
            model=os.environ["OPENAI_MODEL"],
            messages=[{"role": "user", "content": "只回复 OK"}],
        )
        return response.choices[0].message.content

独立脚本可用 asyncio.run(ask_once()) 启动;已有事件循环的框架里由调用方 await ask_once()。不要留下旧的 acreate,也别把同步客户端塞到异步服务后靠增加并发数补救。

迁移验收按路径拆开做

先搜索项目中的 ChatCompletion、acreate 和响应字典访问,再检查这些调用是否来自自己的代码或第三方封装。封装库内部保留旧接口时,需要一起处理其版本约束,不能只改入口脚本。

建议给聊天路径分别留一条正常文本、无文本内容、异常响应的测试。文件上传、音频、流式事件属于其他接口,聊天请求通过不代表它们也迁移完成。发布前从锁文件重建一次环境,可以及时发现开发机上“恰好能跑”的隐式依赖。

旧接口在 SDK 中有专门的兼容报错实现,报错本身已经指明了迁移方向。旧 API 报错源码 临时恢复旧依赖只能作为有回滚计划的救急操作,不应把永久锁到 0.28 当作完成迁移。