提示工程 (Prompts)
构建和管理提示以指导模型行为
PromptTemplate 基础
字符串模板
python
from langchain_core.prompts import PromptTemplate
# 基础模板
prompt = PromptTemplate(
input_variables=["product", "feature"],
template="为{product}写一个广告,突出{feature}这个特点。"
)
# 格式化提示
formatted = prompt.format(
product="智能手表",
feature="健康监测"
)
print(formatted)
# 输出: 为智能手表写一个广告,突出健康监测这个特点。
聊天模板
python
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
# 系统提示 + 用户输入
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个专业的{role}助手。"),
("user", "{user_input}")
])
formatted = prompt.format_messages(
role="Python 编程",
user_input="如何使用列表推导式?"
)
print(formatted)
高级功能
部分变量
python
from langchain_core.prompts import PromptTemplate
# 预设部分变量
prompt = PromptTemplate(
template="向{name}介绍{product},重点介绍{feature}。",
input_variables=["name", "feature"],
partial_variables={"product": "LangChain"}
)
# 只需填入剩余变量
formatted = prompt.format(
name="小明",
feature="智能体功能"
)
消息占位符
python
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
# 使用 MessagesPlaceholder 插入动态消息历史
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个有帮助的助手。"),
MessagesPlaceholder(variable="history"), # 对话历史
("user", "{user_input}")
)
formatted = prompt.format_messages(
history=[
{"role": "user", "content": "你好"},
{"role": "assistant", "content": "你好!有什么可以帮助你的?"}
],
user_input="记得我之前说了什么吗?"
)
Few-shot 示例
静态示例
python
from langchain_core.prompts import FewShotPromptTemplate, PromptTemplate
# 定义示例
examples = [
{"input": "苹果", "output": "红色水果"},
{"input": "香蕉", "output": "黄色水果"},
{"input": "橙子", "output": "橙色水果"},
]
# 示例格式化模板
example_prompt = PromptTemplate(
input_variables=["input", "output"],
template="输入: {input}\n输出: {output}"
)
# 创建 Few-shot 提示
prompt = FewShotPromptTemplate(
examples=examples,
example_prompt=example_prompt,
prefix="根据示例完成任务",
suffix="输入: {input}\n输出:",
input_variables=["input"]
)
# 使用
result = prompt.format(input="西瓜")
print(result)
动态示例选择
python
from langchain_core.prompts import FewShotPromptTemplate
from langchain_core.example_selectors import SemanticSimilarityExampleSelector
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
# 创建示例库
examples = [
{"question": "什么是Python?", "answer": "Python是一种编程语言"},
{"question": "什么是列表?", "answer": "列表是Python的可变序列类型"},
{"question": "什么是字典?", "answer": "字典是Python的键值对数据结构"},
# ... 更多示例
]
# 使用语义相似度选择示例
selector = SemanticSimilarityExampleSelector.from_examples(
examples=examples,
embeddings=OpenAIEmbeddings(),
vectorstore_cls=Chroma,
k=2 # 选择最相似的2个示例
)
# 动态 Few-shot 提示
prompt = FewShotPromptTemplate(
example_selector=selector,
example_prompt=PromptTemplate(
input_variables=["question", "answer"],
template="问题: {question}\n答案: {answer}"
),
suffix="问题: {question}\n答案:",
input_variables=["question"]
)
输出解析器
基础解析
python
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI
# 创建解析链
prompt = PromptTemplate.from_template("讲一个关于{topic}的简短笑话")
output_parser = StrOutputParser()
llm = ChatOpenAI(model="gpt-4o")
# 组合:prompt | llm | parser
chain = prompt | llm | output_parser
result = chain.invoke({"topic": "程序员"})
print(result)
结构化输出解析
python
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import JSONOutputParser
from langchain_openai import ChatOpenAI
# 定义期望的 JSON 结构
parser = JSONOutputParser()
# 提示模板中包含格式说明
prompt = PromptTemplate(
template="回答以下问题,输出格式:{format_instructions}\n\n问题:{question}",
input_variables=["question"],
partial_variables={"format_instructions": parser.get_format_instructions()}
)
llm = ChatOpenAI(model="gpt-4o")
chain = prompt | llm | parser
result = chain.invoke({"question": "Python 的主要特点是什么?"})
print(result) # 返回解析后的字典
自定义解析器
python
from langchain_core.output_parsers import BaseOutputParser
class CommaSeparatedListParser(BaseOutputParser):
"""解析逗号分隔的列表"""
def parse(self, text: str):
return [item.strip() for item in text.split(",")]
@property
def _type(self):
return "comma-separated-list"
# 使用
parser = CommaSeparatedListParser()
result = parser.parse("苹果, 香蕉, 橙子")
print(result) # ['苹果', '香蕉', '橙子']
提示优化技巧
清晰性原则:提示应该明确指定任务、输入格式和输出格式。避免模糊的指令。
python
# ❌ 不好的提示
bad_prompt = "写个排序"
# ✓ 好的提示
good_prompt = """
请用 Python 写一个快速排序函数,要求:
1. 包含完整的函数定义
2. 添加类型注解
3. 添加详细的文档字符串
4. 包含一个简单的使用示例
"""
避免提示注入:当提示包含用户输入时,要警惕提示注入攻击。始终验证和清理用户输入。
python
# 使用提示模板来防止注入
from langchain_core.prompts import PromptTemplate
# 安全:使用模板自动转义
prompt = PromptTemplate(
template="请回答以下问题:{question}",
input_variables=["question"]
)
# 而不是字符串拼接(不安全)
# unsafe = f"请回答以下问题:{user_input}"
管道组合
LangChain 使用 | 操作符将提示、模型和解析器连接成链:
graph LR
A[PromptTemplate] --> B[ChatModel]
B --> C[OutputParser]
C --> D[结果]
python
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI
# 创建组件
prompt = ChatPromptTemplate.from_template("解释{concept},用三句话")
llm = ChatOpenAI(model="gpt-4o")
parser = StrOutputParser()
# 使用 | 组合成链
chain = prompt | llm | parser
# 等价于:
# chain = (
# prompt
# | llm
# | parser
# )
# 调用
result = chain.invoke({"concept": "递归"})
print(result)
常见使用模式
| 模式 | 用途 | 代码示例 |
|---|---|---|
| 系统提示 | 定义助手角色 | ("system", "你是{role}") |
| 少样本 | 提供示例 | FewShotPromptTemplate |
| 对话历史 | 多轮对话 | MessagesPlaceholder("history") |
| 结构化输出 | JSON 解析 | JSONOutputParser() |
| 自动重试 | 修复格式错误 | RunnableRetry |
✏️ 练习题
选择题
1.
MessagesPlaceholder 的主要用途是?
编程题
2. 创建一个聊天提示模板,包含:系统提示、对话历史占位符、用户输入,并实现调用
查看参考答案
python
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_openai import ChatOpenAI
# 创建聊天模板
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个专业的{domain}顾问。"),
MessagesPlaceholder(variable="chat_history"),
("user", "{user_input}")
])
# 创建模型
llm = ChatOpenAI(model="gpt-4o")
# 组合成链
chain = prompt | llm
# 调用
response = chain.invoke({
"domain": "Python 编程",
"chat_history": [
{"role": "user", "content": "什么是装饰器?"},
{"role": "assistant", "content": "装饰器是修改函数行为的函数..."}
],
"user_input": "能举个具体例子吗?"
})
print(response.content)