第3课:LangChain大模型接入:OpenAI、通义千问、DeepSeek通用调用
LangChain作为大模型应用开发框架,支持灵活接入多种主流大模型,包括OpenAI、通义千问、DeepSeek等。通过统一的API接口和模块化设计,开发者可快速实现模型调用、上下文管理及功能扩展。OpenAI接入需配置API密钥,通过ChatOpenAI类调用GPT系列模型。通义千问和DeepSeek需使用自定义封装或HTTP请求,LangChain提供LLM基类便于适配不同厂商的接口规范。通

文章目录
-
- 课程导读 & 学习目标
- 前置知识与环境准备
- 核心概念深度拆解
- 底层运行原理剖析
- 核心API/组件源码解读
- 手把手项目实战教学
- 完整可运行Python代码(带逐行详细注释)
- 环境依赖安装命令
- 常见报错坑点与避坑方案
-
- 坑1:`ImportError: cannot import name 'ChatTongyi' from 'langchain_community.chat_models.tongyi'`
- 坑2:`ImportError: No module named 'langchain_deepseek'`
- 坑3:通义千问返回 `"code": "InvalidApiKey"` 或 401错误
- 坑4:DeepSeek调用返回 `404: model not found`
- 坑5:OpenAI调用报 `RateLimitError` 限流
- 坑6:`dotenv`加载.env文件不生效
- 坑7:`ChatOpenAI`初始化时`base_url`参数名错误
- 本节核心知识点总结
- 课后练习题(含原题+标准答案+详细解析)
- 🔗《30节课 LangChain 从入门到精通》系列课程导航
课程导读 & 学习目标
在上一节课中,我们深入理解了LangChain的Runnable抽象、LCEL声明式编程、回调与可观测性等核心设计思想。你也亲手实现了自定义Runnable,并用流式回调实时监控模型输出。但有一个关键问题始终悬而未决:我们上一节课使用的智谱AI模型,只是众多大模型中的一个。在实际开发中,你可能需要切换通义千问、DeepSeek,甚至同时使用多个模型。
LangChain的“模型无关性”设计思想(我们在第2课提过)正是为了解决这个问题——让开发者用同一套代码,无缝调用不同厂商的大模型,实现“写一次,到处运行”。然而,很多初学者在实践时会遇到两大困惑:
- 厂商差异:OpenAI用
OPENAI_API_KEY,通义千问用DASHSCOPE_API_KEY,DeepSeek用DEEPSEEK_API_KEY,环境变量记不住。 - 包导入差异:
ChatOpenAI、ChatTongyi、ChatDeepSeek,每个模型的导入路径和初始化方式不同,代码改来改去很麻烦。
本节课将彻底解决这些问题。我们不只教你“怎么写代码调用某个模型”,更要让你掌握:
- LangChain模型接入的统一接口体系:理解所有模型调用都遵循的
invoke/stream/batch三件套。 - 三种主流接入方式:
- OpenAI官方及兼容方案(
ChatOpenAI+base_url)。 - 通义千问接入(
ChatTongyi/ChatQwen)。 - DeepSeek接入(
langchain-deepseek/ OpenAI兼容)。
- OpenAI官方及兼容方案(
- 多模型切换的最佳实践:通过配置文件+工厂模式,3行代码切换模型。
- 生产级注意事项:API密钥管理、超时重试、并发控制、成本追踪。
通过本课,你将在LangChain的“模型无关性”战场上彻底站稳脚跟,为后续第4-6课(Prompt工程、Output Parser、Memory)的进阶内容铺平道路。届时,你可以自由选择最合适的模型来完成不同任务,而无需为每个模型重写业务逻辑。
💡 本节课的类比:把LangChain想象成“充电器转换头”——无论你用的是哪个国家(哪个厂商)的插座,转换头(LangChain统一接口)都能让你顺利充电(调用大模型)。
前置知识与环境准备
1.1 Python版本与开发工具
继续沿用前两课的虚拟环境langchain_course,确保Python版本为3.10+。如果尚未创建环境,请参考第1课的依赖安装命令快速搭建。
1.2 你需要准备的三类API密钥
本节课需调用三个不同的大模型服务,请按需注册并获取API密钥:
| 服务商 | 注册地址 | 推荐理由 | 免费额度 |
|---|---|---|---|
| OpenAI | platform.openai.com | 国际主流,生态最完善 | 新用户赠送$5额度(需绑卡) |
| 通义千问(阿里云) | dashscope.aliyun.com | 国内稳定,兼容OpenAI接口 | 新用户送7000万tokens |
| DeepSeek | platform.deepseek.com | 性价比极高,API降价超50% | 新用户送500万tokens |
⚠️ 安全提示:API密钥属于敏感信息,严禁硬编码到代码中。本课全程使用
.env文件管理密钥,该文件也应被.gitignore排除。
1.3 创建.env环境变量文件
在项目根目录更新或创建.env文件:
# OpenAI(如需使用)
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx
# 通义千问(DashScope)
DASHSCOPE_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx
# DeepSeek
DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx
# 如果需要通过OpenAI兼容方式接入其他模型(如智谱、本地Ollama等)
# BASE_URL为自定义,本课用DeepSeek OpenAI兼容时覆盖
# OPENAI_API_BASE=https://api.deepseek.com/v1
1.4 安装依赖包
# 激活虚拟环境
source venv/bin/activate # Mac/Linux
# venv\Scripts\activate # Windows
# 安装LangChain核心依赖(如已安装可跳过)
pip install langchain==0.3.7 langchain-core==0.3.21 langchain-openai==0.2.8 python-dotenv==1.0.1
# 安装通义千问DashScope支持
pip install dashscope
# 安装DeepSeek社区集成包(官方推荐)
pip install langchain-deepseek
# 如需通过OpenAI兼容方式(备选),则无需额外安装
1.5 验证安装
创建check_models.py测试各包能否正常导入:
# 测试各模型包的导入
try:
from langchain_openai import ChatOpenAI
print("✓ langchain_openai 导入成功")
except ImportError as e:
print(f"✗ langchain_openai 导入失败: {e}")
try:
from langchain_community.chat_models.tongyi import ChatTongyi
print("✓ ChatTongyi 导入成功")
except ImportError as e:
print(f"✗ ChatTongyi 导入失败,请检查 dashscope 是否安装")
try:
from langchain_deepseek import ChatDeepSeek
print("✓ ChatDeepSeek 导入成功")
except ImportError as e:
print("✗ langchain_deepseek 导入失败,请检查是否已安装该包")
核心概念深度拆解
2.1 LangChain模型的统一抽象:BaseChatModel
无论调用哪个厂商的大模型,LangChain都通过**BaseChatMessageModel**(常简称为BaseChatModel)抽象基类统一了接口。这意味着:
- 统一调用接口:
.invoke()(同步)、.ainvoke()(异步)、.stream()(流式)、.batch()(批量处理)。 - 统一输入格式:
BaseMessage及其子类(SystemMessage、HumanMessage、AIMessage)。 - 统一输出格式:
AIMessage,包含.content(文本内容)、.response_metadata(token消耗、延迟等元数据)。
📌 LangChain官方的表述:“One API for any model — Every LangChain chat model, regardless of provider, implements the same interface.”
2.2 三种接入模式
LangChain接入大模型有三种方式,本节课将依次讲解前两种(最常用):
模式一:官方集成包(直接调用)
每个主流模型厂商都有自己的LangChain集成包。例如:
- OpenAI:
langchain-openai,提供ChatOpenAI类。 - 通义千问:通过
langchain-community.chat_models.tongyi.ChatTongyi,依赖dashscope。 - DeepSeek:
langchain-deepseek,提供ChatDeepSeek类。
这种模式的优点是类型安全、参数提示完整,缺点是每个模型需要记忆不同的类名和配置参数。
模式二:OpenAI兼容接口(通用方式)
由于OpenAI的API格式已成为行业事实标准,许多模型厂商(包括DeepSeek、智谱GLM、通义千问的部分版本)都提供了与OpenAI兼容的端点。
这种方式只需使用ChatOpenAI这一个类,通过配置base_url和api_key即可切换模型。它的优点是代码复用性极高——切换模型时只需修改几行配置,业务逻辑完全不变。
本课将重点讲解两种模式,让你根据实际场景灵活选用。
模式三:自定义Runnable包装原生API(高级扩展)
当模型厂商没有提供LangChain集成包,且不支持OpenAI兼容接口时,你可以编写自定义Runnable来封装其原生API。本专栏后续的“自定义组件”课会专门讲解。
2.3 模型版本与模型名称对照
不同模型的版本迭代频繁,调用时需要指定正确的model参数。
OpenAI常用模型
| 模型名称 | 适用场景 | 说明 |
|---|---|---|
gpt-4o |
多模态、高推理能力 | OpenAI当前主力模型 |
gpt-4o-mini |
高性价比、快速响应 | 适合简单任务 |
gpt-3.5-turbo |
遗留支持 | 逐渐被淘汰 |
gpt-4-turbo |
长上下文(128K) | 适合推理+长文本 |
通义千问系列模型
阿里云百炼平台提供了丰富的通义千问模型,新用户赠送7000万tokens免费额度:
| 模型名称 | 适用场景 | 特性说明 |
|---|---|---|
qwen-max |
复杂推理、专业分析 | 效果最强,适合多步骤推理 |
qwen-plus |
内容创作、客服问答 | 平衡性能与成本的通用首选 |
qwen-flash |
快速响应、基础对话 | 高性价比,低延迟 |
qwen3.5-27b |
开源部署 | 阿里开源模型,可本地部署 |
💡 注意:通义千问的模型名称和版本更新频繁(如2026年2月发布了Qwen3.5-Flash API)。建议在阿里云百炼控制台查看最新的可用模型列表。
DeepSeek模型
DeepSeek的API模型名通过deepseek-chat和deepseek-reasoner两个端点提供,目前这两个模型名分别指向DeepSeek-V4-Flash的非思考模式和思考模式:
| API模型名 | 实际模型 | 适用场景 |
|---|---|---|
deepseek-chat |
DeepSeek-V4-Flash(非思考模式) | 通用对话,快速响应 |
deepseek-reasoner |
DeepSeek-V4-Flash(思考模式) | 需要推理链路的复杂任务 |
⚠️ 重要提醒:旧模型名
deepseek-chat与deepseek-reasoner将于2026年7月24日后停止使用,届时请切换至新模型名deepseek-v4-pro或deepseek-v4-flash。本课代码将使用最新兼容写法。
底层运行原理剖析
3.1 LangChain模型的“三阶段”调用原理
无论使用哪个模型,LangChain的调用在底层都遵循一个统一的“三阶段”流程:
阶段一:输入转换(LangChain → 厂商格式)
LangChain将标准的BaseMessage列表(其中每个消息包含role和content字段)转换为模型厂商API所需的JSON格式。例如:
- OpenAI需要
{"role": "user", "content": "..."}格式。 - 通义千问DashScope需要
{"user": "..."}格式。 - DeepSeek兼容OpenAI格式。
这一转换由各集成包的_generate方法完成,对用户完全透明。
阶段二:网络请求与模型推理
转换后的请求通过HTTP POST发送到厂商的API端点。这个过程包含:
- 超时控制:防止请求长时间挂起。
- 重试机制:网络抖动或限流时自动重试。
- 流式回传:如果开启
streaming=True,则以SSE(Server-Sent Events)方式逐步接收token。
阶段三:输出标准化(厂商格式 → LangChain格式)
厂商返回的响应(通常是JSON)被解析并封装为标准化的AIMessage对象:
response.content:模型生成的文本内容。response.response_metadata:token消耗统计(token_usage)、finish_reason(停止原因)、延迟等元数据。
3.2 不同模型接入的底层差异对比
| 维度 | OpenAI | 通义千问(DashScope) | DeepSeek |
|---|---|---|---|
| HTTP协议 | HTTPS | HTTPS | HTTPS |
| 认证方式 | Bearer Token | Bearer Token | Bearer Token |
| 请求路径 | /v1/chat/completions |
/compatible-mode/v1/chat/completions |
/v1/chat/completions |
| 必填参数 | model, messages |
model, messages |
model, messages |
| 流式支持 | SSE | SSE | SSE |
| LangChain实现 | ChatOpenAI |
ChatTongyi |
ChatDeepSeek |
3.3 为什么一个“ChatOpenAI”类能调用所有OpenAI兼容模型?
ChatOpenAI类在初始化时会读取base_url参数。如果base_url为空,则默认指向https://api.openai.com/v1;如果指定了其他URL(例如https://api.deepseek.com/v1),则所有请求都会被发送到该地址。ChatOpenAI底层使用OpenAI官方Python SDK,但该SDK也支持自定义base_url,从而实现“一套代码,调用多个模型”。
这背后的设计模式是适配器模式:通过统一的接口,将不同厂商的API差异封装在内部,对外暴露一致的行为。
核心API/组件源码解读
4.1 ChatOpenAI 核心参数详解
ChatOpenAI不仅在官方OpenAI模型中使用,也是接入DeepSeek等兼容模型的首选方式。其核心参数如下(基于LangChain 0.3.x官方文档):
| 参数 | 类型 | 说明 |
|---|---|---|
model |
str |
模型名称,如"gpt-4o"或"deepseek-chat" |
temperature |
float |
控制随机性,0~2,越低输出越确定 |
max_tokens |
int |
最大生成token数 |
api_key |
str |
API密钥,若不传则自动从环境变量读取 |
base_url |
str |
自定义API端点,用于接入兼容模型或代理 |
timeout |
float |
请求超时时间(秒) |
max_retries |
int |
请求失败时的最大重试次数 |
streaming |
bool |
是否启用流式传输 |
organization |
str |
OpenAI组织ID(仅OpenAI官方账号需要) |
4.2 ChatTongyi(通义千问)核心用法
ChatTongyi是LangChain社区包langchain-community中提供的通义千问集成:
from langchain_community.chat_models.tongyi import ChatTongyi
llm = ChatTongyi(
model="qwen-plus", # 选择模型版本
temperature=0.7,
top_p=0.9, # nucleus采样参数
dashscope_api_key="your-key" # 若不传则读取环境变量DASHSCOPE_API_KEY
)
需要注意,ChatTongyi依赖于dashscope包,这是阿里云提供的官方Python SDK,用于调用通义千问API。
4.3 ChatDeepSeek 核心用法
LangChain为DeepSeek提供了官方集成包langchain-deepseek,提供ChatDeepSeek类:
from langchain_deepseek import ChatDeepSeek
llm = ChatDeepSeek(
model="deepseek-chat", # 或 "deepseek-reasoner"
temperature=0.7,
max_tokens=1024,
api_key="your-key", # 若不传则读取DEEPSEEK_API_KEY
timeout=60
)
安装方式:pip install langchain-deepseek。
4.4 三种类的统一调用接口
虽然三个类的名称和初始化参数略有差异,但它们都实现了BaseChatModel接口,因此调用方式完全一致:
# 通用调用模式
response = llm.invoke([HumanMessage(content="你好")])
print(response.content)
# 流式输出
for chunk in llm.stream([HumanMessage(content="你好")]):
print(chunk.content, end="")
# 异步调用
# response = await llm.ainvoke([HumanMessage(content="你好")])
# 批量调用
# responses = llm.batch([messages1, messages2], config={"max_concurrency": 5})
这种统一接口的设计,使得在不同模型之间切换变得异常简单——只需替换llm对象的初始化代码,下游调用代码完全不用修改。
手把手项目实战教学
现在进入实战环节。我们将依次实现:
- OpenAI调用:官方方式 + 国内加速代理。
- 通义千问调用:两种方式(直接调用 + OpenAI兼容)。
- DeepSeek调用:两种方式(官方包 + OpenAI兼容)。
- 多模型切换实战:通过配置文件实现“一键切换”。
实战一:OpenAI调用(官方方式 + 代理加速)
由于OpenAI官方API在国内访问可能受限,我们演示两种方式:直接调用和使用代理(如果配置了代理的话)。
文件:01_openai_demo.py
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage
load_dotenv()
# 方式一:官方端点(需要科学上网环境)
# api_key = os.getenv("OPENAI_API_KEY")
# llm = ChatOpenAI(
# model="gpt-4o-mini", # 使用性价比更高的mini版本
# temperature=0.7
# )
# 方式二:通过代理(如果你配置了代理服务)
# 提前设置环境变量 HTTP_PROXY 和 HTTPS_PROXY
# 或通过 requests 库的配置(略)
# 示例:使用 OpenAI 兼容代理
# 假设你有一个用了一键加速服务的代理端点
api_key = os.getenv("OPENAI_API_KEY")
proxy_base_url = os.getenv("PROXY_BASE_URL")
if proxy_base_url:
llm = ChatOpenAI(
model="gpt-4o-mini",
openai_api_key=api_key,
openai_api_base=proxy_base_url, # 代理地址(OpenAI兼容)
temperature=0.7
)
else:
# 使用官方端点
llm = ChatOpenAI(
model="gpt-4o-mini",
temperature=0.7
)
# 调用模型
messages = [HumanMessage(content="请用一句话介绍什么是机器学习")]
response = llm.invoke(messages)
print("OpenAI回答:", response.content)
💡 善意提示:本栏目鼓励合规使用AI技术。如果你所在地区网络有限制,可考虑使用国内稳定的大模型替代方案(如通义千问、DeepSeek)。
实战二:通义千问调用(ChatTongyi + OpenAI兼容)
文件:02_tongyi_demo.py
import os
from dotenv import load_dotenv
from langchain_core.messages import HumanMessage
load_dotenv()
# ========== 方式一:直接使用 ChatTongyi ==========
try:
from langchain_community.chat_models.tongyi import ChatTongyi
tongyi_llm = ChatTongyi(
model="qwen-plus", # 平衡性能与成本
temperature=0.7,
dashscope_api_key=os.getenv("DASHSCOPE_API_KEY")
)
response = tongyi_llm.invoke([HumanMessage(content="请用一句话介绍什么是LangChain")])
print("【通义千问 - 直接方式】:", response.content)
print("Token消耗:", response.response_metadata.get("token_usage", {}))
except ImportError:
print("需要安装 dashscope: pip install dashscope")
# ========== 方式二:使用 OpenAI 兼容接口 ==========
# 阿里云百炼平台提供了兼容OpenAI的API端点
# 文档参考:https://help.aliyun.com/zh/dashscope/developer-reference/api-details
tongyi_base_url = os.getenv("TONGYI_OPENAI_BASE_URL")
if tongyi_base_url:
from langchain_openai import ChatOpenAI
tongyi_compatible = ChatOpenAI(
model="qwen-plus",
openai_api_key=os.getenv("DASHSCOPE_API_KEY"),
openai_api_base=tongyi_base_url,
temperature=0.7
)
response2 = tongyi_compatible.invoke([HumanMessage(content="请用一句话介绍什么是LangChain")])
print("【通义千问 - OpenAI兼容方式】:", response2.content)
实战三:DeepSeek调用(官方包 + OpenAI兼容)
文件:03_deepseek_demo.py
import os
from dotenv import load_dotenv
from langchain_core.messages import HumanMessage
load_dotenv()
# ========== 方式一:使用官方 langchain-deepseek 包 ==========
try:
from langchain_deepseek import ChatDeepSeek
deepseek_llm = ChatDeepSeek(
model="deepseek-chat", # DeepSeek-V4-Flash非思考模式
temperature=0.7,
api_key=os.getenv("DEEPSEEK_API_KEY"),
timeout=60
)
response = deepseek_llm.invoke([HumanMessage(content="请用一句话介绍什么是RAG技术")])
print("【DeepSeek - 官方包】:", response.content)
print("元数据:", response.response_metadata)
except ImportError:
print("需要安装 langchain-deepseek: pip install langchain-deepseek")
# ========== 方式二:使用 OpenAI 兼容接口 ==========
# DeepSeek 官方提供了 OpenAI 兼容的端点
from langchain_openai import ChatOpenAI
deepseek_compatible = ChatOpenAI(
model="deepseek-chat",
openai_api_key=os.getenv("DEEPSEEK_API_KEY"),
openai_api_base="https://api.deepseek.com/v1", # DeepSeek官方兼容端点
temperature=0.7
)
response2 = deepseek_compatible.invoke([HumanMessage(content="请用一句话介绍什么是RAG技术")])
print("【DeepSeek - OpenAI兼容方式】:", response2.content)
📌 关于模型名称的特别说明:截至2026年5月,DeepSeek的API已升级为DeepSeek-V4,官方推荐使用
deepseek-v4-pro或deepseek-v4-flash作为模型名称,旧的deepseek-chat与deepseek-reasoner将于2026年7月24日停止使用。本课中的示例考虑到兼容性,仍使用deepseek-chat,建议你在实际项目中尽快切换到新模型名称。
实战四:多模型切换(配置文件 + 工厂模式)
这是本课的核心实战——向你展示如何用一个配置文件管理多个模型,实现“切换模型不改业务代码”。
文件:04_model_factory.py
import os
from dotenv import load_dotenv
from langchain_core.language_models import BaseChatModel
from langchain_core.messages import HumanMessage
load_dotenv()
class ModelFactory:
"""模型工厂:根据配置字符串返回对应的模型实例"""
@staticmethod
def get_model(provider: str, model: str = None, temperature: float = 0.7) -> BaseChatModel:
provider = provider.lower()
if provider == "openai":
from langchain_openai import ChatOpenAI
return ChatOpenAI(
model=model or "gpt-4o-mini",
temperature=temperature
)
elif provider == "tongyi":
from langchain_community.chat_models.tongyi import ChatTongyi
return ChatTongyi(
model=model or "qwen-plus",
temperature=temperature,
dashscope_api_key=os.getenv("DASHSCOPE_API_KEY")
)
elif provider == "deepseek":
from langchain_deepseek import ChatDeepSeek
return ChatDeepSeek(
model=model or "deepseek-chat",
temperature=temperature,
api_key=os.getenv("DEEPSEEK_API_KEY")
)
elif provider == "zhipu": # 延续第1课
from langchain_openai import ChatOpenAI
return ChatOpenAI(
model=model or "glm-4",
openai_api_key=os.getenv("ZHIPU_API_KEY"),
openai_api_base=os.getenv("BASE_URL"),
temperature=temperature
)
else:
raise ValueError(f"不支持的模型供应商: {provider}")
# 在配置文件中定义当前使用的模型
# 你可以修改这一行来切换模型,下游代码完全不变
CURRENT_PROVIDER = os.getenv("PROVIDER", "tongyi") # 可选: openai, tongyi, deepseek, zhipu
CURRENT_MODEL = os.getenv("MODEL_NAME") # 可选,留空则使用默认模型
# 创建模型实例
llm = ModelFactory.get_model(
provider=CURRENT_PROVIDER,
model=CURRENT_MODEL,
temperature=0.7
)
# 以下代码无需任何修改,即可自动适配当前模型
print(f"当前使用的模型供应商: {CURRENT_PROVIDER}")
question = "请用一句话介绍什么是LangChain"
response = llm.invoke([HumanMessage(content=question)])
print(f"回答: {response.content}")
print(f"Token使用情况: {response.response_metadata.get('token_usage', {})}")
对应的.env配置:
# 选择当前使用的模型供应商(openai / tongyi / deepseek / zhipu)
PROVIDER=tongyi
# 可选:指定具体模型名称
MODEL_NAME=qwen-plus
# API密钥保持各自的
OPENAI_API_KEY=sk-xxx
DASHSCOPE_API_KEY=sk-xxx
DEEPSEEK_API_KEY=sk-xxx
核心优势:当你想切换模型时,只需修改.env中的PROVIDER值,业务代码一行都不用改。这完美体现了LangChain“统一接口”的设计哲学。
完整可运行Python代码(带逐行详细注释)
将四个实战整合为一个独立脚本,可直接复制运行。只需确保.env文件中配置好了至少一个模型的API密钥。
文件:multi_model_demo.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
LangChain第3课:OpenAI、通义千问、DeepSeek 通用调用完整演示
"""
import os
import sys
from dotenv import load_dotenv
from langchain_core.messages import HumanMessage
# 加载 .env 文件中的环境变量
load_dotenv()
# ============================================================
# 第一部分:OpenAI 调用(官方方式)
# ============================================================
def demo_openai():
"""演示 OpenAI 官方模型调用"""
print("\n" + "=" * 60)
print("【演示一】OpenAI 模型调用")
print("=" * 60)
try:
from langchain_openai import ChatOpenAI
# 从环境变量读取API密钥
api_key = os.getenv("OPENAI_API_KEY")
if not api_key:
print("⚠️ 未配置 OPENAI_API_KEY,跳过 OpenAI 演示")
return
# 初始化模型
llm = ChatOpenAI(
model="gpt-4o-mini", # 模型名称,性价比高
temperature=0.7, # 控制随机性
timeout=60, # 超时时间(秒)
max_retries=2 # 失败重试次数
)
# 调用模型
messages = [HumanMessage(content="请用一句话介绍什么是LangChain")]
response = llm.invoke(messages)
print("✓ OpenAI 调用成功!")
print(f"回答: {response.content}")
print(f"Token消耗: {response.response_metadata.get('token_usage', {})}")
except ImportError:
print("✗ 未安装 langchain-openai,请执行: pip install langchain-openai")
except Exception as e:
print(f"✗ OpenAI 调用失败: {e}")
# ============================================================
# 第二部分:通义千问调用
# ============================================================
def demo_tongyi():
"""演示通义千问(阿里云 Qwen)模型调用"""
print("\n" + "=" * 60)
print("【演示二】通义千问(Qwen)模型调用")
print("=" * 60)
# 检查依赖
try:
import dashscope
from langchain_community.chat_models.tongyi import ChatTongyi
except ImportError:
print("✗ 未安装 dashscope,请执行: pip install dashscope")
return
# 检查API密钥
api_key = os.getenv("DASHSCOPE_API_KEY")
if not api_key:
print("⚠️ 未配置 DASHSCOPE_API_KEY,跳过通义千问演示")
return
# 初始化模型
llm = ChatTongyi(
model="qwen-plus", # qwen-plus 平衡性能与成本
temperature=0.7,
dashscope_api_key=api_key
)
# 调用模型
messages = [HumanMessage(content="请用一句话介绍什么是RAG检索增强生成")]
response = llm.invoke(messages)
print("✓ 通义千问调用成功!")
print(f"回答: {response.content}")
print(f"Token消耗: {response.response_metadata.get('token_usage', {})}")
# ============================================================
# 第三部分:DeepSeek 调用(官方包方式)
# ============================================================
def demo_deepseek():
"""演示 DeepSeek 模型调用"""
print("\n" + "=" * 60)
print("【演示三】DeepSeek 模型调用")
print("=" * 60)
# 检查依赖
try:
from langchain_deepseek import ChatDeepSeek
except ImportError:
print("✗ 未安装 langchain-deepseek,请执行: pip install langchain-deepseek")
return
# 检查API密钥
api_key = os.getenv("DEEPSEEK_API_KEY")
if not api_key:
print("⚠️ 未配置 DEEPSEEK_API_KEY,跳过 DeepSeek 演示")
return
# 初始化模型
# 注意:截至2026年5月,DeepSeek推荐使用 deepseek-v4-flash 或 deepseek-v4-pro
# 此处使用 deepseek-chat 保持向后兼容,后续请切换至新模型名
llm = ChatDeepSeek(
model="deepseek-chat",
temperature=0.7,
api_key=api_key,
timeout=60
)
# 调用模型
messages = [HumanMessage(content="请用一句话介绍什么是Agent智能体")]
response = llm.invoke(messages)
print("✓ DeepSeek 调用成功!")
print(f"回答: {response.content}")
print(f"元数据: {response.response_metadata}")
# ============================================================
# 第四部分:多模型切换工厂
# ============================================================
class ModelFactory:
"""
模型工厂类:根据配置字符串返回对应的模型实例
支持模型:openai, tongyi, deepseek, zhipu
"""
@staticmethod
def get_model(provider: str, model: str = None, temperature: float = 0.7):
"""
获取指定供应商的模型实例
Args:
provider: 模型供应商(openai/tongyi/deepseek/zhipu)
model: 模型名称(可选,不传则使用默认)
temperature: 温度参数
Returns:
BaseChatModel实例
"""
provider_lower = provider.lower()
if provider_lower == "openai":
from langchain_openai import ChatOpenAI
return ChatOpenAI(
model=model or "gpt-4o-mini",
temperature=temperature
)
elif provider_lower == "tongyi":
from langchain_community.chat_models.tongyi import ChatTongyi
return ChatTongyi(
model=model or "qwen-plus",
temperature=temperature,
dashscope_api_key=os.getenv("DASHSCOPE_API_KEY")
)
elif provider_lower == "deepseek":
from langchain_deepseek import ChatDeepSeek
return ChatDeepSeek(
model=model or "deepseek-chat",
temperature=temperature,
api_key=os.getenv("DEEPSEEK_API_KEY")
)
elif provider_lower == "zhipu":
from langchain_openai import ChatOpenAI
return ChatOpenAI(
model=model or "glm-4",
openai_api_key=os.getenv("ZHIPU_API_KEY"),
openai_api_base=os.getenv("BASE_URL"),
temperature=temperature
)
else:
raise ValueError(f"不支持的模型供应商: {provider}")
def demo_model_factory():
"""演示模型工厂:多模型一键切换"""
print("\n" + "=" * 60)
print("【演示四】模型工厂 - 多模型一键切换")
print("=" * 60)
# 从环境变量读取当前使用的模型供应商
current_provider = os.getenv("PROVIDER", "tongyi")
print(f"当前配置的模型供应商: {current_provider}")
try:
# 通过工厂创建模型实例
llm = ModelFactory.get_model(
provider=current_provider,
temperature=0.7
)
# 统一的业务逻辑
question = "请用一句话介绍什么是大语言模型(LLM)"
response = llm.invoke([HumanMessage(content=question)])
print(f"✓ {current_provider.upper()} 调用成功!")
print(f"问题: {question}")
print(f"回答: {response.content}")
except Exception as e:
print(f"✗ {current_provider} 调用失败: {e}")
print(" 请检查环境变量配置(OPENAI_API_KEY / DASHSCOPE_API_KEY / DEEPSEEK_API_KEY)")
# ============================================================
# 主函数
# ============================================================
def main():
"""主入口:依次执行所有演示"""
print("\n" + "=" * 60)
print("LangChain 第3课:多模型通用调用完整演示")
print("=" * 60)
# 依次执行各个演示
demo_openai()
demo_tongyi()
demo_deepseek()
demo_model_factory()
print("\n" + "=" * 60)
print("所有演示执行完毕")
print("=" * 60)
if __name__ == "__main__":
main()
环境依赖安装命令
# 激活虚拟环境
source venv/bin/activate # Mac/Linux
# venv\Scripts\activate # Windows
# LangChain核心依赖
pip install langchain==0.3.7 langchain-core==0.3.21 langchain-openai==0.2.8 python-dotenv==1.0.1
# 通义千问依赖(ChatTongyi方式)
pip install dashscope
# DeepSeek官方集成包
pip install langchain-deepseek
# [可选] 通义千问的OpenAI兼容方式无需额外包
# [可选] 智谱AI已在第1课中配置
# 一键安装全部依赖(推荐)
pip install langchain==0.3.7 langchain-core==0.3.21 langchain-openai==0.2.8 python-dotenv==1.0.1 dashscope langchain-deepseek
常见报错坑点与避坑方案
坑1:ImportError: cannot import name 'ChatTongyi' from 'langchain_community.chat_models.tongyi'
原因:未安装dashscope包。
解决:执行pip install dashscope。
坑2:ImportError: No module named 'langchain_deepseek'
原因:未安装langchain-deepseek包。
解决:执行pip install langchain-deepseek。或使用OpenAI兼容方式接入,无需此包。
坑3:通义千问返回 "code": "InvalidApiKey" 或 401错误
原因:API密钥无效或过期。
解决:
- 登录阿里云百炼控制台重新生成API Key。
- 确认环境变量名正确:
DASHSCOPE_API_KEY(非QWEN_API_KEY)。
坑4:DeepSeek调用返回 404: model not found
原因:模型名称不正确,或使用了已废弃的旧模型名。
解决:截至2026年5月,DeepSeek推荐使用deepseek-v4-flash或deepseek-v4-pro作为模型名称。旧的deepseek-chat和deepseek-reasoner将于2026年7月24日停止使用。建议尽快迁移至新模型名:
# 旧写法(即将废弃)
llm = ChatDeepSeek(model="deepseek-chat")
# 新写法(推荐)
llm = ChatDeepSeek(model="deepseek-v4-flash")
坑5:OpenAI调用报 RateLimitError 限流
原因:请求频率超过API限制(免费账号每分钟数次的限制)。
解决:
- 增加
max_retries参数,让SDK自动重试。 - 使用
batch方法时降低max_concurrency。 - 升级到付费套餐。
坑6:dotenv加载.env文件不生效
原因:.env文件位置不对,或文件名拼写错误。
解决:
- 确保
.env文件与脚本在同一目录,或在项目根目录。 - 使用
load_dotenv(verbose=True)查看加载状态。 - 尝试指定路径:
load_dotenv(dotenv_path="/path/to/.env")。
坑7:ChatOpenAI初始化时base_url参数名错误
原因:不同LangChain版本中参数名不同。0.1.x使用openai_api_base,0.3.x仍支持该参数但推荐使用base_url。
解决:使用openai_api_base保持向后兼容:
llm = ChatOpenAI(
openai_api_key="xxx",
openai_api_base="https://api.deepseek.com/v1", # 使用此参数名更稳妥
model="deepseek-chat"
)
本节核心知识点总结
📌 LangChain的统一模型接口:所有模型都继承自BaseChatModel,提供相同的.invoke()、.stream()、.batch()等方法,实现“One API for any model”。
📌 模型切换的“三种方式”:
- 官方集成包:
langchain-openai、langchain-community.tongyi、langchain-deepseek。 - OpenAI兼容接口:通过
ChatOpenAI+base_url接入任何兼容OpenAI格式的模型。 - 自定义包装:编写自定义Runnable封装原生API(高级)。
📌 OpenAI调用:使用from langchain_openai import ChatOpenAI,核心参数是model和temperature。国内访问可通过base_url配置代理。
📌 通义千问调用:使用from langchain_community.chat_models.tongyi import ChatTongyi,需要安装dashscope包。主要模型:qwen-max(最强)、qwen-plus(均衡)、qwen-flash(高性价比)。
📌 DeepSeek调用:官方包langchain-deepseek提供ChatDeepSeek类。新用户赠送500万tokens免费额度,性价比极高。注意模型名称即将升级迁移。
📌 模型工厂模式:通过配置文件(.env)定义当前使用的模型供应商,业务代码完全复用,实现“一键切换模型”。
📌 API密钥管理最佳实践:
- 使用
.env文件管理,绝不硬编码。 - 各厂商密钥环境变量各不相同:
OPENAI_API_KEY、DASHSCOPE_API_KEY、DEEPSEEK_API_KEY。 - 通过
python-dotenv自动加载。
课后练习题(含原题+标准答案+详细解析)
选择题
1. 以下哪一个是LangChain中所有大模型调用类都实现的统一基类?
A. BaseLLM
B. BaseChatModel
C. BaseLanguageModel
D. Runnable
2. 要通过OpenAI兼容方式接入DeepSeek API,以下代码中正确的是?
A. llm = ChatDeepSeek(model="deepseek-chat")
B. llm = ChatOpenAI(model="deepseek-chat", openai_api_key="xxx")
C. llm = ChatOpenAI(model="deepseek-chat", openai_api_base="https://api.openai.com/v1")
D. llm = ChatOpenAI(model="deepseek-chat", openai_api_key="xxx", openai_api_base="https://api.deepseek.com/v1")
3. 关于通义千问(Qwen)的接入方式,以下说法错误的是?
A. ChatTongyi需要安装dashscope包
B. 通义千问可以通过OpenAI兼容接口接入
C. ChatTongyi的环境变量是QWEN_API_KEY
D. 通义千问有qwen-plus、qwen-max等多个模型版本
4. 以下哪个是DeepSeek新版推荐使用的模型名称(截至2026年5月)?
A. deepseek-chat
B. deepseek-v3
C. deepseek-v4-flash
D. deepseek-reasoner
答案及解析:
-
B。所有聊天模型都继承自
BaseChatModel,它定义了invoke、stream等核心方法。BaseLLM是早期的文本补全模型基类(已逐渐废弃)。Runnable是所有可调用组件的基类,但模型通常以其作为父接口,具体实现为BaseChatModel。 -
D。
ChatOpenAI通过配置openai_api_base指向DeepSeek官方兼容端点https://api.deepseek.com/v1,同时传入DeepSeek的API密钥。选项A是官方包方式而非兼容方式;选项B缺少base_url配置;选项C指向了OpenAI官方端点。 -
C。
ChatTongyi使用的环境变量是DASHSCOPE_API_KEY,QWEN_API_KEY不是标准环境变量名。其他选项均正确。 -
C。根据DeepSeek官方更新日志,旧模型名
deepseek-chat与deepseek-reasoner将于2026年7月24日停止使用,新模型名应为deepseek-v4-pro或deepseek-v4-flash。
简答题
5. 请对比 LangChain 接入大模型的“官方集成包”和“OpenAI兼容接口”两种方式的优缺点。
参考答案:
| 维度 | 官方集成包 | OpenAI兼容接口 |
|---|---|---|
| 优点 | 类型提示完整,模型特有参数支持好(如通义千问的enable_search),官方维护更新及时 |
代码高度复用,切换模型只需改几行配置,业务逻辑完全不变 |
| 缺点 | 每个模型需记忆不同的类名和初始化参数,代码改动较大 | 可能无法完全利用某些模型的特色功能(如专用参数),部分模型兼容性不够完美 |
使用建议:快速原型开发时优先使用OpenAI兼容方式,追求功能完整性和稳定性时使用官方集成包。
6. 设计一个方案,在你的LangChain应用中实现“模型热切换”(不重启服务即可切换模型)。
参考答案:可以使用以下方案:
- 将模型供应商和模型名称配置在配置文件(如
.env或YAML)或数据库配置表中。 - 在代码中使用模型工厂模式(如本课中的
ModelFactory),每次调用模型时根据当前配置动态创建实例。 - 对于需要长期运行的服务,可使用
lru_cache或functools.lru_cache缓存模型实例,避免频繁创建的开销。 - 如需实时切换而不重启服务,可监听配置文件变更(如使用
watchdog库),配置文件变化时自动过期原有缓存,重新创建模型实例。
实践题
7. 编写一段代码,实现一个函数ask_with_cost_tracking(query: str) -> dict,该函数调用任意LangChain模型,返回结果和本次调用的token消耗统计,要求返回格式为{"answer": str, "input_tokens": int, "output_tokens": int, "total_tokens": int, "cost_usd": float}(假设OpenAI定价:输入$0.15/1M tokens,输出$0.6/1M tokens)。
参考答案:
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage
load_dotenv()
# 定价参考 OpenAI GPT-4o-mini(2025年标准)
PRICE_INPUT_PER_1K = 0.00015 # $0.15 per 1M = $0.00015 per 1K
PRICE_OUTPUT_PER_1K = 0.0006 # $0.60 per 1M = $0.0006 per 1K
def ask_with_cost_tracking(query: str) -> dict:
"""
调用模型并返回答案和Token消耗统计
Args:
query: 用户问题
Returns:
包含答案和Token统计的字典
"""
llm = ChatOpenAI(
model="gpt-4o-mini",
temperature=0.7
)
response = llm.invoke([HumanMessage(content=query)])
token_usage = response.response_metadata.get("token_usage", {})
input_tokens = token_usage.get("prompt_tokens", 0) # 输入Token数
output_tokens = token_usage.get("completion_tokens", 0) # 输出Token数
total_tokens = token_usage.get("total_tokens", 0)
# 计算成本(单位:USD)
cost_usd = (input_tokens / 1000 * PRICE_INPUT_PER_1K) + (output_tokens / 1000 * PRICE_OUTPUT_PER_1K)
return {
"answer": response.content,
"input_tokens": input_tokens,
"output_tokens": output_tokens,
"total_tokens": total_tokens,
"cost_usd": round(cost_usd, 6)
}
# 示例调用
if __name__ == "__main__":
result = ask_with_cost_tracking("介绍LangChain的核心功能")
print(f"答案: {result['answer']}")
print(f"输入Token: {result['input_tokens']}")
print(f"输出Token: {result['output_tokens']}")
print(f"总Token: {result['total_tokens']}")
print(f"成本: ${result['cost_usd']}")
解析:此题目考察对模型响应的元数据解析能力。response.response_metadata中的token_usage字段包含了prompt_tokens(输入)和completion_tokens(输出),根据不同模型的定价公式可计算出单次调用的成本。这对于在生产环境中控制API开销非常实用。
🔗《30节课 LangChain 从入门到精通》系列课程导航
🌟 感谢您耐心阅读到这里!
💡 如果本文对您有所启发欢迎:
👍 点赞📌 收藏 📤 分享给更多需要的伙伴。
🗣️ 期待在评论区看到您的想法, 共同进步。
🔔 关注我,持续获取更多干货内容~
🤗 我们下篇文章见~
更多推荐


所有评论(0)