Azure OpenAI代理:无缝迁移OpenAI应用到Azure云服务
1. 项目概述如果你正在使用或开发基于OpenAI官方API的应用比如各种ChatGPT Web UI、LangChain应用但同时又想利用微软Azure OpenAI Service在合规性、稳定性、网络延迟或成本控制上的优势那么你大概率会遇到一个头疼的问题这两者的API并不完全兼容。直接切换意味着你可能需要重写大量代码调整请求格式甚至改变整个调用逻辑。今天要聊的azure-openai-proxy就是为解决这个“甜蜜的烦恼”而生的。它是一个用Go语言编写的高性能反向代理核心使命只有一个将标准的OpenAI API请求无缝、透明地转换为Azure OpenAI API请求。简单来说它在你现有的、面向api.openai.com的应用和Azure OpenAI服务之间架起了一座桥梁。你的应用代码一行都不用改只需要把请求的目标地址从OpenAI官方端点换成这个代理服务的地址剩下的转换工作它会帮你全部搞定。无论是Chat Completions聊天补全、Completions文本补全还是Embeddings嵌入甚至是流式响应Streaming它都支持。这意味着你可以继续使用openai这个Python库、LangChain的OpenAI模块或者任何遵循OpenAI官方API规范的前端项目而背后实际调用的是你部署在Azure上的模型资源。我自己在将几个内部工具和实验项目从OpenAI官方接口迁移到Azure时就深刻体会到了这种兼容层的重要性。手动适配不仅繁琐而且容易出错尤其是在处理模型名称映射、API版本差异和认证方式时。azure-openai-proxy的出现让我几乎实现了“零成本”迁移把精力重新聚焦在业务逻辑本身。接下来我会结合自己的使用和部署经验为你详细拆解这个项目的设计思路、核心配置、多种部署方式以及在实际集成中可能遇到的“坑”和应对技巧。2. 核心设计思路与工作原理拆解在深入配置和部署之前理解azure-openai-proxy是如何工作的能帮助你在遇到问题时更快地定位和解决。它的设计哲学非常清晰扮演一个“翻译官”和“路由员”的角色。2.1 请求响应的完整转换流程当你向azure-openai-proxy发送一个标准的OpenAI API请求时它在内部会经历以下几个关键步骤接收与解析代理服务在8080端口默认监听HTTP请求。它接收到请求后首先会解析请求头特别是Authorization: Bearer key和请求体中的JSON数据。模型名称映射这是最核心的一步。你的请求体中通常会包含model: gpt-3.5-turbo这样的字段。但Azure OpenAI中你使用的是自己创建的部署名称Deployment Name比如my-gpt35-turbo-deployment。代理通过你预先配置的AZURE_OPENAI_MODEL_MAPPER环境变量或配置文件将gpt-3.5-turbo映射到my-gpt35-turbo-deployment。请求格式重构代理会按照Azure OpenAI REST API的格式重新组装HTTP请求。主要变化包括URL重构将原始路径如/v1/chat/completions结合Azure端点AZURE_OPENAI_ENDPOINT和API版本AZURE_OPENAI_API_VER重构成类似https://your-resource.openai.azure.com/openai/deployments/deployment-name/chat/completions?api-version2024-02-01的形式。请求头调整OpenAI使用Authorization: Bearer key而Azure OpenAI除了在URL中带api-key参数也支持在请求头中使用api-key。代理会妥善处理这种认证方式的转换。请求体微调移除或调整一些Azure不支持的字段如果有并确保model字段被替换为deployment_id或通过URL路径体现。转发与代理将重构后的请求转发到真正的Azure OpenAI服务端点。这里它还能智能地处理网络代理HTTP/SOCKS5这对于在某些网络环境下访问Azure服务非常有用。响应回传收到Azure的响应后代理会进行反向转换将响应格式“伪装”成OpenAI官方API的格式然后原路返回给你的客户端。对于流式响应stream: true它同样能保持数据流的完整性和正确格式。整个过程中你的客户端感知不到后端是Azure它始终认为自己是在和标准的OpenAI服务通信。这种透明性正是其价值所在。2.2 为何需要这样一个代理—— 差异的根源理解“为什么”需要代理比知道“怎么用”更重要。OpenAI官方API和Azure OpenAI API的主要差异体现在以下几个方面认证机制OpenAI主要使用Bearer Token在Authorization头中而Azure OpenAI使用API Key通常以api-key请求头或查询参数的形式传递。端点URL结构OpenAI的端点是统一的如https://api.openai.com/v1/...模型通过请求体中的model参数指定。Azure的端点则是每个资源唯一且模型部署名称是URL路径的一部分/deployments/deployment-name/...。API版本管理OpenAI API版本通过请求头如OpenAI-Beta或逐渐迭代的方式管理。Azure OpenAI则明确要求在URL中使用api-version查询参数来指定版本。模型标识符这是最大的障碍。OpenAI使用gpt-4gpt-3.5-turbo这类通用模型名。在Azure上你需要先创建一个模型部署并为其指定一个自定义的部署名称如prod-gpt-4后续所有调用都使用这个部署名。azure-openai-proxy的巧妙之处在于它用一层轻量的代理逻辑完美地弥合了这些差异让你无需关心底层的异构性。3. 环境准备与核心配置详解要让azure-openai-proxy跑起来你需要准备好Azure那边的“原料”并正确配置代理。我们分两步走。3.1 Azure OpenAI 资源准备与信息获取首先你需要在Azure门户中拥有一个已开通了OpenAI服务的资源组。假设你已经创建了一个名为my-openai-resource的资源位于East US区域。你需要收集以下三个核心信息它们就像打开Azure OpenAI大门的钥匙终结点Endpoint在哪里找在Azure门户中进入你的OpenAI资源在左侧菜单找到“密钥与终结点”Keys and Endpoint。格式类似于https://my-openai-resource.openai.azure.com/。注意末尾的斜杠通常不是必须的但保持一致是个好习惯。我的经验建议直接从“密钥与终结点”页面复制避免手动输入错误。这个端点是你所有部署的通用前缀。API 密钥API Key在哪里找和终结点在同一个页面。你会看到KEY1和KEY2两者功能相同可以轮换使用以提高安全性。重要提示这个密钥将作为你的应用或代理访问Azure OpenAI的凭证。务必像保护密码一样保护它不要直接提交到代码仓库。在配置代理时它通常不是直接给代理服务的而是由你的上游应用如ChatGPT-Next-Web在请求头中携带。部署名称Deployment Name与模型映射Model Mapper在哪里找在Azure门户中进入你的OpenAI资源在左侧菜单找到“模型部署”Model Deployments或“部署”Deployments。这里列出了你创建的所有模型部署。关键概念在Azure上你需要先选择一个基础模型如GPT-3.5-Turbo GPT-4然后为其创建一个“部署”。这个部署过程会要求你输入一个部署名称比如我习惯用gpt-35-turbo-001。这个名称就是你以后在API调用中实际使用的标识符。映射关系你的应用请求的是gpt-3.5-turbo但Azure只知道gpt-35-turbo-001。因此你需要告诉代理gpt-3.5-turbo对应gpt-35-turbo-001。这就是AZURE_OPENAI_MODEL_MAPPER环境变量的作用。实操心得部署命名技巧在为Azure模型部署命名时我建议包含一些有意义的标识例如gpt-35-turbo-prod用于生产环境的GPT-3.5。gpt-4-32k-dev用于开发测试的、支持32K上下文的GPT-4。text-embedding-ada-002-v1文本嵌入模型ada-002的第一个版本。 这样的命名在AZURE_OPENAI_MODEL_MAPPER中一目了然也便于后续管理和监控。3.2 代理服务的核心配置方式azure-openai-proxy支持两种主要的配置方式环境变量和配置文件。对于简单场景环境变量足够对于复杂场景如多模型、多端点配置文件更强大。方式一环境变量配置推荐用于单模型/单端点这是最直接的方式通过Docker运行容器时传入。核心环境变量有AZURE_OPENAI_ENDPOINT: 你的Azure OpenAI终结点。AZURE_OPENAI_API_VER: Azure OpenAI API版本例如2024-02-01。务必使用你的部署所支持的API版本可以在Azure OpenAI Studio的“代码视图”中查看。AZURE_OPENAI_MODEL_MAPPER: 模型映射关系。格式为OpenAI模型名Azure部署名。支持多个映射用英文逗号分隔。示例gpt-3.5-turbogpt-35-turbo-prod, gpt-4gpt-4-001, text-embedding-ada-002embedding-ada-002注意映射关系是单向的。当你的应用请求gpt-4模型时代理会将其路由到名为gpt-4-001的Azure部署。方式二配置文件YAML配置用于多模型/多端点当你需要将不同的OpenAI模型映射到不同Azure资源下的不同部署甚至使用不同的API密钥时配置文件提供了更精细的控制。一个典型的config.yaml文件如下所示api_base: /v1 deployment_config: - deployment_name: gpt-35-turbo-prod # Azure上的部署名 model_name: gpt-3.5-turbo # 对应的OpenAI官方模型名 endpoint: https://resource-a.openai.azure.com/ # 该部署所在的终结点 api_key: sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # 该资源对应的API密钥可选通常由上游应用提供 api_version: 2024-02-01 - deployment_name: gpt-4-eu model_name: gpt-4 endpoint: https://resource-b-europe.openai.azure.com/ # 另一个区域的终结点 api_key: sk-yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy api_version: 2024-02-01 - deployment_name: my-embeddings model_name: text-embedding-ada-002 endpoint: https://resource-a.openai.azure.com/ # 可以和第一个部署共用终结点 api_key: sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx api_version: 2024-02-01配置文件 vs 环境变量灵活性配置文件可以轻松管理多个完全独立的Azure资源配置而环境变量方式通常假定所有模型共享同一个端点和API版本。密钥管理在配置文件中可以指定api_key。但请注意更安全的做法是仍然让上游应用在请求头中传递密钥。配置文件中的api_key字段更像是一个“默认值”或“后备值”如果上游请求本身带有Authorization头代理会优先使用请求头中的密钥。将密钥写在配置文件中需确保文件本身的安全如通过Docker Secret或K8s ConfigMap管理。优先级如果同时提供了环境变量和配置文件代理的行为是怎样的根据项目实践和代码逻辑当使用配置文件启动时通过-c参数或默认路径配置文件的设置会覆盖环境变量的设置。对于在配置文件中定义了的模型映射会使用文件中的配置对于未在配置文件中定义的模型代理可能无法处理或回退到环境变量如果支持的话。最清晰的做法是二选一。4. 多种部署与集成方案实战理论讲完我们来点实际的。下面我将展示三种最常用的部署和集成方式从最简单的Docker运行到与流行前端项目的整合。4.1 基础部署使用Docker独立运行这是最快速的启动方式适合测试和简单应用。步骤1拉取镜像docker pull stulzq/azure-openai-proxy:latest步骤2运行容器使用环境变量假设你的Azure端点是https://my-aoai.openai.azure.com/部署映射是gpt-3.5-turbomy-gpt35-deployAPI版本是2024-02-01。docker run -d -p 8080:8080 \ --name aoai-proxy \ -e AZURE_OPENAI_ENDPOINThttps://my-aoai.openai.azure.com/ \ -e AZURE_OPENAI_API_VER2024-02-01 \ -e AZURE_OPENAI_MODEL_MAPPERgpt-3.5-turbomy-gpt35-deploy \ stulzq/azure-openai-proxy:latest这条命令做了以下几件事-d: 后台运行。-p 8080:8080: 将宿主机的8080端口映射到容器的8080端口代理服务默认端口。--name: 给容器起个名字方便管理。-e: 设置环境变量。步骤3测试代理服务容器运行后你可以用curl命令测试代理是否工作正常。注意下面的Your Azure OpenAI Key需要替换成你的真实API密钥KEY1或KEY2。curl --location --request POST http://localhost:8080/v1/chat/completions \ -H Authorization: Bearer Your Azure OpenAI Key \ -H Content-Type: application/json \ -d { model: gpt-3.5-turbo, messages: [ {role: user, content: Hello, how are you?} ], stream: false }如果一切正常你会收到一个格式与OpenAI官方API完全一致的JSON响应。步骤4使用配置文件运行如果你有复杂的配置可以先生成一个config.yaml文件然后通过卷挂载的方式提供给容器。# 假设config.yaml在当前目录 docker run -d -p 8080:8080 \ --name aoai-proxy \ -v $(pwd)/config.yaml:/app/config.yaml \ stulzq/azure-openai-proxy:latest这种方式更干净所有配置都集中在YAML文件里。4.2 集成方案一搭配 ChatGPT-Next-WebChatGPT-Next-Web 是一个设计优雅、功能丰富的ChatGPT Web UI。让它对接Azure OpenAI只需要修改几个环境变量。使用 docker-compose 编排创建一个docker-compose.yml文件内容如下。这种方案将代理和Web UI放在同一个Docker网络中让它们可以通过服务名azure-openai互相访问无需暴露代理端口到宿主机更安全。version: 3.8 services: chatgpt-next-web: image: yidadaa/chatgpt-next-web container_name: chatgpt-next-web ports: - 3000:3000 # 将Web UI映射到宿主机的3000端口 environment: OPENAI_API_KEY: sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # 这里填写你的Azure OpenAI API密钥 BASE_URL: http://azure-openai:8080 # 关键指向代理服务使用服务名和端口 CODE: # 访问密码为空则无需密码 HIDE_USER_API_KEY: 1 # 隐藏用户自行填写API Key的输入框 HIDE_BALANCE_QUERY: 1 # 隐藏余额查询Azure OpenAI无此概念 depends_on: - azure-openai networks: - chatgpt-network azure-openai: image: stulzq/azure-openai-proxy container_name: azure-openai-proxy # 注意这里没有映射端口到宿主机只在Docker网络内暴露 environment: AZURE_OPENAI_ENDPOINT: https://my-aoai.openai.azure.com/ AZURE_OPENAI_API_VER: 2024-02-01 AZURE_OPENAI_MODEL_MAPPER: gpt-3.5-turbomy-gpt35-deploy, gpt-4my-gpt4-deploy networks: - chatgpt-network networks: chatgpt-network: driver: bridge启动与访问在包含docker-compose.yml的目录下运行docker-compose up -d。等待片刻在浏览器中访问http://你的服务器IP:3000。在ChatGPT-Next-Web的界面中你应该可以直接开始对话。它发出的所有请求都会通过azure-openai-proxy服务转发到Azure。注意事项模型列表问题ChatGPT-Next-Web 在启动时会尝试调用/v1/models接口来获取可用的模型列表。Azure OpenAI的接口与此略有不同azure-openai-proxy可能会返回一个固定的或处理后的模型列表。有时前端可能无法正确显示你在AZURE_OPENAI_MODEL_MAPPER中配置的所有模型。如果遇到此问题可以尝试在前端设置中手动指定要使用的模型或者检查代理的日志看是否有错误。4.3 集成方案二搭配 LangChain 应用LangChain是一个用于开发LLM应用的强大框架。如果你现有的LangChain应用使用的是OpenAI的ChatOpenAI或OpenAI类迁移到Azure只需要修改openai_api_base参数。Python 代码示例假设你原来使用OpenAI的代码如下from langchain_openai import ChatOpenAI llm ChatOpenAI( modelgpt-3.5-turbo, openai_api_keyyour-openai-key, temperature0.9 )要切换到通过代理使用Azure OpenAI修改如下from langchain_openai import ChatOpenAI llm ChatOpenAI( modelgpt-3.5-turbo, # 这里仍然写OpenAI的模型名 openai_api_keyyour-azure-openai-key, # 替换为你的Azure API密钥 openai_api_basehttp://localhost:8080/v1, # 关键指向本地运行的代理 temperature0.9 )是的就这么简单。openai_api_base指向你的代理地址注意要包含/v1路径。model参数仍然使用OpenAI的模型名如gpt-3.5-turbo代理会自动将其映射到你在AZURE_OPENAI_MODEL_MAPPER中配置的Azure部署名。环境变量配置推荐更佳实践是通过环境变量配置提高代码的可移植性和安全性。export OPENAI_API_BASEhttp://localhost:8080/v1 export OPENAI_API_KEYyour-azure-openai-key然后在代码中可以不写这些参数LangChain会自动从环境变量读取。from langchain_openai import ChatOpenAI llm ChatOpenAI(modelgpt-3.5-turbo, temperature0.9) # api_base和api_key从环境变量获取5. 高级配置、问题排查与性能调优当项目从测试走向生产或者遇到一些复杂需求时以下几个高级主题和问题排查经验会非常有用。5.1 网络代理与复杂网络环境如果你的服务器无法直接访问Azure OpenAI的端点例如由于网络策略azure-openai-proxy支持配置上游代理。HTTP/HTTPS 代理docker run -d -p 8080:8080 \ --name aoai-proxy \ -e AZURE_OPENAI_ENDPOINThttps://my-aoai.openai.azure.com/ \ -e AZURE_OPENAI_HTTP_PROXYhttp://your-proxy-server:8080 \ ...其他环境变量... stulzq/azure-openai-proxy:latestSOCKS5 代理-e AZURE_OPENAI_SOCKS_PROXYsocks5://your-socks5-server:1080踩坑记录代理认证如果你的代理服务器需要用户名和密码认证格式应为http://username:passwordproxy-host:port。请务必对密码中的特殊字符进行URL编码例如符号应编码为%40否则解析会出错。5.2 常见问题排查速查表在实际部署和使用中你可能会遇到以下问题。这里提供一个快速排查指南。问题现象可能原因排查步骤与解决方案请求返回 401 未授权1. API密钥错误或过期。2. 密钥未正确传递。1. 检查Authorization: Bearer key请求头中的key是否正确是否为有效的Azure OpenAI API密钥。2. 如果是通过配置文件指定api_key检查该密钥是否有权限访问对应端点的部署。3. 在Azure门户中确认密钥未被禁用。请求返回 404 未找到1. Azure终结点Endpoint错误。2. 部署名称Deployment Name不存在或拼写错误。3. API版本不受支持。1. 仔细核对AZURE_OPENAI_ENDPOINT确保没有多余的空格或错误的字符。2. 在Azure门户的“部署”页面确认你配置的部署名如my-gpt35-deploy确实存在且状态为“成功”。3. 检查AZURE_OPENAI_API_VER确保使用的是你的部署所支持的API版本如2024-02-01。请求返回 400 错误请求1. 模型映射Mapper配置错误。2. 请求体中有Azure不支持的参数。1. 检查AZURE_OPENAI_MODEL_MAPPER的格式确保是openai-modelazure-deployment并且没有语法错误。2. 查看代理服务的日志docker logs aoai-proxy通常会有更详细的错误信息提示是哪个参数有问题。流式响应Streaming不工作或中断1. 网络连接不稳定或代理超时。2. 客户端处理流式响应的逻辑有问题。1. 检查代理容器和Azure服务之间的网络延迟和稳定性。2. 尝试在代理的Docker命令中增加超时环境变量如果项目支持或调整上游应用的超时设置。3. 使用简单的curl命令测试流式响应是否正常排除客户端代码问题。Docker容器启动后立即退出1. 关键环境变量缺失或格式错误。2. 配置文件路径错误或格式无效。1. 使用docker logs aoai-proxy查看容器退出前的日志通常会有明确的错误提示如“missing AZURE_OPENAI_ENDPOINT”。2. 检查docker run命令中的环境变量值是否正确用引号括起来特别是包含等号的AZURE_OPENAI_MODEL_MAPPER。3. 如果使用配置文件确认挂载路径正确且YAML文件语法无误。5.3 性能考量与监控建议对于生产环境除了功能正确还需要关注性能和稳定性。资源分配azure-openai-proxy本身是用Go编写的非常轻量通常不需要很多CPU和内存。为Docker容器分配1个CPU核心和512MB内存通常绰绰有余。真正的性能瓶颈和资源消耗主要发生在Azure OpenAI服务端。高可用与负载均衡如果你有非常高的并发需求可以考虑部署多个azure-openai-proxy实例并在前面加一个负载均衡器如Nginx。所有实例指向相同的Azure后端即可。日志与监控日志确保容器的日志被收集例如通过Docker的json-file日志驱动或直接输出到标准输出/错误由宿主机上的日志代理收集。日志对于排查问题至关重要。监控可以监控代理服务的几个关键指标请求速率与延迟通过访问日志或添加监控中间件来统计。错误率关注4xx和5xx状态码的比例。容器资源使用率CPU、内存。健康检查可以为代理服务添加一个简单的HTTP健康检查端点如果项目本身未提供可以定期用一个小请求测试/v1/models并与你的编排系统如Kubernetes集成实现故障自愈。5.4 安全加固建议任何暴露在网络上的服务都需要考虑安全。最小化暴露如非必要不要将azure-openai-proxy的端口默认8080直接暴露到公网。最佳实践是像前面docker-compose例子一样只在内网或Docker网络内访问前端通过Nginx等反向代理暴露。API密钥保护永远不要将API密钥硬编码在代码或配置文件中提交到版本控制系统。使用环境变量、Docker Secrets、Kubernetes Secrets或专业的密钥管理服务来传递密钥。请求限流与认证azure-openai-proxy本身是一个简单的代理不提供高级的限流或用户认证功能。如果你的服务需要对多用户提供且需要限制调用频率或进行用户隔离你需要在代理前面再部署一层网关如Kong, APISIX或编写简单的中间件来实现这些功能。使用HTTPS如果代理服务需要通过公网访问务必在代理前端配置TLS/SSL终止例如使用Nginx或Traefik使用HTTPS加密通信防止API密钥和对话内容被窃听。通过以上这些步骤你应该能够顺利部署并使用azure-openai-proxy将你的应用生态平滑地迁移到Azure OpenAI服务上享受其带来的企业级优势同时保留原有开发范式的便利。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2606805.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!