Langchain的核心组件
-
LLM(大型语言模型):提供文本生成与推理能力,如OpenAI的GPT、阿里云的Qwen等
-
Prompt(提示模板):结构化文本输入,指导LLM生成特定输出
-
Retriever(检索器):从外部数据源获取相关上下文信息
-
Tool(工具):扩展LLM功能的外部接口,如API调用、数据库查询等
以上四个组件通过"链式"(Chain)方式组合,形成完整的工作流。与直接调用LLM不同,LangChain允许开发者将多个组件串联,实现从简单问答到复杂任务处理的各类应用。
1. LLM的调用
一、核心原理:抽象层设计
LangChain 定义了两类核心抽象:
| 接口 | 适用场景 | 方法 |
|---|---|---|
BaseLLM |
纯文本补全(如 GPT-3、Claude Completion) | .invoke("prompt") |
BaseChatModel |
对话式模型(如 GPT-4、Claude Chat、Qwen Chat) | .invoke([HumanMessage(...)]) |
BaseLLM:直接返回文字
BaseChatModel:返回带格式的文本
二、调用方法
方法一:直接调用 LLM(简单文本生成)
python
from langchain_openai import OpenAI # 注意:旧版是 langchain.llms.OpenAI
# 初始化 LLM(使用 OpenAI GPT-3.5)
llm = OpenAI(
model="gpt-3.5-turbo-instruct",
# gpt-3.5-turbo-instruct 补全模型,大部分模型都应用与 Chat 模型而非文本补全模型
temperature=0.7,
api_key="your-api-key",
base_url="https://api.openai.com/v1" # 可替换为 DeepSeek、Moonshot 等
)
# 直接调用
response = llm.invoke("解释量子力学的基本原理")
print(response)
方法二:使用 Chat 模型
python
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, AIMessage
# 初始化 Chat 模型
chat = ChatOpenAI(
model="gpt-4o",
temperature=0.3,
api_key="your-api-key"
)
# 单轮对话
response = chat.invoke([HumanMessage(content="你好!")])
print(response.content) # 输出: "你好!有什么我可以帮你的吗?"
# 多轮对话(带上下文)
messages = [
HumanMessage(content="我叫小明"),
AIMessage(content="很高兴认识你,小明!"),
HumanMessage(content="我今年多大了?")
]
response = chat.invoke(messages)
print(response.content) # 模型会记住"小明"这个名字
方法三:使用 chain 和 prompt模板
python
from langchain_core.prompts import ChatPromptTemplate
# 构建带变量的模板
template = ChatPromptTemplate.from_messages([
("system", "你是一位专业的{role}"),
("human", "{question}")
])
# 绑定 LLM
chain = template | ChatOpenAI(model="gpt-4o")
# 调用
result = chain.invoke({
"role": "数学老师",
"question": "如何解一元二次方程?"
})
print(result.content)
2. Prompt相关组件
一、Prompt组件的核心分类
| 组件类型 | 说明 | 适用场景 |
|---|---|---|
| Prompt Template | 将Prompt按照template进行格式化,处理变量和提示词组合 | 通用提示词生成 |
| Selectors | 根据不同条件选择不同提示词 | 条件化提示词选择 |
Prompt Template的子组件
| 组件 | 说明 | 使用示例 |
|---|---|---|
| PromptTemplate | 创建文本消息提示模板,用于与大语言模型/文本生成模型交互 | 通用文本提示 |
| ChatPromptTemplate | 创建聊天消息提示模板,一般用于与聊天模型交互 | 对话式交互 |
| MessagePlaceholder | 消息占位符,在聊天模型中对不确定是否需要的消息进行占位 | 动态对话历史 |
| SystemMessagePromptTemplate | 创建系统消息提示模板,角色为系统 | 系统指令 |
| HumanMessagePromptTemplate | 创建人类消息提示模板,角色为人类 | 用户输入 |
| AIMessagePromptTemplate | 创建AI消息提示模板,角色为AI | AI响应 |
| PipelinePromptTemplate | 创建管道消息,将提示模板作为变量进行快速复用 | 复杂提示组合 |
二、核心组件使用详解
1. ChatPromptTemplate(聊天消息提示模板)
基础用法
python
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.messages import SystemMessage, HumanMessage, AIMessage
chat_prompt = ChatPromptTemplate.from_messages([
("system", "你是一位专业的{role},请用简洁明了的方式回答问题"),
("human", "{input}"),
("ai", "好的,我将为您解答:")
])
# 格式化提示
prompt_value = chat_prompt.invoke({
"role": "金融分析师",
"input": "如何计算股票的市盈率?"
})
# 转换为字符串或消息列表
print("to_string:", prompt_value.to_string())
print("to_messages:", prompt_value.to_messages())
包含对话历史的模板:
python
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
chat_prompt = ChatPromptTemplate.from_messages([
("system", "你是OpenAI开发的聊天机器人,当前时间:{now}"),
MessagesPlaceholder("chat_history"), # 动态历史消息
("human", "{input}")
]).partial(now="2024-06-22")
# 模拟对话历史
chat_history = [
("human", "我叫慕小课"),
("ai", "你好,我是ChatGPT")
]
# 生成提示
prompt_value = chat_prompt.invoke({
"chat_history": chat_history,
"input": "我今年多大了?"
})
print("生成的提示:", prompt_value.to_messages())
2. 消息模板组件
SystemMessagePromptTemplate:
python
from langchain_core.prompts import SystemMessagePromptTemplate
system_prompt = SystemMessagePromptTemplate.from_template(
"你是一位专业的{role},请用简洁明了的方式回答问题"
)
# 使用示例
system_prompt.format(role="数据科学家")
HumanMessagePromptTemplate:
python
from langchain_core.prompts import HumanMessagePromptTemplate
human_prompt = HumanMessagePromptTemplate.from_template(
"请回答关于{topic}的问题:{input}"
)
# 使用示例
human_prompt.format(topic="人工智能", input="什么是深度学习?")
AIMessagePromptTemplate
python
from langchain_core.prompts import AIMessagePromptTemplate
ai_prompt = AIMessagePromptTemplate.from_template(
"根据{context},{response}"
)
# 使用示例
ai_prompt.format(context="深度学习是机器学习的一个分支", response="它使用神经网络进行学习")
3. PromptTemplate(基础文本提示模板)
单变量模板:
python
from langchain.prompts import PromptTemplate
# 1. 定义模板(含1个动态变量{name})
template = "请用{name}的语气说一句自我介绍,不超过30字"
prompt_template = PromptTemplate(
input_variables=["name"], # 声明变量名
template=template # 提示词模板
)
# 2. 填充变量生成提示词
prompt = prompt_template.format(name="程序员")
print("生成的提示词:", prompt)
# 3. 调用模型
from langchain_openai import OpenAI
llm = OpenAI(model="gpt-3.5-turbo-instruct")
response = llm.invoke(prompt)
print("模型输出:", response)
多变量模板:
python
from langchain.prompts import PromptTemplate
# 定义含2个变量的模板(场景和主题)
template = "请为{scene}场景设计3个关于{topic}的问题,要求简洁明了"
prompt_template = PromptTemplate(
input_variables=["scene", "topic"],
template=template
)
# 填充变量(例如:面试场景 + Python主题)
prompt = prompt_template.format(scene="Python面试", topic="列表与元组")
print("生成的提示词:", prompt)
带默认值的模板(使用partial方法):
python
from langchain.prompts import PromptTemplate
template = "你是一名{role}工程师,请帮我设计{feature}用例,重点突出{style}的设计"
prompt = PromptTemplate(
input_variables=["role", "feature", "style"],
template=template
)
# 设置默认值
partial_prompt = prompt.partial(style="条件覆盖")
# 传入剩余变量
full_prompt = partial_prompt.format(role="资深测试", feature="单元测试")
print(full_prompt)
# 输出:你是一名资深测试工程师,请帮我设计单元测试用例,重点突出条件覆盖的设计
4.高级用法
从文件加载提示模板
python
# 假设template.txt文件内容为:"分析{topic}的主要优势和劣势。"
with open("template.txt", "r") as f:
template = f.read()
prompt = PromptTemplate(
input_variables=["topic"],
template=template
)
print(prompt.format(topic="软件测试"))
# 输出:分析软件测试的主要优势和劣势。
动态选择提示词(使用Selectors)
python
from langchain_core.prompts import PromptTemplate, FewShotPromptTemplate
from langchain_core.example_selectors import LengthBasedExampleSelector
examples = [
{"input": "你好", "output": "你好!有什么可以帮你的吗?"},
{"input": "今天天气怎么样?", "output": "今天天气晴朗,气温25度。"},
]
example_prompt = PromptTemplate(
input_variables=["input", "output"],
template="Input: {input}\nOutput: {output}",
)
# 基于长度选择示例
example_selector = LengthBasedExampleSelector(
examples=examples,
example_prompt=example_prompt,
k=1, # 选择1个示例
get_length=lambda x: len(x["input"]) # 按输入长度排序
)
# 创建少样本提示模板
few_shot_prompt = FewShotPromptTemplate(
example_selector=example_selector,
example_prompt=example_prompt,
prefix="请根据以下示例回答问题:",
suffix="Input: {input}\nOutput:",
input_variables=["input"]
)
# 生成提示
prompt = few_shot_prompt.format(input="明天会下雨吗?")
print(prompt)
3. Retriever相关组件及使用方法
一、Retriever核心类型
| 类型 | 适用场景 | 优势 |
|---|---|---|
| VectorStoreRetriever | 语义相似度检索(基于向量数据库) | 语义理解能力强,适合复杂查询 |
| BM25Retriever | 关键词匹配检索(无需向量计算) | 无需额外计算,轻量快速 |
| MultiVectorRetriever | 复杂文档结构检索(多信息块) | 支持文档的多维度信息检索 |
二、基础使用方法
1. VectorStoreRetriever(向量检索器)
python
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
# 初始化嵌入模型
embeddings = OpenAIEmbeddings(model="text-embedding-ada-002")
# 创建向量数据库(以Chroma为例)
vectorstore = Chroma(
persist_directory="docs/chroma_store",
embedding_function=embeddings
)
# 转换为Retriever
retriever = vectorstore.as_retriever(
search_type="similarity", # 搜索类型
search_kwargs={"k": 4} # 返回文档数量
)
# 执行检索
docs = retriever.get_relevant_documents("LangChain的Retriever是什么?")
for doc in docs:
print(doc.page_content[:100] + "...")
2. BM25Retriever(稀疏检索器)
python
from langchain_community.retrievers import BM25Retriever
from langchain.schema import Document
# 准备文档
docs = [
Document(page_content="LangChain是一个用于构建LLM应用的框架。"),
Document(page_content="RAG结合了检索与生成技术。"),
Document(page_content="Retriever是LangChain中的核心组件。")
]
# 创建检索器
retriever = BM25Retriever.from_documents(docs)
# 执行检索
results = retriever.get_relevant_documents("LangChain框架是什么?")
for doc in results:
print(doc.page_content)
三、参数解释
1. search_type(搜索类型)
| 类型 | 适用场景 | 核心逻辑 |
|---|---|---|
similarity |
基础技术查询,优先相关性 | 基于余弦相似度,返回Top-K最相关的文档 |
mmr |
技术文档汇总、多维度学习 | 通过lambda_mult控制多样性(0→纯相关,1→纯多样) |
similarity_score_threshold |
精准技术筛选,剔除低相关内容 | 仅返回相似度得分高于阈值的文档 |
2. search_kwargs(检索配置)
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
k |
int | 4 | 返回的相关文档数量 |
filter/expr |
str/dict | None | 元数据过滤条件(如筛选"category:langchain") |
fetch_k |
int | 20 | MMR检索专用,先获取fetch_k条相似文档,再筛选k条 |
lambda_mult |
float | 0.5 | MMR检索专用,平衡相关性与多样性 |
score_threshold |
float | None | 相似度阈值,仅保留得分高于该值的文档 |
3. Tool相关组件
一、参数解释
| 组件 | 说明 | 必需性 |
|---|---|---|
name |
工具的唯一标识(如 weather、add) |
必需 |
description |
工具功能描述(模型判断是否调用的依据) | 必需 |
args_schema |
参数校验 Schema(输入验证和提示) | 必需 |
_run |
同步执行方法 | 推荐实现 |
_arun |
异步执行方法 | 推荐实现(常涉及网络请求) |
二、Tool 的工作流程
-
模型接收用户需求(如"北京今天的天气怎么样?")
-
模型分析后判断需要调用工具
-
Tool 组件执行调用,获取外部数据
-
Tool 将结果返回给模型
-
模型结合工具结果,生成最终回复
三、工具的绑定与调用
绑定工具到模型
python
from langchain_community.llms import OpenAI
# 初始化模型
llm = OpenAI(model="gpt-3.5-turbo-instruct")
# 绑定工具(使用装饰器方式)
weather_tool = get_weather
llm = llm.bind_tools([weather_tool])
# 或者使用 BaseTool 方式
weather_tool = WeatherTool()
llm = llm.bind_tools([weather_tool])
触发工具调用并处理结果
python
# 调用模型
response = llm.invoke("北京今天的天气怎么样?")
# 检查是否需要调用工具
if response.tool_calls:
# 获取第一个工具调用
tool_call = response.tool_calls[0]
# 根据工具名称调用对应的工具
if tool_call["name"] == "weather":
# 调用工具
tool_result = weather_tool.invoke(tool_call["args"])
# 将工具结果添加到消息中
response = response + tool_result
# 生成最终回复
final_response = llm.invoke(response)
print(final_response)