大家好,我是锋哥。最近连载更新《基于LangChain的RAG与Agent智能体》技术专题。
本课程主要介绍和讲解RAG,LangChain简介,接入通义千万大模型,Ollama简介以及安装和使用,OpenAI库介绍和使用,以及最重要的基于LangChain实现RAG与Agent智能体开发技术。同时也配套视频教程 《2027版 基于LangChain的RAG与Agent智能体开发视频教程》
LangChain框架提供了提示词模版类,方便我们构建大模型提示词。
模版的思想是: 数据+模版=最终提示词
在LangChain core核心包里,定义了三种类型的提示词模版,分别是通用提示词模版PromptTemplate,少样本提示词模板FewShotPromptTemplate,聊天会话提示词模版ChatPromptTemplate。这个三个提示词模版都继承自基础提示词模版BasePromptTemplate,BasePromptTemplate类拥有format格式化方法,以及BasePromptTemplate继承自Runnable类,Runnable类拥有invoke调用方法。
通用提示词模版PromptTemplate
我们通过通用提示词模版PromptTemplate,以及变量动态注入,生成我们需要的提示词。
我们来看一个简单示例:
from langchain_community.llms.tongyi import Tongyi
from langchain_core.prompts import PromptTemplate
# 定义一个模板,包含两个变量:product 和 price
template = "请帮我写一段关于 {product} 的广告,重点是它的价格只有 {price} 元,吸引用户购买。"
# 创建 PromptTemplate 对象
prompt = PromptTemplate(
input_variables=["product", "price"], # 输入变量
template=template # 模板
)
# 通过 format 方法填充变量,生成最终提示词
final_prompt = prompt.format(product="智能手表", price="299")
print(final_prompt)
model = Tongyi(model="qwen-plus") # 创建模型
result = model.invoke(input=final_prompt) # 调用模型
print(result)
运行输出:
LangChain中的chain链式语法
在 LangChain 中,Chain(链)是一个核心组件,用于把不同的处理步骤串联起来,上一个组件的输出作为下一个组件的输入,形成一个可复用的处理流程。简单来说,它就是“输入 → 处理 → 输出”的流水线,但可以是多步的,每一步都可以是不同类型的操作。
LangChain Chain的链式语法 对象1 | 对象2 | ... | 对象 n 这个 | 链式符号 底层实现是吧 对象的 模式 __or()__魔法方法重写了。大家有兴趣的可以扩展研究学习下。
下面我们用LangChain的高级写法chain链式写法实现下。
from langchain_community.llms.tongyi import Tongyi
from langchain_core.prompts import PromptTemplate
# 定义一个模板,包含两个变量:product 和 price
template = "请帮我写一段关于 {product} 的广告,重点是它的价格只有 {price} 元,吸引用户购买。"
# 创建 PromptTemplate 对象
prompt = PromptTemplate(
input_variables=["product", "price"], # 输入变量
template=template # 模板
)
model = Tongyi(model="qwen-plus") # 创建模型
# 创建链式调用
chain = prompt | model
# 调用模型
result = chain.invoke(input={"product": "智能手表", "price": "299"})
print(result)
运行输出:
少样本提示词模板FewShotPromptTemplate
FewShotPromptTemplate是支持少量样本的提示词模版。
我们来看下下面的简单示例:
from langchain_community.llms.tongyi import Tongyi
from langchain_core.prompts import PromptTemplate, FewShotPromptTemplate
# 定义几个示例,每个示例包含句子和对应的情感标签
examples = [
{"sentence": "今天天气真好,心情愉快!", "sentiment": "正面"},
{"sentence": "这部电影太无聊了,浪费时间。", "sentiment": "负面"},
{"sentence": "这家餐厅的食物非常美味,服务也很棒。", "sentiment": "正面"},
{"sentence": "产品质量很差,用了几天就坏了。", "sentiment": "负面"},
]
# 创建一个格式化示例的模板
example_prompt = PromptTemplate(
input_variables=["sentence", "sentiment"],
template="句子:{sentence}\n情感:{sentiment}"
)
# 创建 FewShotPromptTemplate 对象
few_shot_prompt = FewShotPromptTemplate(
examples=examples, # 传入示例列表
example_prompt=example_prompt, # 每个示例的格式化方式
prefix="请根据以下示例判断新句子的情感是正面还是负面:\n", # 前缀
suffix="句子:{input}\n情感:", # 后缀,包含变量 input
example_separator="\n\n", # 示例之间的分隔符
input_variables=["input"] # 定义输入变量
)
# 使用 format 方法填充新句子,生成完整的提示词
new_sentence = "这个手机性价比很高,值得购买。"
final_prompt = few_shot_prompt.format(input=new_sentence)
print(final_prompt)
# 创建模型
model = Tongyi(model="qwen-plus")
# 调用模型
result = model.invoke(input=final_prompt)
print(result)
运行输出:
我们采用Chain链式写法改下:
from langchain_community.llms.tongyi import Tongyi
from langchain_core.prompts import PromptTemplate, FewShotPromptTemplate
# 定义几个示例,每个示例包含句子和对应的情感标签
examples = [
{"sentence": "今天天气真好,心情愉快!", "sentiment": "正面"},
{"sentence": "这部电影太无聊了,浪费时间。", "sentiment": "负面"},
{"sentence": "这家餐厅的食物非常美味,服务也很棒。", "sentiment": "正面"},
{"sentence": "产品质量很差,用了几天就坏了。", "sentiment": "负面"},
]
# 创建一个格式化示例的模板
example_prompt = PromptTemplate(
input_variables=["sentence", "sentiment"],
template="句子:{sentence}\n情感:{sentiment}"
)
# 创建 FewShotPromptTemplate 对象
few_shot_prompt = FewShotPromptTemplate(
examples=examples, # 传入示例列表
example_prompt=example_prompt, # 每个示例的格式化方式
prefix="请根据以下示例判断新句子的情感是正面还是负面:\n", # 前缀
suffix="句子:{input}\n情感:", # 后缀,包含变量 input
example_separator="\n\n", # 示例之间的分隔符
input_variables=["input"] # 定义输入变量
)
# 使用 format 方法填充新句子,生成完整的提示词
new_sentence = "这个手机性价比很高,值得购买。"
final_prompt = few_shot_prompt.format(input=new_sentence)
# print(final_prompt)
# 创建模型
model = Tongyi(model="qwen-plus")
# 调用模型
# result = model.invoke(input=final_prompt)
# print(result)
# 采用链式chain写法
chain = few_shot_prompt | model
result = chain.invoke(input=new_sentence)
print(result)
运行输出:
聊天会话提示词模版ChatPromptTemplate
ChatPromptTemplate 是 LangChain 中专为聊天模型(如 ChatGPT)设计的提示模板。与普通文本补全模型不同,聊天模型的输入是一系列消息,每条消息包含角色(如系统、人类、AI)和内容。ChatPromptTemplate 允许你以结构化方式定义这些消息,并支持动态插入变量,最终生成一组聊天消息供模型使用。
我们来看一个示例:
from langchain_community.llms.tongyi import Tongyi
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
# 1. 定义聊天提示模板
chat_template = ChatPromptTemplate.from_messages([
("system", "你是一个友好的AI助手,会结合对话历史回答用户问题。"), # 系统消息:设定AI基础角色
MessagesPlaceholder("history"), # 对话历史占位符:后续会被真实历史数据替换
("human", "我的新问题是:{user_question}") # 当前用户的提问(带变量占位)
])
# 2. 准备对话历史数据
history_data = [
("human", "你好,请问什么是LangChain?"),
("ai", "LangChain是构建大模型应用的框架,方便连接数据源和工具。"),
("human", "那它能做聊天机器人吗?"),
("ai", "可以!它提供对话管理、记忆等能力,很适合开发聊天机器人。")
]
# 3. 调用模板,传入对话历史 + 当前问题
prompt_value = chat_template.invoke({
"history": history_data,
"user_question": "LangChain和LangGraph的区别?"
})
# 4. 查看最终格式化后的完整提示
print("格式化后的完整对话消息:")
for msg in prompt_value.messages:
print(f"{msg.type}: {msg.content}")
# 定义模型
model = Tongyi(model="qwen-plus") # 创建模型
# result = model.invoke(input=prompt_value) # 调用模型 invoke完整输出
# print(result)
result = model.stream(input=prompt_value) # 调用模型 stream流式输出
for chunk in result:
print(chunk, end="", flush=True)
运行输出:
我们换成chain链式调用试下:
from langchain_community.llms.tongyi import Tongyi
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
# 1. 定义聊天提示模板(和图片结构一致)
chat_template = ChatPromptTemplate.from_messages([
("system", "你是一个友好的AI助手,会结合对话历史回答用户问题。"), # 系统消息:设定AI基础角色
MessagesPlaceholder("history"), # 对话历史占位符:后续会被真实历史数据替换
("human", "我的新问题是:{user_question}") # 当前用户的提问(带变量占位)
])
# 2. 准备对话历史数据(和图片红框结构一致)
history_data = [
("human", "你好,请问什么是LangChain?"),
("ai", "LangChain是构建大模型应用的框架,方便连接数据源和工具。"),
("human", "那它能做聊天机器人吗?"),
("ai", "可以!它提供对话管理、记忆等能力,很适合开发聊天机器人。")
]
# 3. 调用模板,传入对话历史 + 当前问题
# prompt_value = chat_template.invoke({
# "history": history_data,
# "user_question": "LangChain和LangGraph的区别?"
# })
# 4. 查看最终格式化后的完整提示
# print("格式化后的完整对话消息:")
# for msg in prompt_value.messages:
# print(f"{msg.type}: {msg.content}")
# 定义模型
model = Tongyi(model="qwen-plus") # 创建模型
# result = model.invoke(input=prompt_value) # 调用模型 invoke完整输出
# print(result)
# result = model.stream(input=prompt_value) # 调用模型 stream流式输出
# for chunk in result:
# print(chunk, end="", flush=True)
# chain链式调用
chain = chat_template | model
result = chain.stream(input={
"history": history_data,
"user_question": "LangChain和LangGraph的区别?"
})
for chunk in result:
print(chunk, end="", flush=True)
运行输出:
在 LangChain 中,format 方法和 invoke 方法用于不同的目的,理解它们的区别对于正确使用 LangChain 至关重要。下面是它们的主要区别:
| 方法 | format 方法 | invoke 方法 |
|---|---|---|
| 定义 | 用于格式化输入模板或字符串,处理占位符或参数替换 | 用于执行链操作,调用链中的多个组件并返回结果 |
| 用途 | 主要用于字符串和模板的格式化,准备数据 | 主要用于实际执行链操作,通常涉及模型推理或API调用 |
| 返回值 | 返回一个格式化后的字符串 | 返回链的最终执行结果,可能是一个对象、字典或其他数据结构 |
| 输入 | 传入格式化字符串和参数,替换占位符 | 接受输入数据并调用链中的函数或模型进行处理 |
| 场景 | 用于生成输入模板,构建动态内容的场景 | 用于执行实际的数据处理、推理或交互操作的场景 |