主题
LangChain 模型的三种创建方式详解
本文结合第 02 章“模型的创建与调用”,解释厂商专用集成类、OpenAI 协议兼容方式和 init_chat_model() 统一初始化的区别、联系与适用场景。
这里的“创建模型”指创建一个用于调用模型服务的 Python 客户端对象。它不会训练模型,也不会把在线模型的权重下载到本地。
示例按课件使用的 LangChain Python 1.x 风格编写,仅做静态语法检查,未调用真实模型服务。模型 ID、接口地址、参数别名及支持的集成类型,以实际平台和安装版本为准。
1. 三种方式先看全貌
| 方式 | 典型写法 | 核心作用 |
|---|---|---|
| 厂商专用集成类 | ChatDeepSeek(...)、ChatTongyi(...) | 直接创建针对特定服务的适配对象 |
| OpenAI 协议兼容方式 | ChatOpenAI(model=..., base_url=...) | 使用 OpenAI 集成连接支持相应兼容接口的服务 |
| 统一初始化方式 | init_chat_model(model=..., model_provider=...) | 根据配置选择并创建具体的集成类 |
前两种主要解决“用什么适配类调用服务”,第三种解决“怎样统一选择并创建适配类”。因此,它们可以组合使用。
例如,init_chat_model() 既可以创建 ChatDeepSeek,也可以创建连接兼容平台的 ChatOpenAI。
text
创建入口 最终使用的适配类 模型服务
直接使用 ChatDeepSeek ──────────→ ChatDeepSeek ───────────→ DeepSeek 官网
直接使用 ChatOpenAI ────────────→ ChatOpenAI ─────────────→ base_url 指定的平台
init_chat_model
├─ model_provider="deepseek" ─→ ChatDeepSeek ───────────→ DeepSeek 官网或相应服务地址
└─ model_provider="openai" ───→ ChatOpenAI ─────────────→ OpenAI 官方或兼容平台2. 先分清模型、服务平台、协议和适配类
| 概念 | 回答的问题 | 例子 |
|---|---|---|
| 模型 | 使用哪个模型? | 某个 DeepSeek 模型、qwen-plus |
| 服务平台 | 由谁部署并提供访问入口? | DeepSeek 官网、阿里云百炼、本地推理服务 |
| API 协议 | 请求和响应如何组织? | OpenAI Chat Completions、Responses、平台专有接口 |
| LangChain 适配类 | 用哪个 Python 类连接服务? | ChatDeepSeek、ChatOpenAI、ChatTongyi |
| 创建入口 | 怎样得到适配对象? | 直接实例化,或使用 init_chat_model() |
同一个模型可能由多个平台提供服务。同一个平台也可能提供多种 API 接口。
因此,看到“DeepSeek 模型”还不足以决定接入方式。还要知道它部署在哪个平台,以及该平台开放了什么接口。
3. 方式一:厂商专用集成类
3.1 基本原理
直接导入对应的 LangChain 集成类,再创建实例。
| 服务或集成 | 典型类 | 所属包举例 |
|---|---|---|
| DeepSeek | ChatDeepSeek | langchain-deepseek |
| DashScope / 通义千问 | ChatTongyi | langchain-community,另需对应 SDK 等依赖 |
| Anthropic | ChatAnthropic | langchain-anthropic |
| Ollama | ChatOllama | langchain-ollama |
集成类把 LangChain 的消息、工具定义和调用参数转换为服务端需要的形式,再把响应转换为 LangChain 消息对象。
3.2 示例:使用 ChatDeepSeek
安装本篇主要示例所需依赖;课程项目已有固定依赖时,优先使用课程的版本配置:
bash
pip install langchain langchain-deepseek langchain-openai python-dotenv在示例项目根目录创建 .env:
dotenv
DEEPSEEK_API_KEY=替换为你的DeepSeek密钥
DEEPSEEK_MODEL=替换为DeepSeek平台当前支持的模型ID下面各段 Python 示例可以分别保存运行,使用同一份 .env。示例显式读取模型 ID,避免把课件中的某个模型名称当成始终可用的名称。
python
import os
from dotenv import load_dotenv
from langchain_deepseek import ChatDeepSeek
load_dotenv()
model = ChatDeepSeek(
model=os.environ["DEEPSEEK_MODEL"],
api_key=os.environ["DEEPSEEK_API_KEY"],
)
response = model.invoke("请用一句话解释什么是 LangChain。")
print(response.content)此处使用 DeepSeek 集成的默认服务地址。需要自定义地址时,应核对当前集成版本接受的参数名,不能假定所有集成的参数和别名完全相同。
load_dotenv() 默认不会覆盖已存在的环境变量;显式使用 override=True 才会让 .env 中的值覆盖同名环境变量。真实密钥不应提交到版本库,应将 .env 加入 .gitignore。
3.3 专用集成类与厂商原生 SDK 的区别
这两个概念容易混淆:
| 用法 | 所属层次 | 调用形式举例 |
|---|---|---|
| LangChain 专用集成 | LangChain 模型接口 | ChatTongyi(...).invoke(...) |
| 厂商原生 SDK | 厂商自己的客户端接口 | dashscope.Generation.call(...) |
二者都可以调用模型,但只有前者天然采用 LangChain 的模型调用接口。原生 SDK 的返回类型和调用方式由厂商定义。
3.4 优势与适用场景
- 更有针对性地处理该服务的参数、响应和扩展字段。
- 可以接入 LangChain 的消息、提示词、工具和 Runnable 调用流程。
- 适合主要使用某一家服务,或需要其专有能力的项目。
专用集成也有边界:厂商刚开放的能力,不一定已经被当前版本封装。切换集成时,可能需要调整导入、依赖、认证方式和部分参数。
4. 方式二:OpenAI 协议兼容方式
4.1 为什么 ChatOpenAI 能调用其他厂商?
部分平台提供与 OpenAI API 相兼容的接口。只要服务支持相应的请求和响应结构,ChatOpenAI 就可以按兼容方式连接该服务。
使用 ChatOpenAI 不代表请求一定发送给 OpenAI,也不代表底层模型一定来自 OpenAI。
4.2 示例:通过兼容接口连接 DeepSeek
沿用前面的 .env:
python
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
load_dotenv()
model = ChatOpenAI(
model=os.environ["DEEPSEEK_MODEL"],
api_key=os.environ["DEEPSEEK_API_KEY"],
base_url="https://api.deepseek.com/v1",
)
response = model.invoke("请用一句话解释什么是 LangChain。")
print(response.content)三个参数分别负责不同的事情:
| 参数 | 含义 | 本例 |
|---|---|---|
model | 调用目标服务中的哪个模型 | .env 中指定的 DeepSeek 模型 |
api_key | 用哪个服务的凭证认证 | DeepSeek 平台的密钥 |
base_url | 请求发往哪个 API 基础地址 | DeepSeek 的兼容接口地址 |
这里的 base_url 是基础地址,通常不需要自行追加 /chat/completions。具体路径以平台和集成文档为准。
4.3 换成百炼平台会发生什么?
例如调用百炼的千问兼容接口时,可以继续使用 ChatOpenAI,把配置换成:
| 参数 | 配置 |
|---|---|
model | 账户可用的千问模型 ID,例如平台支持时的 qwen-plus |
api_key | 百炼平台的 API Key |
base_url | 对应地域的百炼兼容地址,例如中国内地服务的 https://dashscope.aliyuncs.com/compatible-mode/v1 |
不能只换模型名,仍保留另一平台的密钥和地址。模型 ID、地址和密钥必须与目标服务匹配。
4.4 兼容范围有什么限制?
“兼容 OpenAI”需要按具体能力理解:
| 兼容层面 | 需要核实的内容 |
|---|---|
| API 端点 | 支持 Chat Completions、Responses,还是仅支持其中一个? |
| 请求参数 | 是否接受输出长度、工具、结构化输出及推理相关参数? |
| 响应字段 | 文本、工具调用、token 用量、扩展字段是否符合预期? |
| 流式输出 | 是否支持所需的流式事件和用量统计? |
| 模型能力 | 该模型本身是否支持工具、图片、严格 Schema 等能力? |
能完成普通聊天,不代表其他能力也完整兼容。ChatOpenAI 不能给服务端增加尚未实现的能力,也不保证保留所有厂商特有字段。需要特定能力时,应核对专用集成与兼容接口各自的支持范围。
适合使用此方式的场景包括:平台提供 OpenAI 兼容接口、多个服务希望复用接入代码,或者尚无合适的专用集成。
5. 方式三:init_chat_model() 统一初始化
5.1 它是一个模型对象工厂
init_chat_model() 根据模型标识和 model_provider,选择相应的 LangChain 集成类。
python
from langchain.chat_models import init_chat_model对于本篇这种固定配置且未启用运行时可配置字段的用法,可以把它理解为“帮你实例化具体的模型类”。
5.2 示例:选择 DeepSeek 专用集成
python
import os
from dotenv import load_dotenv
from langchain.chat_models import init_chat_model
load_dotenv()
model = init_chat_model(
model=os.environ["DEEPSEEK_MODEL"],
model_provider="deepseek",
api_key=os.environ["DEEPSEEK_API_KEY"],
)
response = model.invoke("请用一句话解释什么是 LangChain。")
print(response.content)本例选择 ChatDeepSeek,与前面直接创建专用集成对象的调用路径相对应。
5.3 示例:选择 OpenAI 集成,连接兼容接口
python
import os
from dotenv import load_dotenv
from langchain.chat_models import init_chat_model
load_dotenv()
model = init_chat_model(
model=os.environ["DEEPSEEK_MODEL"],
model_provider="openai",
api_key=os.environ["DEEPSEEK_API_KEY"],
base_url="https://api.deepseek.com/v1",
)
response = model.invoke("请用一句话解释什么是 LangChain。")
print(response.content)本例选择 ChatOpenAI,然后连接 DeepSeek 的兼容接口。
这里的 model_provider="openai" 表示选择 OpenAI 集成,不表示把 DeepSeek 模型变成 OpenAI 模型。 最终请求地址由该集成的默认地址或显式配置的 base_url 决定。
5.4 “自适应”有哪几种写法?
以下是创建对象的写法,不包含真实模型调用。model_id 仍从前面的 .env 读取:
python
import os
from dotenv import load_dotenv
from langchain.chat_models import init_chat_model
load_dotenv()
model_id = os.environ["DEEPSEEK_MODEL"]
# 写法一:显式指定集成类型。
explicit_model = init_chat_model(
model=model_id,
model_provider="deepseek",
)
# 写法二:将集成类型写在模型字符串前缀中。
prefixed_model = init_chat_model(
model=f"deepseek:{model_id}",
)
# 写法三:省略集成类型,尝试根据模型名称推断。
# 只有当前版本能识别该模型名时才适用,否则可能报错。
inferred_model = init_chat_model(
model=model_id,
)前两种写法明确选择集成。第三种依赖当前 LangChain 版本的内置推断规则,不能保证识别任意模型名,也无法仅凭名称可靠确定模型所在的平台。
例如,同名 DeepSeek 模型可能由官网或其他平台提供服务。即便推断到了 DeepSeek 集成,也不能据此得知你实际想使用百炼的接口。
项目中接入兼容平台、自定义模型名或第三方部署时,显式指定集成类型、地址和凭证通常更清楚。
5.5 它不会自动完成哪些事?
- 不会自动安装集成包。选择
deepseek仍需要安装langchain-deepseek,选择openai仍需要安装langchain-openai。 - 不会联网探测任意服务,再自动推断其协议。
- 不会根据问题自动选择最聪明或最便宜的模型。
- 不会自动在服务故障后切换到另一家供应商。
- 不会消除不同模型之间的参数、认证和能力差异。
统一初始化方便的是创建入口。运行时路由、故障回退和成本策略,需要额外配置或实现。
6. 三种方式创建后,怎样调用?
采用上述方式得到的 LangChain 聊天模型对象,都可以通过统一的调用入口使用:
| 调用入口 | 用途 |
|---|---|
model.invoke(...) | 等待一次完整结果 |
model.stream(...) | 逐块消费输出 |
model.batch([...]) | 处理多个输入 |
await model.ainvoke(...) | 异步等待一次结果 |
统一入口的存在,不意味着所有服务的底层实现和支持能力相同。例如流式输出、工具调用、结构化输出的具体行为,仍取决于模型、服务端和集成版本。
invoke() 通常返回 LangChain 的 AIMessage,通过 response.content 读取内容。对于多模态或内容块形式的结果,content 不一定是单一字符串,应按实际返回结构处理。
7. 对比与选型建议
| 比较项 | 厂商专用集成类 | OpenAI 兼容方式 | init_chat_model() |
|---|---|---|---|
| 具体类由谁选择 | 开发者直接指定 | 开发者直接指定 ChatOpenAI | 根据显式配置或内置规则选择 |
| 主要价值 | 针对服务适配 | 复用兼容接入方式 | 统一对象创建入口 |
| 专有能力支持 | 取决于专用集成版本 | 取决于兼容范围和字段处理 | 取决于最终选中的集成 |
| 切换平台的改动 | 可能需要换类、依赖和配置 | 通常先调整模型、地址、密钥,再核实能力 | 可集中修改创建配置,再核实依赖和能力 |
| 主要限制 | 各集成配置可能不同 | 兼容可能不完整 | 支持列表、推断规则和具体集成的限制 |
实际选择可以按下面的顺序判断:
- 确认服务平台和所需能力。 先知道模型部署在哪里、需要普通聊天还是工具等能力。
- 选择适配方式。 有合适的专用集成时评估专用类;平台明确提供所需的 OpenAI 兼容能力时,可以使用
ChatOpenAI。 - 选择创建入口。 学习时可直接实例化,方便理解调用路径;项目需要集中配置和切换模型时,可以使用
init_chat_model()。 - 验证实际需要的功能。 切换模型或平台后,检查文本、流式、工具和结构化输出中项目真正使用的部分。
对于百炼、OpenRouter 等平台上的 DeepSeek 模型,应按该平台的接口选择集成,并使用该平台的地址、密钥和模型 ID;不能因为名称中有 DeepSeek,就直接套用 DeepSeek 官网的配置。
8. 常见问题
使用 ChatOpenAI,是不是一定要 OpenAI 的 API Key?
不一定。连接哪个平台,就使用该平台认可的凭证。示例连接 DeepSeek 时,使用的是 DeepSeek 的 API Key。
model_provider 是不是填写模型的研发厂商?
在 init_chat_model() 中,它用于选择集成实现,不能简单等同于模型研发厂商。通过 OpenAI 兼容接口调用千问时,可以选择 openai 集成。
所有专用集成类都能通过 init_chat_model() 创建吗?
不能这样保证。某个类存在于 LangChain 生态中,不代表它在当前版本的统一工厂中有对应注册项。应查看当前版本的支持列表,必要时直接实例化专用类。
init_chat_model() 是不是一定比直接实例化更强?
它主要统一创建入口。最终采用同一个集成、同一个服务和同一组配置时,不能因为换了创建入口就获得额外的模型能力。
统一创建后,是不是只改 model 就能随意换厂商?
不能保证。跨平台通常还涉及地址、凭证、依赖、参数和模型能力。统一创建可以集中管理这些配置,但不会自动解决所有差异。
9. 延伸阅读
- 原课件:第 02 章模型的创建与调用
- 本章补充:Chat Completions API 与 Responses API 详细对照
- LangChain 模型文档
- LangChain DeepSeek 集成文档
- LangChain OpenAI 集成文档
外部链接用于查阅实际安装版本的接口与能力,本篇整理未逐项在线核验最新版本。