这将帮助你开始使用 OpenRouter 聊天模型 。OpenRouter 是一个统一的 API,通过单一端点提供对来自多个提供商(OpenAI、Anthropic、Google、Meta 等)模型的访问。
要获取可用模型的完整列表,请访问 OpenRouter 模型页面 。
集成详情
模型特性
要通过 OpenRouter 访问模型,你需要创建一个 OpenRouter 帐户 ,获取 API 密钥,并安装 langchain-openrouter 集成包。
LangChain OpenRouter 集成位于 langchain-openrouter 包中:
pip install -U langchain-openrouter
前往 OpenRouter 密钥页面 注册并生成 API 密钥。完成后,设置 OPENROUTER_API_KEY 环境变量:
import getpass
import os
if not os . getenv ( "OPENROUTER_API_KEY" ):
os . environ [ " OPENROUTER_API_KEY " ] = getpass . getpass ( "Enter your OpenRouter API key: " )
要启用模型调用的自动跟踪,请设置你的 LangSmith API 密钥:
os . environ [ " LANGSMITH_API_KEY " ] = getpass . getpass ( "Enter your LangSmith API key: " )
os . environ [ " LANGSMITH_TRACING " ] = "true"
实例化
现在我们可以实例化模型对象并生成聊天补全:
from langchain_openrouter import ChatOpenRouter
model = ChatOpenRouter (
model = "anthropic/claude-sonnet-4.5" ,
temperature = 0 ,
max_tokens = 1024 ,
max_retries = 2 ,
# 其他参数...
)
messages = [
(
"system" ,
"You are a helpful assistant that translates English to French. Translate the user sentence." ,
),
( "human" , "I love programming." ),
]
ai_msg = model . invoke ( messages )
ai_msg . content
"J'adore la programmation."
流式传输
for chunk in model . stream ( "Write a short poem about the sea." ):
print ( chunk . text , end = "" , flush = True )
也支持异步流式传输:
async for chunk in model . astream ( "Write a short poem about the sea." ):
print ( chunk . text , end = "" , flush = True )
工具调用
OpenRouter 使用与 OpenAI 兼容的工具调用格式。你可以描述工具及其参数,并让模型返回一个 JSON 对象,其中包含要调用的工具及其输入。
绑定工具
通过 ChatOpenRouter.bind_tools,你可以将 Pydantic 类、字典模式、LangChain 工具或函数作为工具传递给模型。在底层,这些会被转换为 OpenAI 工具模式,并在每次模型调用时传递。
from pydantic import BaseModel , Field
class GetWeather ( BaseModel ):
"""Get the current weather in a given location"""
location : str = Field ( description = "The city and state, e.g. San Francisco, CA" )
model_with_tools = model . bind_tools ([ GetWeather ])
ai_msg = model_with_tools . invoke (
"what is the weather like in San Francisco" ,
)
ai_msg
AIMessage(content='', response_metadata={'finish_reason': 'tool_calls'}, tool_calls=[{'name': 'GetWeather', 'args': {'location': 'San Francisco, CA'}, 'id': 'call_abc123', 'type': 'tool_call'}], usage_metadata={'input_tokens': 68, 'output_tokens': 17, 'total_tokens': 85})
工具调用
AIMessage 有一个 tool_calls 属性。它包含标准化格式的工具调用,与模型提供商无关。
[{'name': 'GetWeather',
'args': {'location': 'San Francisco, CA'},
'id': 'call_abc123',
'type': 'tool_call'}]
严格模式
传递 strict=True 以保证模型输出与工具定义中提供的 JSON Schema 完全匹配:
model_with_tools = model . bind_tools ([ GetWeather ], strict = True )
有关绑定工具和工具调用输出的更多信息,请前往 工具调用 文档。
结构化输出
ChatOpenRouter 支持通过 with_structured_output 方法进行结构化输出。有两种方法可用:function_calling(默认)和 json_schema。
使用 with_structured_output 生成结构化的模型响应。指定 method="json_schema" 以使用基于 JSON Schema 的结构化输出;否则该方法默认为函数调用。 from langchain_openrouter import ChatOpenRouter
from pydantic import BaseModel , Field
model = ChatOpenRouter ( model = "openai/gpt-5.4" )
class Movie ( BaseModel ):
"""A movie with details."""
title : str = Field ( description = "The title of the movie" )
year : int = Field ( description = "The year the movie was released" )
director : str = Field ( description = "The director of the movie" )
rating : float = Field ( description = "The movie's rating out of 10" )
structured_model = model . with_structured_output ( Movie , method = "json_schema" )
response = structured_model . invoke ( "Provide details about the movie Inception" )
response
Movie ( title = 'Inception' , year = 2010 , director = 'Christopher Nolan' , rating = 8.8 )
指定 response_format 并使用 ProviderStrategy 以在生成代理最终响应时启用结构化输出。 from langchain . agents import create_agent
from langchain . agents . structured_output import ProviderStrategy
from pydantic import BaseModel
class Weather ( BaseModel ):
temperature : float
condition : str
def weather_tool ( location : str ) -> str :
"""Get the weather at a location."""
return "Sunny and 75 degrees F."
agent = create_agent (
model = "openrouter:openai/gpt-5.4" ,
tools = [ weather_tool ],
response_format = ProviderStrategy ( Weather ),
)
result = agent . invoke ({
"messages" : [{ "role" : "user" , "content" : "What's the weather in SF?" }]
})
result [ " structured_response " ]
Weather ( temperature = 75.0 , condition = 'Sunny' )
你可以使用 function_calling 和 json_schema 方法传递 strict=True 以强制精确遵循模式。json_mode 不支持 strict 参数。
structured_model = model . with_structured_output ( Movie , method = "json_schema" , strict = True )
推理输出
对于支持推理的模型(例如 anthropic/claude-sonnet-4.5、deepseek/deepseek-r1),你可以通过 reasoning 参数启用推理令牌。详情请参阅 OpenRouter 推理文档 :
model = ChatOpenRouter (
model = "anthropic/claude-sonnet-4.5" ,
max_tokens = 16384 ,
reasoning = { "effort" : "high" , "summary" : "auto" },
)
ai_msg = model . invoke ( "What is the square root of 529?" )
# 通过 content_blocks 访问推理内容
for block in ai_msg . content_blocks :
if block [ " type " ] == "reasoning" :
print ( block [ " reasoning " ])
有关内容块的更多信息,请参阅 标准内容块 指南。
reasoning 字典支持两个键:
effort:控制推理令牌预算。值:"xhigh"、"high"、"medium"、"low"、"minimal"、"none"。
summary:控制响应中返回的推理摘要的详细程度。值:"auto"、"concise"、"detailed"。
推理令牌使用量包含在 usage_metadata 中:
print ( ai_msg . usage_metadata )
# {'input_tokens': ..., 'output_tokens': ..., 'total_tokens': ...,
# 'output_token_details': {'reasoning': ...}}
努力到预算的映射取决于模型。例如,Google Gemini 模型将努力映射到内部的 thinkingLevel,而不是精确的令牌预算。详情请参阅 OpenRouter 推理文档 。
多模态输入
OpenRouter 支持接受它们的模型的 多模态输入 。可用的模态取决于你选择的模型——详情请查看 OpenRouter 模型页面 。
支持的输入方法
方法 图像 音频 视频 PDF HTTP/HTTPS URL ✅ ❌ ✅ ✅ Base64 内联数据 ✅ ✅ ✅ ✅
图像输入
使用带有列表内容格式的 HumanMessage 提供图像输入和文本。
from langchain_openrouter import ChatOpenRouter
from langchain . messages import HumanMessage
model = ChatOpenRouter ( model = "openai/gpt-4o" )
message = HumanMessage (
content = [
{ "type" : "text" , "text" : "Describe this image." },
{
"type" : "image" ,
"url" : "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg" ,
},
]
)
response = model . invoke ([ message ])
音频输入
提供音频输入和文本。音频以 base64 内联数据形式传递。
import base64
from pathlib import Path
from langchain_openrouter import ChatOpenRouter
from langchain . messages import HumanMessage
model = ChatOpenRouter ( model = "google/gemini-2.5-flash" )
audio_data = base64 . b64encode ( Path ( "/path/to/audio.wav" ). read_bytes ()). decode ( "utf-8" )
message = HumanMessage (
content = [
{ "type" : "text" , "text" : "Transcribe this audio." },
{
"type" : "audio" ,
"base64" : audio_data ,
"mime_type" : "audio/wav" ,
},
]
)
response = model . invoke ([ message ])
视频输入
视频输入会自动转换为 OpenRouter 的 video_url 格式。
from langchain_openrouter import ChatOpenRouter
from langchain . messages import HumanMessage
model = ChatOpenRouter ( model = "google/gemini-2.5-pro-preview" )
message = HumanMessage (
content = [
{ "type" : "text" , "text" : "Describe this video." },
{
"type" : "video" ,
"url" : "https://example.com/video.mp4" ,
},
]
)
response = model . invoke ([ message ])
PDF 输入
提供 PDF 文件输入和文本。
from langchain_openrouter import ChatOpenRouter
from langchain . messages import HumanMessage
model = ChatOpenRouter ( model = "google/gemini-2.5-pro-preview" )
message = HumanMessage (
content = [
{ "type" : "text" , "text" : "Summarize this document." },
{
"type" : "file" ,
"url" : "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf" ,
"mime_type" : "application/pdf" ,
},
]
)
response = model . invoke ([ message ])
令牌使用量元数据
调用后,令牌使用量信息可在响应的 usage_metadata 属性上获取:
ai_msg = model . invoke ( "Tell me a joke." )
ai_msg . usage_metadata
{'input_tokens': 12,
'output_tokens': 25,
'total_tokens': 37}
当底层提供商在其响应中包含详细的令牌细分时,它们会自动显示。当提供商不报告这些字段或其值为零时,这些字段将被省略。
推理令牌
output_token_details.reasoning 报告模型用于内部思维链推理的令牌数量。这在使用推理模型(例如 deepseek/deepseek-r1、openai/o3)或显式启用推理时出现:
from langchain_openrouter import ChatOpenRouter
model = ChatOpenRouter (
model = "anthropic/claude-sonnet-4.5" ,
reasoning = { "effort" : "high" },
)
ai_msg = model . invoke ( "What is the square root of 529?" )
ai_msg . usage_metadata
{'input_tokens': 39,
'output_tokens': 98,
'total_tokens': 137,
'output_token_details': {'reasoning': 62}}
缓存输入令牌
input_token_details.cache_read 报告从提供商提示缓存中提供的输入令牌数量,input_token_details.cache_creation 报告首次调用时写入缓存的令牌数量。
提示缓存需要在消息内容块中显式设置 cache_control 断点。在你想要缓存的内容块上传递 {"cache_control": {"type": "ephemeral"}}:
from langchain_openrouter import ChatOpenRouter
model = ChatOpenRouter ( model = "anthropic/claude-sonnet-4.5" )
long_system = "You are a helpful assistant. " * 200
messages = [
( "system" , [{ "type" : "text" , "text" : long_system , "cache_control" : { "type" : "ephemeral" }}]),
( "human" , "Say hi." ),
]
# 第一次调用写入缓存
ai_msg = model . invoke ( messages )
ai_msg . usage_metadata
{'input_tokens': 1210,
'output_tokens': 12,
'total_tokens': 1222,
'input_token_details': {'cache_creation': 1201}}
# 第二次调用从缓存读取
ai_msg = model . invoke ( messages )
ai_msg . usage_metadata
{'input_tokens': 1210,
'output_tokens': 12,
'total_tokens': 1222,
'input_token_details': {'cache_read': 1201}}
如果消息内容块上没有 cache_control,提供商将不会缓存提示,这些字段也不会出现。
流式传输时,从最后一个块聚合令牌使用量:
stream = model . stream ( "Tell me a joke." )
full = next ( stream )
for chunk in stream :
full += chunk
full . usage_metadata
{'input_tokens': 12,
'output_tokens': 25,
'total_tokens': 37}
响应元数据
调用后,提供商和模型元数据可在 response_metadata 属性上获取:
ai_msg = model . invoke ( "Tell me a joke." )
ai_msg . response_metadata
{'model_name': 'anthropic/claude-sonnet-4.5',
'id': 'gen-1771043112-yLUz3txgvHSjkyCQK8KQ',
'created': 1771043112,
'object': 'chat.completion',
'finish_reason': 'stop',
'logprobs': None,
'model_provider': 'openrouter'}
native_finish_reason 字段(如果存在)包含底层提供商的原始完成原因,可能与规范化的 finish_reason 不同。
提供商路由
OpenRouter 上的许多模型由多个提供商提供服务。openrouter_provider 参数让你可以控制哪些提供商处理你的请求以及如何选择它们。
排序和过滤提供商
使用 order 设置首选提供商顺序。OpenRouter 按顺序尝试每个提供商,如果一个不可用,则回退到下一个:
model = ChatOpenRouter (
model = "anthropic/claude-sonnet-4.5" ,
openrouter_provider = {
"order" : [ "Anthropic" , "Google" ],
"allow_fallbacks" : True , # 默认;如果需要,回退到顺序列表之外
},
)
要将请求限制为仅特定提供商,请使用 only。要排除某些提供商,请使用 ignore:
# 仅使用这些提供商(不回退到其他提供商)
model = ChatOpenRouter (
model = "openai/gpt-4o" ,
openrouter_provider = { "only" : [ "OpenAI" , "Azure" ]},
)
# 使用除 DeepInfra 之外的任何提供商
model = ChatOpenRouter (
model = "meta-llama/llama-4-maverick" ,
openrouter_provider = { "ignore" : [ "DeepInfra" ]},
)
按成本、速度或延迟排序
默认情况下,OpenRouter 在提供商之间进行负载平衡,优先选择成本较低的。使用 sort 更改优先级:
# 优先选择最快的提供商(最高的令牌/秒)
model = ChatOpenRouter (
model = "openai/gpt-4o" ,
openrouter_provider = { "sort" : "throughput" },
)
# 优先选择延迟最低的提供商
model = ChatOpenRouter (
model = "openai/gpt-4o" ,
openrouter_provider = { "sort" : "latency" },
)
数据收集策略
如果你的用例要求提供商不存储或训练你的数据,请将 data_collection 设置为 "deny":
model = ChatOpenRouter (
model = "anthropic/claude-sonnet-4.5" ,
openrouter_provider = { "data_collection" : "deny" },
)
按量化过滤
对于开放权重模型,你可以将路由限制为特定精度级别:
model = ChatOpenRouter (
model = "meta-llama/llama-4-maverick" ,
openrouter_provider = { "quantizations" : [ "fp16" , "bf16" ]},
)
路由参数
route 参数控制高级路由行为:
"fallback":启用跨提供商的自动故障转移(默认行为)。
"sort":基于 openrouter_provider 中配置的排序策略进行路由。
model = ChatOpenRouter (
model = "anthropic/claude-sonnet-4.5" ,
route = "fallback" ,
)
组合选项
提供商选项可以组合在一起:
model = ChatOpenRouter (
model = "openai/gpt-4o" ,
openrouter_provider = {
"order" : [ "OpenAI" , "Azure" ],
"allow_fallbacks" : False , # 严格——仅使用顺序中的提供商
"require_parameters" : True , # 跳过不支持所有参数的提供商
"data_collection" : "deny" ,
},
)
完整选项列表请参阅 OpenRouter 提供商路由文档 。
应用归属
OpenRouter 支持通过 HTTP 头进行应用归属。你可以通过初始化参数或环境变量设置这些:
model = ChatOpenRouter (
model = "anthropic/claude-sonnet-4.5" ,
app_url = "https://myapp.com" , # 或 OPENROUTER_APP_URL 环境变量
app_title = "My App" , # 或 OPENROUTER_APP_TITLE 环境变量
)
可观测性和跟踪
OpenRouter 可以将请求数据广播到配置的可观测性目标。ChatOpenRouter 暴露两个相关参数:session_id 用于将相关请求分组到单个逻辑工作流下,trace 用于每个请求的跟踪元数据。详情请参阅 OpenRouter 广播文档 。
使用 session_id 分组请求
传递 session_id 以将多个请求与同一工作流(对话、代理运行、批处理作业、CI 运行等)关联。最大 256 个字符。
model = ChatOpenRouter (
model = "anthropic/claude-sonnet-4.5" ,
session_id = "workflow-abc-123" , # 或 OPENROUTER_SESSION_ID 环境变量
)
当未提供显式 session_id 时,OPENROUTER_SESSION_ID 环境变量在实例化时被读取,这允许进程标记每个请求,而无需在应用程序代码中传递该值。
你也可以在每次调用时覆盖该值:
model . invoke ( "Summarize the doc" , session_id = "workflow-abc-123-step-1" )
使用 trace 添加跟踪元数据
传递 trace 以附加每个请求的元数据,OpenRouter 会将其转发到广播目标。识别的键是 trace_id、trace_name、span_name、generation_name 和 parent_span_id;其他键作为自定义元数据传递。
model = ChatOpenRouter (
model = "anthropic/claude-sonnet-4.5" ,
trace = {
"trace_id" : "trace-789" ,
"span_name" : "summarize" ,
},
)
session_id 和 trace 是独立的——session_id 在 OpenRouter 端将请求分组到逻辑工作流中,而 trace 则注释单个请求。
API 参考
有关所有 ChatOpenRouter 功能和配置的详细文档,请前往 ChatOpenRouter API 参考。
有关 OpenRouter 平台、模型和功能的更多信息,请参阅 OpenRouter 文档 。
将这些文档连接 到 Claude、VSCode 等,通过 MCP 获取实时答案。