导读
提示工程(Prompt Engineering)是一门新兴的学科,专注于提示词的开发和优化,旨在帮助用户在各种场景和研究领域中更好地利用大语言模型(Large Language Model, LLM)。掌握相关的提示工程技能将有助于用户更全面地了解大语言模型的能力和局限性。
六条获得更好结果的策略
策略一、写下明确的指示
大语言模型不会读心术,无法洞悉您的内心,因此写下明确的指示,向模型清晰传达您的意图至关重要。如果模型输出内容过长,请要求简洁回复。如果模型输出内容过于简单,请要求专业水准的写作。如果您对模型输出内容的格式不满意,请举例展示您期望的格式。模型需要猜测您的需求的可能性越低,您获得理想答案的可能性就越高。
技巧一:提供详细的请求信息,以获得更相关的答复
为了获得高度相关的回复,请确保在请求中提供任何重要的细节或上下文信息。否则,模型只能猜测您的意图。
反面示例 | 正确姿势 |
谁是总统? | 2014年,谁是美国总统? |
给我推荐一些电影 | 给我推荐3-5部中国内地近3年上映的喜剧电影 |
编写代码计算斐波那契数列 | 编写python代码计算斐波那契数列,对每行代码进行注释,解释代码的作用以及为什么要这样写 |
技巧二:要求模型进行角色扮演
示例1:
我希望你能充当一个故事讲述者。你将创作引人入胜、富有想象力和扣人心弦的娱乐故事,以吸引听众。可以是童话故事、教育性的故事,或者其他任何类型的故事,能够吸引人们的注意力和想象力。根据目标受众,你可以选择特定的主题或话题来讲述故事,比如,如果是给儿童,你可以谈论动物;如果是成年人,以历史为基础的故事可能更能吸引他们。我的第一个请求是:"我需要一个关于坚持不懈的有趣故事。"
示例2:
我希望你能充当一位小说家。你将创作出引人入胜的创意故事,能够吸引读者长时间阅读。你可以选择任何类型的小说,如奇幻、浪漫、历史虚构等,但目标是写出具有出色情节、吸引人物和意外高潮的作品。我的第一个请求是:"我需要写一本设定在未来的科幻小说。"
技巧三:通过使用分隔符清晰标识输入内容的不同部分
在文本中使用三引号、XML 标记、章节标题等分隔符,有助于将需要区别对待的部分进行划分。
示例1:
总结由三引号分隔的文本,不要超过50个字。
"""文本内容"""
示例2:
你将收到两篇关于同一主题的文章(用 XML 标记分隔)。首先总结每篇文章的论点,然后指出哪篇文章的论点更好,并解释原因。
<文章>第一篇文章</文章>
<文章>第二篇文章</文章>
示例3:
我们将为您提供论文摘要和建议标题。论文标题应让读者对论文主题有一个很好的概念,但也应醒目。如果标题不符合这些标准,请提出 5 个备选标题。
摘要:论文摘要
标题:论文标题
对于这类简单的任务,使用分隔符可能不会对输出质量产生影响。然而,对于更复杂的任务,明确任务细节就变得尤为重要。请确保模型无需费力地理解您对其提出的确切要求。
技巧四:指定完成任务所需的步骤
对于某些任务,最好以一系列连贯的步骤来明确指定。明确写出这些步骤可以使模型更容易地按照它们进行操作。
示例:
使用以下分步说明来回复用户输入。
步骤 1 - 用户将用三引号提供文本。用一句话概括这段文字,前缀为 "Summary: "。
步骤 2 - 将步骤 1 中的摘要翻译成西班牙语,前缀为 "Translation:".
技巧五:提供示例
提供适用于所有示例的一般说明通常比通过示例演示任务的所有排列组合更有效,但在某些情况下,提供示例可能更容易。例如,如果您打算让模型复制一种难以明确描述的回应用户询问的特定风格,这就是所谓的 "少样本"提示。
示例:
中文:我爱你
英文:I love you
中文:我想你
英文:I miss you
中文:你在哪儿?
英文:
模型输出:
Where are you?
技巧六:指定所需的输出长度
您可以要求模型生成具有给定目标长度的输出。目标输出长度可以用字数、句数、段落数、要点数等来指定。但请注意,指示模型生成特定字数的精确度并不高。模型可以更可靠地生成特定段落数或要点数的输出。
示例1:
用大约 50 个字概括用三引号分隔的文本。
"""文本内容"""
示例2:
用两个段落概括用三引号分隔的文本。
"""文本内容"""
示例3:
用三个要点概括用三引号分隔的文本。
"""文本内容"""
策略二、提供参考文本
大语言模型在被问及深奥话题、引文和URLs等问题时,常常能自信地编造虚假答案。为了避免出现这类问题,需要尽可能的给模型提供参考文本。就像学生在考试时借助小抄能表现更好一样,向模型提供参考文本可以减少虚构的回答。这样做有助于提供更准确的回复,减少虚构内容。
技巧一:要求模型使用参考文本来进行回答
如果我们能够为模型提供与当前查询相关的可靠信息,那么就可以指示模型使用所提供的信息来撰写答案。
系统:使用所提供的以三引号分隔的文章回答问题。如果在文章中找不到答案,请写 "我找不到答案"。
用户:<插入文章,每篇用三引号分隔>。
问题:<此处插入问题>
技巧二:要求模型引用参考文献进行回答
如果输入中已经包含了相关知识,那么可以直接要求模型通过引用所提供文档中的段落来为答案添加引文。需要注意的是,输出中的引文可以通过编程验证,即与所提供文档中的字符串进行匹配。
系统:您将收到一份用三引号分隔的文档和一个问题。您的任务是仅使用所提供的文档回答问题,并引用用于回答问题的文档段落。如果文件中不包含回答问题所需的信息,则只需写出 "信息不足"。如果提供了问题的答案,则必须注明引文。使用以下格式引用相关段落({"引用":...})。
用户:"""<此处插入文件>"""
问题:<此处插入问题>
策略三、将复杂任务分解为简单子任务
就像在软件工程中将复杂系统分解为一组模块化组件一样,在大型模型的最佳实践中也是如此。复杂任务通常比简单任务具有更高的错误率。此外,复杂任务通常可以重新定义为一系列简单任务的工作流程,其中较早任务的输出用于构建后续任务的输入。
技巧一:使用意图分类确定与用户查询最相关的指令
对于需要大量独立指令集来处理不同情况的任务,首先对查询类型进行分类并使用该分类来确定有益的指令。这可以通过定义固定类别并硬编码与处理特定类别任务相关的指令来实现。这一过程还可以递归应用,将任务分解为一系列阶段。这种方法的优势在于,每次查询只包含执行任务下一阶段所需的指令,与使用单次查询执行整个任务相比,错误率更低。
技巧二:对于需要超长对话的对话应用,可总结或过滤之前的对话
由于模型的上下文长度是固定的,因此用户和助手之间的对话(整个对话都包含在上下文窗口中)无法无限期地进行下去。
解决这一问题的方法有很多,其中之一就是对对话中的前几轮进行总结。一旦输入的大小达到预设的阈值长度,就会触发一个查询,对部分对话进行总结,而之前对话的总结可以作为系统消息的一部分。或者,在整个对话过程中也可以在后台异步地对之前的对话进行总结。另一种解决方案是动态选择与当前查询最相关的先前对话部分。
技巧三:分段总结长文档并递归构建完整摘要
由于模型的上下文长度是固定的,因此在一次查询中,模型无法用来总结长度超过上下文长度减去生成摘要长度的文本。
要总结一本书等超长文档,我们可以使用一系列查询来总结文档的每个部分。章节摘要可以串联起来并进行总结,从而产生摘要的摘要。这个过程可以递归进行,直到整个文档完成摘要。如果需要使用前面章节的信息来理解后续章节的内容,还有一个有用的技巧,那就是在总结给定内容的同时,对该内容之前的文本进行流水账式总结。
策略四、给模型一些时间“思考”
如果让你计算17乘以28,你可能不会立即知道答案,但是给你一些时间你可以算出来。同样地,模型在试图立即回答问题时会产生更多的推理错误,而不是花时间思考答案。在回答之前要求模型给出“思考过程”可以帮助模型更可靠地推理出正确答案。
技巧一:在匆忙得出结论之前,要求模型自己找出解决方案
有时候,如果我们明确指示模型在得出结论之前先根据第一原理进行推理,会得到更好的结果。例如,假设我们想要模型来评估学生对数学问题的解答。最明显的方法是简单地问模型,学生的解法是否正确。
系统:确定学生的解决方案是否正确。
用户:
问题陈述:我正在建造一个太阳能发电装置,请计算财务费用。
土地成本为 100 美元/平方英尺
我可以以每平方英尺 250 美元的价格购买太阳能电池板
我通过谈判签订了一份维护合同,每年的固定维护费用为 10 万美元,每平方英尺的额外维护费用为 10 美元。
运营第一年的总成本与平方英尺数的函数关系是什么?
学生解答:设 x 为安装面积(平方英尺)。
土地成本:100x
太阳能电池板成本:250x
维护成本:100000 + 100x
总成本:100x + 250x + 100000 + 100x = 450x + 100000
回答:该学生的解决方案是正确的。
但实际上学生的解并不正确!我们可以通过要求模型先生成自己的解决方案,让模型成功注意到这一点。
系统:首先自己想出解决问题的办法。然后将自己的解法与学生的解法进行比较,评估学生的解法是否正确。在自己完成问题之前,不要决定学生的解法是否正确。
用户:
问题陈述:我正在建造一个太阳能发电装置,我需要帮助计算财务费用。
土地成本为 100 美元/平方英尺
我可以以每平方英尺 250 美元的价格购买太阳能电池板
我通过谈判签订了一份维护合同,每年的固定维护费用为 10 万美元,每平方英尺的额外维护费用为 10 美元。
运营第一年的总成本与平方英尺数的函数关系是什么?
学生解答:设 x 为安装面积(平方英尺)。
土地成本:100x
太阳能电池板成本:250x
维护成本:100000 + 100x
总成本:100x + 250x + 100000 + 100x = 450x + 100000
模型:
设 x 为安装面积(平方英尺)。
土地成本:100x
太阳能电池板成本:250x
维护成本:100000 + 10x
总成本:100x + 250x + 100000 + 10x = 360x + 100000
该学生的解决方案不正确。他们在计算维护成本时出了错,用了 100x,而不是 10x。正确的第一年运营总成本是 360x + 100000。
技巧二:使用内心独白或一系列询问来隐藏模型的推理过程
前面的策略表明,在回答具体问题之前,模型对问题进行详细推理有时是很重要的。对于某些应用,模型得出最终答案的推理过程不宜与用户共享。例如,在辅导应用中,我们可能希望鼓励学生自己找出答案,但模型对学生解决方案的推理过程可能会向学生透露答案。
内心独白是一种可以用来缓解这种情况的策略。内心独白的原理是指示模型将输出结果中不对用户公开的部分转化为结构化格式,以便于解析。然后,在向用户展示输出结果之前,先对输出结果进行解析,只让部分输出结果可见。
示例:
系统:
请按照以下步骤回答用户的问题。
第 1 步 - 首先自己找出问题的解决方案。不要依赖学生的解决方案,因为它可能是不正确的。在此步骤中,请用三引号("""""")括起您的所有工作。
第 2 步 - 将您的解法与学生的解法进行比较,并评估学生的解法是否正确。将此步骤中的所有作业用三引号("""""")括起来。
第 3 步 - 如果学生出错了,确定在不泄露答案的情况下,可以给学生什么提示。将这一步的所有作业用三引号("""""")括起来。
第 4 步 - 如果学生犯了错误,则将上一步的提示提供给学生(不带三重引号)。不要写 "第 4 步 - ......",而是写 "提示:"。
用户:
问题陈述:<插入问题陈述>
学生解决方案:<插入学生解决方案>
技巧三:询问模型之前是否有遗漏
假设我们正在使用一个模型来列出与特定问题相关的信息源摘录。在列出每个摘录后,模型需要确定是否应该开始写另一个摘录,还是应该停止。如果源文件很大,模型很容易过早停止,无法列出所有相关摘录。在这种情况下,通常可以通过提示模型进行后续查询来找到之前遗漏的摘录,从而获得更好的性能。
系统:
您将收到一份用三引号分隔的文档。你的任务是选择与以下问题相关的摘录:"人工智能历史上发生了哪些重大范式转变"。
确保摘录包含解释这些内容所需的所有相关上下文,换句话说,不要摘录缺少重要上下文的小片段。提供如下 JSON 格式的输出:
{"摘录":"..."},
...
{"摘录":"..."}]
用户:
"""<此处插入文件>"""
模型:
[{"摘录":"模型在此写入摘录"}、
...
{"摘录":"模型在此写下另一段摘录"}]
用户:
还有更多相关摘录吗?注意不要重复摘录,还要确保摘录包含解释所需的所有相关上下文。换句话说,不要提取缺少重要上下文的小片段。
策略五、合理使用外部工具
通过将其他工具的输出提供给模型,弥补模型的不足之处。例如,文本检索系统(有时称为RAG或检索增强生成)可以向模型提供相关文档信息。像 OpenAI 的代码解释器这样的代码执行引擎可以帮助模型进行数学计算和代码运行。如果使用工具而不是语言模型可以更可靠或更高效地完成任务,那么将任务分担给工具可以同时发挥两者的优势。
技巧一:使用嵌入式搜索实现高效的知识检索
如果作为输入的一部分,模型可以利用外部信息源。这可以帮助模型生成更多信息和最新回复。例如,如果用户询问有关特定电影的问题,那么在模型的输入中添加有关该电影的高质量信息(如演员、导演等...)可能会很有用。嵌入可用于实现高效的知识检索,以便在运行时将相关信息动态添加到模型输入中。
文本嵌入是一个可以衡量文本字符串之间相关性的向量。相似或相关的字符串会比不相关的字符串靠得更近。这一事实以及快速向量搜索算法的存在,意味着嵌入可以用来实现高效的知识检索。特别是,文本语料库可以分割成若干块,每个块都可以嵌入和存储。然后,可以嵌入给定的查询,并执行矢量搜索,从语料库中找到与查询最相关的嵌入文本块(即在嵌入空间中最接近的文本块)。
技巧二:使用代码执行来获取更精确的计算或调用外部 API
语言模型本身无法准确执行算术或长时间计算。在需要的情况下,可以指示模型编写和运行代码,而不是自己进行计算。特别是,可以指示模型将需要运行的代码放入指定的格式中。产生输出后,可以提取并运行代码。最后,如有必要,可将代码执行引擎的输出作为下一次查询的模型输入。
技巧三:让模型访问特定函数
The Chat Completions API 允许在请求中传递函数描述列表。这样,模型就能根据提供的模式生成函数参数。生成的函数参数由 API 以 JSON 格式返回,可用于执行函数调用。函数调用提供的输出可以在下一个请求中反馈到模型中,以结束循环。这是使用 OpenAI 模型调用外部函数的推荐方式。
策略六、系统地测试变化
有时,很难说清一项改变(如新指令或新设计)会使系统变得更好还是更差。通过观察一些示例可能会发现哪个更好,但在样本量较小的情况下,很难区分是真正的改进还是随机的运气。也许改变有助于提高某些输入的性能,但会降低其他输入的性能。
评估程序(或称 "evals")对优化系统设计非常有用。好的 evals 包括
-
能代表真实世界的使用情况(或至少具有多样性)
-
易于自动化或重复
-
包含许多测试用例,以提高统计能力(参见下表中的指导原则)
检测差异 | 95% 置信度所需的样本量 |
30% | ~10 |
10% | ~100 |
3% | ~1000 |
1% | ~10000 |
产出评估可以由计算机、人工或混合方式完成。计算机可以根据客观标准(例如只有一个正确答案的问题)以及一些主观或模糊标准自动进行评估,其中模型输出由其他模型查询进行评估。
当存在一系列被认为质量同样高的可能输出时(例如,对于答案较长的问题),基于模型的评估就会非常有用。哪些内容可以通过基于模型的评估进行实际评估,哪些内容需要人工评估,这两者之间的界限是模糊的,并且随着模型能力的提高而不断变化。
总结
本文主要分享如何通过采用不同策略从大语言模型中获得更优质的反馈结果。同时,上文所描述的方法有时可进行组合使用,以达到更佳的效果。熟练掌握以上六条策略,可以帮助你更好的使用大语言模型。
我是无界生长,如果你觉得我分享的内容对你有帮助,欢迎点个关注,持续接收最新的AI学习资料。