【LangChain|Day01】LangChain 核心概念和模型调用笔记
文章目录
📅 更新日期:2026-06-11
1. LangChain 简介
1.1 LangChain 是什么?
LangChain 不开发大模型,而是为各种大模型提供统一的调用接口和功能封装。 可以把它理解成大模型开发的万能工具箱,把开发 LLM 应用时的常见操作(调用模型、管理提示词、存储对话记忆、分析文档等)封装成标准化的 API,让开发者能像搭积木一样快速构建复杂的 LLM 应用。
1.2 LangChain 的六大核心功能模块
LangChain 的架构围绕六个核心模块展开,每个模块解决 LLM 应用开发中的一个关键环节:
| 模块 | 功能说明 | 类比理解 |
|---|---|---|
| 模型调用(Model I/O) | 提供统一接口调用各类大模型 | 万能遥控器,一键切换不同品牌 |
| 提示词工程(Prompt) | 管理和复用提示词模板,支持变量插值、少样本示例等 | 给模型的问题模板库 |
| 会话记忆(Memory) | 存储和管理多轮对话的上下文历史 | 给模型配上一个记忆力 |
| 文档处理(Retrieval) | 加载、分割、向量化外部文档,实现 RAG(检索增强生成) | 给模型外挂一个知识库 |
| 执行链(Chains) | 将多个操作串联成流水线,上一个的输出 → 下一个的输入 | 工厂流水线,多道工序自动衔接 |
| 智能体(Agents) | 让模型自主决策调用哪些工具、按什么顺序执行 | 给模型装上大脑和双手 |
核心设计理念:我认为 链(Chain)是 LangChain 的灵魂。 LangChain 这个名字本身就包含了 “Chain”(链),它的精髓在于:将多个独立操作串联起来,上一步的输出自动成为下一步的输入。比如:
加载文档 → 文本分割 → 生成向量 → 存入数据库 → 检索 → 生成回答,这一整套流程在 LangChain 中可以用几行代码清晰地串联起来。
1.3 链式调用中的内存优化:流式(Stream)机制
一个常见的问题是:链式调用时,上一步的输出是暂存在内存里再传给下一步的吗?如果输出特别大,会不会撑爆内存?
答案是:取决于你使用哪种调用方式。
invoke()(阻塞式):默认情况下,上一步的完整结果确实会先完整存储在内存中,再传递给下一步。如果中间结果是一个 10MB 的 JSON,这 10MB 就会完整占据内存。stream()(流式):模型逐 token 生成并返回,数据像水流一样向前推进,每个环节只处理当前这个片段,不需要在内存中一次性缓存完整结果,从而大幅降低内存峰值。
但是需要注意:要实现真正的全链路流式,Chain 中的每一个环节都必须支持流式传递。 如果中间某个环节不支持流式,数据仍然会在那个环节被完整缓存。
一句话总结:选择
stream()还是invoke(),取决于你对实时性和内存占用的需求。这在后续的代码实践中会具体体现。
2. 环境安装与依赖解析
2.1 一键安装
pip install langchain langchain-openai langchain-ollama langchain-chroma dashscope chromadb bs4 jq -i https://pypi.tuna.tsinghua.edu.cn/simple
小技巧:使用清华镜像源(
-i https://pypi.tuna.tsinghua.edu.cn/simple)可以大幅提升国内用户的下载速度。
2.2 各依赖包的作用
| 包名 | 作用 | 通俗理解 |
|---|---|---|
langchain |
核心包,提供 LangChain 最核心的功能(链、提示词模板、记忆、init_chat_model 统一入口等) |
工具箱的本体 |
langchain-openai |
OpenAI 协议适配包,调用所有兼容 OpenAI API 协议的模型(DeepSeek、千问、智谱、OpenAI 官方等)。注意:不限于 OpenAI 公司,任何兼容 OpenAI 接口的服务都可以用它调用 | 最常用的万能遥控器 |
langchain-ollama |
Ollama 支持包,专门用于调用本地 Ollama 部署的大模型 | 本地模型的专用遥控器 |
langchain-chroma |
ChromaDB 支持包,向量数据库适配器,用于 RAG(检索增强生成) | 给知识库配备的「搜索引擎接口」 |
dashscope |
阿里云通义千问 Python SDK。SDK(Software Development Kit)即模型厂商提供的官方代码库,封装了认证、请求、响应解析等细节 | 千问的「官方遥控器」 |
chromadb |
ChromaDB 数据库本身,一个轻量级的向量数据库 | 向量搜索引擎本体 |
bs4 |
BeautifulSoup4,HTML 解析库,加载网页文档时用于提取内容 | 网页内容提取器 |
jq |
轻量灵活的命令行 JSON 处理工具 | JSON 数据处理小助手 |
补充说明:之后我们所说的 langchain.chat_models 是 langchain 核心包内的一个模块(不是独立的 pip 包),init_chat_model() 函数就定义在其中。导入方式为 from langchain.chat_models import init_chat_model。
init_chat_model() 只省记类名和路径的力气,但省不了 pip install,也省不了 API Key 的配置。
2.3 ⚠️ langchain-community 已被淘汰
因为在学习的时候,学习的教程内容是 pip install langchain-community,但是在实践写代码的时候,发现它已被官方淘汰
在 LangChain v1.0(2025 年 10 月发布)之后,langchain-community 的 GitHub 仓库已归档(只读),不再维护。所有模型类已迁移到专用 provider 包:
# ❌ 旧写法(langchain-community,已废弃)
from langchain_community.chat_models import ChatOpenAI
现代 LangChain(v1.0+)的安装策略是:
# 核心包(必装)
pip install langchain langchain-core
# 按需安装厂商专用包用到什么装什么
pip install langchain-openai # OpenAI / 任何 OpenAI 协议兼容的模型
pip install langchain-deepseek # DeepSeek 官方集成(v1.0.1,PyPI 月下载量 54 万+)
pip install langchain-ollama # Ollama 本地模型
pip install langchain-anthropic # Claude 系列
pip install langchain-google-genai # Gemini 系列
2.4 init_chat_model():它到底帮你做了什么?
学习的过程中,疑问:init_chat_model 是万能接口吗?我是不是装了它就不用装厂商包了?API Key 它能帮我自动搞定吗?
我们来一步步拆解。
2.4.1 init_chat_model 的本质:一个智能分发器
init_chat_model() 会根据你指定的 "provider:model" 字符串,自动去 import 对应的厂商包(比如 langchain-deepseek、langchain-openai),然后创建对应的模型实例。
所以,你仍然需要提前 pip install 好对应的厂商包。
# 写法1:用独立的厂商类(需要自己记类名和导入路径)
from langchain_deepseek import ChatDeepSeek # 需要 pip install langchain-deepseek
model = ChatDeepSeek(model="deepseek-chat")
# 写法2:用 init_chat_model(只需一个字符串,内部自动帮你找到 ChatDeepSeek)
from langchain.chat_models import init_chat_model # 核心包已装
model = init_chat_model("deepseek:deepseek-chat") # 内部会 import langchain_deepseek(也需要你装)
init_chat_model 帮你省掉的是:记忆每个厂商的类名和导入路径的麻烦,切换厂商只需改一个字符串。
2.4.2 API Key 和环境变量是怎么处理的?
规则很简单:init_chat_model 会根据 provider 自动去读对应厂商的环境变量。
| provider | 自动读取的环境变量 | 对应的厂商包 | 备注 |
|---|---|---|---|
openai |
OPENAI_API_KEY |
langchain-openai |
|
deepseek |
DEEPSEEK_API_KEY |
langchain-deepseek |
|
anthropic |
ANTHROPIC_API_KEY |
langchain-anthropic |
|
google_genai |
GOOGLE_API_KEY |
langchain-google-genai |
|
ollama |
不需要 API Key | langchain-ollama |
本地服务,默认地址 http://localhost:11434 |
如果你在代码里显式传了 api_key="sk-xxx",它就优先用你传的;如果不传,就自动去读对应的环境变量。init_chat_model 不会帮你“变出” API Key,你需要自己申请并设置到环境变量里。
2.4.3 init_chat_model 提供了什么?
- 自动设置
base_url:比如你写"deepseek:deepseek-chat",它会自动把base_url设为https://api.deepseek.com,你不需要去查文档。 - 厂商特有能力的支持:如果安装了厂商专用包,
init_chat_model内部会优先使用专用类(如ChatDeepSeek),这样就能拿到一些通用接口拿不到的“特产”。比如 DeepSeek R1 模型的reasoning_content(思考过程),用ChatOpenAI套壳是拿不到的。
一个极简的总结:
- 写
init_chat_model("deepseek:deepseek-chat")时,它自动帮你做了三件事:
① 自动 importlangchain_deepseek(你需要提前装)
② 自动设置base_url="https://api.deepseek.com"
③ 自动读取环境变量DEEPSEEK_API_KEY - 如果你用
ChatOpenAI去调 DeepSeek,必须手动指定base_url和api_key,并且api_key的默认环境变量名是OPENAI_API_KEY,很容易搞混。
3. ChatModel 调用
这是 LangChain 最核心、最常用的模块。我们将从统一入口函数开始,逐步深入到各种调用方式和消息类型。
3.1 初始化模型:init_chat_model
3.1.1 为什么需要 init_chat_model()?
如果按需安装厂商专用包用到什么装什么,切换模型厂商意味着要改类名、改导入路径、甚至改参数名:
# ❌ 旧方式:每个厂商一个类,切换成本高
from langchain_openai import ChatOpenAI # OpenAI
from langchain_anthropic import ChatAnthropic # Anthropic
from langchain_ollama import ChatOllama # Ollama
model = ChatOpenAI(model="gpt-4o") # 切到 Claude 就得改类名和导入
model = ChatAnthropic(model="claude-sonnet-4-5-20250929")
init_chat_model() 解决了这个痛点:一个函数初始化所有厂商的模型:
from langchain.chat_models import init_chat_model
# ===== 方式一:明确指定 provider(推荐,最可靠)=====
model = init_chat_model("openai:gpt-4o") # OpenAI
model = init_chat_model("anthropic:claude-sonnet-4-5-20250929") # Anthropic(固定版本,推荐)
model = init_chat_model("deepseek:deepseek-chat") # DeepSeek
model = init_chat_model("google_genai:gemini-2.5-flash") # Gemini
model = init_chat_model("ollama:llama3.1") # Ollama 本地
# ===== 方式二:自动推断 provider(仅限知名模型前缀)=====
model = init_chat_model("gpt-4o") # 自动识别 → openai
model = init_chat_model("claude-sonnet-4-5") # 自动识别 → anthropic(claude 前缀)
model = init_chat_model("deepseek-chat") # 自动识别 → deepseek
model = init_chat_model("gemini-2.5-flash") # 自动识别 → google_genai
格式说明:
"provider:model_name",冒号前是 provider 标识,冒号后是具体的模型名。provider 标识由对应的langchain-<provider>包定义。
关于 Anthropic 模型名:官方推荐使用固定版本 ID(如
claude-sonnet-4-5-20250929),避免使用浮动别名(如claude-sonnet-4-5)。因为浮动别名可能被 Anthropic 静默升级指向新版本,导致你的应用行为意外变化。同理,OpenAI 的gpt-4o也是浮动别名,生产环境建议固定到具体日期版本。
3.1.2 传递模型参数
init_chat_model() 支持两类参数:
① 标准参数(所有厂商通用):
model = init_chat_model(
"deepseek-chat", # model_provider 自动推断
api_key="sk-xxxxxxxxxxxxx", # API 密钥(不传则自动读环境变量)
base_url="https://api.deepseek.com", # 自定义 API 地址(不传则使用厂商默认值)
temperature=0.5, # 控制随机性(范围 0~2,0 = 最确定,2 = 最随机)
max_tokens=1000, # 最大输出 token 数
timeout=60, # 请求超时秒数
max_retries=3, # 失败重试次数
stop=["\n\n"], # 停用词,遇到这些词就停止生成
)
temperature 取值指南(范围 0~2,遵循 OpenAI API 规范):
温度区间 效果 适用场景 0 ~ 0.3 输出确定、稳定,几乎每次一致 数据提取、分类、代码生成、翻译 0.4 ~ 0.7 适度创造性,自然但不偏离主题 日常对话、内容总结 0.8 ~ 1.2 输出多样化 创意写作、头脑风暴 1.3 ~ 2.0 非常随机,可能出现意外结果 探索性生成(实际使用较少)
② 非标准参数(厂商特有)—— 用 model_kwargs 透传:
model = init_chat_model(
"deepseek:deepseek-chat",
temperature=0.0,
model_kwargs={
"top_p": 0.9, # 核采样参数(厂商特有)
"frequency_penalty": 0.5, # 频率惩罚(减少重复)
}
)
原理:
model_kwargs中的参数会被原封不动地合并到发送给模型 API 的请求体中。这样即使某些参数不是 LangChain 标准参数,也能正常传递。你可以把它理解为:“LangChain 不认识这些参数,但请帮我把它们原样传给模型厂商。”
3.2 调用方式
| 方法 | 行为 | 返回值 | 适用场景 | 类比 |
|---|---|---|---|---|
invoke() |
阻塞式,等待模型生成完整响应后一次性返回 | 一个完整的 AIMessage 对象 |
需要完整结果再继续处理 | 等人把话全部说完再转述给你 |
stream() |
流式,逐 token 返回 | 一个生成器/迭代器,每次 yield 一个 AIMessageChunk |
需要实时展示(如聊天 UI) | 同声传译,来一句翻一句 |
batch() |
阻塞式,客户端并发处理多个请求 | list[AIMessage] |
大量独立请求,提高吞吐量 | 同时给多人布置任务,等所有人完成后一起收结果 |
补充知识 —
batch_as_completed():除了batch(),LangChain 还提供了batch_as_completed()方法。它同样是批量处理,但每完成一个请求就立即返回该结果(不等待其他请求完成),结果可能乱序到达。适合需要尽快展示部分结果的场景。
3.2.1 invoke() 基础调用
from langchain.chat_models import init_chat_model
model = init_chat_model(
model="deepseek-v4-pro"
)
# 传入字符串(内部自动包装成 HumanMessage)
response = model.invoke("Hello, world!")
print(response.content)
# 输出: "Hello, world! How can I help you today?"
3.2.2 stream() 流式输出
response = model.stream("Hello, world!")
for chunk in response:
print(chunk.content, end="", flush=True)
# 逐字输出,用户体验更好:不需要盯着空白屏幕等待
代码细节解释:
end="":避免flush=True:强制立即将缓冲区内容输出到屏幕,确保用户能实时看到每个字(否则 Python 可能等缓冲区满了才输出,失去流式意义)
3.2.3 batch() 批量处理
questions = [
"什么是 Python?",
"什么是 JavaScript?",
"什么是 Rust?",
]
responses = model.batch(questions) # 一次性提交,内部线程池并发处理
for q, r in zip(questions, responses):
print(f"Q: {q}")
print(f"A: {r.content}\n")
性能提示:
batch()适合需要同时处理大量独立请求的场景。相比循环调用invoke(),batch 内部使用线程池并发执行,能显著提高吞吐量。你还可以通过config={"max_concurrency": 5}控制最大并发数。注意区分:这里的
batch()是客户端并发,不同于 OpenAI 等厂商提供的服务端 Batch API(后者提交任务后异步处理,通常有延迟但费用更低)。
3.2.4 关键问题:invoke() 只能放字符串吗?三种方法的界限是什么?
这是很多初学者困惑的地方。让我来梳理清楚。
答案:invoke()、stream()、batch() 都可以接收字符串,也都可以接收消息列表。 这两个维度是正交的,调用方式和输入格式是两套独立的分类体系。
用一张图来理解:
输入格式(传什么) 调用方式(怎么传)
───────────────────── ─────────────────────
字符串 "你好" invoke() → 阻塞,返回完整结果
消息列表 [SystemMessage, stream() → 流式,逐 token 返回
HumanMessage] batch() → 批量,一次处理多个
四种合法的组合示例:
from langchain.chat_models import init_chat_model
from langchain_core.messages import HumanMessage, SystemMessage
model = init_chat_model(
model="deepseek-v4-pro"
)
# 组合1:字符串 + invoke
response = model.invoke("你好")
print(response.content)
# 组合2:字符串 + stream
for chunk in model.stream("你好"):
print(chunk.content, end="", flush=True)
# 组合3:消息列表 + invoke
messages = [
SystemMessage(content="你是专业的翻译助手"),
HumanMessage(content="请翻译:Hello world")
]
response = model.invoke(messages)
print(response.content)
# 组合4:消息列表 + stream
for chunk in model.stream(messages):
print(chunk.content, end="", flush=True)
结论:选择字符串还是消息列表,取决于你是否需要设定系统角色;选择 invoke 还是 stream,取决于你是否需要实时展示。
3.3 使用消息列表:SystemMessage、HumanMessage、AIMessage
当需要设定 AI 的系统角色(行为规则、语气、输出格式等)时,就要传入消息列表而不是简单字符串。
为什么需要传入消息列表而不是简单字符串?
三个核心原因:
- 设定系统角色:通过
SystemMessage控制 AI 的行为风格和输出格式——字符串做不到这一点 - 多轮对话:需要把之前的
HumanMessage和AIMessage一同传入,维持对话上下文 - 接入 Memory 模块:后续的会话记忆功能要求使用消息列表格式,它是 LangChain 生态的标准数据格式
3.3.1 完整写法
from langchain.chat_models import init_chat_model
from langchain_core.messages import HumanMessage, SystemMessage
model = init_chat_model(
model="deepseek-v4-pro"
)
messages = [
SystemMessage(content="你是一个专业的代码审查助手,回复请使用 Markdown 格式。"),
HumanMessage(content="请审查这段代码:def add(a,b): return a+b")
]
response = model.invoke(messages)
print(response.content)
三种消息类型与 OpenAI 协议的对应关系
| LangChain 消息类型 | OpenAI role |
作用 | 举例 |
|---|---|---|---|
SystemMessage |
system |
设定 AI 的行为规则、角色、输出格式 | “你是专业的代码审查助手,回复用 Markdown 格式” |
HumanMessage |
user |
用户的问题或指令 | “帮我写一个快速排序算法” |
AIMessage |
assistant |
AI 的回复(多轮对话时用于传入历史回复) | “好的,以下是快速排序的实现…” |
三种消息在多轮对话中的流转示意:
第1轮:用户输入 → HumanMessage 模型回复 → AIMessage 第2轮:[SystemMessage, HumanMessage₁, AIMessage₁, HumanMessage₂] 模型回复 → AIMessage₂ 第3轮:[SystemMessage, HM₁, AIM₁, HM₂, AIM₂, HM₃] ...可以看到,每一轮都需要把之前的
HumanMessage和AIMessage全部带上,会话记忆。
3.3.2 简写形式(元组)
LangChain 还支持用元组代替消息对象,代码更简洁:
from langchain.chat_models import init_chat_model
model = init_chat_model(
model="deepseek-v4-pro"
)
messages = [
("system", "你是一个专业的代码审查助手,回复请使用 Markdown 格式。"),
("human", "请审查这段代码:def add(a,b): return a+b")
]
response = model.invoke(messages)
print(response.content)
转换规则(LangChain 内部自动完成):
| 元组写法 | 自动转换为 |
|---|---|
('system', '...') |
SystemMessage(content='...') |
('human', '...') |
HumanMessage(content='...') |
('ai', '...') |
AIMessage(content='...') |
优点:少写 import,代码更紧凑直观。
局限:简写只支持这三种基本角色。如果后续用到
ToolMessage(工具调用消息)、FunctionMessage(函数调用消息)等高级类型,还是需要用完整的消息类。另外,元组写法无法携带name、additional_kwargs等附加字段。
3.4 与原生 OpenAI SDK 对照
把 LangChain 的调用方式和原生 OpenAI SDK 放在一起对比,能更清楚地理解 LangChain 做了哪些封装:
原生 OpenAI SDK 方式:
from openai import OpenAI
client = OpenAI(
api_key="sk-xxx",
base_url="https://api.deepseek.com" # 调用 DeepSeek 兼容接口
)
response = client.chat.completions.create(
model="deepseek-v4-pro",
messages=[
{"role": "system", "content": "You are a helpful assistant"},
{"role": "user", "content": "Hello, world!"},
],
stream=False
)
print(response.choices[0].message.content)
LangChain 方式:
from langchain.chat_models import init_chat_model
model = init_chat_model("deepseek:deepseek-v4-pro")
response = model.invoke("Hello, world!")
print(response.content)
对照总结:
| 步骤 | 原生 OpenAI SDK | LangChain |
|---|---|---|
| 初始化客户端 | OpenAI(api_key=..., base_url=...) |
init_chat_model("provider:model") 或 ChatOpenAI(model=..., api_key=..., base_url=...) |
| 发起调用 | client.chat.completions.create(...) |
client.invoke(...) / client.stream(...) / client.batch(...) |
| 传入消息 | messages=[{"role": ..., "content": ...}](字典列表) |
直接传字符串(简单对话)或消息对象列表 |
| 获取结果 | response.choices[0].message.content |
response.content |
| 流式控制 | 通过 stream=True/False 参数切换 |
通过 invoke() / stream() 两个不同方法切换 |
| 代码嵌套层级 | 3 层(.choices[0].message.content) |
1 层(.content) |
3.5 Ollama 本地部署的模型如何使用?
Ollama 让你可以在本地运行开源大模型,无需联网、无需 API Key、完全免费。LangChain 通过 langchain-ollama 包提供了完整的支持。
from langchain.chat_models import init_chat_model
# ===== 方式一:init_chat_model 统一入口(推荐)=====
model = init_chat_model("ollama:llama3.1") # 自动使用本地 Ollama 服务
# 等价于 init_chat_model("ollama:qwen2.5") # 切换模型只需要改名字
# ===== 方式二:直接使用 langchain-ollama 包 =====
from langchain_ollama import ChatOllama
model = ChatOllama(
model="llama3.1", # 本地已下载的模型名
temperature=0.7,
base_url="http://localhost:11434", # Ollama 默认地址,一般不需要改
)
response = model.invoke("用一句话解释什么是机器学习")
print(response.content)
前置条件:使用前需要先安装 Ollama 并拉取模型:
# 安装 Ollama(macOS/Linux/Windows 均支持) # 然后拉取模型 ollama pull llama3.1 # Meta 的 Llama 3.1 ollama pull qwen2.5 # 阿里的通义千问 2.5 ollama pull nomic-embed-text # 嵌入模型(RAG 用) # 查看已安装的模型 ollama list
4 嵌入模型调用(Embeddings)
嵌入模型和对话模型有本质区别:对话模型输出文字,嵌入模型输出向量。 两者不能混用,你无法用对话模型来生成向量做语义搜索。
4.1 调用 OpenAI 嵌入模型
from langchain_openai import OpenAIEmbeddings
embeddings = OpenAIEmbeddings(
model="text-embedding-3-small", # 输出 1536 维向量,性价比高
# model="text-embedding-3-large", # 输出 3072 维向量,更精确但更贵
)
vector = embeddings.embed_query("什么是机器学习?")
print(f"向量维度: {len(vector)}") # 1536
print(f"前5个值: {vector[:5]}") # 示例:[0.023, -0.145, 0.008, -0.067, 0.034]
4.2 调用 Ollama 本地嵌入模型
from langchain_ollama import OllamaEmbeddings
embeddings = OllamaEmbeddings(
model="nomic-embed-text", # 免费本地嵌入模型,输出 768 维向量
)
# 使用前需要先拉取:ollama pull nomic-embed-text
vector = embeddings.embed_query("Hello world!")
print(f"向量维度: {len(vector)}") # 768
4.3 embed_query vs embed_documents两个方法
# embed_query:对单个查询文本生成向量
query_vec = embeddings.embed_query("如何学 Python?")
# → [0.023, -0.145, 0.008, -0.067, 0.034, ...](一个向量)
# embed_documents:对批量待检索的文档生成向量
doc_vecs = embeddings.embed_documents([
"Python 是解释型语言",
"Java 是编译型语言",
"Rust 是系统编程语言",
])
# → [[0.023, ...], [0.112, ...], [-0.045, ...]](三个向量,每个都是浮点数列表)
为什么要分成两个方法? 因为部分嵌入模型(如 OpenAI 的 text-embedding-3 系列、BGE 系列、E5 系列等)对查询和文档使用不同的编码策略(非对称嵌入),以提升检索精度。
直观理解:查询通常是简短的问句(“怎么学Python?”,可能就几个词),文档则是大段的长文本(几百到几千字)。如果用完全相同的编码方式,「短查询」和「长文档」在向量空间中的分布会有偏差。非对称嵌入就是让模型学会「这是查询格式,用查询编码器处理;那是文档格式,用文档编码器处理」,从而让匹配更准确。
当然,对于简单场景或部分模型(如
nomic-embed-text),两个方法底层可能没什么区别——但有了这个接口设计,切换高级模型时你就无需改代码了。
补充:LLM 、ChatModel、Embedding 三大类的历史问题
在旧教程中学习到:"模型分三大类:LLM 、ChatModel、Embedding。
在 LangChain v1.0 中,这个区分已经是历史问题了。 原因:
BaseLLM类虽然还存在于langchain-core中(兼容考虑),但所有主流厂商包(langchain-openai、langchain-anthropic等)都只提供BaseChatModel实现init_chat_model()只返回BaseChatModel子类实例- 官方文档已经不再提及独立的 LLM 接口
- 在 LangChain 0.2.0 中,
from langchain.llms import XXX已经被标记为 deprecated
LangChain 核心架构(本文覆盖范围)
┌─────────────────────────────────────────────────┐
│ 模型调用 (Model I/O) │
│ │
│ init_chat_model() ← 统一入口,替代所有厂商类 │
│ ├── invoke() ← 阻塞,返回完整 AIMessage │
│ ├── stream() ← 流式,逐 token 实时输出 │
│ ├── batch() ← 批量并发,提高吞吐量 │
│ └── batch_as_completed() ← 批量流式,完成即返回 │
│ │
│ 输入格式(与调用方式正交,可任意组合): │
│ ├── 字符串 "你好" │
│ ├── 消息列表 [System, Human, AI, ...] │
│ └── 元组简写 [('system', '...'), ('human', '...')]│
├─────────────────────────────────────────────────┤
│ 嵌入模型 (Embeddings) │
│ ├── OpenAIEmbeddings ← 云端(1536/3072 维) │
│ ├── OllamaEmbeddings ← 本地(如 768 维) │
│ ├── embed_query() ← 单个查询 → 向量 │
│ └── embed_documents() ← 批量文档 → 向量列表 │
└─────────────────────────────────────────────────┘
以上为个人学习总结,旨在梳理个人理解。如有疏漏或不当之处,欢迎指正与交流。如果文章对你有帮助,别忘了点个赞、留个言,让更多的小伙伴看到~ 我们下篇再见!
更多推荐

所有评论(0)