LangChain 模型创建与调用完全指南:从入门到生产实践
前言
如果说 LangChain 框架是构建 AI 应用的"操作系统",那么模型的创建与调用就是其中最基础也是最关键的一环。无论是接入云端大模型(如 DeepSeek、千问),还是部署本地模型(通过 Ollama),都需要掌握统一的调用范式。
本文基于 LangChain v1.2,系统梳理模型创建的三种方式、模型调用的六种方法,以及返回值解析、参数配置等进阶内容。文中包含大量可直接运行的代码示例,助你快速上手。
一、模型调用的基础认知
1.1 从 Model I/O 说起
在 LangChain v0.3 时代,框架提出了经典的 Model I/O 三阶段模型:
输入提示(Format) → 调用模型(Predict) → 输出解析(Parse)
分别对应三个核心组件:PromptTemplate → Model → OutputParser。
GPT-3 时代以补全模型为主,LangChain 通过高层 API 封装,使模型能完成对话、工具调用、结构化输出等任务。GPT-3.5 之后,对话模型(ChatModel)成为绝对主流,本文也只聚焦于对话模型。
1.2 三个维度看模型初始化
| 维度 | 分类 | 推荐 |
|---|---|---|
| 调用谁的 API | 模型提供商专用库 / LangChain 统一方式 | 统一方式 |
| 参数存放位置 | 配置文件(.env)/ 硬编码 | 配置文件 |
| 模型位置 | 在线部署 / 本地部署 | 视场景而定 |
1.3 主流大模型服务平台
| 平台 | 特点 | 适合人群 |
|---|---|---|
| OpenRouter | 全球主流,含国外模型 | 需科学上网 |
| CloseAI | 亚洲最大中转平台 | 国内开发者首选 |
| 阿里云百炼 | 企业端友好,新用户免费额度 | 企业用户 |
| 硅基流动 | 性价比高 | 个人开发者 |
| 百度千帆 | 百度生态 | 百度生态用户 |
| 火山引擎 | 字节多模态生态 | 多模态需求 |
无论选择哪个平台,配置只需要三个要素:模型名、api-key、base-url。
二、模型创建的三种方式
方式一:使用模型提供商的专用类(最直接)
LangChain 为各大模型供应商提供了专用 Model 类,开箱即用。
DeepSeek
pip install langchain-deepseek python-dotenv
.env 配置:
DEEPSEEK_API_KEY=<Your API Key>
DEEPSEEK_BASE_URL=https://api.deepseek.com
推荐写法(依赖默认行为,自动读取环境变量):
from langchain_deepseek import ChatDeepSeek
from dotenv import load_dotenv
load_dotenv(override=True)
deepseek_llm = ChatDeepSeek(model="deepseek-v4-flash")
print(deepseek_llm.invoke("请介绍一下你自己"))
ChatDeepSeek 内部通过
secret_from_env("DEEPSEEK_API_KEY")自动读取环境变量,DEFAULT_API_BASE也有默认值,无需手动传入。
智谱 AI
pip install langchain-community pyjwt
from langchain_community.chat_models import ChatZhipuAI
from dotenv import load_dotenv
import os
load_dotenv(override=True)
zhipu_llm = ChatZhipuAI(
model="glm-5.1",
api_base=os.getenv("ZHIPUAI_BASE_URL"),
api_key=os.getenv("ZHIPUAI_API_KEY"),
)
print(zhipu_llm.invoke("请介绍一下你自己"))
通义千问(阿里云百炼)
pip install dashscope
注意:千问基于专用 SDK(DashScope),不要添加 OpenAI 兼容格式的
base_url,否则会报错。
from langchain_community.chat_models import ChatTongyi
from dotenv import load_dotenv
import os
load_dotenv(override=True)
tongyi_llm = ChatTongyi(
api_key=os.getenv("DASHSCOPE_API_KEY"),
model="qwen-plus",
)
print(tongyi_llm.invoke("请介绍一下你自己"))
兼容用法:通过 ChatOpenAI 统一调用
大多数 API 平台都遵循 OpenAI 接口规范,因此可以通过 ChatOpenAI 作为通用入口:
from langchain_openai import ChatOpenAI
# 调用 DeepSeek
deepseek_llm = ChatOpenAI(
api_key=os.getenv("DEEPSEEK_API_KEY"),
base_url=os.getenv("DEEPSEEK_BASE_URL"),
model="deepseek-v4-flash",
)
# 调用智谱
zhipu_llm = ChatOpenAI(
api_key=os.getenv("ZHIPUAI_API_KEY"),
base_url=os.getenv("ZHIPUAI_BASE_URL"),
model="glm-5.1",
)
# 调用千问(需设置正确的 base_url)
tongyi_llm = ChatOpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
model="qwen-plus",
)
中转平台:OpenRouter
pip install langchain-openrouter
from langchain_openrouter import ChatOpenRouter
model = ChatOpenRouter(
model="deepseek/deepseek-v4-flash",
api_key=os.getenv("OPENROUTER_API_KEY"),
)
print(model.invoke("一句话介绍下你自己"))
方式二:使用 init_chat_model() 统一接口(推荐)
init_chat_model 是 LangChain v1.x 推出的统一模型创建入口,根据模型名称自动匹配对应的供应商类。优势在于:统一语法、易于切换、自动适配。
# 统一模型创建入口案例
from langchain.chat_models import init_chat_model
model = init_chat_model(
"provider:model_name", # 冒号前是供应商,后面是模型名
api_key="your-api-key",
temperature=0.7,
max_tokens=1000,
)
调用 DeepSeek:
model = init_chat_model(
model="deepseek:deepseek-v4-flash", # 冒号前是供应商,后面是模型名
api_key=os.getenv("DEEPSEEK_API_KEY"),
base_url=os.getenv("DEEPSEEK_BASE_URL"),
)
调用阿里百炼(兼容方式,声明 model_provider="openai"):
model = init_chat_model(
model="qwen-plus",
model_provider="openai",
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)
支持的 model_provider 包括但不限于:openai、deepseek、anthropic、ollama、groq、huggingface、openrouter、google_genai、mistralai、cohere 等。
小结:同一个 DeepSeek 模型可通过多种方式调用:
| 来源 | 可用方式 |
|---|---|
| DeepSeek 官网 | ChatDeepSeek() / ChatOpenAI() / init_chat_model() |
| 阿里云百炼 | ChatTongyi() / ChatOpenAI() / init_chat_model() |
| OpenRouter | ChatOpenRouter() / ChatOpenAI() / init_chat_model() |
方式三:本地模型 —— Ollama 部署与调用
Ollama 是一个开源的本地大模型运行框架,可一键部署 DeepSeek、Qwen 等主流模型。
安装与下载模型
官网下载安装包:https://ollama.com
# 下载并运行模型
ollama run deepseek-r1:1.5b
常用命令:
| 命令 | 说明 |
|---|---|
ollama pull llama3 |
下载模型 |
ollama run llama3 |
运行模型 |
ollama list |
查看已下载模型 |
ollama rm llama3 |
删除模型 |
ollama serve |
启动 API 服务 |
LangChain 调用 Ollama
pip install langchain-ollama
from langchain_ollama import ChatOllama
ollama_llm = ChatOllama(model="deepseek-r1:1.5b")
result = ollama_llm.invoke("你好,请介绍一下你自己")
print(result)
也可通过 init_chat_model 统一调用:
ollama_llm = init_chat_model(
model="deepseek-r1:1.5b",
model_provider="ollama",
)
三、模型调用的六种方法
LangChain 提供了六种调用方式,覆盖同步/异步、单次/批量、一次性/流式等场景:
| 方法 | 特点 | 适用场景 |
|---|---|---|
invoke() |
阻塞式,一次性返回 | 问答、批处理 |
stream() |
流式输出,逐 token 返回 | 聊天机器人、长文本生成 |
batch() |
批量处理,并行执行 | 高并发批处理 |
ainvoke() |
异步版 invoke | 高并发 Web 应用 |
astream() |
异步流式输出 | 高并发 + 流式 |
abatch() |
异步批量处理 | 高并发 Web 应用 |
3.1 invoke() —— 最核心的调用方法
response = model.invoke("翻译成英文:你好世界")
print(response.content)
invoke 支持三种输入格式:
① 纯文本(最简单):
response = model.invoke("什么是斐波那契数列?")
② 字典列表(推荐,最灵活):
messages = [
{"role": "system", "content": "你是一个专业的数学老师。"},
{"role": "user", "content": "2 + 3 * 2 = ?"},
{"role": "assistant", "content": "8"},
{"role": "user", "content": "我刚才问了什么问题?"}
]
response = model.invoke(messages)
三种角色:
| 角色 | 对应字典 | 作用 |
|---|---|---|
| system | {"role": "system", ...} |
设定 AI 行为、角色、规则 |
| user | {"role": "user", ...} |
用户输入 |
| assistant | {"role": "assistant", ...} |
AI 历史回复(用于记忆) |
③ 消息对象列表(类型安全):
from langchain_core.messages import SystemMessage, HumanMessage, AIMessage
messages = [
SystemMessage("你是一个专业的数学老师。"),
HumanMessage("2 + 3 * 2 = ?"),
AIMessage("8"),
HumanMessage("我刚才问什么问题了?")
]
response = model.invoke(messages)
3.2 stream() —— 流式输出
for chunk in model.stream("写一首七言律诗,总结大模型的发展"):
print(chunk.text, end="", flush=True) # 逐 token 输出
优点:响应更快、体验更流畅、可实时展示模型思考过程。
3.3 batch() —— 批量调用
messages = ["你好,你是谁?", "2 + 3 * 5 = ?", "中国首都在哪里?"]
responses = model.batch(messages)
for response in responses:
print(response.content)
batch() 等所有请求完成后按原始顺序返回。如果希望按完成顺序接收,可使用 batch_as_completed():
for index, response in model.batch_as_completed(messages):
print(f"第 {index} 个完成:{response.content}")
性能对比:批量调用相较循环调用可节省 60% 以上的时间。
3.4 异步调用:ainvoke / astream / abatch
在 Web 应用中,同步调用会阻塞线程。异步方法让请求在后台执行,主线程继续处理其他任务。
import asyncio
async def main():
# 发起异步调用但不等待
task = asyncio.create_task(model.ainvoke("用一句话解释人工智能"))
# 继续执行其他逻辑
print("模型请求已发送,继续执行本地任务...")
await asyncio.sleep(1)
# 获取结果
response = await task
print(response.content)
asyncio.run(main())
astream() 异步流式输出和 abatch() 异步批量处理的用法类似,完整代码可参考官方文档。
四、深入理解 invoke 的返回值
invoke() 返回的是一个 AIMessage 对象,不仅仅是文本,还包含丰富的元数据。
4.1 AIMessage 结构剖析
response = model.invoke("用一句话解释什么是 AI")
# 1. 文本内容
print(response.content)
# 2. 响应元数据
metadata = response.response_metadata
print(f"使用的模型: {metadata['model_name']}")
print(f"结束原因: {metadata['finish_reason']}")
# 3. Token 用量
usage = metadata.get('token_usage', {})
print(f"输入 tokens : {usage.get('prompt_tokens')}")
print(f"输出 tokens : {usage.get('completion_tokens')}")
print(f"总计 tokens : {usage.get('total_tokens')}")
# 4. 延迟性能(毫秒)
latency = usage.get('latency_checkpoint', {})
print(f"首 Token 时间: {latency.get('service_ttft_ms')}ms")
print(f"总耗时: {latency.get('total_duration_ms')}ms")
4.2 关键字段解析
| 字段 | 说明 |
|---|---|
content |
模型生成的文本答案 |
response_metadata.token_usage |
Token 用量详情(输入/输出/总计) |
response_metadata.model_name |
实际使用的模型名称 |
response_metadata.finish_reason |
结束原因:stop(正常)/ length(超长截断) |
response_metadata.latency_checkpoint |
延迟性能指标(首 Token 时间、Token 间间隔等) |
tool_calls |
工具调用列表(Function Calling 场景) |
usage_metadata |
标准化的 Token 统计 |
4.3 多轮对话的记忆管理
大模型本身不记上下文——每次调用都是"失忆"的。需要手动管理对话历史:
conversation = [
{"role": "system", "content": "你是一个非常友好的AI助手"},
{"role": "user", "content": "你好,我叫小明"}
]
response1 = model.invoke(conversation)
print(f"AI回复:{response1.content}")
# 把 AI 回复追加到对话历史
conversation.append({"role": "assistant", "content": response1.content})
conversation.append({"role": "user", "content": "我叫什么名字?"})
response2 = model.invoke(conversation)
print(f"AI回复:{response2.content}") # 能正确回答"小明"
五、进阶技巧
5.1 模型配置画像 profile
LangChain v1.1+ 支持通过 model.profile 查看模型的能力画像:
from langchain_openrouter import ChatOpenRouter
model = ChatOpenRouter(model="openai/gpt-4o-mini")
print(model.profile)
输出示例:
{
'max_input_tokens': 128000,
'max_output_tokens': 16384,
'text_inputs': True,
'image_inputs': True,
'audio_inputs': False,
'tool_calling': True,
'structured_output': True
}
注意:是否返回完整 profile 取决于集成时是否声明了能力画像。DeepSeek 官方类暂未声明,返回为空。
5.2 常用初始化参数速查
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
model |
str | 模型名称(必需) | 无 |
temperature |
float | 输出随机性,0.0~2.0 | 0.7 |
max_tokens |
int | 最大输出 token 数 | None |
timeout |
float | 超时时间(秒) | None |
max_retries |
int | 失败重试次数 | 6 |
temperature 使用建议:
| 范围 | 适用场景 |
|---|---|
| 0.0 - 0.3 | 数学计算、数据提取、分类、代码生成 |
| 0.5 - 0.7 | 聊天、问答(平衡创造性与一致性) |
| 0.8 - 1.5 | 写作、头脑风暴 |
| 1.5 - 2.0 | 诗歌、故事创作 |
5.3 运行时动态配置 config
config 参数允许在调用时动态覆盖模型行为,无需重新初始化:
response = model.invoke(
"讲个笑话",
config={
"run_name": "joke_generation", # LangSmith 追踪名称
"tags": ["test", "development"], # 分类标签
"metadata": {"user_id": "123"}, # 附加元数据
"configurable": {
"temperature": 0.9,
"max_tokens": 200
}
}
)
configurable中的参数优先级高于初始化参数,但仅对当次调用生效。需要先在初始化时通过configurable_fields声明哪些参数允许被动态覆盖。
model = init_chat_model(
model="deepseek:deepseek-v4-flash",
temperature=0.2,
max_tokens=500,
configurable_fields=("model", "temperature", "max_tokens"),
)
5.4 美化输出
# 方式1:pretty_print()
response = model.invoke("你是谁?")
response.pretty_print()
# 方式2:rich 库
from rich import print as rprint
rprint(response)
5.5 异常处理
try:
response = model.invoke("Hello")
print(response.content)
except ValueError as e:
print(f"配置错误: {e}")
except ConnectionError as e:
print(f"网络错误: {e}")
except Exception as e:
print(f"未知错误: {e}")
总结
本文覆盖了 LangChain v1.2 中模型创建与调用的全部核心内容:
| 模块 | 核心要点 |
|---|---|
| 创建方式 | 专用类 → init_chat_model() 统一接口 → Ollama 本地部署 |
| 调用方法 | invoke / stream / batch + 对应的异步版本 |
| 输入格式 | 纯文本 / 字典列表(推荐) / 消息对象 |
| 返回值 | AIMessage 包含 content、token_usage、延迟指标等丰富信息 |
| 进阶技巧 | profile、config 动态配置、model_kwargs/extra_body |
最重要的建议:新项目直接使用
init_chat_model()创建模型,用.env管理密钥,用字典列表传消息,从invoke()开始、按需引入 stream 和异步。
官方文档:LangChain Models(英文) | 中文文档
更多推荐




所有评论(0)