使用AsyncOpenAI通过LLM Proxy网关异步调用多种大模型的实践指南
1. 引言
随着大型语言模型(LLM)的快速发展,开发者需要集成多种模型(如GPT-4、Claude、Llama等)以满足不同场景的需求。然而,各家模型提供商往往提供差异化的API接口,导致集成工作复杂且重复。LLM Proxy网关应运而生,它作为统一接入层,对外暴露与OpenAI兼容的API,内部根据请求路由到不同的后端模型,大大简化了多模型调用的复杂度。
本文详细介绍了如何使用AsyncOpenAI通过LLM Proxy网关异步调用多种主流大模型。我们从异步编程原理出发,解释了网关的作用,并通过丰富的代码示例展示了基础调用、流式输出、多轮对话、错误重试及并发请求等实践技巧。借助网关的统一接口和异步编程的高效性,开发者可以轻松构建灵活、可扩展的多模型AI应用。
本文旨在详细介绍如何使用Python的openai库中的AsyncOpenAI类,通过LLM Proxy网关异步调用多种主流大模型。我们将深入探讨异步调用的原理、网关配置方法,并通过丰富的代码示例展示多种调用类型(包括非流式、流式、多轮对话、错误处理与重试等),帮助读者快速构建高效、健壮的AI应用。
2. 异步调用原理
2.1 异步IO与asyncio
异步编程基于事件循环,允许程序在等待I/O操作(如网络请求)时切换执行其他任务,从而提升并发性能。Python的asyncio库提供了协程支持,通过async/await关键字定义和等待异步操作,使单线程也能高效处理大量并发请求。
2.2 AsyncOpenAI的工作机制
AsyncOpenAI是OpenAI官方Python库(版本≥1.0)提供的异步客户端,内部基于httpx.AsyncClient实现非阻塞HTTP请求。当调用await client.chat.completions.create(...)时,当前协程会挂起,直到HTTP响应返回,期间事件循环可以处理其他任务。这使得在大量请求场景下能充分利用系统资源,避免线程阻塞。
2.3 LLM Proxy网关的路由原理
LLM Proxy网关作为中间层,接收符合OpenAI格式的请求(例如/v1/chat/completions),根据请求中的model字段将请求转发到对应的后端服务,并完成必要的协议转换。例如,一个model="claude-2"的请求可能被转换为Anthropic Claude的API格式。这样,客户端只需维护一套API调用逻辑,即可无缝切换和组合多种模型。
3. 配置LLM Proxy网关
在使用AsyncOpenAI之前,需要将客户端指向网关地址,并提供网关要求的API密钥(用于认证和计费)。典型配置如下:
from openai import AsyncOpenAI
client = AsyncOpenAI(
base_url="https://your-llm-proxy-gateway.com/v1", # 网关的OpenAI兼容端点
api_key="your-gateway-api-key" # 网关认证密钥
)
网关通常定义了一套模型名称映射规则,客户端只需指定逻辑模型名,网关会自动路由到实际后端。以下是一个假设的映射示例:
| 客户端指定的model | 实际后端模型 |
|---|---|
| gpt-4 | OpenAI GPT-4 |
| gpt-3.5-turbo | OpenAI GPT-3.5 |
| claude-2 | Anthropic Claude 2 |
| llama2 | Meta Llama 2 |
注意:实际网关的模型名称可能有所不同,请根据具体网关文档配置。
4. 多种异步调用方法详解
下面我们将介绍几种常见的异步调用模式,每种模式都适用于不同场景。
4.1 基础完成调用(非流式)
发送单轮对话,等待完整响应后返回内容。适合对响应时间不敏感、需要一次性获取完整结果的场景。
关键参数:
model: 模型名称(由网关定义)messages: 对话消息列表(支持system、user、assistant角色)max_tokens: 生成的最大token数temperature: 控制随机性(0~2)
4.2 流式完成调用
通过设置stream=True,响应将以迭代块的形式返回,客户端可以逐块接收并实时展示,提升用户体验。使用async for遍历流式响应。
4.3 多轮对话
通过维护消息列表(包含历史对话),可以实现上下文连贯的多轮对话。每次用户输入后,将之前的助手回复追加到消息列表中,再发起新请求。
4.4 函数调用(可选)
部分模型(如GPT-4)支持函数调用,允许模型输出结构化数据以触发外部工具。网关如果支持函数调用格式,可在请求中传递functions参数。但不同模型对函数调用的支持程度不同,需查阅网关文档确认。
4.5 错误处理与重试
网络波动、限流或服务不可用可能导致请求失败。应使用try-except捕获异常(如APIError、APITimeoutError),并结合指数退避策略实现重试。
4.6 超时控制
通过timeout参数设置请求超时时间(如timeout=30.0),防止长时间阻塞。超时设置可以传递给客户端或单次请求。
5. 完整代码示例
本节将展示一个完整的Python脚本,涵盖上述多种调用模式。请确保已安装openai库(≥1.0):
pip install openai
5.1 定义通用异步函数
我们首先定义一个通用的异步函数,用于发起聊天完成请求,并处理基本错误。
import asyncio
from openai import AsyncOpenAI, APIError, APITimeoutError
# 网关配置(请替换为实际值)
GATEWAY_BASE_URL = "https://your-llm-proxy-gateway.com/v1"
GATEWAY_API_KEY = "your-gateway-api-key"
async def create_chat_completion(
model: str,
messages: list,
max_tokens: int = 100,
temperature: float = 0.7,
stream: bool = False,
timeout: float = 30.0
):
"""
通用异步聊天完成函数
"""
client = AsyncOpenAI(
base_url=GATEWAY_BASE_URL,
api_key=GATEWAY_API_KEY,
timeout=timeout
)
try:
response = await client.chat.completions.create(
model=model,
messages=messages,
max_tokens=max_tokens,
temperature=temperature,
stream=stream
)
return response
except APITimeoutError:
print(f"请求超时 ({timeout}s)")
raise
except APIError as e:
print(f"API错误: {e}")
raise
except Exception as e:
print(f"未知错误: {e}")
raise
5.2 非流式调用示例:比较多个模型的响应
以下示例向多个模型发送相同的问题,并打印每个模型的回复。
async def non_stream_example():
messages = [
{"role": "system", "content": "你是一个有帮助的助手。"},
{"role": "user", "content": "用一句话解释什么是异步编程。"}
]
models = ["gpt-4", "gpt-3.5-turbo", "claude-2", "llama2"]
for model in models:
try:
response = await create_chat_completion(
model=model,
messages=messages,
max_tokens=50
)
content = response.choices[0].message.content
print(f"{model} 响应:\n{content}\n{'-'*40}")
except Exception:
print(f"{model} 调用失败,跳过\n{'-'*40}")
5.3 流式调用示例:实时输出内容
流式调用特别适合聊天机器人或需要即时反馈的场景。
async def stream_example():
messages = [
{"role": "user", "content": "讲一个简短的笑话。"}
]
model = "gpt-3.5-turbo" # 可替换为其他支持流式的模型
response = await create_chat_completion(
model=model,
messages=messages,
max_tokens=100,
stream=True
)
print(f"{model} 流式响应:")
async for chunk in response:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
print("\n" + "-"*40)
5.4 多轮对话示例:维持上下文
通过维护消息列表,实现多轮交互。
async def multi_turn_example():
conversation = [
{"role": "system", "content": "你是一个旅游顾问。"},
{"role": "user", "content": "推荐一个适合夏季旅游的海滨城市。"},
]
model = "claude-2"
# 第一轮
response1 = await create_chat_completion(
model=model,
messages=conversation,
max_tokens=150
)
assistant_reply = response1.choices[0].message.content
print(f"助手: {assistant_reply}")
# 追加助手回复和用户新问题
conversation.append({"role": "assistant", "content": assistant_reply})
conversation.append({"role": "user", "content": "那里的美食有什么特色?"})
# 第二轮
response2 = await create_chat_completion(
model=model,
messages=conversation,
max_tokens=150
)
print(f"助手: {response2.choices[0].message.content}")
5.5 带重试逻辑的调用
封装一个重试装饰器或函数,实现指数退避重试。
async def call_with_retry(model, messages, max_retries=3):
for attempt in range(max_retries):
try:
response = await create_chat_completion(model, messages, max_tokens=100)
return response.choices[0].message.content
except Exception as e:
print(f"第{attempt+1}次尝试失败: {e}")
if attempt == max_retries - 1:
raise
await asyncio.sleep(2 ** attempt) # 指数退避
async def retry_example():
messages = [{"role": "user", "content": "你好!"}]
result = await call_with_retry("gpt-3.5-turbo", messages)
print(result)
5.6 并发调用多个模型
利用asyncio.gather同时向多个模型发起请求,提升效率。
async def concurrent_example():
messages = [{"role": "user", "content": "什么是量子计算?"}]
models = ["gpt-4", "claude-2", "llama2"]
tasks = [create_chat_completion(model, messages, max_tokens=80) for model in models]
results = await asyncio.gather(*tasks, return_exceptions=True)
for model, result in zip(models, results):
if isinstance(result, Exception):
print(f"{model} 出错: {result}")
else:
print(f"{model}: {result.choices[0].message.content[:100]}...")
print("-"*40)
5.7 主函数运行所有示例
async def main():
print("=== 非流式调用 ===")
await non_stream_example()
print("\n=== 流式调用 ===")
await stream_example()
print("\n=== 多轮对话 ===")
await multi_turn_example()
print("\n=== 带重试的调用 ===")
await retry_example()
print("\n=== 并发调用 ===")
await concurrent_example()
if __name__ == "__main__":
asyncio.run(main())
6. 关键注意事项
- 网关兼容性:确保网关完整支持OpenAI聊天完成格式,特别是
stream模式和messages结构。部分网关可能对某些参数有限制,需查阅文档。 - 模型参数差异:不同模型对
max_tokens、temperature等参数的支持范围可能不同,建议为每个模型设置合理的默认值。 - 错误处理与重试:生产环境必须考虑网络抖动和限流,合理设置重试次数和退避策略,避免雪崩效应。
- 性能考量:异步调用可结合
asyncio.Semaphore控制并发度,防止网关过载或被限流。同时,适当设置超时避免资源浪费。 - 安全性:API密钥应通过环境变量或密钥管理服务注入,切勿硬编码在代码中。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)