Part 3: Prompts(提示)
文章目录
-
- [Part 3: Prompts(提示)](#Part 3: Prompts(提示))
-
- [3.1 提示工程基础](#3.1 提示工程基础)
- [3.2 PromptTemplate](#3.2 PromptTemplate)
- [3.3 ChatPromptTemplate](#3.3 ChatPromptTemplate)
-
- [from_messages 方法](#from_messages 方法)
- [MessagesPlaceholder 详解](#MessagesPlaceholder 详解)
- [partial 方法](#partial 方法)
- [完整 Demo](#完整 Demo)
- [3.4 FewShotPromptTemplate](#3.4 FewShotPromptTemplate)
- [3.5 提示最佳实践](#3.5 提示最佳实践)
3.1 提示工程基础
提示的结构
提示(Prompt)
系统指令(System)
定义 AI 角色和行为
上下文(Context)
背景信息和约束
输入数据(Input)
用户的具体内容
输出格式(Output)
期望的输出格式
3.2 PromptTemplate
所有参数
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
input_variables |
list[str] |
必填 | 模板中的变量名列表 |
template |
str |
必填 | 模板字符串,{变量名} 作为占位符 |
template_format |
str |
"f-string" |
模板格式:"f-string" 或 "jinja2" |
partial_variables |
dict |
None |
预填充的变量 |
validate_template |
bool |
True |
是否验证模板语法 |
python
# demo_prompt_template.py
from langchain_core.prompts import PromptTemplate
# from_template:自动提取变量名(推荐)
prompt = PromptTemplate.from_template(
"请用{language}写一个关于{topic}的{style}文章,大约{count}字。"
)
print(prompt.input_variables) # ['language', 'topic', 'style', 'count']
formatted = prompt.format(language="中文", topic="AI", style="科普", count="500")
print(formatted)
# 构造函数方式
prompt = PromptTemplate(
input_variables=["name", "age"],
template="你好,我叫{name},今年{age}岁。",
)
# jinja2 模板格式
prompt = PromptTemplate(
input_variables=["items"],
template="{% for item in items %}- {{ item }}\n{% endfor %}",
template_format="jinja2",
)
print(prompt.format(items=["苹果", "香蕉", "橙子"]))
# partial:预填充部分变量
prompt = PromptTemplate.from_template("你是一个{role}。请回答:{question}")
translator_prompt = prompt.partial(role="翻译专家")
print(translator_prompt.format(question="hello 怎么翻译?"))
3.3 ChatPromptTemplate
from_messages 方法
python
# demo_chat_prompt_template.py
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.messages import HumanMessage, AIMessage
# 方式一:元组格式(推荐)
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个{role},回答要{style}。"),
("human", "{question}"),
])
messages = prompt.format_messages(role="Python 专家", style="通俗", question="什么是装饰器?")
# 方式二:消息类
prompt = ChatPromptTemplate.from_messages([
HumanMessage(content="请将以下文本翻译成{language}:{text}"),
])
# 方式三:from_template 快捷方法
prompt = ChatPromptTemplate.from_template("请解释{concept}")
MessagesPlaceholder 详解
python
# demo_messages_placeholder.py
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.messages import HumanMessage, AIMessage
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个有帮助的 AI 助手。"),
MessagesPlaceholder(variable_name="chat_history"), # 插入对话历史
("human", "{user_input}"),
])
chat_history = [
HumanMessage(content="我叫小明"),
AIMessage(content="你好小明!"),
]
messages = prompt.format_messages(
chat_history=chat_history,
user_input="我叫什么名字?"
)
# AI 能从历史中知道用户叫小明
# 可选占位符
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个客服机器人。"),
MessagesPlaceholder(variable_name="history", optional=True),
("human", "{question}"),
])
messages = prompt.format_messages(question="你好") # 不提供 history 也可以
partial 方法
python
# demo_chat_prompt_partial.py
from langchain_core.prompts import ChatPromptTemplate
# 创建时预填充
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个{role},使用{language}回答。"),
("human", "{question}"),
], partial_variables={"role": "编程专家", "language": "中文"})
messages = prompt.format_messages(question="什么是 Python?")
# 运行时预填充
teacher_prompt = prompt.partial(role="老师")
messages = teacher_prompt.format_messages(question="什么是光合作用?")
完整 Demo
python
# demo_chat_prompt_full.py
from dotenv import load_dotenv
load_dotenv()
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.messages import HumanMessage, AIMessage
from langchain_openai import ChatOpenAI
# 代码审查助手
code_review_prompt = ChatPromptTemplate.from_messages([
("system", "你是一位资深代码审查专家。请审查代码的质量、安全性和性能。"),
("human", "请审查以下 {language} 代码:\n```{language}\n{code}\n```"),
])
model = ChatOpenAI(model="gpt-4o-mini", temperature=0.3)
chain = code_review_prompt | model
result = chain.invoke({"language": "Python", "code": "def add(a, b): return a + b"})
print(result.content)
# 带对话历史的翻译助手
translation_prompt = ChatPromptTemplate.from_messages([
("system", "你是一个专业翻译。翻译成{target_language}。只输出翻译结果。"),
MessagesPlaceholder(variable_name="history", optional=True),
("human", "{text}"),
])
chain = translation_prompt | model
result = chain.invoke({"target_language": "英文", "text": "今天天气真好", "history": []})
print(result.content)
3.4 FewShotPromptTemplate
所有参数
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
examples |
list[dict] |
[] |
示例列表 |
example_prompt |
PromptTemplate |
必填 | 格式化每个示例的模板 |
prefix |
str |
"" |
示例前的前缀 |
suffix |
str |
"" |
示例后的后缀 |
input_variables |
list[str] |
[] |
最终提示的输入变量 |
example_separator |
str |
"\n\n" |
示例间的分隔符 |
示例选择器
| 选择器 | 说明 | 适用场景 |
|---|---|---|
LengthBasedExampleSelector |
根据输入长度选择示例数量 | 输入长度变化大 |
SemanticSimilarityExampleSelector |
根据语义相似度选择 | 示例种类多 |
完整 Demo
python
# demo_fewshot_prompt.py
from dotenv import load_dotenv
load_dotenv()
from langchain_core.prompts import PromptTemplate, FewShotPromptTemplate
from langchain_core.prompts.example_selector import LengthBasedExampleSelector
from langchain_openai import ChatOpenAI
examples = [
{"input": "开心 -> 英文", "output": "happy"},
{"input": "悲伤 -> 英文", "output": "sad"},
{"input": "愤怒 -> 英文", "output": "angry"},
]
example_prompt = PromptTemplate.from_template("输入: {input}\n输出: {output}")
few_shot_prompt = FewShotPromptTemplate(
examples=examples,
example_prompt=example_prompt,
prefix="翻译助手示例:",
suffix="\n输入: {input}\n输出:",
input_variables=["input"],
example_separator="\n---\n",
)
print(few_shot_prompt.format(input="兴奋 -> 英文"))
# 使用 LengthBasedExampleSelector
all_examples = [
{"input": f"情绪{i} -> 英文", "output": f"emotion{i}"}
for i in range(8)
]
selector = LengthBasedExampleSelector(
examples=all_examples,
example_prompt=example_prompt,
max_length=200,
)
dynamic_prompt = FewShotPromptTemplate(
example_selector=selector,
example_prompt=example_prompt,
prefix="翻译示例:",
suffix="\n输入: {input}\n输出:",
input_variables=["input"],
)
model = ChatOpenAI(model="gpt-4o-mini", temperature=0.0)
chain = few_shot_prompt | model
result = chain.invoke({"input": "兴奋 -> 英文"})
print(result.content)
3.5 提示最佳实践
| 原则 | 说明 | 示例 |
|---|---|---|
| 明确具体 | 清楚说明你想要什么 | "写一篇 300 字的 Python 入门教程" |
| 提供角色 | 给 AI 设定专业角色 | "你是一位有 10 年经验的 Python 开发者" |
| 给出示例 | 通过示例展示期望格式 | FewShot 提示 |
| 分步骤 | 复杂任务拆分为步骤 | "第一步...第二步...第三步..." |
| 指定格式 | 明确输出格式要求 | "请用 JSON 格式输出" |
python
# 常见模式
from langchain_core.prompts import ChatPromptTemplate
# 角色 + 任务 + 约束
prompt = ChatPromptTemplate.from_messages([
("system", "你是一位{role}。\n任务:{task}\n约束:{constraints}"),
("human", "{input}"),
])
# 思维链(Chain of Thought)
cot_prompt = ChatPromptTemplate.from_messages([
("system", "请一步一步地思考问题。"),
("human", "问题:{question}\n\n思考过程:\n1. ...\n\n最终答案:..."),
])
| 反模式 | 问题 | 正确做法 |
|---|---|---|
| "帮我写东西" | 太模糊 | "帮我写一篇 300 字的 Python 入门教程" |
| "不要做X" | 负面指令效果差 | "请做Y"(正面指令) |
| 模板中硬编码 | 不灵活 | 使用变量 {variable} |