LangChain 模型调用全家桶:LLM、聊天模型、嵌入模型、流式输出
认识了 LangChain 的全貌之后,第一个要拿下的就是模型调用——这是所有 LLM 应用的"发动机"。LangChain 最让人舒服的地方在于:不管底层是 OpenAI、通义千问、DeepSeek,还是本地 Ollama 跑的 Llama,上层代码写法几乎一模一样。本文带你一口气搞懂 LangChain 模型调用的全部姿势。
一、LangChain 里的两种"模型"
在 LangChain 的世界里,"模型"不是一个模糊的概念,而是有明确分类的。打开 langchain 的模型货架,你会看到两条主线:
| 类型 | 类名 | 输入 | 输出 | 典型场景 |
|---|---|---|---|---|
| LLM(传统大模型) | LLM | 纯文本字符串 | 纯文本字符串 | 文本补全、续写、翻译 |
| ChatModel(聊天模型) | ChatModel | 消息列表 | 消息对象 | 多轮对话、带角色的交互 |
1.1 LLM:老派的"文本进,文本出"
LLM 是 LangChain 早期的主要接口,输入一个字符串,返回一个字符串,简单粗暴:
from langchain_openai import OpenAI
llm = OpenAI(model="gpt-3.5-turbo-instruct")
result = llm.invoke("请用一句话概括人工智能")
print(result)
# "人工智能是让机器模拟人类智能行为的科学与技术。"
不过说实话,现在 99% 的场景都用 ChatModel,LLM 接口已经逐渐退居二线。你只需要知道它存在,但实际开发中优先选 ChatModel。
1.2 ChatModel:消息列表进,消息对象出
ChatModel 是当前的主流。它接收一个消息列表,返回一个消息对象。消息不是简单的字符串,而是有"角色"的:
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini")
# 消息列表:每条消息都有"角色"
messages = [
("system", "你是一个幽默的助手,回答要风趣。"),
("human", "为什么程序员喜欢用深色模式?"),
]
response = llm.invoke(messages)
print(response.content)
# "因为光会吸引 bug!😂"
核心区别一句话:LLM 是"给一段文字,回一段文字";ChatModel 是"给一段对话,回一句回复"。 后者更符合现代大模型的实际交互方式。
二、消息的三件套:System、Human、AI
ChatModel 的消息列表不是随便写的,每条消息都有明确的角色。LangChain 支持三种核心消息类型:
| 消息类型 | 角色 | 含义 | 谁来写 |
|---|---|---|---|
SystemMessage | system | 系统级指令,定义 AI 的行为边界 | 你 |
HumanMessage | human / user | 用户说的话 | 你(或你的用户) |
AIMessage | ai / assistant | AI 的回复 | 模型 |
2.1 三种写法,任你选
LangChain 提供了三种消息写法,从啰嗦到简练,你可以按喜好选择:
from langchain.schema import SystemMessage, HumanMessage, AIMessage
# 写法一:完整对象写法(最啰嗦,但最严谨)
messages = [
SystemMessage(content="你是专业的 Python 代码审查员"),
HumanMessage(content="这段代码有什么问题?"),
]
# 写法二:元组简写(推荐,日常用最舒服)
messages = [
("system", "你是专业的 Python 代码审查员"),
("human", "这段代码有什么问题?"),
]
# 写法三:字典写法(JS 开发者可能会喜欢)
messages = [
{"role": "system", "content": "你是专业的 Python 代码审查员"},
{"role": "user", "content": "这段代码有什么问题?"},
]
# 三种写法效果完全一样,llm.invoke(messages) 都能正确识别
日常推荐用元组简写——看着清爽,写着快,一行搞定一个角色。
2.2 多轮对话怎么传?
把历史消息原样塞回去就行,LangChain 会自动处理上下文:
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini")
# 第一轮
history = [
("system", "你是一个数学老师"),
("human", "什么是勾股定理?"),
]
response = llm.invoke(history)
print(response.content) # AI 回答了勾股定理
# 把 AI 的回复塞进历史,再问第二轮
history.append(("ai", response.content)) # 把 AI 回复加入历史
history.append(("human", "举个例子说明一下")) # 追加新问题
response = llm.invoke(history)
print(response.content) # AI 基于上下文给出了例子
这就是 LangChain Memory 组件的底层原理——维护一个消息列表,每次调用时把历史拼回去。后面讲 Memory 时你会发现,它的本质就是帮你自动管理这个列表。
三、一个 ChatOpenAI,通吃所有厂商
这是 LangChain 最实用的设计之一。因为 OpenAI 的 API 格式已经成为事实标准,国内几乎所有大模型厂商都提供了 OpenAI 兼容接口。这意味着:
你只需要学会
ChatOpenAI这一个类,就能调用 OpenAI、通义千问、DeepSeek、智谱、月之暗面……所有兼容 OpenAI 协议的模型。 换模型就是改两行配置,业务代码纹丝不动。
3.1 通义千问(阿里)
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="qwen-plus", # 模型名
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", # 通义千问的兼容端点
api_key="sk-xxxxxxxx" # 你的 API Key
)
response = llm.invoke([("human", "介绍一下杭州")])
print(response.content)
3.2 DeepSeek
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="deepseek-chat",
base_url="https://api.deepseek.com/v1",
api_key="sk-xxxxxxxx"
)
response = llm.invoke([("human", "用 Rust 写一段快速排序")])
print(response.content)
3.3 智谱 GLM
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="glm-4",
base_url="https://open.bigmodel.cn/api/paas/v4",
api_key="xxxxxxxx"
)
response = llm.invoke([("human", "解释一下量子纠缠")])
3.4 月之暗面 Moonshot
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="moonshot-v1-8k",
base_url="https://api.moonshot.cn/v1",
api_key="sk-xxxxxxxx"
)
response = llm.invoke([("human", "写一首关于秋天的诗")])
看明白了吗? 四个厂商,四段代码,区别只有
model和base_url。这就是 LangChain 统一接口的威力——厂商是"插件",你的代码是"主机",换插件不影响主机运行。
四、本地模型:Ollama 让 GPU 不闲置
云端 API 虽好,但有些场景你更想要本地模型——数据不出门、不用联网、没有调用次数限制、零成本。Ollama 就是本地部署大模型的最简单方式。
4.1 安装 Ollama 并拉一个模型
# 去 ollama.com 下载安装 Ollama(Windows/Mac/Linux 都支持)
# 安装后拉一个模型:
ollama pull qwen2.5:7b # 通义千问 2.5 7B 版本
ollama pull llama3.1:8b # Meta Llama 3.1 8B 版本
4.2 用 LangChain 调用本地模型
from langchain_ollama import ChatOllama
# 本地模型,不需要 api_key,不需要联网
llm = ChatOllama(
model="qwen2.5:7b",
temperature=0.7,
)
response = llm.invoke([("human", "用一句话解释什么是 Docker")])
print(response.content)
4.3 云端 vs 本地:一张表选型
| 场景 | 推荐方案 | 原因 |
|---|---|---|
| 快速原型、Demo | 云端 API | 部署零成本,模型能力强 |
| 敏感数据、隐私合规 | 本地 Ollama | 数据不出本地 |
| 高频调用、成本敏感 | 本地 Ollama | 一次投入,无限调用 |
| 需要最强模型能力 | 云端 API | 本地小模型能力有限 |
| 开发调试、离线环境 | 本地 Ollama | 不依赖网络 |
一句话:开发阶段用云端 API 快速验证,上线后按需切换到本地模型。 LangChain 的统一接口让这个切换几乎零成本。
五、流式输出:让 AI “一个字一个字地往外蹦”
普通调用 invoke() 是等模型完整生成后一次性返回——用户盯着空白屏幕干等,体验很差。流式输出 stream() 让模型每生成一个 token 就立刻送到前端,像 ChatGPT 那样逐字显示。
5.1 基础流式输出
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini")
# stream() 返回一个生成器,逐个送出 token
for chunk in llm.stream([("human", "讲一个关于程序员的冷笑话")]):
print(chunk.content, end="", flush=True)
# 效果:一个字一个字地往外蹦,就像打字机一样
5.2 异步流式输出
如果你在 Web 框架(如 FastAPI)里用,异步流式是标配:
import asyncio
from langchain_openai import ChatOpenAI
async def stream_chat():
llm = ChatOpenAI(model="gpt-4o-mini")
async for chunk in llm.astream([("human", "讲一个笑话")]):
print(chunk.content, end="", flush=True)
asyncio.run(stream_chat())
5.3 本地 Ollama 同样支持流式
from langchain_ollama import ChatOllama
llm = ChatOllama(model="qwen2.5:7b")
for chunk in llm.stream([("human", "介绍一下 Python 的装饰器")]):
print(chunk.content, end="", flush=True)
流式输出的本质:不是模型更快了,而是"用户感知更快了"。就像餐厅上菜,一道一道端上来比全部做好再一起端,体验好得多。
六、嵌入模型:把文字变成"坐标"
嵌入模型(Embedding Model)和聊天模型是两码事,但经常被一起用到。它的工作不是"说话",而是把一段文字转换成一串数字向量——就像给每段文字分配一个 GPS 坐标:
- 语义相近的文字,坐标也相近
- “苹果好吃” 和 “我喜欢吃苹果” 的向量距离很近
- “苹果好吃” 和 “今天下雨” 的向量距离很远
6.1 调用嵌入模型
from langchain_openai import OpenAIEmbeddings
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
# 把文字变成向量
vec = embeddings.embed_query("LangChain 是一个大模型开发框架")
print(len(vec)) # 1536 维向量
print(vec[:5]) # [0.0123, -0.0045, 0.0234, ...]
6.2 嵌入模型的用途
| 用途 | 原理 |
|---|---|
| 语义搜索 | 把问题和文档都转成向量,找距离最近的文档 |
| 文本聚类 | 相似内容的向量聚在一起,自动分类 |
| 推荐系统 | 找到和你喜欢的内容"坐标相近"的其他内容 |
| RAG 知识库 | 这是嵌入模型最常见的落地场景 |
嵌入模型是 RAG(检索增强生成)的地基,后面讲向量存储和 RAG 时会大量用到。现在你只需要记住:它把文字变成"坐标",语义相近的文字坐标也相近。
七、common 参数:控制模型"性格"的几个旋钮
调用模型时,有几个参数几乎每次都会用到。它们就像音响上的旋钮,控制着模型的"创造力"和"稳定性":
| 参数 | 含义 | 取值范围 | 怎么调 |
|---|---|---|---|
temperature | 随机性 / 创造力 | 0 ~ 2 | 0=严谨确定,1=均衡,>1=天马行空 |
max_tokens | 最大输出长度 | 正整数 | 短回答 256,长回答 2048+ |
top_p | 核采样,控制词汇选择范围 | 0 ~ 1 | 通常和 temperature 二选一调 |
from langchain_openai import ChatOpenAI
# 严谨模式:写代码、做数学题
strict_llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
# 创意模式:写诗、写故事
creative_llm = ChatOpenAI(model="gpt-4o-mini", temperature=1.2)
# 均衡模式:日常对话
balanced_llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.7)
经验法则:需要准确答案时 temperature 往低调,需要创意灵感时 temperature 往高调。 写代码用 0,写诗用 1.0+,日常聊天用 0.7。
八、总结
| 要点 | 一句话 |
|---|---|
| LLM vs ChatModel | 现代开发一律用 ChatModel,LLM 已退居二线 |
| 消息三种角色 | System(定规则)、Human(提问)、AI(回答) |
| 多厂商调用 | 一个 ChatOpenAI 通吃所有兼容 OpenAI 协议的模型 |
| 本地模型 | Ollama + ChatOllama,数据不出门,零成本调用 |
| 流式输出 | stream() 让模型逐字输出,用户体验大幅提升 |
| 嵌入模型 | 把文字变向量,语义搜索和 RAG 的地基 |
| 核心参数 | temperature 控制创造力,max_tokens 控制长度 |
LangChain 模型层的设计哲学就一句话:把"用什么模型"和"怎么用模型"彻底解耦。 换模型只改配置,业务逻辑纹丝不动——这才是框架该有的样子。

336

被折叠的 条评论
为什么被折叠?



