Skip to main content
本文将帮助您快速上手 OpenRouter 聊天模型。OpenRouter 是一个统一 API,通过单一端点提供来自多个提供商(OpenAI、Anthropic、Google、Meta 等)的模型访问。
API 参考有关所有功能和配置选项的详细文档,请参阅 ChatOpenRouter API 参考。
完整的可用模型列表,请访问 OpenRouter 模型页面

概述

集成详情

可序列化JS/TS 支持下载量最新版本
ChatOpenRouterlangchain-openrouterbetaDownloads per monthPyPI - Latest version

模型功能

工具调用结构化输出图像输入音频输入视频输入Token 级流式输出原生异步Token 用量对数概率

安装配置

要通过 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 类、字典 schema、LangChain 工具或函数作为工具传入模型。在底层,这些会被转换为 OpenAI 工具 schema 并在每次模型调用时传入。
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 属性,包含与模型提供商无关的标准化格式工具调用。
ai_msg.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-4.1")

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)
使用 ProviderStrategy 指定 response_format,在生成 Agent 最终响应时启用结构化输出。
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-4.1",
    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_callingjson_schema 方法可以传入 strict=True 以强制严格遵守 schema。json_mode 方法不支持 strict 参数。
structured_model = model.with_structured_output(Movie, method="json_schema", strict=True)

推理输出

对于支持推理的模型(如 anthropic/claude-sonnet-4.5deepseek/deepseek-r1),可以通过 reasoning 参数启用推理 token。详情请参阅 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:控制推理 token 预算。可选值:"xhigh""high""medium""low""minimal""none"
  • summary:控制响应中返回的推理摘要的详细程度。可选值:"auto""concise""detailed"
推理 token 用量包含在 usage_metadata 中:
print(ai_msg.usage_metadata)
# {'input_tokens': ..., 'output_tokens': ..., 'total_tokens': ...,
#  'output_token_details': {'reasoning': ...}}
effort 到 budget 的映射取决于具体模型。例如,Google Gemini 模型将 effort 映射到内部的 thinkingLevel,而非确切的 token 预算。详情请参阅 OpenRouter 推理文档

多模态输入

OpenRouter 支持接受多模态输入的模型的多模态输入。可用的模态取决于您选择的模型——请查看 OpenRouter 模型页面了解详情。

支持的输入方式

方式图像音频视频PDF
HTTP/HTTPS URL
Base64 内联数据
并非所有模型都支持所有模态。请查看 OpenRouter 模型页面了解各模型的具体支持情况。

图像输入

使用 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])

Token 用量元数据

调用后,响应的 usage_metadata 属性中将包含 token 用量信息:
ai_msg = model.invoke("Tell me a joke.")
ai_msg.usage_metadata
{'input_tokens': 12,
 'output_tokens': 25,
 'total_tokens': 37}
当底层提供商在响应中包含详细的 token 分解时,这些信息会自动呈现。当提供商未报告这些字段或其值为零时,相关字段将被省略。

推理 token

output_token_details.reasoning 报告模型用于内部思维链推理的 token 数量。当使用推理模型(如 deepseek/deepseek-r1openai/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}}

缓存输入 token

input_token_details.cache_read 报告从提供商提示缓存中获取的输入 token 数量,input_token_details.cache_creation 报告在首次调用时写入缓存的 token 数量。 提示缓存需要在消息内容块中明确设置 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,提供商不会缓存提示,这些字段也不会出现。
流式传输时,从最后一个块聚合 token 用量:
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 更改优先级:
# 优先选择最快的提供商(最高 token/秒)
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 参数

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,       # 严格模式——仅使用 order 中的提供商
        "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 环境变量
)

API 参考

有关 ChatOpenRouter 所有特性和配置的详细文档,请参阅 ChatOpenRouter API 参考。 更多关于 OpenRouter 平台、模型和功能的信息,请参阅 OpenRouter 文档