跳到主要内容OpenRouter 实战:用一个接口调用多家 AI 模型 | 极客日志PythonAIjava
OpenRouter 实战:用一个接口调用多家 AI 模型
OpenRouter 把 OpenAI、Anthropic、Google、Mistral 等多家提供商的模型收进同一套接口,适合原型验证、模型对比和成本控制。文章给出了注册、开启免费模型权限、创建 API Key 的流程,并分别展示了 OpenAI SDK、直接 HTTP 请求和官方 Python SDK 的接法。随后覆盖免费模型、流式输出、多轮对话、代码生成、模型对比、参数调优和工具调用等常见场景,最后补了几类常见问题和更稳妥的使用习惯。
OpenRouter 实战:用一个接口调用多家 AI 模型
OpenRouter 到底解决什么问题
OpenRouter 不是某个单一模型,而是一个把多个 AI 提供商接到同一套接口上的聚合平台。对开发者来说,它更像一个转接层:拿着同一个 API 密钥、同一套请求格式,就能调用 OpenAI、Anthropic、Google、Mistral 等提供商的模型。平台里有 500+ 主流模型,也有一批带 :free 后缀的免费模型。
它最实用的地方,不是'模型多'这件事本身,而是你不用为了换模型重写一堆适配代码。原型阶段想试效果,直接切模型;线上想控成本,也可以按任务选更便宜的方案。遇到单一模型波动时,还能做故障切换,这比把所有东西绑在一家厂商上省心。

注册、开通免费模型和 API Key
先到 https://openrouter.ai 注册账号。支持 Google 登录,也能直接用邮箱注册,流程不复杂。
免费模型能不能用,关键不在代码,通常是账号里有个隐私选项没开。进入右上角头像的 Settings → Privacy,把 Agree to the free models data policy 勾上并保存。这个步骤漏掉了,后面即使请求写对了,也可能一直拿不到免费模型。
接着去 API Keys 页面创建密钥:
- 点击 Create Key
- 填一个名字,必要的话顺手设个额度限制
- 复制并保存好密钥
这个密钥只会显示一次,丢了就只能重新生成。
Python 里常用的三种调用方式
1)直接复用 OpenAI SDK
如果你已经在项目里用 OpenAI SDK,这种接法最顺手。OpenRouter 提供 OpenAI 兼容接口,改 base_url 和 api_key 就能跑。
import os
from openai import OpenAI
from dotenv import load_dotenv
load_dotenv()
client = OpenAI(
base_url="https://openrouter.ai/api/v1",
api_key=os.getenv("OPENROUTER_API_KEY"),
default_headers={
"HTTP-Referer": "https://your-website.com",
"X-Title": "Your App Name"
}
)
():
completion = client.chat.completions.create(
model=,
messages=[{: , : }]
)
(completion.choices[].message.content)
__name__ == :
asyncio
asyncio.run(main())
async
def
main
await
"openai/gpt-3.5-turbo"
"role"
"user"
"content"
"用一句话解释什么是人工智能?"
print
0
if
"__main__"
import
2)直接发 HTTP 请求
不想引入 SDK,requests 就够了。脚本工具、临时验证接口的时候,我更倾向用这种方式,少一层封装,排错也直接。
import requests
import os
import json
from dotenv import load_dotenv
load_dotenv()
url = "https://openrouter.ai/api/v1/chat/completions"
headers = {
"Authorization": f"Bearer {os.getenv('OPENROUTER_API_KEY')}",
"Content-Type": "application/json",
"HTTP-Referer": "https://your-website.com",
"X-Title": "Your App Name"
}
data = {
"model": "deepseek/deepseek-r1-distill-llama-70b:free",
"messages": [{"role": "user", "content": "推荐 3 本 Python 入门书籍"}]
}
response = requests.post(url, headers=headers, data=json.dumps(data))
result = response.json()
print(result["choices"][0]["message"]["content"])
3)使用 OpenRouter Python SDK
官方也有自己的 SDK,不过现在还是 Beta。接口体验会更贴近平台本身,但如果你已经在用 OpenAI SDK,它的优势没那么大,是否切过去主要看项目习惯。
from openrouter import OpenRouter
import os
from dotenv import load_dotenv
load_dotenv()
client = OpenRouter(
api_key=os.getenv("OPENROUTER_API_KEY"),
base_url="https://openrouter.ai/api/v1"
)
async def main():
response = await client.chat.completions.create(
model="mistralai/mistral-7b-instruct:free",
messages=[{"role": "user", "content": "什么是大语言模型?"}]
)
print(response.choices[0].message.content)
if __name__ == "__main__":
import asyncio
asyncio.run(main())
7 个常见场景,基本够你起步
免费模型先跑通
先用 :free 模型把链路打通最稳。学习阶段没必要一上来就烧付费模型,接口、权限、请求格式这几件事确认没问题之后,再换正式模型。
async def free_model_demo():
completion = await client.chat.completions.create(
model="mistralai/mistral-7b-instruct:free",
messages=[{"role": "user", "content": "写一首关于程序员的短诗"}]
)
print("免费模型结果:")
print(completion.choices[0].message.content)
if __name__ == "__main__":
import asyncio
asyncio.run(free_model_demo())
流式响应
聊天类应用里,流式输出比一次性返回更像'真的在生成'。用户不会盯着空白页等半天,这个体验差异很明显。
async def streaming_demo():
print("AI 正在思考,将实时显示结果:")
stream = await client.chat.completions.create(
model="openai/gpt-3.5-turbo",
messages=[{"role": "user", "content": "解释什么是流式响应?"}],
stream=True
)
async for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
if __name__ == "__main__":
import asyncio
asyncio.run(streaming_demo())
多轮对话
大模型本身不记事,连续对话靠你在代码里维护 messages。这部分没什么技巧,就是别把历史消息丢了。
async def multi_turn_demo():
messages = [
{"role": "system", "content": "你是一个友好的助手,擅长解释技术概念"},
{"role": "user", "content": "什么是 OpenRouter?"}
]
response = await client.chat.completions.create(
model="anthropic/claude-3-haiku",
messages=messages
)
assistant_msg = response.choices[0].message
print("AI:", assistant_msg.content)
messages.append(assistant_msg)
messages.append({"role": "user", "content": "它和直接调用 OpenAI API 有什么区别?"})
response2 = await client.chat.completions.create(
model="anthropic/claude-3-haiku",
messages=messages
)
print("AI:", response2.choices[0].message.content)
if __name__ == "__main__":
import asyncio
asyncio.run(multi_turn_demo())
代码生成和解释
如果是写业务逻辑、补注释、解释一段实现,代码模型通常更合适。这里 temperature 低一点,输出会稳一些。
async def code_generation_demo():
prompt = """
写一个 Python 函数,实现以下功能:
1. 接收一个列表作为输入
2. 计算列表中所有偶数的平方和
3. 返回结果
4. 添加详细注释
"""
response = await client.chat.completions.create(
model="deepseek/deepseek-coder-6.7b-instruct:free",
messages=[{"role": "user", "content": prompt}],
temperature=0.3
)
print("生成的代码:")
print(response.choices[0].message.content)
if __name__ == "__main__":
import asyncio
asyncio.run(code_generation_demo())
一行切换模型做对比
这是 OpenRouter 最好用的地方之一。你不用改请求结构,只要替换 model,就能看到不同模型在同一问题上的差异。做选型时,这比看宣传页靠谱得多。
async def model_comparison_demo():
prompt = "解释量子计算的基本原理,用简单易懂的语言"
models = ["openai/gpt-3.5-turbo", "anthropic/claude-3-haiku", "mistralai/mistral-7b-instruct:free"]
for model in models:
print(f"\n===== {model} =====")
response = await client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": prompt}]
)
print(response.choices[0].message.content[:200] + "...")
if __name__ == "__main__":
import asyncio
asyncio.run(model_comparison_demo())
参数调优
temperature 和 max_tokens 基本是最常调的两个参数。前者控制发散程度,后者控制长度;如果还想更收敛一点,再配合 top_p。
async def parameter_tuning_demo():
messages = [{"role": "user", "content": "写一个关于太空探索的故事"}]
print("=== 高随机性(temperature=0.9)===")
response1 = await client.chat.completions.create(
model="openai/gpt-3.5-turbo",
messages=messages,
temperature=0.9,
max_tokens=200
)
print(response1.choices[0].message.content)
print("\n=== 低随机性(temperature=0.1)===")
response2 = await client.chat.completions.create(
model="openai/gpt-3.5-turbo",
messages=messages,
temperature=0.1,
max_tokens=200,
top_p=0.1
)
print(response2.choices[0].message.content)
if __name__ == "__main__":
import asyncio
asyncio.run(parameter_tuning_demo())
工具调用
如果模型要接外部能力,比如查天气、查订单、读内部接口,工具调用就派上用场了。OpenRouter 可以走 MCP 或标准 Function Calling,写法和你熟悉的 OpenAI 工具调用差别不大。
async def tool_calling_demo():
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市名称"}
},
"required": ["city"]
}
}
}]
response = await client.chat.completions.create(
model="openai/gpt-3.5-turbo",
messages=[{"role": "user", "content": "北京今天的天气怎么样?"}],
tools=tools,
tool_choice="auto"
)
tool_calls = response.choices[0].message.tool_calls
if tool_calls:
print("需要调用工具:", tool_calls[0].function.name)
if __name__ == "__main__":
import asyncio
asyncio.run(tool_calling_demo())
常见坑和我会怎么处理
常见问题
- 免费模型不可用,先查隐私设置,别急着怀疑代码。
- API 调用失败时,优先看三件事:密钥、模型名、余额或频率限制。模型名可以去 https://openrouter.ai/models 查。
- 响应慢的时候,通常不是 OpenRouter 本身'坏了',更多是模型本身慢,或者输出太长。先缩短
max_tokens,再考虑换模型。
实际上更稳的做法
dotenv 管密钥,不要硬编码。
- 请求外面包一层
try-except,失败时至少能把错误信息打出来。
- 原型阶段先用免费模型;生产里按任务选模型,别默认永远最贵,也别为了省钱把体验打没了。
- 对话历史别无限堆,长了就是 token 成本。
- 多看控制台里的调用统计,很多时候问题不是'模型不行',而是你选型没对上任务。
还能继续往哪走
OpenRouter 跑通以后,后面可以做的事其实不少:批量请求、自定义路由、缓存常见结果、多模态模型接入,或者把它挂到 Web、桌面、移动端应用里。真正有价值的不是'接入了多少模型',而是你能不能把模型选择变成可控的工程决策。
总结
OpenRouter 的价值很朴素:把原本分散的模型接口收拢成一套,少写适配,方便切换,也方便比较。它特别适合原型验证、模型选型和成本控制;如果你的项目后面还会换模型,这种统一入口会省很多事。
相关免费在线工具
- RSA密钥对生成器
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
- Keycode 信息
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
- Escape 与 Native 编解码
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
- Mermaid 预览与可视化编辑
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
- JavaScript / HTML 格式化
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
- JavaScript 压缩与混淆
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online