提示工程(Prompt Engineering),也称为上下文提示,是一种通过不更新模型的权重/参数来引导LLM行为朝着特定结果的方法。这是与AI有效交流所需结果的过程。提示工程可以用于各种任务,从回答问题到算术推理乃至各种应用领域,理解提示工程,能够帮助我们了解LLM的限制和能力。
为了理解提示工程,先要澄清什么是Prompt。
Prompt提示是什么呢?
Prompt提示是模型接收以生成响应或完成任务的初始文本输入。我们给AI一组Prompt输入,用于指导模型生成响应以执行任务。这个输入可以是一个问题、一段描述、一组关键词,或任何其他形式的文本,用于引导模型产生特定内容的响应。
例如,在chatGPT中,用户通常使用 prompt 来与大语言模型进行交互,请求回答问题、生成文本、完成任务等。模型会根据提供的 prompt 来生成一个与之相关的文本,尽量符合用户的要求。
从不同的视角, 可以对Prompt 进行不同的分类。在这里,尝试根据可解释性、交互方式和应用领域三个方面对Prompt 进行分类。
硬提示(hard prompt )是手工制作的、预定义的带有离散输入标记的文本,或者文本模板。静态提示可以合并到程序中用于编程、存储和重用,基于大模型的应用程序可以有多个提示模板供其使用。
尽管模板带来了一定程度的灵活性,但是提示语仍然需要被设置得很好才行,换句话说,静态提示一种硬编码的提示。
建立在LangChain 之上的基于大模型的 很多应用程序,其提示模板在很大程度上是静态的,它指示代理执行哪些操作。一般来说,模板包括: 定义了可以访问哪些工具,何时应该调用这些工具,以及一般的用户输入。
软提示(soft prompt )是在提示调优过程中创建的。与hard prompt 不同,软提示不能在文本中查看和编辑,包含一个嵌入或一串数字,代表从大模型中获得知识。软提示缺乏软可解释性。人工智能发现与特定任务相关的软提示,但不能解释为什么它。与深度学习模型本身一样,软提示也是不透明的。软提示可以替代额外的训练数据,一个好的语言分类器软提示有几百到几千个额外的数据点。
提示微调包括了在使用 LLM 之前使用一个小的可训练模型。小模型用于对文本提示进行编码并生成特定于任务的虚拟令牌。这些虚拟令牌被预先追加到Prompt上并传递给 LLM。调优过程完成后,这些虚拟令牌将存储在一个查找表中,并在推断期间使用,从而替换原来的小模型。当提供上下文时,LLM 的表现要好得多,而且提示微调是一种快速有效的方法,能够以动态地创建急需的上下文。
"online" 和 "offline" 是一种方式来区分模型互动中 prompt 的使用方式。这两种分类表示了 prompt 在与大模型互动的时间和方式上的不同。
在线提示(Online prompt) 是在与模型的实时互动中提供的提示,通常用于即时的交互式应用。这种提示在用户与模型进行实际对话时提供,用户可以逐步输入、编辑或更改提示,在在线聊天、语音助手、实时问题回答等应用中常见。
离线提示(Offline prompt )是预先准备好的提示,通常在用户与模型的实际互动之前创建。这种提示在没有用户互动时预先设计和输入,然后整批输入模型进行批量处理。在离线文本生成、文章写作、大规模数据处理等应用中常见。
对提示分类为 "online" 或 "offline" ,可帮助确定如何有效地使用提示,以满足不同应用的需求。在线提示通常用于需要实时交互和即时反馈的情况,而 离线提示则适用于需要大规模处理或预生成文本的情况。根据具体应用和使用情境,您可以选择适当的提示类型。
用途分类可以帮助确定 prompt 的主要目标,以便更有效地使用它们。以下是一些常见的 prompt 类别:
Information Retrieval (信息检索):这些 prompt 用于从模型中检索特定信息,如回答问题、提供事实或解释概念。用途包括问答、信息检索、事实核实等。
Text Generation (文本生成):这些 prompt 用于指导模型生成文本,可能是文章、故事、评论等。用途包括创意写作、内容生成、自动摘要等。
Translation (翻译):这些 prompt 用于将文本从一种语言翻译成另一种语言。用途包括机器翻译应用。
Sentiment Analysis (情感分析):这些 prompt 用于评估文本的情感倾向,如正面、负面或中性。用途包括社交媒体监测、情感分析应用。
Programming and Code Generation (编程和代码生成):这些 prompt 用于生成计算机程序代码或解决编程问题。用途包括编程辅助、自动化代码生成等。
Conversation (对话):这些 prompt 用于模拟对话或聊天,并回应用户提出的问题或评论。用途包括聊天机器人、虚拟助手等。
Task-Specific (特定任务):这些 prompt 针对特定应用或任务,如制定旅行计划、编写营销文案、生成报告等。用途因任务而异。
Custom Applications (自定义应用):这些 prompt 针对特定领域或自定义应用,具体用途由用户定义。用途根据用户需求而定。
通过将 prompt 分类为不同的用途,可以更好地理解模型如何应用于各种任务和情境。这有助于选择合适的提示类型,并设计它们以满足特定需求。
在应用Prompt的时候,我们需要理解一个Prompt 可能包含的6个要素:任务,上下文,示例,角色,格式和语气,而且这些要素是按重要性降序排列的。
任务序列是由动词引导的,例如generate, drive, write, analyze等,而且需要明确任务目标。例如:
背景上下文极具挑战性, 一般要描述什么是用户的背景信息,成功的结果希望是什么样子,以及他们处于怎样的环境中,例如:
基本上,对所有主要语言模型进行的研究表明,在提示中包含例子都将产生更高质量的答案。 例如:
如果想为团队内的某个职位撰写一份JD,prompt可以是首先向ChatGPT提供情景描述(context),然后再根据已经准备好的描述提供一个参考案例(example)。
这是你希望人工智能所扮演的角色。想象一下你有一个问题,想咨询专家来解决这些疑问。例如,如果你在锻炼时受伤,你会去找一位有康复治疗师。如果你正在找工作,你会向招聘人员寻求建议。例如:
想象一下实现的目标,可以是个人或团体的目标,比如找到工作、成为一位优秀的演讲者等。所有这些都是零散的想法,但借助人工智能的帮助,可以将它们整理成一个特定的格式,比如一个表格。我们也可以希望得到电子邮件、要点、代码块等格式。这些格式对我们的工作也很有用,例如段落和标记。
看一个电子邮件示例,给一个上下文、一个任务,并要求AI使用标题格式。
如果正确衡量要使用的音调类型,“语气”者一个元素就很容易理解。
在这6个要素中,任务是必须的,上下文和示例非常重要,而且最好也要有角色、格式和语气。下面shi一个实际示例,需要在电子邮件中传达包含相关和有影响力信息的内容。
那么,Prompt 如何在LLM起作用的呢?它个工作原理又是什么呢?
在试图理解Prompt 的工作原理之前, 需要理解大模型是如何生成文本的。简单起见,可以把大模型的文本生成理解为目标文本的补全, 在理解了LLM 文本生成的工作原理之后,就可能对Prompt 有一个相对清楚的理解。
例如,假设想让“Paris is the city…”这句话继续下去。编码器使用Bloom-560M模型发送我们拥有的所有token的logits,这些logits可以使用softmax函数转换为选择生成token的概率。
如果查看top 5个输出token,它们都是有意义的。我们可以生成以下看起来合法的短语:
Paris is the city of love.
Paris is the city that never sleeps.
Paris is the city where art and culture flourish.
Paris is the city with iconic landmarks.
Paris is the city in which history has a unique charm.
然后, 有不同的策略来选择token。
简单来说,贪婪采样的模型在每一步都选择它认为最有可能的词语——它不考虑其他可能性或探索不同的选择。模型选择概率最高的词语,并基于选择的词语继续生成文本。
使用贪婪策略是计算效率高且直接的方法,但也会带来重复或过于确定性的输出。由于模型在每一步中只考虑最可能的标记,可能无法捕捉到上下文和语言的全部多样性,也不能产生最富创造力的回答。模型的这种目光短浅的特点仅仅关注每一步中最可能的标记,而忽视了对整个序列的整体影响。
示例中生成的输出可能是:Paris is the city of the future. The
beam搜索是文本生成中使用的另一个策略。在beam搜索中,模型假设一组最有可能的前“k”个token,而不仅仅考虑每个步骤中最有可能的token。这组k个token被称为“beam”。
模型通过为每个token生成可能的序列,并通过扩展每个beam在文本生成的每个步骤中跟踪它们的概率来生成可能的序列。这个过程会一直持续下去,直到达到生成文本的所需长度或者每个beam遇到一个“终止”标记的时候。模型会从所有beam中选择具有最高整体概率的序列作为最终输出。从算法的角度来看,创建beam就是扩展一个k叉树。在创建beam之后,选择具有最高整体概率的分支作为最终输出。
示例中生成的输出可能是:Paris is the city of history and culture.
简单来说就是通过选择一个随机值,并将其映射到所选的词汇来选择下一个词。可以将其想象为旋转轮盘,每个词汇的区域由其概率决定。概率越高,选中该词的机会越大。这是一个相对简单的计算解决方案,由于相对较高的随机性,句子(或词语序列)可能每次都会不同。
一般地,使用softmax函数将logit转换为概率。在这里,为随机采样引入了温度——一种影响文本生成随机性的超参数。比较一下激活函数,可以更好地理解温度如何影响概率计算。
在引入温度之后,与典型的softmax不同之处在于分母除以了温度T。温度越高(趋向1)输出结果会更加多样化,而温度越低(趋向0),输出结果则更加集中并更具确定性。当T = 1的时候,演变为最初使用的softmax函数。
虽然可以根据温度来调整概率,另一个改进是使用前k个token而不是全部token。这将增强文本生成的稳定性,又不会太大程度上降低创造力。现在只对前k个token进行温度下的随机抽样。唯一可能的问题可能是选择数字k,以下是如何改进它。
top-p采样不是指定一个固定的“k”令牌数量,而是使用一个概率阈值“p”。该阈值代表了希望在采样中包括的累积概率。模型在每个步骤中计算所有可能令牌的概率,然后按照降序的方式对它们进行排序。
该模型将继续添加token到生成的文本中,直到它们的概率之和超过指定的阈值。top-p采样的优势在于它允许根据上下文进行更动态和自适应的标记选择。每步选择的标记数量可以根据该上下文中token的概率而变化,这可以产生更多样化和更高质量的输出。
在预训练语言模型中,解码策略对于文本生成非常重要。有多种方法来定义概率,又有多种方法来使用这些概率。温度控制了解码过程中token选择的随机性。较高的温度增强了创造力,而较低的温度则关注连贯性和结构。虽然创造力可以带来有趣的语言体验,但适度的稳定性可以确保生成的文本的优雅。
那么,Prompt 的本质大概应该是语义特征的显式表达, Prompt 的工作机制很可能只是影响大模型所选择生成文本token 的概率。由于大模型在很大程度上是一个黑盒子,其涌现特性具有难解释性,而海量的数据关系很难抽象出确定性的特征,只能是概率性结果。另一方面,用户的需求千变万化,并且对于需求的表达更是极具多样性。因此, Prompt 很可能在某些限定的领域才存在一些通用的表达方式。
提示工程(Prompt Engingering),也被称为在上下文中提示,是指如何与 LLM 通信的方法,以引导其行为为期望的结果,而无需更新模型权重。提示工程关注提示词的开发和优化,帮助用户将大模型用于各场景和研究领域。这是一门经验科学,Prompt Engingering的效果在不同模型之间可能有很大差异,因此需要大量的试验和启发。
因此,提示工程旨在获取这些提示并帮助模型在其输出中实现高准确度和相关性,掌握提示工程相关技能将有助于用户更好地了解大型语言模型的能力和局限性。特别地, 矢量数据库、agent和prompt pipeline已经被用作在对话中,作为向 LLM 提供相关上下文数据的途径。
提示工程不仅仅是关于设计和研发提示词。它包含了与大语言模型交互和研发的各种技能和技术。提示工程在实现和大语言模型交互、对接,以及理解大语言模型能力方面都起着重要作用。用户可以通过提示工程来提高大语言模型的安全性,也可以赋能大语言模型,比如借助专业领域知识和外部工具来增强大语言模型能力。例如,流水线、Agent代理、CoT思维链等基于 LLM 的实现都是以某种形式的提示工程为前提的。
提示工程涉及选择、编写和组织提示,以便获得所需的输出,主要包括以下方面:
Prompt 格式:确定 prompt 的结构和格式,例如,问题形式、描述形式、关键词形式等。
Prompt 内容:选择合适的词语、短语或问题,以确保模型理解用户的意图。
Prompt 上下文:考虑前文或上下文信息,以确保模型的回应与先前的对话或情境相关。
Prompt 编写技巧:使用清晰、简洁和明了的语言编写 prompt,以准确传达用户的需求。
Prompt 优化:在尝试不同 prompt 后,根据结果对 prompt 进行调整和优化,以获得更满意的回应。
提示工程可以帮助改善大语言模型的性能,使其更好地满足用户需求。这是在与模型互动时常用的策略,特别是在自然语言处理任务和生成性任务中,如文本生成、答案生成、文章写作等。
Zero-shot Prompting涉及将任务输入模型,而没有任何示例表明所需的输出,因此称为Zero-shot 。例如,我们可以向模型提供一个句子,并期望它输出该句子的情感。让我们看一个来自DAIR-AI的示例:
-Prompt: Classify the text into neutral, negative, or positive. Text: I think the vacation is okay.**** Output: Neutral
few-shot prompting则是通过提供模型少量高质量的示例,这些示例包括目标任务的输入和期望输出。通过观察这些良好的示例,模型可以更好地理解人类意图和生成准确输出的标准。因此,与zero-shot相比,few-shot 通常会产生更好的性能。然而,这种方法可能会消耗更多的token,并且在处理长文本的输入或者输出的时候可能会遇到上下文长度限制的问题。
大型语言模型(例如GPT-3)在zero-shot能力方面表现出色。但对于复杂任务,few-shot 提示性能更好。为了提高性能,我们使用,few-shot 提示进行上下文学习,通过在提示中提供演示来指导模型执行任务。换句话说,将模型置于一些特定任务的示例中有助于提高模型性能。
让我们看一下面的例子,来自https://arxiv.org/abs/2005.14165
- Prompt: A "whatpu" is a small, furry animal native to Tanzania.An example of a sentence that uses the word whatpu is:We were traveling in Africa and we saw these very cute whatpus.
我们可以从上面的提示中看到,模型被给定一个例子,然后能够为下一个问题生成答案。
指令提示是LLM的最常见用途,尤其是像ChatGPT这样的聊天机器人。举个提示指令的例子:
- - Prompt: Define Onomatopoeia **in** one sentence.
- **** Output: Onomatopoeia **is** the use of words that imitate **or** suggest the natural sound of a thing **or** action.
指令提示旨在向大语言模型提供指令提示示例,以便它可以消除训练或测试差异(模型是在Web规模语料库上训练并在大多数指令上进行测试),并模拟聊天机器人的实际使用场景。指令提示使用(任务说明,输入,真实输出)元组对预训练模型进行微调,以使模型更好地与用户意图对齐并遵循说明。与说明模型交互时,应该详细描述任务要求,尽量具体和准确,清楚地指定要做什么(而不是说不要做某事)。
Prompt Engingeering 之所以成为工程方式,是因为存在着各种相对复杂的Prompt方式,主要包括思维链(CoT) 和 递归提示( Recursive Prompting)等。
Chain-of-Thought(CoT)提示生成一系列短句,即被称为推理链的句子。这些句子描述了逐步推理逻辑,导致最终答案,对于复杂推理的任务和较大的模型,可获得更多的好处。常见的两种基本CoT提示包括Few-shot CoT 和 Zero-Shot CoT,并在下面对它们进行描述。
Few-shot CoT 允许模型查看一些高质量推理链的演示。让我们看 下面的例子:
7.1.2 Zero-shot CoT
Zero-shot CoT是由Kojima等人在2022年首先提出的,它在提示中添加了“让我们逐步思考”,有助于提高模型性能。让我们看一个下面的例子:
- Prompt:
- **-** I went to the market **and** bought 10 apples. I gave 2 apples to the neighbor **and** 2 to the repairman. I then went **and** bought 5 more apples **and** ate 1. How many apples did I remain **with**?
- **-** Let's think step by step.
- Output:
- - First, you started with 10 apples.
- -You gave away 2 apples to the neighbor and 2 to the repairman, so you had 6 apples left.
- -Then you bought 5 more apples, so now you had 11 apples.
- -Finally, you ate 1 apple, so you would remain with 10 apples.
Zero-shot CoT能够帮助我们看到模型内部,并了解它是如何推理得出答案的。
递归提示是一种问题解决方法,它涉及将复杂问题分解成更小、更易管理的子问题,然后通过一系列提示递归地解决这些子问题。这种方法对需要组合泛化的任务尤其有用,其中语言模型必须学习如何组合不同的信息来解决问题。
在自然语言处理的背景下,递归提示可以使用少量提示方法将复杂问题分解为子问题,然后顺序解决提取的子问题,使用前一个子问题的解决方案来回答下一个子问题。这种方法可以用于数学问题或问答等任务,其中语言模型需要能够将复杂问题分解为更小、更易管理的部分,以得出解决方案。例如:
- Calculate the product of the length **and** width:
- prompt: "What is the product of 8 and 6?"
- answer: 48
-
- Substitute the given values **for** length **and** width into the equation:
- prompt: "What is the area of a rectangle with length 8 and width 6?"
- answer: "The area of a rectangle with length 8 and width 6 is 48."
recursive prompting 的更多示例 如下:
自我提问(self-ask )可以视为另一种类型的递归提示,是一种反复提示模型提出后续问题以迭代构建思维过程的方法。后续问题可以通过搜索引擎结果来回答。类似地,IRCoT 和 ReAct将迭代 CoT 提示与对 Wikipedia API 的查询相结合,以搜索相关实体和内容,然后将其添加回上下文中。示例如下:
思维树(Tree of Thought)通过探索每一步的多种推理可能性来扩展 CoT。它首先将问题分解为多个思维步骤,并在每个步骤中生成多个思维,实质上是创建一个树形结构。搜索过程可以是广度优先过程或深度优先的过程,而每个节点的评估分类器可以通过Prompt提示的方式完成。
一般而言,Prompt 相当于一系列前缀令牌,它们增加了在给定输入时获得所需输出的概率。因此,可以将它们视为可训练的参数,并通过梯度下降法直接在嵌入空间上对它们进行优化,例如 AutoPrompt ,Prefix-Tuning ,P 微调和 Prompt-Tuning,从自动提示到提示微调的趋势是设置的逐渐简化。
APE是一种在模型生成的Prompt候选集中搜索的方法,然后根据选择的得分函数过滤候选人集,以最终选择得分最高的最佳候选提示。
提示 LLM 根据输入输出健值对形式的一个小集合尝试生成候选指令。
给定一个数据集 Dtrain = {(x,y)} ,希望找到一个指令ρ,使:
f (.)是每个样本的得分函数,例如执行精度或对数概率。
使用蒙特卡罗搜索方法进行迭代,通过promt生成下列指令的变体,同时保持语义,提出语义相似的变体,从而改进最佳候选项。
为了自动构建思维链,Shum 等人(2023)提出了增强-修剪-选择,一个三步过程:
增强: 使用few-shot或zero shot 的 CoT Prompt 生成给定问题的多个伪思维链;
修剪: 基于生成的答案是否匹配基本真相来修剪这些伪思维链。
选择: 应用降低方差的梯度策略来学习选定示例的概率分布,同时考虑将示例的概率分布作为策略,并将验证集的准确性作为奖励。
采用聚类技术对问题进行抽样,然后生成链(2023)。LLM 倾向于犯某些类型的错误,一类错误可以在嵌入空间中相似,因此可以组合在一起。通过只从频繁错误集群中抽样一个或几个,可以防止一个错误类型的过多错误演示,并收集一组不同的示例。
问题聚类: 嵌入问题并采用K-means聚类的运行方式。
演示选择: 从每个聚类中选择一组有代表性的问题,即从一个聚类中选择一个演示样例。每个簇中的样本按照到簇中心的距离进行排序,首先选择离簇中心较近的样本。
基本关系的生成: 使用zero-shot CoT 为选定的问题生成推理链,构造few-shot prompt进行推理。
提示工程的实现涉及到基于LLM应用中的各个方面,这里给出一些提示工程的常见实践:
静态提示:Prompt可以遵循zero、single或few shot的方法。LLM 的生成能力通过在Prompt中包含示例数据来遵循一次性学习或几次性学习得到了极大的增强。
上下文提示:上下文提示在生成响应时提供对 LLM 的参考框架,在很大程度上可以避免 LLM 的幻觉。
提示模板:静态提示转换为模板,其中键值被替换为占位符,占位符在运行时被应用程序的值/变量替换。提示模板中的变量或占位符通过用户提出的问题,以及从知识存储中搜索的知识来填充,因此也称为提示注入或实体注入。
提示链:提示链,也称为LLM链,是创建一个由一系列模型调用组成的链的概念。这一系列调用相继发生,其中一个链的输出作为另一个链的输入。每个链的目标都是小型且范围良好的子任务,因此单个 LLM 是用于寻址任务的多个有序子组件之一。
提示流水线:在机器学习中,流水线可以描述为端到端结构,来协调事件和数据流。流水线由触发器启动或启动; 并且基于某些事件和参数,遵循一个流程,该流程将产生一个输出。对于提示流水线而言,流在大多数情况下是由用户请求启动的,请求被定向到特定的提示模板。因此,提示流水线可以描述为提示模板的智能扩展。
Agent代理:对于 LLM 相关的操作,其自动化的形式是所谓的Agent代理。提示链是执行预先确定和设置的操作序列,Agent 不遵循预先确定的事件顺序,可以保持高度的自主性。Agent可以访问一组工具,任何属于这些工具范围的请求都可以由Agent处理。执行流水线为Agent提供了自治权,在代理到达最终答案之前可能需要进行多次迭代。
CoT提示:CoT提示使大型语言模型(LLM)能够处理常识推理和算术等复杂任务。通过Prompt建立CoT推理并相应地指导 LLM,这是一种相当直接的实现。标准提示与CoT提示的对比如下:
思维链提示特别有用的地方在于,通过分解 LLM 输入和 LLM 输出,它创建了一个洞察和解释窗口。
8. ChatML:LLM 的主要安全漏洞和滥用途径是Prompt注入攻击,ChatML 将允许针对这些类型的攻击提供保护。为了消除prompt注入攻击,会话被分为以下几个层次或角色: 系统、助理和用户等, 然后做相应的prompt防护。
有人可以说,Prompt Engineering是以某种方式构建的自然语言。但OpenAI首席执行官所指的似乎是真正的非结构化和高度直观的交互界面,在某种程度上,这种说法是值得商榷的,因为如此多的技术和创新都是基于Prompt engineering的基本原理来实现的。
考虑到企业用例,操纵LLM的两种主要方法是微调和将上下文参考数据注入到推理prompt中,两种方法不是互斥的。模型微调会更改LLM的行为和响应,RAG通过上下文参考来补充用户的输入。
提示工程的主要挑战之一是问题的陈述和形式化表达,将思想中存在的需求转化为文本请求。退一步而言,在传统的聊天机器人中建立上下文是非常重要的。上下文首先是通过根据一个或多个意图对用户输入进行分类来建立的,通过先前的对话、对其他系统的API调用等建立进一步的上下文。上下文在很大程度上也取决于时间和地点,以及提出问题时的背景参考是什么。
除了上下文感知外,歧义性是另一个挑战。有些形式的歧义对我们人类来说很容易理解,但传统上对NLU/聊天机器人来说很难。在OpenAI的实现中,LLM输入方面出现了chatML,定义了角色,并为LLM的输入提供了明确的结构。LLM输出方面出现了function call,聊天的完成模式被设置为事实上的标准。
意图、上下文、歧义和消除歧义都是任何对话的组成部分。有了人类语言界面,语境和语境感知将永远是重要的。歧义是存在的,一定程度的歧义消除是人类对话的一部分。在对话中,我们不断使用“歧义消除”来确立意义和意图,在上下文中可以在一定程度上自动消除歧义。例如,要求LLM生成五个选项,然后让用户选择生成的最佳答案,就是一种消除歧义的形式。
企业实施将是特定于领域的,需要约束,并具有一定程度的域外检测。问题或请求的分解对于创建一个思维链推理过程非常重要。微调设置模型行为,而RAG为LLM创建了一个上下文参考,以便在推理过程中使用。数据管理将始终是LLM应用程序的一部分。
复杂性从不会消失,只会从一个地方转移到另一个地方。
【参考资料与关联阅读】
https://github.com/openai/grade-school-math
https://github.com/dair-ai/Prompt-Engineering-Guide
https://lilianweng.github.io/posts/2023-03-15-prompt-engineering
https://crfm.stanford.edu/2023/03/13/alpaca.html
https://learnprompting.org/docs/basics/instructions
https://txt.cohere.ai/how-to-train-your-pet-llm-prompt-engineering/
https://arxiv.org/pdf/2302.07842.pdf
Ivan Reznikov,“How Does an LLM Generate Text?”
Cobus Greyling,“the future of prompt engineering”
DatHero,“Master the Perfect ChatGPT Prompt Formula”