多模型 API 调用:一套代码同时调用 GPT、Claude 等大模型
💡 摘要:通过构建 MultiModelComparator 架构,抽象不同厂商 SDK 差异,实现并发调用多个大模型并对比响应内容、延迟和 Token 消耗。
引言
你在开发 AI 应用时,有没有遇到过这样的困扰:
- 用 GPT-4o 写的提示词,换成 Claude 效果就不一样
- 想同时测试多个模型的输出质量,但每个模型的 SDK 调用方式都不同
- 想知道哪个模型响应更快、更省 Token,但要手动一个个测
不同厂商的大模型 API 接口各不相同,调用方式、响应格式、参数名称都不一样。如果为每个模型写一套调用代码,不仅冗余,还难以维护和对比。
本文将教你如何用统一的架构,一套代码同时调用 GPT-4o、Claude 等多个模型,并自动生成对比报告。
核心概念
统一响应数据结构
要对比多个模型,首先需要统一的数据格式。不同厂商的 API 返回的数据结构差异很大:
| 字段 | OpenAI | Anthropic |
|---|---|---|
| 内容路径 | response.choices[0].message.content |
response.content[0].text |
| 输入 Token | response.usage.prompt_tokens |
response.usage.input_tokens |
| 输出 Token | response.usage.completion_tokens |
response.usage.output_tokens |
我们用一个 Python dataclass 来统一封装:
python
from dataclasses import dataclass
@dataclass
class ModelResponse:
"""模型响应数据结构"""
content: str # 模型输出内容
model_name: str # 模型名称
input_tokens: int # 输入 token 数
output_tokens: int # 输出 token 数
latency_ms: float # 响应延迟(毫秒)
💡 为什么用 dataclass?
自动提供
__init__、__repr__等方法,减少样板代码。比手写类简洁得多。
SDK 差异适配
不同厂商的 SDK 调用方式差异很大:
OpenAI GPT-4o:
python
client = AsyncOpenAI(api_key=api_key)
response = await client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": prompt}],
temperature=0.7
)
Anthropic Claude:
python
client = AsyncAnthropic(api_key=api_key)
response = await client.messages.create(
model="claude-3-5-sonnet-latest",
messages=[{"role": "user", "content": prompt}],
max_tokens=2048,
temperature=0.7
)
关键差异:
- OpenAI 用
chat.completions.create(),Claude 用messages.create() - Claude 必须指定
max_tokens,OpenAI 可选 - 响应内容的提取路径完全不同
异步并发调用
如果要同时调用多个模型,串行调用 意味着总时间 = 各模型延迟之和。使用异步并发可以让多个 API 调用同时发起,总时间 ≈ 最慢模型的延迟。
python
import asyncio
async def compare_responses(self, prompt: str) -> Dict[str, ModelResponse]:
"""同时调用多个模型并返回对比结果"""
tasks = [
self.query_gpt4o(prompt),
self.query_claude(prompt)
]
results = await asyncio.gather(*tasks)
return {r.model_name: r for r in results}
💡 asyncio.gather():同时启动多个异步任务,等待全部完成后统一返回结果。比串行快得多。
原理深入
MultiModelComparator 架构设计
整个对比框架采用工厂模式,每个模型对应一个独立的方法:
MultiModelComparator
├── query_gpt4o() → ModelResponse
├── query_claude() → ModelResponse
└── compare_responses() → Dict[str, ModelResponse]
设计优势:
- 扩展简单 :新增模型只需添加一个
query_xxx()方法,在compare_responses()中加入对应的 task - 统一返回 :所有方法都返回相同的
ModelResponse类型 - 异常隔离:单个模型失败不影响其他模型(可配合 try/except)
延迟测量
使用 time.time() 记录每个 API 调用的实际耗时:
python
start_time = time.time()
response = await client.chat.completions.create(...)
latency = (time.time() - start_time) * 1000 # 转换为毫秒
延迟测量包含:网络请求时间 + 模型推理时间 + 响应返回时间。
代码示例
完整实现
python
from typing import Dict
import os
from dataclasses import dataclass
from openai import AsyncOpenAI
import time
from anthropic import AsyncAnthropic
import asyncio
@dataclass
class ModelResponse:
"""模型响应数据结构"""
content: str
model_name: str
input_tokens: int
output_tokens: int
latency_ms: float
class MultiModelComparator:
"""多模型 API 统一调用类"""
def __init__(self):
# 从环境变量读取 API Key,避免硬编码
self.api_keys = {
'openai': os.getenv('OPENAI_API_KEY'),
'anthropic': os.getenv('ANTHROPIC_API_KEY'),
}
async def query_gpt4o(self, prompt: str) -> ModelResponse:
"""调用 GPT-4o 模型"""
start_time = time.time()
client = AsyncOpenAI(api_key=self.api_keys['openai'])
response = await client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": prompt}],
temperature=0.7
)
latency = (time.time() - start_time) * 1000
return ModelResponse(
content=response.choices[0].message.content,
model_name="gpt-4o",
input_tokens=response.usage.prompt_tokens,
output_tokens=response.usage.completion_tokens,
latency_ms=latency
)
async def query_claude(self, prompt: str) -> ModelResponse:
"""调用 Claude 3.5 Sonnet"""
start_time = time.time()
client = AsyncAnthropic(api_key=self.api_keys['anthropic'])
response = await client.messages.create(
model="claude-3-5-sonnet-latest",
messages=[{"role": "user", "content": prompt}],
max_tokens=2048,
temperature=0.7
)
latency = (time.time() - start_time) * 1000
return ModelResponse(
content=response.content[0].text,
model_name="claude-3.5-sonnet",
input_tokens=response.usage.input_tokens,
output_tokens=response.usage.output_tokens,
latency_ms=latency
)
async def compare_responses(self, prompt: str) -> Dict[str, ModelResponse]:
"""同时调用多个模型并返回对比结果"""
tasks = [
self.query_gpt4o(prompt),
self.query_claude(prompt)
]
results = await asyncio.gather(*tasks)
return {r.model_name: r for r in results}
运行测试与对比报告
python
async def main():
comparator = MultiModelComparator()
test_prompt = "用 Python 实现一个快速排序算法,并解释时间复杂度"
print("正在并发调用多个模型...")
results = await comparator.compare_responses(test_prompt)
# 打印对比报告
print("\n===== 模型对比报告 =====")
for model_name, response in results.items():
print(f"\n【{model_name}】")
print(f"响应时间:{response.latency_ms:.0f}ms")
print(f"输入 Token: {response.input_tokens}")
print(f"输出 Token: {response.output_tokens}")
print(f"内容预览:{response.content[:100]}...")
asyncio.run(main())
输出示例:
===== 模型对比报告 =====
【gpt-4o】
响应时间:1230ms
输入 Token: 45
输出 Token: 312
内容预览:def quick_sort(arr):
if len(arr) <= 1:
return arr
...
【claude-3.5-sonnet】
响应时间:980ms
输入 Token: 38
输出 Token: 285
内容预览:快速排序(Quicksort)是一种基于分治思想的高效排序算法...
实战应用
如何扩展更多模型?
只需添加新的查询方法,并在 compare_responses() 中注册:
python
async def query_gemini(self, prompt: str) -> ModelResponse:
"""调用 Google Gemini"""
start_time = time.time()
# Gemini SDK 调用代码...
latency = (time.time() - start_time) * 1000
return ModelResponse(...)
# 在 compare_responses 中添加
tasks = [
self.query_gpt4o(prompt),
self.query_claude(prompt),
self.query_gemini(prompt) # 新增
]
添加异常处理
单个模型失败不应影响其他模型:
python
async def query_gpt4o(self, prompt: str) -> ModelResponse:
try:
# ... 调用代码
return ModelResponse(...)
except Exception as e:
return ModelResponse(
content=f"调用失败:{str(e)}",
model_name="gpt-4o",
input_tokens=0,
output_tokens=0,
latency_ms=-1
)
最佳实践
- API Key 从环境变量读取 :使用
os.getenv()避免硬编码敏感信息 - 统一响应格式 :所有模型返回相同的
ModelResponse结构,便于后续处理 - 异步并发 :使用
asyncio.gather()减少总等待时间 - 异常隔离:单个模型失败不应影响其他模型的调用
- 延迟测量:包含网络请求 + 推理 + 响应的完整时间
- 温度统一 :对比时保持
temperature一致,否则输出风格差异会干扰判断
总结
多模型 API 调用的核心要点:
- 统一数据结构 :用
ModelResponsedataclass 封装不同模型的响应 - SDK 适配:OpenAI 和 Anthropic 的调用方式不同,需分别适配
- 异步并发 :
asyncio.gather()让多个 API 调用同时进行 - 对比报告:统一格式后,轻松对比响应内容、延迟和 Token 消耗
- 扩展简单:新增模型只需添加一个查询方法
掌握了多模型 API 调用,就能高效对比不同模型的性能和输出质量,为应用选择最合适的模型。