提示工程
提示的种类
1. 指令(Instruction)
定义: 指令部分明确地告诉模型任务的整体目标和具体要求,解释需要完成的工作以及处理问题的方式。这部分通常是固定的,用于设定模型在当前对话或任务中的角色及行为准则。
作用:
- 为模型定义角色或职责。
- 指导模型如何使用输入信息处理问题。
- 确保模型的回答符合用户的预期。
示例:
- “你是一个专业的医学顾问,能够回答有关健康和医疗的问题。”
- “请作为一个法律顾问,提供与合同法相关的问题解答。”
- “你是一个代码助手,帮助用户解决编程问题,并解释代码逻辑。”
细化要点:
- 角色明确化:通过描述模型的身份和任务,赋予它专业性和专注性。
- 任务细化:使用清晰的语言说明具体要求,比如“逐步解释”、“直接回答问题”或“提供代码示例”。
2. 上下文(Context)
定义: 上下文部分为模型提供额外的知识来源,作为处理当前任务的辅助信息。这些信息可以来自手动输入、外部工具调用、API数据或从知识库中检索的相关内容。
作用:
- 弥补模型在训练数据中的知识空白。
- 提高生成回答的准确性和相关性。
- 为复杂任务提供详细背景和补充材料。
示例:
- 如果模型要回答某个技术问题,可以提供技术文档的摘录作为上下文。
- 对于历史类问题,可以传递从向量数据库中检索到的相关资料。
- 在实时任务中,上下文可以是从API返回的最新数据(如天气或金融数据)。
细化要点:
- 上下文来源:上下文可以通过查询知识库(如矢量数据库)、工具(如计算器)、API等动态获取,也可以是手动编辑的内容。
- 相关性:上下文信息必须与任务密切相关,避免因冗余信息降低模型性能。
- 动态更新:对于时间敏感型任务(如新闻回答),上下文需要保持实时更新。
3. 提示输入(Prompt Input)
定义: 提示输入是模型需要解决的具体问题,或者用户想要模型完成的具体任务。这部分可以看作是输入的核心内容,通常以变量的形式传递给提示模板。
作用:
- 定义任务的具体范围和细节。
- 为模型提供明确的操作对象或问题。
- 使模板可以复用,通过不同的提示输入解决类似的任务。
示例:
- 问题型输入:用户问:“为什么天空是蓝色的?”
- 任务型输入:用户请求:“生成一个包含5个元素的随机数组。”
- 代码型输入:用户要求:“优化下面的代码片段,使其运行更高效。”
细化要点:
- 独立性:提示输入和指令可以合二为一,但分离出来更结构化,便于复用。
- 细化要求:明确提示输入中的变量范围和期望的输出形式。
- 灵活性:提示输入的具体内容可以动态变化,以适应不同的场景需求。
4. 输出指示器(Output Indicator)
定义: 输出指示器是用于标记生成文本开始的引导部分,帮助模型理解从哪里开始生成具体的回答或代码。
作用:
- 明确输出的开始点。
- 提示模型以某种格式或逻辑输出内容。
- 引导模型进入特定的生成模式,例如推理、回答、或代码输出。
示例:
- 自然语言输出:使用“解:”提示模型开始回答问题。
- 代码输出:使用“import”提示模型生成Python代码。
- 推理过程:使用“Thought:”提示模型解释其推理过程。
细化要点:
- 引导性:选择适合任务的标记词汇,以提示模型切换到正确的输出模式。
- 任务适配性:例如,在代码生成任务中,输出指示器可以是特定的编程语言关键词。
- 简洁性:通常输出指示器不需要过多描述,起到标记作用即可。
PromptTemplate
# 使用PromptTemplate
template = """\
你是一个素质低下的业务咨询顾问。
你给一个销售{product}的公司起一个名字
"""
prompt = PromptTemplate.from_template(template)
print(prompt.format(product="鲜花"))
输出:
你是一个素质低下的业务咨询顾问。
你给一个销售鲜花的公司起一个名字
ChatPromptTemplate
openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Who won the world series in 2020?"},
{"role": "assistant", "content": "The Los Angeles Dodgers won the World Series in 2020."},
{"role": "user", "content": "Where was it played?"}
]
)
消息必须是消息对象的数组,其中每个对象都有一个角色(系统、用户或助理)和内容。对话可以短至一条消息,也可以来回多次。
通常,对话首先由系统消息格式化,然后是交替的用户消息和助理消息。
系统消息有助于设置助手的行为。例如,你可以修改助手的个性或提供有关其在整个对话过程中应如何表现的具体说明。但请注意,系统消息是可选的,并且没有系统消息的模型的行为可能类似于使用通用消息,例如“你是一个有用的助手”。
用户消息提供助理响应的请求或评论。
助理消息存储以前的助理响应,但也可以由你编写以给出所需行为的示例。
FewShot
Few-Shot(少样本)、One-Shot(单样本)和与之对应的 Zero-Shot(零样本)的概念都起源于机器学习。如何让机器学习模型在极少量甚至没有示例的情况下学习到新的概念或类别,对于许多现实世界的问题是非常有价值的,因为我们往往无法获取到大量的标签化数据。
使用FewShotPromptTemplate
首先,创建一些示例,作为提示的样本。其中每个示例都是一个字典,其中键是输入变量,值是这些输入变量的值。
# 1. 创建一些示例
samples = [
{
"flower_type": "玫瑰",
"occasion": "爱情",
"ad_copy": "玫瑰,浪漫的象征,是你向心爱的人表达爱意的最佳选择。"
},
{
"flower_type": "康乃馨",
"occasion": "母亲节",
"ad_copy": "康乃馨代表着母爱的纯洁与伟大,是母亲节赠送给母亲的完美礼物。"
},
{
"flower_type": "百合",
"occasion": "庆祝",
"ad_copy": "百合象征着纯洁与高雅,是你庆祝特殊时刻的理想选择。"
},
{
"flower_type": "向日葵",
"occasion": "鼓励",
"ad_copy": "向日葵象征着坚韧和乐观,是你鼓励亲朋好友的最好方式。"
}
]
# 创建提示词模板
from langchain.prompts import PromptTemplate
template = "鲜花类型:{flower_type}\n场合:{occasion}\n文案:{ad_copy}"
prompt_sample = PromptTemplate(input_variables=["flower_type", "occasion", "ad_copy"],
template=template)
print(prompt_sample.format(**samples[0]))
# 创建FewShotPromptTemplate 对象
from langchain.prompts.few_shot import FewShotPromptTemplate
prompt = FewShotPromptTemplate(
examples=samples,
example_prompt=prompt_sample,
suffix="鲜花类型:{flower_type}\n场合{occasion}",
input_variables=["flower_type", "occasion"],
)
print(prompt.format(flower_type="菊花",occasion="热情"))
FewShotPromptTemplate是一个更复杂的提示模板,它包含了多个示例和一个提示。这种模板可以使用多个示例来指导模型生成对应的输出。目前我们创建一个新提示,其中包含了根据指定的花的类型“野玫瑰”和场合“爱情”。
调用大模型创建新文案
import os
os.environ['OPENAI_API_KEY']='sk-mduGNGc05FuHrfR5URGnAY9Ir9Rbho24186WfLBfKvNUYioS'
from langchain.llms import OpenAI
model = OpenAI(model_name='gpt-3.5-turbo-instruct',
base_url='<https://api.openai-proxy.org/v1>')
result = model(prompt.format(flower_type="菊花", occasion="热情"))
print(result)
调用示例选择器
如果我们的示例很多,那么一次性把所有示例发送给模型是不现实而且低效的。另外,每次都包含太多的Token也会浪费流量(OpenAI是按照Token数来收取费用)。
LangChain提供了示例选择器,来选择最合适的样本。
# 创建一个使用示例选择器的FewShotPromptTemplate对象
prompt = FewShotPromptTemplate(
exampe_selector=example_selector,
example_prompt=prompt_sample,
suffix="鲜花类型:{flower_type}\n场合:{occasion}",
input_variables=["flower_type", "occasion"],
)
print(prompt.format(flower_type="红玫瑰",occasion="爱情"))
它首先创建了一个SemanticSimilarityExampleSelector对象,这个对象可以根据语义相似性选择最相关的示例。然后,它创建了一个新的FewShotPromptTemplate对象,这个对象使用了上一步创建的选择器来选择最相关的示例生成提示。
然后,我们又用这个模板生成了一个新的提示,因为我们的提示中需要创建的是红玫瑰的文案,所以,示例选择器example_selector会根据语义的相似度(余弦相似度)找到最相似的示例,也就是“玫瑰”,并用这个示例构建了FewShot模板。