前言:本篇博客所有内容均参考 吴恩达老师的『ChatGPT Prompt Engineering for Developers』,以及个人的一些想法也加入里面了。
目录
前言:本篇博客所有内容均参考 吴恩达老师的『ChatGPT Prompt Engineering for Developers』,以及个人的一些想法也加入里面了。
一. 指导原则
1. 编写清晰而具体的提示
1.1 使用分隔符来清楚分割指令和内容
由于视频中openai的版本晚于当前版本,于是便用最新版本的openai作为示例代码
版本 openai == 1.40.6
1.1.1 环境准备
pip install openai
from openai import OpenAI
def get_completion(prompt,model="gpt-3.5-turbo"):
openai = OpenAI(
base_url = httpx.URL("Your base url"),# 填写url
api_key = "Your openai api")# 填写key
messages = [{"role": "user", "content": prompt}]
response = openai.chat.completions.create(
model = model,
messages = messages,
temperature=0,
stream=False
)
# print(response)
return response.choices[0].message.content
使用分割符来分割自己的指令和内容
text = """
你应该通过提供清晰具体的指令表达你想要一个模型去做的东西。这将会引导模型输出期望的结果并且减少接收到错误或不相关回复的概率。
不要把清晰的提示和简短的提示混为一谈。在许多情况下,更长的提示提供更清晰的内容,能够让模型输出更多正确更相关的输出
"""
prompt = f"""
用一句话总结下面用三个`包裹的文本。
```{text}```
"""
response = get_completion(prompt)
也就是在prompt标清哪一部分是指令,哪一部分是内容。
1.2 要求结构化的输出
text = """
在探索人类心理复杂性的书籍中,ID为001的《思考,快与慢》(*Thinking, Fast and Slow*),由丹尼尔·卡尼曼(Daniel Kahneman)撰写,
是一本关于认知心理学的经典之作,属于心理学(Psychology)类型。紧随其后,ID为002的《影响力》(*Influence: The Psychology of Persuasion*),
作者是罗伯特·西奥迪尼(Robert B. Cialdini),这本书进一步探讨了人类行为背后的社会心理学(Social Psychology)机制。
同样引人深思的是ID为003的《枪炮、病菌与钢铁》(*Guns, Germs, and Steel*),由贾雷德·戴蒙德(Jared Diamond)创作,它以非小说类(Non-fiction)
历史书籍的形式,揭示了人类社会发展的复杂因素。最后,ID为004的《夜晚的图书馆》(*The Midnight Library*),由马特·海格(Matt Haig)撰写,属于文学(
Fiction)类别,这本小说通过探索无尽可能性的平行世界,将哲学与自我发现的主题引入了读者的视野。
"""
prompt = f"""
请提取下面用```包裹的文字,提取的内容包括,id,title,author,genre
你的回答应该是List[Dict]的形式。
需要提取内容的文字如下:
```{text}```
"""
response = get_completion(prompt)
eval(response.strip("```python").strip("```"))
如上,需要自己去告诉LLM应该如何去输出,如何去结构化的输出自己想要输出的东西。
1.3 要求模型检查是否满足条件
text_1 = f"""
泡一杯茶很简单!首先,你需要把水烧开。当水在烧的时候,\
拿一个杯子并放入一袋茶叶。当水烧热后,直接将水倒在茶包上。\
让它泡一会儿,这样茶就可以浸泡出来了。几分钟后,把茶包取出来。\
如果你喜欢,可以根据口味加入一些糖或牛奶。\
就是这样!你可以享用一杯美味的茶了。
"""
prompt = f"""
你将会得到一段由三引号分隔的文本。\
如果其中包含一系列指令,\
请按照以下格式重写这些指令:
步骤 1 - ...
步骤 2 - …
…
步骤 N - …
如果文本不包含一系列指令,\
那么只需写“未提供步骤。”
\"\"\"{text_1}\"\"\"
"""
response = get_completion(prompt)
print(response)
问题中有一个分支条件,如果有指令就输出指令,没有指令就输出未提供步骤,这就是让模型自己去检查是否满足条件
text_2 = f"""
今天阳光明媚,鸟儿在歌唱。\
这是一个在公园散步的美好日子。\
花儿盛开,树木在微风中轻轻摇曳。\
人们在外面享受着美好的天气。\
有些人正在野餐,有些人在玩游戏,\
或者只是躺在草地上放松。\
这是一个完美的日子,适合在户外度过时间,\
欣赏大自然的美丽。
"""
prompt = f"""
你将会得到一段由三引号分隔的文本。\
如果其中包含一系列指令,\
请按照以下格式重写这些指令:
步骤 1 - ...
步骤 2 - …
…
步骤 N - …
如果文本不包含一系列指令,\
那么只需写“未提供步骤。”
\"\"\"{text_2}\"\"\"
"""
response = get_completion(prompt)
print(response)
text = "😘"
prompt = f"""
你将会得到由```包裹的表情,请判断
表情的态度。
如果是喜欢的态度,请用🫂来回复。
如果是其他不相关的态度,用🤷♂️来回复。
```{text}```
"""
response = get_completion(prompt)
print(response)
1.4 few shot 少样本提示
意思为,给LLM一些举例说明来教模型应该怎样去输出问题的答案,以此来提高回答的相关性和准确率。
prompt = """
你的任务是根据情景对话回复三个符号之中的一个。
第一个符号是 O.O , 意思是: 真的!
第二个符号是 o.o, 意思是: 假的!
第三个符号是 O.o, 意思是: 真的假的?(惊讶)
举例说明:
示例一:
<User>: 地球是圆形的
<LLM>: O.O
示例二:
<User>: 有100个太阳
<LLM>: o.o
示例三:
<User>: 我之前爬过100次泰山!
<LLM>: O.o
现在开始对话:
<User>: 我一口气能吃100个包子
"""
response = get_completion(prompt)
print(response)
text = """
你的任务是以一致的风格回答。
<child>: 教我关于耐心的事。
<grandparent>: 河流刻画最深的山谷源自一处不起眼的泉水;最宏伟的交响乐始于一个简单的音符;最精致的织锦始于一根孤单的线。
<child>: 教我关于韧性的事。
"""
response = get_completion(text)
print(response)
2. 给模型思考的时间(COT)
transformer架构的模型计算就是forward过一遍整个模型。那么如何体现出让模型去思考呢?如何去增加思考的时间呢?
答案是,让模型按照一定的步骤去回答问题,最终得到问题的答案。这样就能够引导模型去一步一步思考,think step by step,然后通过强制分步骤回答问题,最终达到增加思考的计算量,进而增加思考的时间。
这里就相当于COT(chain of thought), 也是思维链的开篇之作,
COT的prompt包含三个部分
- 指令:用于描述问题并且告知大模型的输出格式;
- 逻辑依据:指 CoT 的中间推理过程,可以包含问题的解决方案、中间推理步骤以及与问题相关的任何外部知识;
- 示例:指以少样本的方式为大模型提供输入输出对的基本格式,每一个示例都包含:问题,推理过程与答案。
2.1 指定完成任务所需的步骤
text = """
在一个迷人的村庄里,兄妹俩杰克和吉尔出发去山顶的水井取水。当他们欢快地唱歌攀爬时,
不幸发生了——杰克绊倒在一块石头上,从山坡上跌下,而吉尔紧随其后。尽管略有磕碰,
这对兄妹还是回到了家中,得到温馨的拥抱。尽管发生了意外,他们的冒险精神依然高昂,
他们继续愉快地探索。
"""
prompt = f"""
执行以下操作:
1 - 用一句话总结以下用三重反引号括起来的文本。
2 - 将总结翻译成法语。
3 - 列出法语总结中的每个名字。
4 - 输出一个 JSON 对象,包含以下键:french_summary、num_names。
用换行符分隔你的回答。
文本:
```{text}```
"""
response = get_completion(prompt)
print(response)
COT的例子
text = """
你有一个装满了苹果和橙子的水果篮子。
总共有 12 个水果,其中 8 个是苹果,
其余的都是橙子。如果你从篮子里随机拿出一个水果,
它是苹果的概率是多少?
"""
prompt = f"""
你是逻辑推理的专家,请根据问题按照步骤进行推理,最后给出答案。
记住,你需要一步一步的经过仔细思考之后的推理。
你的推理过程应该先将问题分割为若干个子问题,
然后通过逐步解决每个子问题,最后回答出问题最终的答案。
你必须按照示例的形式输出。
示例:
示例1:
问题: 在一个池塘里有莲花,莲花每天都会翻倍。假设莲花在第20天覆盖了整个池塘的面积,那么在第几天莲花覆盖了池塘的一半?
思维链:
1. 莲花每天都会翻倍,也就是说前一天的莲花数量是今天的一半。
2. 在第20天,莲花覆盖了整个池塘。
3. 第19天莲花覆盖了池塘的一半,因为第19天的莲花数量翻倍后就覆盖了整个池塘。
4. 第19天莲花覆盖了池塘的一半。
答案: 第19天。
示例2: