摘要: 本文介绍了langchain.prompts中基础的提示词模板的高级用法,包括利用PipelinePrompt组合Prompt使用,多模态场景、动态占位符的使用等进行了介绍。
文章目录
-
- [1. 背景](#1. 背景)
- [2. PipelinePrompt](#2. PipelinePrompt)
-
- [2.1 组合两个Prompt模板](#2.1 组合两个Prompt模板)
- [2.2 多模态模板](#2.2 多模态模板)
- [3. 聊天提示词模板](#3. 聊天提示词模板)
- [4. 占位符MessagesPlaceholder](#4. 占位符MessagesPlaceholder)
-
- [4.1 基本用法](#4.1 基本用法)
- [4.2 多轮对话](#4.2 多轮对话)
- [4.3 可选占位符配置](#4.3 可选占位符配置)
- [4.4 动态示例选择](#4.4 动态示例选择)
1. 背景
在实际应用中提示词通常并非单一使用,而是多种模板结合起来使用,尤其在大型的Agent中,好的提示词模板设计,对后续的开发会起到事半功倍的效果。
2. PipelinePrompt
PipelinePrompt是LangChain框架中用于组合多个Prompt模板的核心组件,它通过模块化设计实现Prompt的复用和灵活组装。其核心思想类似于软件开发中的管道模式(Pipeline Pattern),将多个处理步骤串联成流水线,前序步骤的输出作为后续步骤的输入。
2.1 组合两个Prompt模板
示例:
python
from langchain.prompts.pipeline import PipelinePromptTemplate
from langchain.prompts.prompt import PromptTemplate
# 定义子模板1:系统指令
intro_template = PromptTemplate.from_template(
"你是一个专业翻译,负责将{input_language}翻译为{output_language}:"
)
# 定义子模板2:翻译示例
example_template = PromptTemplate.from_template(
"示例:'{example_input}' -> '{example_output}'"
)
# 组合为完整PipelinePrompt
full_prompt = PipelinePromptTemplate(
final_prompt=PromptTemplate.from_template(
"{intro}\n{example}\n请翻译:{text}"
),
pipeline_prompts=[
("intro", intro_template),
("example", example_template)
]
)
# 使用示例
print(full_prompt.format(
input_language="英文",
output_language="中文",
example_input="Hello",
example_output="你好",
text="Good morning"
))
输出:
markup
你是一个专业翻译,负责将英文翻译为中文:
示例:'Hello' -> '你好'
请翻译:Good morning
2.2 多模态模板
以下是一个结合视觉和文本的多模态PipelinePromptTemplate示例,用于生成图片描述并回答相关问题。
python
from langchain.prompts.pipeline import PipelinePromptTemplate
from langchain.prompts import PromptTemplate
import base64
import httpx
# 子模板1:图片描述生成
vision_template = PromptTemplate.from_template(
"分析这张图片:{image_base64}\n"
"请列出图中3个最显著的特征(如物体、颜色、动作)"
)
# 子模板2:问题回答
qa_template = PromptTemplate.from_template(
"基于以下图片特征:{vision_analysis}\n"
"回答用户问题:{user_question}\n"
"要求:包含对图片特征的引用"
)
# 构建多模态流水线
multimodal_prompt = PipelinePromptTemplate(
final_prompt=PromptTemplate.from_template(
"多模态问答系统:\n"
"{vision_part}\n"
"{qa_part}"
),
pipeline_prompts=[
("vision_part", vision_template),
("qa_part", qa_template)
]
)
# 使用示例(需替换真实图片URL)
image_url = "https://example.com/park.jpg"
image_data = base64.b64encode(httpx.get(image_url).content).decode("utf-8")
formatted_prompt = multimodal_prompt.format(
image_base64=f"<<Image>>{image_data}",
user_question="图中人们在做什么活动?"
)
print(formatted_prompt)
该示例演示了如何分阶段处理多模态输入:先提取视觉特征,再结合特征回答问题。实际运行时需要接入多模态模型来处理图像数据。
3. 聊天提示词模板
聊天模型中的四种消息:AIMessage、HumanMessage、SystemMessage、ChatMessage分别对应着4种聊天消息模板:AIMessagePromptTemplate、HumanMessagePromptTemplate、SystemMessagePromptTemplate、ChatMessagePromptTemplate;
可以通过这些模板,构建引导整个会话流程。典型的工作流程:
- System设定角色和规则
- Human收集用户输入
- AI按预定格式响应
- 通过ChatPromptTemplate组合成完整对话链:
1. SystemMessagePromptTemplate 设定AI角色和对话规则:
python
from langchain.prompts import SystemMessagePromptTemplate
system_template = "你是一位专业心理咨询师,用温暖平和的方式回答用户问题"
system_prompt = SystemMessagePromptTemplate.from_template(system_template)
# 输出:SystemMessage(content='你是一位...', additional_kwargs={})
2. HumanMessagePromptTemplate结构化用户输入:
python
from langchain.prompts import HumanMessagePromptTemplate
human_template = "我的问题是关于{topic},具体情况:{details}"
human_prompt = HumanMessagePromptTemplate.from_template(human_template)
# 使用:human_prompt.format(topic="失眠", details="连续一周睡不着")
3. AIMessagePromptTemplate控制AI响应格式:
python
from langchain.prompts import AIMessagePromptTemplate
ai_template = """建议方案:
1. {solution1}
2. {solution2}"""
ai_prompt = AIMessagePromptTemplate.from_template(ai_template)
# 输出带编号列表的响应
4. ChatPromptTemplate 构建完整对话流程:
python
from langchain.prompts import ChatPromptTemplate
chat_template = ChatPromptTemplate.from_messages([
system_prompt,
human_prompt,
ai_prompt
])
chain = chat_template | ChatOpenAI()
chain.invoke({
"topic": "焦虑",
"details": "考前心慌",
"solution1": "深呼吸练习",
"solution2": "制定复习计划"
})
5.多模态支持:
实际应用中,通常需要支持在单个PromptTemplate中组合文本、图像URL等数据类型,例如构建包含图像和文本的多模态消息。
python
edu_prompt = ChatPromptTemplate.from_messages([
SystemMessage(content="你是数学辅导AI,需:\n1. 识别手写答案\n2. 指出错误步骤"),
# 保留最近3轮对话
MessagesPlaceholder(variable_name="dialogue", optional=True),
# 混合输入
HumanMessage(content=[
{"type": "text", "text": "问题:{question}"},
{"type": "image_url", "image_url": "{handwriting}"},
{"type": "audio_url", "audio_url": "{voice_note}"}
])
])
# 调用示例(无历史对话时)
prompt = edu_prompt.format_messages(
question="求x²+2x+1=0的解",
handwriting="https://example.com/student_work.jpg",
voice_note="https://example.com/voice_q.mp3"
)
4. 占位符MessagesPlaceholder
MessagesPlaceholder是LangChain中用于动态插入消息列表的占位符组件,属于BaseMessagePromptTemplate的子类。它允许在构建聊天提示模板时预留位置,后续通过变量注入实际消息内容。
- 动态消息插入:支持在运行时填充任意数量的消息(如对话历史)。
- 多角色兼容:可处理SystemMessage、HumanMessage、AIMessage等混合类型消息。
- 条件控制:通过optional参数控制占位符是否必填。
4.1 基本用法
python
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.messages import HumanMessage, SystemMessage
# 定义包含占位符的模板
chat_prompt = ChatPromptTemplate.from_messages([
SystemMessage(content="你是一个助手"),
MessagesPlaceholder(variable_name="history"),
HumanMessage(content="{input}")
])
# 填充实际消息
formatted = chat_prompt.format_messages(
history=[
HumanMessage(content="你好"),
AIMessage(content="有什么可以帮您?")
],
input="今天天气如何"
)
4.2 多轮对话
结合ConversationBufferMemory实现上下文保持:
python
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory(return_messages=True)
memory.save_context(
{"input": "推荐一本小说"},
{"output": "《三体》值得一读"}
)
# 使用记忆中的历史对话
prompt_with_history = chat_prompt.format_messages(
history=memory.load_memory_variables({})["history"],
input="作者是谁?"
)
4.3 可选占位符配置
python
optional_placeholder = MessagesPlaceholder(
variable_name="history",
optional=True
) # 未提供变量时返回空列表:ml-citation{ref="2" data="citationList"}
4.4 动态示例选择
在Few-shot场景中,通过MessagesPlaceholder动态插入示例对话:
python
few_shot_prompt = ChatPromptTemplate.from_messages([
SystemMessage(content="根据示例回答问题"),
MessagesPlaceholder("examples"),
HumanMessage(content="{question}")
])