面向GPT、Claude、Grok三种大模型,设计统一调用封装类,仅需切换模型标识即可自动适配各SDK的入参、响应解析与异常捕获,内置超时与重试机制,返回标准化字典结构,大幅降低多模型切换的维护成本,适合批量开发与API网关场景。
做AI开发的朋友都知道,切换不同大模型时各家SDK的入参、返回格式、异常处理差异巨大,每次都要改大量代码,维护成本高得离谱。无论是OpenAI GPT、Anthropic Claude,还是XAI Grok,没有一个统一的标准。今天分享一个统一调用类的封装,仅需切换模型标识,底层自动适配三家模型的参数、响应解析与异常捕获,同时内置超时、重试和统一返回结构。适合批量开发、API网关中转等场景,不用再为每个模型单独写一套调用逻辑。

长期稳定更新的攒劲资源: >>>点此立即查看<<<
# 安装三家官方SDK
pip install openai anthropic xai python-dotenv
环境版本:
使用.env文件统一管理各家密钥,避免硬编码密钥,方便多环境切换。新建 .env 文件:
# OpenAI GPT
OPENAI_API_KEY=sk-xxx
# Claude
ANTHROPIC_API_KEY=sk-ant-xxx
# Grok
XAI_API_KEY=xai-xxx
import os
import time
from dotenv import load_dotenv
from openai import OpenAI, APIError, APIConnectionError, RateLimitError
from anthropic import Anthropic, APIError as AnthropicAPIError
from xai import Xai, APIError as XaiAPIError
# 加载环境变量
load_dotenv()
class UnifiedAIClient:
"""
多模型统一调用封装
支持:GPT / Claude / Grok
对外统一 chat_completion 方法,入参、返回格式标准化
"""
def __init__(self, model_type: str):
"""
初始化客户端
:param model_type: 模型类型,可选值 gpt / claude / grok
"""
self.model_type = model_type.lower()
self.client = None
self._init_client()
def _init_client(self):
"""根据模型类型初始化对应SDK客户端"""
if self.model_type == "gpt":
self.client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
elif self.model_type == "claude":
self.client = Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))
elif self.model_type == "grok":
self.client = Xai(api_key=os.getenv("XAI_API_KEY"))
else:
raise ValueError("model_type 仅支持 gpt / claude / grok")
def chat_completion(
self,
messages: list,
model_name: str,
temperature: float = 0.1,
max_tokens: int = 1024,
retry_times: int = 2,
timeout: int = 30
) -> dict:
"""
统一对话入口
:param messages: 消息列表 [{"role":"user","content":"xxx"}]
:param model_name: 模型名称 gpt-3.5-turbo / claude-3-haiku / grok-2
:param temperature: 随机性 0~1
:param max_tokens: 最大输出长度
:param retry_times: 失败重试次数
:param timeout: 请求超时时间
:return: 标准化返回字典 {"code":0, "content":"文本", "usage":{消耗统计}}
"""
err_msg = ""
for i in range(retry_times + 1):
try:
if self.model_type == "gpt":
return self._call_gpt(messages, model_name, temperature, max_tokens, timeout)
elif self.model_type == "claude":
return self._call_claude(messages, model_name, temperature, max_tokens, timeout)
elif self.model_type == "grok":
return self._call_grok(messages, model_name, temperature, max_tokens, timeout)
except (RateLimitError, APIConnectionError, APIError, AnthropicAPIError, XaiAPIError) as e:
err_msg = str(e)
# 限流/网络异常延时重试
time.sleep(1.5)
continue
# 多次重试全部失败
return {
"code": -1,
"content": f"请求失败,重试{retry_times}次均报错:{err_msg}",
"usage": {}
}
def _call_gpt(self, messages, model, temp, max_tok, timeout):
"""内部:调用GPT接口并标准化返回"""
resp = self.client.chat.completions.create(
model=model,
messages=messages,
temperature=temp,
max_tokens=max_tok,
timeout=timeout
)
return {
"code": 0,
"content": resp.choices[0].message.content.strip(),
"usage": {
"prompt_tokens": resp.usage.prompt_tokens,
"completion_tokens": resp.usage.completion_tokens,
"total_tokens": resp.usage.total_tokens
}
}
def _call_claude(self, messages, model, temp, max_tok, timeout):
"""内部:调用Claude并适配参数、标准化返回"""
resp = self.client.messages.create(
model=model,
messages=messages,
temperature=temp,
max_tokens=max_tok,
timeout=timeout
)
return {
"code": 0,
"content": resp.content[0].text.strip(),
"usage": {
"prompt_tokens": resp.usage.input_tokens,
"completion_tokens": resp.usage.output_tokens,
"total_tokens": resp.usage.input_tokens + resp.usage.output_tokens
}
}
def _call_grok(self, messages, model, temp, max_tok, timeout):
"""内部:调用Grok,参数格式与GPT完全兼容"""
resp = self.client.chat.completions.create(
model=model,
messages=messages,
temperature=temp,
max_tokens=max_tok,
timeout=timeout
)
return {
"code": 0,
"content": resp.choices[0].message.content.strip(),
"usage": {
"prompt_tokens": resp.usage.prompt_tokens,
"completion_tokens": resp.usage.completion_tokens,
"total_tokens": resp.usage.total_tokens
}
}
# ==================== 使用示例 ====================
if __name__ == "__main__":
test_msg = [
{"role": "user", "content": "用Python写一个批量读取Excel的工具类"}
]
# 1. 调用GPT
gpt_client = UnifiedAIClient(model_type="gpt")
gpt_res = gpt_client.chat_completion(messages=test_msg, model_name="gpt-3.5-turbo")
print("GPT返回:", gpt_res["content"])
print("消耗统计:", gpt_res["usage"])
# 2. 调用Claude
claude_client = UnifiedAIClient(model_type="claude")
claude_res = claude_client.chat_completion(messages=test_msg, model_name="claude-3-haiku-20240307")
print("Claude返回:", claude_res["content"])
# 3. 调用Grok
grok_client = UnifiedAIClient(model_type="grok")
grok_res = grok_client.chat_completion(messages=test_msg, model_name="grok-2")
print("Grok返回:", grok_res["content"])
三家模型消息列表 messages 格式完全通用,不用适配各家差异化 role 参数。直接传入标准的 [{"role": "user", "content": "..."}] 即可,底层自动映射。
无论调用哪个模型,返回字典结构一致:code 状态码、content 文本内容、usage token 消耗统计。上层业务无需分别解析,直接拿 result["content"] 就能用。
捕获限流(429)、网络超时、接口报错,自动延时重试。批量脚本里大幅降低崩溃概率,再也不用担心单次请求失败导致整个流程中断。
屏蔽各家 SDK 独有的异常类,对外只通过 code=-1 标识失败,错误信息统一输出。上层代码只需判断 code 即可,不需要 import 一堆异常类型。
后续新增模型(比如 Gemini、DeepSeek 等)只需在类里新增 _call_xxx 方法,对外调用函数 chat_completion 完全不用改动。这种设计堪称“开闭原则”的典范。
报错:InvalidRequestError: Unexpected parameter messages
原因:早期 Claude SDK 入参结构和 GPT 差异极大,不能直接复用 GPT 调用逻辑。
解决方案:单独封装 _call_claude 做参数适配,统一上层调用入口。注意 messages 的格式以及 max_tokens 参数名别搞混。
GPT:prompt_tokens / completion_tokens
Claude:input_tokens / output_tokens
统一封装后自动映射字段,对外输出相同 key(prompt_tokens, completion_tokens, total_tokens),方便做计费统计、额度管控。
单模型单密钥并发有限,单纯加 sleep 效率极低。拓展思路:可在此类封装基础上搭建密钥池调度,自动切换可用渠道,解决高频调用限流问题。比如维护一个 key_list,遇到限流自动轮换下一个 key。
这套封装非常适合作为中转网关的基础组件,以下几个方向可以进一步打磨:
这套统一封装的核心价值在于:消除多模型切换的重复代码,让开发者专注于业务逻辑而非底层 API 适配。标准化返回结构极大降低了上层业务维护成本,而自带的重试与异常捕获机制,让稳定性远高于原生单模型调用。如果是高频批量调用场景,可在此基础上扩展多渠道调度池,解决限流、成本、网络三大痛点。一句话:一次封装,搞定所有主流大模型。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述