结构化输出指南:三个必备prompt提示技巧


结构化输出指南:三个必备prompt提示技巧

仅用于站内搜索,没有排版格式,具体信息请跳转上方微信公众号内链接

点击“蓝字”关注我们
当我们尝试将LLM融入到实际的应用程序或工作流程中时,却常常遇到一个棘手的问题——模型输出的信息格式并不总是我们所期望的。它们的回答往往是一段段自由形式的文本,这对于人类理解来说可能足够,但对于代码和自动化系统而言,处理起来却困难重重。这时候,结构化输出(StructuredOutput)的重要性就凸显出来了。本文将为初学者详细介绍结构化输出的概念、重要性,并深入讲解三个必备的提示技巧,帮助大家更好地从大语言模型中获取可用的结构化数据。
结构化输出,简单来说,就是让大语言模型以一种清晰、可预测、有组织的格式返回信息,例如整齐的列表、带有标签的数据字段(键值对形式:key:value),甚至是简单的表格,而不是一长段对话式的文本。这一概念在实际应用中具有举足轻重的意义。
以构建一个利用人工智能分析客户评论的应用程序为例。当我们向模型询问“总结这条评论,并告诉我提到的产品和客户的总体情绪”时,模型可能给出这样的回复:“嗯,看起来客户简·D购买了‘MegaWidget3000’,并且非常不满意。她提到产品只用了两天就坏了,整个体验让她感到非常沮丧。”这样的回答对于人类来说很容易理解,但对于应用程序的代码而言,却充满挑战。代码需要从这段文本中费力地找出产品名称(“MegaWidget3000”),判断情绪(“不满意”还是“沮丧”才是主要情绪呢?),甚至可能还需要提取客户名称(如果有需要的话)。而且,如果模型下次使用了不同的表述,比如用“感到失望”代替“不满意”,那么用于解析情绪的代码可能就会出错。
相比之下,结构化的输出则能避免这些问题。例如:
这种结构化的格式将混乱的对话式文本转化为干净、有序的数据,使得代码能够可靠地处理。
通常,获取大语言模型结构化输出主要有两种途径:原生模型功能和提示工程。
随着人工智能模型的不断发展,一些模型增加了内置的请求结构化数据的方法。例如,谷歌的Gemini模型通常可以直接使用函数描述或特定的模式,有时还能与Pydantic等工具集成;OpenAI的模型(如GPT-4)提供了“JSON模式”或“函数调用”等功能,旨在将输出强制转换为特定的JSON结构。然而,这些原生功能虽然强大,但往往依赖于特定的模型。不同模型请求结构化数据的方式可能不同,这可能会使开发者锁定在特定的供应商,并且可能需要学习其特定的API或库,增加了使用的复杂性。
与依赖原生模型功能不同,提示工程是一种更为通用的方法。它的核心思想非常简单,就是在向模型发出的指令(即提示)中,直接明确地告诉模型你期望的输出格式。这种方法不依赖于特定的模型,几乎适用于大多数大语言模型。它充分利用了模型理解和遵循指令的核心能力,让开发者能够灵活地定义所需的结构,例如请求YAML或特定的JSON格式。此外,通过提示工程获取结构化输出,不需要预先学习复杂的模型特定API,降低了使用门槛,对于初学者来说是一种更为友好的选择。接下来,我们将重点介绍基于提示工程的三个必备技巧。
在请求大语言模型进行结构化输出时,选择合适的格式至关重要。JSON(JavaScriptObjectNotation)在Web开发和API中应用广泛,但它对于大语言模型来说,有时可能会带来一些问题,特别是在处理包含引号或多行文本的情况时。
JSON有严格的规则,字符串必须用双引号(”)括起来。如果文本本身包含双引号,则必须使用反斜杠(\)进行转义,例如"。同样,字符串中的换行符需要表示为\n。大语言模型在处理这些规则时常常会遇到困难,这主要源于它们处理文本的方式——分词(tokenization)。大语言模型会将文本分解为较小的部分(词元),这些词元可能是完整的单词、单词的一部分,或者是单个字符/符号。在分词过程中,像\这样的转义字符或\n这样的格式标记有时会被不恰当地拆分,模型也可能难以在其庞大的训练数据中学习何时以及如何正确应用这些复杂的上下文规则。由于这种底层的分词机制,大语言模型在一致地处理转义字符方面表现不佳。

相比之下,YAML(YAMLAin’tMarkupLanguage)在处理这类情况时具有明显的优势。YAML旨在更易于人类阅读,并且对于字符串,特别是多行字符串,具有更灵活的规则,这使得它对转义和格式错误的敏感度较低。同样以提取上述对话为例,用YAML格式表示则更加简洁:
在这个例子中,不需要对引号进行转义,换行也显得很自然。这里使用了YAML的块标量风格(|)。
YAML提供了多种强大的处理多行字符串的方式。其中,字面量风格(|)会精确保留块中的换行符,源YAML中的每一行新行在结果字符串中都会变成一个换行符(\n)。例如:
其结果字符串为:”Line1\nLine2\n\nLine4\n”(注意其中的双换行和最后的换行)。
折叠风格(>)则会将块内的大多数换行符折叠为空格,将文本视为一长行,仅为了可读性而进行换行。它会保留空白行(这些空白行在结果字符串中会变成\n)。例如:

此外,还可以通过添加“咬尾指示符”(+、-)来进一步控制块标量末尾的换行符处理方式。默认情况下(无指示符,即|或>),如果有一个尾随换行符,会保留它,但会删除任何额外的尾随换行符;使用|+或>+表示保留所有尾随换行符;使用|-或>-则表示删除所有尾随换行符,包括最后一个(如果存在)。
在实际应用中,当提示大语言模型进行结构化输出,且输出内容可能包含复杂字符串时,我们应该明确要求使用YAML格式,并将输出包含在yaml…块中。如果可能出现多行文本且格式很重要,还应在提示中指定多行风格(|或>)。一般情况下,除非有特定需求,否则不需要指定咬尾指示符。同时,即使YAML具有灵活性,也一定要在代码中对输出进行解析和验证,可以使用断言(assert)或其他模式检查方法,以确保数据的准确性和可用性。通过使用YAML,尤其是其多行处理能力,可以显著减少因JSON的严格规则和大语言模型的分词挑战而导致的格式错误。
在许多实际任务中,我们需要大语言模型从提供的列表中识别特定的项目,例如根据某些标准筛选或选择项目。一种常见的做法是要求模型返回它选择的项目的文本内容,但这种方法在处理真实世界中的文本时往往不可靠,因为真实文本可能包含各种格式问题和噪声。
假设我们有一批产品评论,希望利用大语言模型标记出其中看起来像垃圾邮件的评论(例如包含可疑链接或无意义内容的评论)。输入的评论列表可能如下所示:
这个列表中的文本包含了各种变化,如标点符号、大小写、间距、符号,甚至可能存在拼写错误(这里虽未明确添加,但实际情况中可能出现)。

此时,大语言模型对于这个示例的预期输出应该是一个数字列表,并且很可能按照请求的YAML结构进行格式化(结合技巧一):
这样的输出具有诸多优点:它很简单,只是一个整数列表;整数不存在拼写错误、间距问题或标点符号变化,具有稳定性;验证也很容易,只需检查输出是否是一个包含在预期范围内(0-5)有效整数的列表;并且可以直接在代码中使用,通过遍历这些索引,无论原始评论内容多么混乱,都能够可靠地访问或删除原始评论列表中的相应评论。
因此,当要求大语言模型从提供的可能复杂或混乱的字符串列表中选择或识别项目时,我们应该在提示中为列表提供清晰的索引(或唯一、简单的标识符),并指示模型仅输出与所选项目对应的索引/标识符列表。同时,要验证输出是否是一个包含有效索引/标识符的列表。这种方法极大地提高了处理从嘈杂的真实世界文本输入中进行选择的任务的可靠性,避免了脆弱的字符串匹配,使用稳定的索引来确保任务的准确性。
第三个技巧可能乍一看有些违反直觉,即故意要求大语言模型在其结构化输出中添加“额外”的自然语言,我们通过YAML注释(#)来实现这一点。这样做不仅是为了提高输出的可读性,更重要的是为了提高结构化数据本身的准确性。
当我们要求大语言模型执行复杂任务(如分析多个评论并输出要删除的评论索引列表)并立即生成结构化数据时,模型有时可能会“急于”完成任务。在没有明确的步骤来整合其发现或在确定结构化格式之前对其选择进行推理的情况下,很容易出现错误。它可能会遗漏某个项目、包含错误的项目,或者在复杂的分类中出错。从分析直接跳到最终结构的过程可能不太可靠。
为了缓解这个问题,我们可以指示大语言模型在输出关键结构化数据之前,先生成一段自然语言注释来解释其推理过程。这不仅仅是为了让我们之后更容易理解输出内容(尽管这是一个额外的好处),更重要的是,它迫使大语言模型在最关键的时候进行一个“思维链”步骤。
在处理输入(例如评论列表)时,大语言模型首先进行分析。在输出索引列表之前,它必须先生成注释,总结为什么选择这些特定的索引。这使它回到自然语言推理模式,整合其发现。在明确阐述了推理之后,大语言模型现在更有准备输出正确的索引列表或准确的结构化值。生成注释就像是一个“认知减速带”,它中断了直接跳到结构化输出的过程,促使模型进行片刻的思考,这通常会导致更准确的结果,特别是对于需要综合或判断的任务(如从列表中选择多个项目或进行细致的分类)。

通过强制模型先生成“#Identifiedreviews…”这样的注释,我们增加了后续列表[1,3,5]准确的可能性,因为模型在输出数字之前必须用自然语言明确说明其选择的理由。
在实际应用中,为了利用嵌入推理来提高准确性,我们首先要确定那些大语言模型需要进行判断或综合的关键结构化输出(例如选定项目的列表、分类、总结字段)。然后,指示模型在这些特定字段之前添加YAML注释(#reasoning…),将其构建为在数据点之前需要总结其发现或理由的形式。这种方法在大语言模型不仅仅是提取简单事实,而是进行选择或将分析结果总结为结构化格式时最为有效。可以把它想象成要求大语言模型在完成结构化答案之前,先在注释中“展示其初步工作”。这个嵌入推理的步骤是提高结构化输出可靠性和准确性的强大技术。


文章作者: ZejunCao
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 ZejunCao !
  目录