升级openai库导致的404错误排查记录

背景

OpenAI自从23年11月引入后就没有更新过,一直是0.27.0,近期由于项目需要想引入Agently框架,此框架依赖的OpenAI库较新,于是就需要升级OpenAI库。

新升级的OpenAI库版本为:

错误引出

升级完运行下,首先遇到了这个错误404 - {'error': {'code': '404', 'message': 'Resource not found'}},堆栈如下:

错误分析1

可以看出,在使用OpenAIEmbedding在进行向量嵌入时报的错,我们使用的是Azure部署的OpenAI服务,出现此错误一般是由于Azure Endpoint,Deployment,API Version,API Key,Model Version这几项信息中的某一项有问题。断点调试OpenAIEmbedding的URL如下:

复制代码
https://openaiquanshi.openai.azure.com//deployments/meeting-embedding/embeddings?api-version=2023-07-01-preview

直接用curl向这个URL发送请求,确实报了404:

复制代码
~ % curl -i -X POST -H 'Content-Length:100' 'https://openaiquanshi.openai.azure.com//deployments/meeting-embedding/embeddings?api-version=2023-07-01-preview'
HTTP/2 404 
content-length: 56
content-type: application/json
apim-request-id: 61063a5d-bb28-4299-a267-a8ddb8de870c
strict-transport-security: max-age=31536000; includeSubDomains; preload
x-content-type-options: nosniff
date: Wed, 17 Jul 2024 01:42:52 GMT

{"error":{"code":"404","message": "Resource not found"}}%     

**真实原因:**openai接口的URL Path存在版本兼容性,v1版本需要在域名后多加一个/openai用于区分azure和openai(如:https://xxx.openai.azure.com/openai),并且这个URL的修改openai库内部会自动完成。但是openai库内部有个逻辑:只有openai_api_base中没有/openai这个串时才会添加。代码如下所示:

python 复制代码
if is_openai_v1():
    # For backwards compatibility. Before openai v1, no distinction was made
    # between azure_endpoint and base_url (openai_api_base).
    openai_api_base = values["openai_api_base"]
    if openai_api_base and values["validate_base_url"]:
        if "/openai" not in openai_api_base:
            values["openai_api_base"] += "/openai"
            warnings.warn(
                "As of openai>=1.0.0, Azure endpoints should be specified via "
                f"the `azure_endpoint` param not `openai_api_base` "
                f"(or alias `base_url`). Updating `openai_api_base` from "
                f"{openai_api_base} to {values['openai_api_base']}."
            )

这里有个漏洞,由于azure的openai_api_base域名是由客户企业自己命名的,如果客户命名的域名以openai开头(如:https://openaixxx.openai.azure.com),openai库内部的URL拼接逻辑将不会执行到,最终v1+版本的openai库发出的请求却没有在域名后携带/openai, 导致404 Resource Not found

**解决办法:**模仿上面的方法,写一个函数is_openai_v1提前进行openai库的版本判断和URL修正。

python 复制代码
def is_openai_v1() -> bool:
    from importlib.metadata import version
    from packaging.version import Version, parse
    _version = parse(version("openai"))
    return _version >= Version("1.0.0")
   
api_base = os.environ["OPENAI_API_BASE"]
   
if is_openai_v1():
    api_base = os.path.join(api_base, "openai")

print(api_base)

输出的api_base如下:

python 复制代码
https://openaiquanshi.openai.azure.com/openai/deployments/meeting-embedding

错误分析2

api_base已经正确,但运行项目还是报404, 同时弹出了如下警告:

python 复制代码
=============================== warnings summary ===============================
/Users/a200007/work/ucgit/ucserver/summaryserver/venv/lib/python3.10/site-packages/langchain/embeddings/openai.py:319: UserWarning: If you have openai>=1.0.0 installed and are using Azure, please use the `AzureOpenAIEmbeddings` class.
    warnings.warn(

按照上面提示,对于azure,当openai库大于1.0.0时,我们需要使用AzureOpenAIEmbeddings代替OpenAIEmbeddings

python 复制代码
from langchain.embeddings.azure_openai import AzureOpenAIEmbeddings

api_base = os.environ["OPENAI_API_BASE"]

if is_openai_v1():
    api_base = os.path.join(api_base, "openai")

embedding_function = AzureOpenAIEmbeddings(
    deployment=embedding_deployment, 
    chunk_size=embedding_max_inputs,
    openai_api_base = api_base

使用此embedding_function做测试:

python 复制代码
tensor = embedding.embed_query("今天你去哪儿了?")
print(tensor)

> [0.0018476681179545632, -0.003048808135045326, 0.013323151742329006, -0.012344790841118551, -0.027643358824239652, 0.015491746640257776, -0.02547476299498829, -0.0032466613330973887, -0.03310223727411042, -0.017236592553203055, 0.012407106567011756, -0.005380982628351025, 0.00047866445067163386, ......(1535)]

错误分析3

继续运行,又报了404,这次是一个新的位置:

前面是embeddings的错误,这次是langchain中chat_models的错误,猜想应该都是URL兼容性的问题,于是在构造llm实例时,也加了openai版本的判断和url的处理:

python 复制代码
api_base = os.environ["OPENAI_API_BASE"]
if is_openai_v1():
	api_base = os.path.join(api_base, "openai")
llm = AzureChatOpenAI(
    temperature=0,
    max_tokens=4096,
    ......
    openai_api_base=api_base
)

这样修改后终于运行正常。

参考资料

相关推荐
楚兴3 分钟前
ACP 到底解决了什么?让 IDE 和 Coding Agent 解耦
人工智能·后端·架构
楚兴12 分钟前
DeepSeek Harness 到底在做什么?拆开 Agent 的运行时
人工智能·后端·架构
baopixiaoz14 分钟前
BeeQuant × BeeAgent:AI驱动智能交易
大数据·人工智能·python·区块链
名字还没想好☜18 分钟前
Go 标准库 flag 包实战:参数解析、子命令、自定义 Value 类型与默认值
开发语言·后端·golang·go
米花米唐20 分钟前
Spring AI 2.0 MCP服务器搭建与使用
后端
公爵爱学习23 分钟前
无人机定点飞行-介绍
开发语言·图像处理·python·学习·线性回归·无人机
stillstream_ink24 分钟前
OpenCart UI 自动化测试实战:POM 四层架构 + 失败自动截图 + 飞书通知
python·测试
databook27 分钟前
Beta 分布:如何用“成功”和“失败”来预测下次尝试
python·数据挖掘·数据分析
zhanghaha131436 分钟前
Python进阶教程:27_subprocess 模块 零基础超详细教程
开发语言·python
程序猿DD36 分钟前
OctaFuse Gateway 2.9.0:用户限流控制、自定义转发头与管理后台升级
后端·api