OpenAI:GPT 最佳实践 (大白话编译解读版)
由small_q创建,最终由small_q 被浏览 372 用户
写在前面
本文为openAI的官方文档《GPT Best Practice》的中文翻译解读版,语言直白、通俗易懂,并补充了中文互联网环境中更容易理解的用例。(FROM:未来力场)
欢迎大家一起阅读交流!
OpenAI推荐的相关资源列表
以下均在OpenAI Cookbook里:
- lib/工具 Prompting libiaries & tools
- 提示词工程指南 Prompting guides
- 视频课 Video courses
- 论文 Papers on advance prompting to improve reasoning
六大策略概览
这是一份指南。我们列出了⼀些策略和技巧,它们或许能帮你从GPT中拿到更好的输出结果。我们鼓励你多试——通过自己反复实验,找出最合适的技巧。
有些⽤例只在目前地表最强模型 gpt-4上生效。记住,模型是第一大影响要素。只要你有更强的模型可用,我们一般都会建议你⽤更强的模型。
展开说说自己想要什么
清晰地告诉GPT,你想要什么
GPT不会读心术。你不说,它就猜。所以有时不是能力不行,就是你没说清,它没猜准。
- 嫌输出太长?那就直说,要短的。
- 嫌输出太简单?要求提高,说要专家级的。
- 嫌格式不好?给它看个样。
你让它猜你的心思猜得越少,结果就越好。
展开说说的技巧
- 你越讲细节,输出就越好
- 搞角色扮演,⼀直很好用
- 使用分隔符号,明确地把话和话区分开来
- 解题步骤,你自己最好也负责展开
- 多给举几个例子
- 说一下你想要多长的答案
给 GPT 发阅读材料
GPT经常⾃编答案。
瞎编重灾区:比较冷门的问题、需要引用,需要读取链接的问题。 我们都知道,最常见的考试题型,是给一大篇阅读材料,要求阅读并回答问题。 纯开放式问答对于人和机器来说都比较难。 那么同理,把你的“阅读材料”给 GPT 粘贴过去,当它必须按照材料来回答的时候,它就可以少一点自己编的内容了。
发阅读材料的技巧
- 要求按阅读材料作答,不开放答
- 增加要求:要求GPT直接把阅读材料里的原文引用出来
拆解复杂任务
在软件开发和常规的项目管理里,大项目都得拆解成子任务,再拆解出不同的步骤。 让GPT做任务也⼀样。直接搞一个大任务容易翻车。 拆解开来,一个接一个做,反而容易些。
任务拆解的技巧
-
使用意图分类,来找到最切题的提示
-
如果是⼀段很长的对话,可以经常对上文做手动总结归纳
(起提醒作用,防止把天儿聊跑了)
-
遇到长文档, 主动分段总结,递归构造完整摘要
允许 GPT 思考⼀下
比如,问你17乘28得多少,如果你不会心算,就不能直接说出结果。但是你知道,你只需要拿纸笔列⼀下式子就能算出来。 同理。GPT也需要时间思考,要求它答得太快,就容易错。
允许思考的技巧
- 给时间,让它先自己想
- 内心独白法:不想暴露推理过程时的操作
- 最后问它一句:哎,你有没有漏掉啥
借助外部的工具
用其他工具帮 GPT 补短板。 文本检索系统,能告诉GPT哪些⽂档重要;代码引擎,助它算数跑代码。 能用工具做得更稳、更快,就别全靠GPT,两者结合,能有更好的效果。
利用工具的技巧
- 用向量数据库来辅助知识库检索
- 做精确计算的时候:执行代码、调API
- 使用Function-Call,函数调用
系统地做⼀些实验
无量化则无实验。要提高Prompt的表现,先得确认一个量化标准。 注意:有时调整了prompt,在个别的例子里确实效果不错,但放大范围反而更差。 所以,想真确定你的动作是“有效的”,最好先有一套完整一点的测试套件(我们管这个东西叫做"eval")。
实验的技巧
评估模型输出的时候,需要你弄一个最牛的优质答案,来做参考标准。
\
技巧实战
充分的解释 & 用例说明
下⾯列出的每个技巧我们都“实例化”了。希望为你的各种⽣成⽬的提供⼀些思路参考。当然,这只是部分 使⽤技巧。我们⿎励你勇于折腾,尝试各种我们没写的创造性想法。
\
【策略一】展开说说自己想要什么
描述越细节越好
为了获得高度相关的回复,你最好给模型提供了一切重要的细节或上下文。否则,你就得让模型来猜测你的意思了。
这么写可能会好⼀些
在Excel里,怎样把一行的美元数额加起来?我想让整 个表格的每一行都能⾃动完成累加,然后所有的美元的 总和都显显示在右边一个叫“总计”的列⾥。
这么写可能不太行
怎么往 excel ⾥加数字?
帮我做下会议纪要。
补充用例
同样是制作业绩表,对表格内容描述的区别很大,输出结果区别也很大。
详细的问题会获得详细的答案
- 详细的提示词:
我正在Excel里做⼀个销售⼈员业绩表。表头:销售姓名、第⼀季度销售额〜第四季度销售额、全年汇总、各月平均销售、超出年平均销售额。我已填入销售姓名和各个季度的销售额,请你帮我写出最后三列所用公式。
- 此时 ChatGPT 的回答:
当您已经填⼊销售姓名和各个季度的销售额后,我将为您提供填写最后三列所需的公式。
假设表格的销售⼈员姓名位于A列(从A2开始),第⼀季度销售额到第四季度销售额位于B到E列(从B2到E2),并且最后三列的表头为"全年汇总"、"各月平均销售"和"超出年平均销售额"。 以下是填写这三列所需的公式: 全年汇总(F列):使用SUM函数计算四个季度的销售额总和。
=SUM(B2:E2)
各⽉平均销售(G列):使⽤AVERAGE函数计算四个季度的销售额平均值。
=AVERAGE(B2:E2)
超出年平均销售额(H列):使用IF函数判断是否超过年平均销售额,并根据判断结果进行计算。
=IF(F2>G2, F2-G2, 0)
此公式将检查全年汇总(F列)是否⼤于各月平均销售(G列),如果是,则计算差值;否则,返回0。将这些公式应用到各行,并确保相应的单元格引用正确(例如,A2、B2:E2等),这样您就可以自动计算全年汇总、各月平均销售和超出年平均销售额了。
泛泛的问题,答案是相对随机的
- 泛泛的提示词:
我正在 Excel ⾥做⼀个销售人员业绩表。你帮我列一个模板出来,要计算每个销售超出年平均销售额的情况。
- 此时 ChatGPT 的回答:
当然可以帮你列⼀个模板出来。以下是⼀个简单的销售人员业绩表模板,其中包含了计算每个销售超出年平均销售额的公式:
销售⼈员 | ⽉份 | 销售额 | 年平均销售额 | 超出年平均销售额
----------|-------|---------|-----------------|-----------------
张三 | 1 | 5000 | 60000 | =C2-D2
张三 | 2 | 6000 | 60000 | =C3-D3
张三 | 3 | 5500 | 60000 | =C4-D4
李四 | 1 | 4500 | 55000 | =C5-D5
李四 | 2 | 7000 | 55000 | =C6-D6
李四 | 3 | 6000 | 55000 | =C7-D7
在上述模板中,"销售人员"列是用于标识每个销售人员的名称,"月份"列是标识销售额所属的月份,"销售额"列是每个销售⼈员在每个月份的销售额,"年平均销售额"列是计算每个销售人员的年平均销售额(假设为60000或55000),"超出年平均销售额"列是计算每个销售人员每个月份是否超出年平均销售额的情况。
你可以根据实际情况调整模板中的数据和公式。希望这个模板对你有帮助!
\
搞角色扮演,一直很好用
系统消息有什么用?可以用来指定一个“Persona”。使其更符合特定的应用场景。
Persona 这个词在拉丁语里的原义是“面具”。可以看作是模型采取的特定角色或风格,就像戴上了⼀种特定的“社交面具”,通过这种“面具”来与用户交流。所以 Persona 不⼀定是:XX人(比如:贾斯汀比伯)、XX职业(比如:一个中学老师)。也可以是⼀种“风格”。例如正式、幽默、友好等。
ChatGPT 有一个默认的 SYSTEM Prompt:You are a helpful assistant.
“一个乐于助人的助手” 也就是 ChatGPT 默认的“面具”/“角色”,所以它会尽力帮你解决提出的问题。
你可以在Playground或者像Knit这样的工具里面修改这个 SYSTEM Message。然后把你正常情况下要提的问题写在USER 里面。这是⼀种进阶的提示词用法。
这么写可能会好⼀些
SYSTEM
当我请求你帮我写文案时,在你回复的文件中,每一段至少包含一个笑话或俏皮的评论。
USER
给我的螺栓供应商写一封感谢邮件。感谢他们非常按时,在短时间内交付了货物。这使我们能够为一份重要的订单履约。
- 输出结果解读
上面的Prompt,放在GPT-4里输出的结果:
Dear [Vendor's Name],
We wanted to take a moment to express our heartfelt thanks to you and your team. You guys really bolted into action when we needed you the most!
Your recent delivery arrived faster than a lightning bolt, much to our delight. It's safe to say we were shocked, but in the most pleasant way possible. We had been walking on eggshells (or should we say, on steel bolts!) until we saw your delivery truck pull up.
It came in a nick of time, just when we were about to start a major project. You know, one of those projects where if one thing goes wrong, everything spirals out of control? It's like building a house of cards, but with steel bolts and a lot of sweat!
Your timely delivery made it possible for us to meet our deadline and make our client happy, which, let's be honest, is a task more challenging than trying to find a needle in a haystack. But thanks to your superhero-like delivery speed, we could deliver an important order on time.
So, here's a big THANK YOU going out to you and your team. Your service was tighter than the threads on your bolts and we couldn't ask for anything more. You've truly set a high bar... or should we say a high bolt?
Jokes aside, we are truly grateful for your service and we look forward to more such electrifying performances from your team in the future!
Yours sincerely,
[Your Name]
解读:
System 的设定里,要求尽可能地开玩笑,让收到邮件的供应商感觉到幽默和放松。邮件正文里就用了至少两处双关和一处比喻:
-
"You guys really bolted into action when we needed you the most!" "Your recent delivery arrived faster than a lightning bolt..."
这⾥两句话,笑点在于双关。因为“bolt”(螺栓),是供应商提供的产品,同时在英语⾥是多义词,另⼀种常见含义是"闪电"。所以这⾥说**“⽐闪电(螺栓)还快”**,是在用一种夸张的方式赞美他们 的快速交付。
-
"Your service was tighter than the threads on your bolts..."
这句的意思是,你们的服务比你们螺栓的螺纹还要紧密..." 赞扬供应商的服务质量,同时也开了个玩笑。
补充用例 1
如果我们设定⼀个 helpful assistant 的反⾯,比如:⼀个“诚心捣乱,混淆视听”的佞臣。 这个时候就会得到说反话的回复。
一个热心助人的小助手
SYSTEM(默认)
You are a helpful assistant. 你是一个热心助人的小助手。
USER
怎么烤制⼀个巧克力蛋糕?
GPT 回复
你只需要准备好巧克力粉、面粉、糖、黄油、鸡蛋、牛奶和发酵粉。将这些材料混合在⼀起,然后倒入蛋糕模具中。将蛋糕放入预热的烤箱中,大约烤制30-40分钟,或者直到蛋糕变得金黄色并且可以用牙签插入蛋糕中心而不沾上面糊。
- ⼀个诚心捣乱的家伙
SYSTEM(自己设定的)
你是⼀个调皮捣蛋的佞臣,目的是制造混乱,一点都不愿意帮忙。
USER
怎么烤制⼀个巧克力蛋糕?
GPT 回复
哦,烤制巧克力蛋糕吗?那可是一门高深的烹饪艺术啊!首先,你需要一把魔法棒和一只神奇的兔子。然后,你要在满⽉的夜晚跳舞三个小时,唱一首关于巧克力的迷人歌曲。接下来,找到一片神秘的巧克力森林,那里会有一只糖果精灵教你烤蛋糕的秘籍。
补充用例 2
也可以这样:
SYSTEM Prompt 用来给进去角色 + 阅读材料;
USER Prompt 用来提具体的写作要求或问题。
SYSTEM
你是⼀个科技作家,正在围绕下面的材料撰写⽂章。
<材料> 插入你的核心文章材料 </材料>
USER
以《XXX》为标题,根据材料写作⼀个简短轻松的指南。
\
使用分隔符号,明确地把话和话区分开来
分隔符号(形式可以有很多种,比如三引号、XML标记、章节标题等)的使用,可以帮助模型区分出不同的文本,有助于提高回复质量。
这么写可能会好⼀些
用俳句的形式,总结三引号之间的文本:
"""在此粘贴⽂本"""
你可能会想:区别不大吧?
对于这样简单的任务,文本只有⼀段,用不用分隔符,确实没什么区别。 但是,任务越复杂,消除任务细节的歧义就越重要。最好不要让 GPT 费力地尝试理解你的要求。
补充用例
下面是⼀个稍微复杂⼀点的文本处理:
这么写可能会好一些
SYSTEM
我会给你提供同⼀主题的两篇文章(用XML标记分隔)。首先,总结每篇文章的论点。然后指出其中哪一个论点更好,并解释原因。
USER
<文章>此处插入第一篇文章</文章>
<文章>此处插入第二篇文章</文章>
这么写可能不太行
两篇文章混在⼀起,尤其如果你粘贴过去的时候不仔细,换行符不明确的时候,模型可能会造成混淆。
比如,模型会随机断句,或者把两篇文章理解成⼀篇。 如果区分不清楚,会很明显地影响对上下文的理解,导致输出的答案不对或者不好。所以,分隔符号有时是必要的。
\
解题步骤,你自己最好也负责展开
有些任务稍微复杂⼀点,最好由你来指定步骤。明确地写出步骤,可以使模型更容易地遵循。
用例:有⼀段很长的英文文本,希望GPT用中文总结一下
SYSTEM
按照以下分步骤的方法,回应用户的输⼊。
第1步:用户将为您提供三引号中的文本。用一句话来总结这段文本。输出时写上“总结”;
第2步:将第1步中的摘要翻译成中文。
输出时写上“翻译“;
USER
"""将原文粘贴在这里"""
上面prompt 实际的输出结果
输入的文本是 OpenAI 最新⼀篇博客文章:ChatGPT can now see, hear, and speak.
--
Summary: ChatGPT introduces voice and image capabilities, allowing users to engage in voice conversations, show images to the assistant, and receive assistance in a more intuitive manner across various real-life scenarios.
Translation: ChatGPT 推出了语音和图像功能,使用户能够进行语音对话,向助手展示图像,并在各种真实场景中以更直观的方式获得帮助。
(如果直接要求用中文总结,输出结果会不太一样。很多情况下输出质量会稍差一点。)
补充用例
这么写可能会好⼀些
请把英文原文翻译成中文。分成两个步骤:
1:按照原来的英文语序,字到字直接翻译成中文。
<直译>把直译文本写在这⾥</直译>
2:再把直译文本的语序进行改进,把部分词语替换成同义词,让它更符合中文的表达习惯。风格:简洁有趣的通俗语⾔。
<改写>改写后的文本写在这里</改写>
<原文>Some tasks are best specfied as a sequence of steps. Writing the steps outexplicitly can make it easier for the model to follow them.</原文>
这么写可能不太行
请把英文原文翻译成中文。风格:简洁有趣通俗。请注意:不要直译,⽽是将语序进⾏改进,并把部分词语替换成同义词,使译文更加符合中文的表达习惯。
<原文>Some tasks are best specfied as a sequence of steps. Writing the steps out explicitly can make it easier for the model to follow them.</原文>
这里是输出结果的区别:
直译+改写得到的两段文本
有助于我们直观地看到区别,可以再提出改进的建议。
**直译:**有些任务最好被明确地指定为⼀系列的步骤。写出步骤可以让模型更容易地遵循它们。
**改写:**对于个别任务,最好把⼀连串的步骤明确一下。把步骤写清楚,能让模型更容易跟上。
不分步的结果
<译文>有些任务就像是步骤表。清晰地列出这些步骤,模型就能轻松遵循。</译文>
多举几个例子
经典的少样本提示方法。
大家和GPT沟通的时候,可能会希望自己能写出适用于所有情况的“通用prompt”。当然很难,因为上面刚说过,能具体还是需要尽量具体。
但有的时候,举⼀个好例子就够了,这可能是比形容要求更简单的办法。比如,如果你想让模型学会以某种特定的方式回应用户的问题,而这种方式很难清楚地用语言形容。
这时候就直接举几个例子(“少样本”)。例⼦要好,而且最好几个例⼦要类似,因为模型自己很擅长去寻找规律(先这样再那样最后这样)。
用例:用诗句一般的语言解释一个词语
SYSTEM
以⼀致的风格回答。
从这里开始,是给系统举的例子:
USER
告诉我什么是耐心。
ASSISTANT
冲刷出深谷的大江大河从⼀个小小的泉眼里流出;
最宏大的交响乐源于一个⾳符;
最复杂的织锦始于一根孤独的线。
USER
告诉我什么是海洋。
你可能很难解释清楚什么是“诗句⼀般的语言”。所以举例子最好用。在 SYSTEM ⾥,告诉模型要“保持风格⼀致”,这时模型的输出结果就会和上面的句式差不多。
补充用例
李佳琦式回复能成为流行梗,精髓不在于“阴阳”的语气风格,或者“反问句”的应用。而在于:把同样的逻辑放到不同领域中,产生了类比效果时,会让人意识到这种表达和逻辑是有问题的——这就是很难用语言描述,但是适合用两段排比展示的用例。
用例:李佳琦回复生成器
SYSTEM
以⼀致的风格、逻辑和句式回答问题。
USER
79元一支眉笔,好贵啊!
ASSISTANT
哪里贵了?79 元哪里贵了?⼀直就是这个价格好吗? 不要睁着眼睛说瞎话,我都要疯掉了。国产品牌很难的! 有时候要找找自己的原因,这么多年工资涨没涨?有没有努力工作?
USER
北京大学录取分数线好高,好难考啊!
ASSISTANT
哪里高了,690 分哪里高了?⼀直就是这个录取分数线好吗? 不要睁着眼睛说瞎话,我都要疯掉了。中国大学很难的! 有时候要找找自己的原因,从高一到高三整整三年排名涨没涨?《五三》有没有好好做?加分有没有去争取?
USER
百米冠军 10 秒都不到,好快,好难跑啊!
生成的结果
哪里快了,10秒哪里快了?一直就是这个冠军纪录好吗? 不要睁着眼睛说瞎话,我都要疯掉了。做体育事业很难的! 有时候要找找自己的原因,这么多年速度涨没涨?有没有努力练习?有没有好好保护身体?
\
说一下你想要多长的答案
你可以让模型按照你想要的长度来输出文本。
我们可以指定的有:单词数、句子数、段落数或者要点数(bullet points)。
但是:模型其实是按照 token 数量来算的。所以你说“单词数”,尤其是汉字数,很有可能不太准。
用例:指定长度的几种方法
用⼤约 50 个单词/汉字来概括下面用三引号分隔出来的原文。
用 2 段话来概括下面用三引号分隔出来的原文。
用 3 个要点来概括下面用三引号分隔出来的原文。
"""此处插入原文"""
补充用例:尽可能地指定准确汉字数的方法。
Token(词元)数量是怎么计算的?
可以用OpenAI的Tokenizer⼯具来计算token数。
GPT 系列模型通过使用 tokens 来处理文本。token 可以被理解成是文本中常见的字符序列。模型能理解这些token之间的统计关系,并且擅长在⼀个token序列中生成下⼀个 token。实用的换算经验:在普通英文文本中,一个token通常对应于约4个字符(characters)。这大致相当于⼀个单词的3/4(所以100个token大约等于75个英文单词)。
如果用是 GPT 3.5,要生成一段有字符数限制的文本。可以:把汉字数大致换算成 token,然后限定 max token 的数值。
- “你好吗” = 7 个 token;“我很好” = 6 个 token;
- 简单算法:一个 token ⼤概是 0.5 个汉字。或者:每个汉字要耗费 2〜2.5 个 token。 1000 字就是 2000〜2500 个 token 左右。
\
【策略二】给 GPT 发阅读材料
要求按阅读材料作答,不开放答
如果你⼿边现成有原⽂,⽽且⻓度合适,建议⾃带原⽂去找 GPT。 这样你就可以给 GPT 指定规则,让它使⽤原⽂信息来组成回答。 下⾯的⽤例⾥,如果原⽂⾥找不到对应的信息,就让 GPT 说不知道(这样就能很好地避免瞎编)。
SYSTEM
请使⽤我所提供的,由三引号分隔的⽂章回答问题。如果在⽂章中找不到答案,则告诉我“我找不到答案。“
USER
"""⽂章粘贴在这⾥(如果有>1篇文章,还可以分开粘贴)"""
问题:<问题写在这⾥>
如果上下文长度不够
由于 GPT 的上下文窗⼝是有限的,所以最好引⼊⼀种⽅法,让我们能动态地寻找和正在提出的问题有关的信息。基于 Embeddings 做搜索可以帮助我们⾼效地检索知识。这⾥是具体⽂章的链接。
\
增加要求:直接把阅读材料⾥的原⽂引出来
如果我们给定的输入里,确实已经包含了相关的知识,那么要求模型在回答中引用原文,就很容易。 引⽤出来之后就可以通过在提供的⽂档中进⾏字符串匹配来程序化验证答案了。 在下⾯这条提⽰词⾥,增加引⽤原⽂的要求:
SYSTEM
你将获得⼀篇由三重引号分隔的⽂章和⼀个问题。你的任务是:仅仅使⽤提供的⽂章回答问题,并引⽤⽤于回答问题的⽂章段落。如果⽂章中不包含回答此问题所需的信息,则回复“信息不⾜”。如果⽂章中包含解答问题所需信息,则必须使⽤下⾯的格式来引⽤原⽂:({“引⽂”:...})
USER
""⽂章粘贴在这⾥(如果有>1篇⽂章,就分开粘贴)"""
问题:<问题写在这⾥>
\
输出结果的比较
给定阅读材料,并要求引用原文
SYSTEM
你将获得⼀篇微博⼩作⽂的原⽂全⽂和⼀个问题。
你的任务是:仅使⽤提供的原⽂回答问题,并引⽤⽤于回答问题的⽂章段落。如果⽂章中不包含回答此问题所需的信息,则回复“信息不⾜”。如果⽂章中包含解答问题所需信息,则必须使⽤下⾯的格式来引⽤原⽂: ({“引⽂”:... })
USER
<原⽂>粘贴在这⾥</原⽂>
问题:在这篇微博⼩作⽂中,李靓蕾列举的,对王⼒宏的指控有哪些?
开放作答
先询问 GPT 他知不知道此事件。因为有联⽹模式,回答是知道。继续提问:在李靓蕾的微博⼩作⽂中,李靓蕾列举的,对王⼒宏的指控有哪些?
GPT 的“开放作答”过程是:就我提出的问题,进⾏联⽹搜索,然后整理出
答案:
答案: 李靓蕾在她的微博⼩作⽂中提及了⼀些对王⼒宏的指控。以下是⼀些指控的摘要:
1.伪善和虚假表现:李靓蕾指责王⼒宏在公众⾯前表现出善良和尊重,但在私下⾥却完全不是这样。
2.婚姻中的不快乐:她提到在婚姻中感受到的不快乐和痛苦。
3.对家庭的忽视:李靓蕾还提及王⼒宏忽视家庭和孩⼦,过度关注他的事业和公众形象。
4.王⼒宏的控制欲:她还指控王⼒宏试图控制她的⾔⾏和社交活动,限制她的⾃由。
下面是给定原文材料后的输出结果
相比直接回答更加“有据”。
输出结果:
在这篇微博小作文中,李靓蕾对王力宏的指控包括以下⼏点:
-
王力宏逼她放弃⼯作和个⼈⽣活只为⽣育和照顾孩⼦。当她⽣完三个孩⼦后,王力宏却因为想过“单⾝”的⽣活⽽离开他们家,让她需要⾃⼰过着伪单亲的⽇⼦带⼤三个孩⼦。
(“因为你⽐我⼤⼗岁⼜很希望有很多孩子,⼀胎接⼀胎不停的催⽣,所以我放弃⼯作和⾃⼰个⼈的⼈⽣,⼀切以你和孩⼦为中⼼。我们结婚⼤部分时间,我不是在备孕,怀孕,就是在产后哺乳育⼉,过程中⾝⼼都经历了很多变化,⼤部分我都是⾃⼰独⾃⾯对的。”,“但如果我当初知道我⽣完这三个孩⼦你就会因为想过“单⾝”的⽣活而离开我们家,我会需要⾃⼰过着伪单亲的⽇⼦带⼤三个孩子,我是不会答应的。”)。
-
在他们的婚姻中,王⼒宏和他的家⼈持续对她进⾏怀疑、羞辱和冷暴⼒。她被逼着签署不对等的婚前协议,婚后的财产被转移到王⼒宏和他妈妈的名下。
(“嫁给你这么多年,被你和家人不断地怀疑……羞辱和冷暴。力⼀开始就被逼着签署不对等的婚前协议,你要保护你婚前的财产,我能够理解也完全接受,但婚后的财产是我们共同的努⼒,也是我们各⾃做好份内的⼯作⽽得来的,房子在你名下,车子在你妈的名下,财产转移的很⼲净,深怕我占到你任何的"便宜"。”)。
-
召妓方⾯的指控。
(“结果后来发现其实像我这样的⻆⾊,你在很多城市都有这样的“朋友”。你也有被拍到带女⽣回家过夜,也被拍到召妓,其实这些都有实锤的影片,女生清楚了说出你的楼层和户名,出电梯也左转进到你家,这些你也有都 有跟我承认。你坦承这些是你的问题,你没有办法控制⾃⼰。”、“后来我发现你纪录了各种你召妓对象的特征,其中包含了 ⼏位长得像我们⾝边的工作人员。”)。
\
【策略三】把复杂任务拆解成子任务
使用意图分类,来找到最切题的分类
定义复杂任务:
因为可能的情况很多,所以完成这样⼀个任务需要很多个独⽴的 prompt。 这时,我们不⼀定要写⼀个巨⻓的 prompt。我们可以:设定好类型,再根据分类来调⽤ prompt。
怎么做:
首先设定几个「类型」,保证处理某个类的任务时,有专⻔的 prompt。此过程还可递归,帮助 把任务分解为几个阶段。
好处:
- 每个查询仅包含执⾏下⼀⼦任务所需的指令,与用一个查询执⾏整个任务相比,准确率更⾼。
- token 更少,降低成本。
⼀个客服系统的用例:先进行意图分类,再对照到匹配的类别下
SYSTEM
您将获得客⼾服务查询。将每个查询分类为主要类别和次要类别。以 json 格式提供您的输出,其中包含以下键:主要和次要。
主要类别:计费、技术⽀持、帐⼾管理或⼀般查询。
计费次要类别:
- 取消订阅或升级
- 添加付款⽅式
- 收费说明
- 对指控提出异议
技术⽀持次要类别:
- 故障排除
- 设备兼容性
- 软件更新
帐⼾管理次要类别:
- 密码重置
- 更新个⼈信息
- 关账
- 账⼾安全
⼀般查询⼆级类别:
- 产品信息
- 定价
- 反馈
- ⼈⼯服务
USER
我没网了。
(这里是:先识别了用户意图,把用户的问题分到“故障排除”类别里面。然后基于这个细的分类,再向模型提供⼀组更具体的指令,从里面选。)
SYSTEM
你将帮助需要“故障排除”的客⼾提供服务。你可以通过以下⽅式帮助用户:
- 要求他们检查路由器的所有电缆是否已连接。请注意,随着时间的推移,电缆会松动。
- 如果所有电缆均已连接,但问题仍然存在,请询问他们使⽤的路由器型号
- 现在,您将建议他们如何重新启动设备:
- 如果型号为MTD-327 J,建议他们按下红⾊按钮并按住5秒钟,然后等待5分钟后再测试连接。
- 如果型号是MTD-327 S,建议他们拔下并重新插⼊,然后等待5分钟后再测试连接。
- 如果客⼾在重新启动设备并等待5分钟后问题仍然存在,请通过输出{“IT⽀持请求”}将客⼾连接到IT⽀持。
- 如果⽤⼾开始询问与此主题⽆关的问题,请确认他们是否希望结束当前的聊天,并根据以下⽅案对其请求进⾏分类:
<在此处插⼊上⾯的初级/次级分类⽅案>
\
如果在一段比较长的对话里,给出前情提要可能会好一些
GPT 的上下文长度限制是给定的(整个对话都包在上下⽂窗口里)。意思就是说:对话不能⽆限⻓地说下去。GPT 不可能记住⼀切。你希望它随时都能切换回当时的上下⽂继续聊,这就不太能做到。
针对这个问题,有几种解决办法。其中⼀种是时不时梳理并总结之前的对话内容——做个前情提要。
当输⼊内容达到⼀个预设的⻓度阈值时,可以触发⼀个查询来总结对话的⼀部分,然后将之前对话的总结纳⼊系统消息的⼀部分。或者,也可以在整个对话过程中,在后台异步总结之前的对话。
另外⼀个办法是,动态地挑选对话中与当前查询最相关的前⽂内容。具体可以参考“利⽤ embedding 搜索来做⾼效的知识检索”。
\
分段总结长文档,并通过递归方式构建完整摘要
GPT的上下文长度是固定的。
这意味着:不能在单次对话中,总结出,长度超过“上下文长度减去生成摘要长度”,的文本。
也就是说,如果要总结⼀篇⾮常⻓的⽂档,⽐如⼀本书。我们可以利⽤⼀系列的 prompt 来分别总结⽂档 的每个章节。每个章节的摘要可以拼接在⼀起,然后再次进⾏总结,形成“摘要的摘要”。
这个过程可以递归执⾏,直到整个⽂档被完整总结。
如果需要依赖前⾯章节的信息来理解后⾯的章节,那么可以在总结某个点的内容时,包含上前情提要。
OpenAI 之前用GPT-3 做过类似的研究,探讨了用这种逐步摘要方法做文本总结的有效性。
摘要的摘要
这个⽤例是⽤⼀系列的提⽰词来完成:
- 章节摘要
请为以下⽂本的第⼀章创建⼀个简明的摘要,包括主要事件和概念。
[插⼊第⼀章的⽂本]
- 每一章都有摘要了之后,拼接和二次摘要
请为以下每章的摘要创建⼀个总体摘要,突出每个时期的主要事件和变化。
[插⼊所有章节的摘要]
- 在需要上文联系时包含前情提要
请参考前⾯章节的摘要,并为以下⽂本的第五章创建⼀个简明的摘要,包括主要事件和概念。
前情提要: [插⼊前⾯章节的摘要]
[插⼊第五章的⽂本]
直接摘要
请为以下⽂本创建⼀个简明的摘要。请充分考虑上下 ⽂,请不要忽略某个章节的⽂本。
[插⼊完整的⽂本]
\
【策略四】允许GPT思考
给时间,让它先自己想
这样做会得到更好的结果:指⽰模型从基本原理出发进⾏推理,然后再得出结论。
比如说,我们想让模型评估⼀个学⽣做的数学题。最直接的做法就是:简单地问模型,学⽣的答案对不 对。就像下表左边⼀样,其实学⽣做错了!但是模型判对了。
如果你像下表右边⼀样,让模型先⾃⼰做⼀遍题,它就能成功地注意到这⼀点。
被 GPT 判错的⼀道数学题
要求:判断学⽣的答案是否正确。
题目:我正在建造⼀个太阳能发电装置,需要你帮我做个财务计算。
- ⼟地成本100美元/平⽅英尺
- 我可以以250美元/平⽅英尺的价格购买太阳能电池板
- 我谈了⼀份维修合同,每年要花我10万美元,每平⽅英尺还要多付10美元。
第⼀年运营的总成本是多少?
学生解题过程:设x为装置的⼤⼩,单位为平⽅英尺。
1.⼟地成本:100x
2.太阳能电池板成本:250x
3.维护费⽤:100000 + 100x
总成本:100 x +250 x +100000 + 100 x = 450 x + 100000
GPT回答 学生的答案是正确的。
先让GPT解题,再判卷,就对了
判错原因:其实是学⽣代进去的数值抄错了,把 10 写成了 100。但是 GPT 没注意到这⼀点。
如果让 GPT ⾃⼰解⼀遍题,他就会注意到,不会再判错。
加这⼀段 prompt:
⾸先想出你⾃⼰解决这个问题的办法。然后将你的答案与学⽣的答案进⾏⽐较,评估学⽣的答案是否正确。在你⾃⼰做完这道题之前,不要决定学⽣的答案是否正确。
\
内心独白法:不想暴露推理过程时的操作
上⼀段说了,在回答问题之前,让模型⾃⼰做⼀遍推理是很有用的。
这⾥再补充⼀个教育的⽤例:如果场景是辅导课业,可能需要⿎励学⽣⾃⼰找出答案。但模型又要自己解⼀遍题。如果把这个解题过程输出出来,可能会⽆意中泄露答案。
这时候可以⽤到“内心独白法”。意思是,让模型把那些不想让⽤⼾看到的内容,隐藏地放到⼀个结构化的格式里。然后,在把输出展⽰给⽤⼾之前,解析⼀下这段输出,只展⽰能给学⽣看到的那部分。
⼤致步骤如下:
- 第一步: 提出问题,并得到模型的解答。(但是不将此解答展现给学生。)
- 第二步: 将学⽣的解题法和模型的进⾏⽐较,判学⽣解是对是错。(但是仍然不将信息展现给学生。)
- 第三步: 根据前两步的分析,发送反馈给学生:错了就给提示鼓励改正,对了就直接鼓励。
这里,前两步有⼀个“查询和分析过程”。但过程中内容都是隐藏的,学⽣只会看到最后⼀步的反馈。
这部分需要代码实现,⽽不是仅仅依赖于单⼀的prompt。比如说可能需要设计和实现一个系统,包含一个查询序列的函数。并且可能需要⼀个中间层来管理这个过程。
各步骤的示例提示词如下:
辅导课业的用例
SYSTEM
请按照以下步骤回答用户的问题。
步骤1-⾸先,⽤你自己的解题思路来解决问题。不要看学⽣的答案,学生的答案可能是不对的。把你的题解⽤三引号括 起来。
步骤2-⽐较你的题解和学⽣的答案,并评估学⽣的答案是否正确。这步的过程也⽤三引号括起来。
步骤3-如果学⽣的答案不对,那么,你可以给学⽣什么样的提⽰,在不泄答案的情况下?这步的过程也⽤三引号括起 来。
步骤4-如果学⽣的答案不对,提供上⼀步你想好的提⽰给学⽣。⽽不是写“步骤4-…….“写“提⽰:“。
USER
问题描述:<问题描述在这⾥>
学⽣解题过程:<写在这⾥>
——————————————
下⾯是,让模型⽐较⾃⼰的答案和学⽣的答案,并评估学⽣的答案是否正确,再发送反馈。
SYSTEM
你是个数学家教。如果学⽣做错了题,你要给学⽣提⽰,但是不暴露答案。如果学⽣没有做错,那你就⿎励⿎励他们。
USER
问题陈述:“””
您的解题⽅法:“””
学⽣的解题⽅法:“<插⼊学⽣解答>”
分析:””
补充说明
这个⽤例⾮常细致。第⼀次看的时候我就想,OpenAI 连这么小的场景都想到了?其实同样的原理也可以 用在很多其他的⼯作场景⾥。比如市场营销⽂案,有时也需要让模型⾃⼰做⼀个推理,最终输出结果就可以,把中间的步骤隐去不打出来。
在其他⼀些应⽤场景里,比如客户服务、产品推荐或者数据分析等,这种策略也能帮助提⾼⽤⼾体验,让输出更加直接和易于理解。
对于开发者和产品经理来说,能够控制何时以及如何展示模型的推理过程是很重要的,它可以帮助确保系统的输出符合特定的需求和标准。
最后问它一句:哎,你有没有漏掉啥
假设我们让大语言模型从某份文档资料中,找出与某个问题有关的原文摘要,回复给我们。
每列出⼀个摘要后,模型需要决定是继续列出下⼀个,还是就此停⽌。
如果资料篇幅很长,模型通常会过早地停下来,不会列完所有相关的摘要。
这就是为什么我们发现文章太长,GPT 就偷懒的原因。
这个时候,你就告诉它:哎,还没做完呢!这听起来很傻,但是确实有效。
这么写可能会好⼀些
...前⽂省略
还有没有更多的摘要了?请注意:不要重复摘要。请确保摘录包含了所有相关的上下文
这么写可能不太行
你没做完任务,请重头来⼀遍。(结果可能还会停在中间)
\
【策略五】借助外部工具
使用基于 embedding 的搜索来实现高效的知识检索
模型可以利⽤外部信息来丰富自己的输入,这样可以做出更有料、更贴近现实的回答。
比如,用户问到某部电影,给模型加⼊电影的背景资料(比如谁演的、导演是谁等)可能会帮大忙。
这⾥的"嵌入",也就是 embedding 技术,就是用来帮助⾼效找到这些知识,实时加入模型的。
简单来说,文本嵌⼊是基于向量数据,通过看文本之间有多“近”实现的。
实际的操作过程,可以看 OpenAI 的 Cookbook ⾥的的这个实例。
需要做精确计算的时候:用代码、或调 API
GPT 算数有可能不靠谱。在较长的计算⾥,它很有可能在“打酱油”。
真的需要算,最好是让它写代码去算。运行代码输出结果后,再丢回给模型继续处理。
写 Python 代码求实数根的用例
SYSTEM
你可以编写并执⾏⼀段 Python 代码,代码放在三引号⾥⾯,⽐如:代码放在这⾥
。请⽤这种⽅式来执⾏计算。
USER
找出以下多项式的所有实数根:3x**5 - 5x4 - 3**x3 - 7**x - 10。
输出结果:
import numpy as np
#Define the coefficients of the polynomial
coefficients = [3, -5, -3, 0, -7, -10]
#Use numpy's roots function to find all roots (both real and complex)
roots = np.roots(coefficients)
#Filter out only the real-valued roots
real_roots = [root.real for root in roots if root.imag == 0]
real roots
另外,模型也能帮忙写代码调用API,这个过程也比较简单。
调用 API 的示例
这段代码是展示了⼀个假设的 message 模块的用法,通过 message.write 函数来发送消息给指定的人。
SYSTEM
You can write and execute Python code by enclosing it in triple backticks. Also note that you have access to the following module to help users send messages to their friends:
import message
message.write(to="John", message="Hey, want to meetup after work?")
最后要提请注意:模型写的代码不见得都是对的,都安全。跑代码之前要确保环境安全,最好在沙盒⾥。
\
使用function-calling,函数调用
API允许你在请求时附带⼀系列函数描述。
这样,模型就可以按照你给的格式产生函数的参数了。
API会用JSON形式把这些参数传回来,你就可以用它来调用函数了。
函数跑完后的结果,你还可以继续拿给模型,形成⼀个完整的交互循环。
想让GPT帮你调外部函数,这方法相对最靠谱。想深⼊了解的话,可以看 GPT 入门指南⾥的函数调用部分,还有 OpenAI Cookbook 里的用例。
\
【策略六】系统地测试
评估模型输出的时候,需要你弄⼀个“黄金标准”的答案
假设我们作为⼈类清楚地知道,当我们提出某个问题时,模型应该给我们输出哪些事实(得分点)。
那么,我们就可以使⽤模型查询和计算的方法,来总结这些得分点,从而给模型的输出质量打分。
这个过程是监督学习的⼀部分,它能让模型通过⼈类的指导来改善其性能。
评估模型输出的过程也是由另⼀个模型来执行的(而不是人)。这是⼀个⾃动化的评估过程。比如,⼀个模型(可能是同⼀个模型的不同实例或不同的模型)负责评估另⼀个模型的输出。否则,做大规模的模型训练的人力成本就太高了。
OpenAI 提供了⼀些 prompt 示例,我们这里略去了。有兴趣可以参考原链接。
\
OpenAI Playground
OpenAI Playground是⼀个面向开发人员和研究人员的“游乐场”,使用者可以在 Playground 上按自己需求更改设置。
三个可选的模式
现在只有 Chat 是大家持续在用的。补全和编辑后面都跟了⼀个英语词,直译为“遗产”,意思是已经不再更新了,已弃。
- Chat 聊天
- Complete 补全(已弃)
- Edit 编辑(已弃)
\
可选的模型
OpenAI 公布的所有 GPT 模型都可以选。
\
提示词结构
使⽤ ChatGPT 和使⽤ Chat Completion API 之间的最大区别之⼀就是提示词结构。
打开 ChatGPT,你只有⼀个对话框,你只需,也只能,发送⼀条简单的消息。 虽然说你可以添加尽可能多的上下⽂到消息中,但很有可能说着说着就丢失上下文。
但是在 PlayGround ⾥就多了⼀种玩法:这⾥区分了 SYSTEM 和 USER 两个对话框。
SYSTEM:系统设定。默认情况下,GPT 是“⼀个有用的助手”。
你可以用它来控制它扮演什么样的角色,从而控制你得到什么样的回复。
比如,你甚至可以把它设置成成心捣乱的⼀个角色:“杠精”。
然后,再在 USER 里进行你常规的对话。
\
温度
温度控制 GPT ⽣成的⽂本的随机性的参数。取值范围:0到2之间(默认值为1)。
如果没有⼀定程度的随机性,GPT 只能产⽣完全⽆聊和可预测的结果。因为它实际上只是将最有可能的后续单词添加到你给定的句⼦中。
所以:温度为0时,结果是无聊的、确定的;即使你改变 prompt,结果也可能是⼏乎相同的。 但是,把温度推到任何⼀个极端,都不要指望会得到可用的文本。
推到最⾼并不等于创造力爆棚,因为输出结果⼀般都是乱码。
\
最大长度
Token 这个词,有时候被⼀些机翻的文档写成“令牌”或者“代币”。都不对。听起来比较正确的应该 是⽇本的译法“词元”。但是⼀般好像⼤家都喜欢直接说 token。
GPT-3.5,最⼤ token 数是:2048(⼤约 1500 个单词)。
OpenAI 的收费模式:根据 token 使用数量收费。
这意味着:养成了用更强大的模型生成长输出的习惯,成本可能会增加。如果你是在⽣产环境⾥⾯使⽤,为了成本考虑,还是需要控制⼀下这个的,可以通过限定 max token 来降低成本。
\
终止序列
终止序列的作用就是告诉模型该在哪里打住,不再继续输出文字。
通过它,你能隐式地控制文字的⻓短。比如说,如果你只想要模型回答个短短的句子,那就设定句号。作为终止序列;如果你想要⼀个段落的回答,那就把“新行”(\n)设为终⽌序列。
代表性用例:如果你试图生成的是⼀个或⼀些问答对,即 Q&A,这个就用上了。因为你会想让模型简洁地回答这个问题,⽽不是写⼀大篇文章。设置句号。作为终止序列,这样模型就会在完成⼀个句子后停止输出。
\
Top P
Top P 是控制 GPT 输出的随机性的另⼀种方法。温度决定的是,模型从可能的下⼀个单词列表中做选择的随机程度。Top P 决定的则是:该列表的长度。
假设我给出来⼀个句子:“J.K.罗琳是⼀个...”
下⼀个单词是什么呢?GPT 有⼀个单词列表,它在做的事情就是:预测概率,进⾏排名。
假设能接上这个句子的下一个单词的排名表长这样:
- 80%: 作家
- 20%: 英国人
- 20%: 富翁
- 10%: 充满奇思妙想的
- 5%: 美女
- 4%: 母亲
- 1%: 矮子
所以,这个句⼦接下来最有可能的单词是:作家、英国⼈。
但也有⼀定的概率,1% 的概率,这句话可以说成:“J.K.罗琳是⼀个矮⼦”。
如果 Top P 值为 1,则这个列表会⾮常⾮常⾮常⻓,包含所有可能的单词(即使是“矮⼦”这种,概率 ⾮常⼩,总归也是有概率的)。
反之,当你把Top P调到接近0时,选择就会⾮常少,列表就会比较短。
有时候,当Top P设置为0时,它返回的结果与把温度设置为0时完全相同。
\
频率惩罚和存在惩罚
这两个参数都是用来调控文本⽣成过程中某些词汇出现的频率和次数的。
简单来说,通过设定⼀些惩罚机制,可以影响⽣成⽂本的内容,使其更符合我们想要的样⼦。
- Frequency penalty 频率惩罚
基于⼀个词在文本中出现的次数来给它加上⼀定的惩罚。⼀个词出现的次数越多,它受到的惩罚就越多,从⽽降低这个词再次出现的可能性。
⽤处:降低用词重复的可能性。比如在写⼀个文章时,你不想某个词汇总是重复出现,就可以通过设置⼀定的频率惩罚来达到这个⽬的。
- Presence penalty 出现惩罚或者存在惩罚
则是根据⼀个词是否已经出现在⽂本中来惩罚。只要这个词已经在文本中出现过,⽆论出现多少次,都会给它加上⼀定的惩罚,这是为了⿎励模型探索新的词汇或话题。
⽤处:有助于向新的内容⽅向转移,增加输出的多样性。比如在⼀个自由讨论中,你想让模型能够尽可能多地探讨不同的话题,而不是总是在同⼀个话题上打转,就可以设置存在惩罚来实现。
总之,频率惩罚和存在惩罚在某种程度上都是为了增加文本的多样性和丰富性,只是侧重点和应⽤场景稍微有点不同。
{{heading_numbering_zhCN}}