【技术专题】基于LangChain的RAG与Agent智能体 - LangChain提示词模版

0 阅读8分钟

大家好,我是锋哥。最近连载更新《基于LangChain的RAG与Agent智能体》技术专题。

QQ截图20260324143646.jpg 本课程主要介绍和讲解RAG,LangChain简介,接入通义千万大模型,Ollama简介以及安装和使用,OpenAI库介绍和使用,以及最重要的基于LangChain实现RAG与Agent智能体开发技术。同时也配套视频教程 《2027版 基于LangChain的RAG与Agent智能体开发视频教程》

LangChain框架提供了提示词模版类,方便我们构建大模型提示词。

模版的思想是: 数据+模版=最终提示词

image.png

在LangChain core核心包里,定义了三种类型的提示词模版,分别是通用提示词模版PromptTemplate,少样本提示词模板FewShotPromptTemplate,聊天会话提示词模版ChatPromptTemplate。这个三个提示词模版都继承自基础提示词模版BasePromptTemplate,BasePromptTemplate类拥有format格式化方法,以及BasePromptTemplate继承自Runnable类,Runnable类拥有invoke调用方法。

image.png

通用提示词模版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)

运行输出:

image.png

LangChain中的chain链式语法

在 LangChain 中,Chain(链)是一个核心组件,用于把不同的处理步骤串联起来,上一个组件的输出作为下一个组件的输入,形成一个可复用的处理流程。简单来说,它就是“输入 → 处理 → 输出”的流水线,但可以是多步的,每一步都可以是不同类型的操作。

LangChain Chain的链式语法 对象1 | 对象2 | ... | 对象 n 这个 | 链式符号 底层实现是吧 对象的 模式 __or()__魔法方法重写了。大家有兴趣的可以扩展研究学习下。

image.png

下面我们用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)

运行输出:

image.png

少样本提示词模板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)

运行输出:

image.png

我们采用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)

运行输出:

image.png

聊天会话提示词模版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)

运行输出:

image.png

我们换成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)

运行输出:

image.png

LangChain 中,format 方法和 invoke 方法用于不同的目的,理解它们的区别对于正确使用 LangChain 至关重要。下面是它们的主要区别:

方法format 方法invoke 方法
定义用于格式化输入模板或字符串,处理占位符或参数替换用于执行链操作,调用链中的多个组件并返回结果
用途主要用于字符串和模板的格式化,准备数据主要用于实际执行链操作,通常涉及模型推理或API调用
返回值返回一个格式化后的字符串返回链的最终执行结果,可能是一个对象、字典或其他数据结构
输入传入格式化字符串和参数,替换占位符接受输入数据并调用链中的函数或模型进行处理
场景用于生成输入模板,构建动态内容的场景用于执行实际的数据处理、推理或交互操作的场景