附录 A:高级提示技术

提示简介

提示(Prompting)是与语言模型交互的主要接口,其过程是设计输入以引导模型生成期望的输出。这包括构建请求、提供相关上下文、指定输出格式以及展示预期的响应类型。设计良好的提示可以最大限度地发挥语言模型的潜力,从而生成准确、相关且具有创造性的响应。相反,设计不佳的提示可能导致模糊、不相关或错误的输出。

提示工程的目标是始终如一地从语言模型中获得高质量的响应。这需要理解模型的能力和局限性,并有效地传达意图目标。提示工程涉及通过学习如何最好地指示人工智能来发展与其沟通的专业技能。

本附录详细介绍了超越基本交互方法的各种提示技术。它探讨了构建复杂请求、增强模型推理能力、控制输出格式以及整合外部信息的方法。这些技术适用于构建从简单聊天机器人到复杂多智能体系统的各种应用,并能提高智能体应用的性能和可靠性。

智能体模式,即构建智能系统的架构结构,在主章节中有详细说明。这些模式定义了智能体如何进行规划、使用工具、管理记忆以及协作。这些智能体系统的有效性取决于其与语言模型进行有意义交互的能力。

核心提示原则

语言模型有效提示的核心原则:

有效提示基于指导与语言模型沟通的基本原则,这些原则适用于各种模型和任务复杂性。掌握这些原则对于持续生成有用且准确的响应至关重要。

清晰性与具体性:指令应清晰明确且具体。语言模型会根据模式进行解释,多个可能的解释可能导致意外的响应。定义任务、期望的输出格式以及任何限制或要求。避免使用模糊语言或假设。不充分的提示会导致模糊且不准确的响应,阻碍有意义的输出。

简洁性:虽然具体性至关重要,但不应以牺牲简洁性为代价。指令应直接明了。冗余的措辞或复杂的句子结构可能会使模型困惑或掩盖主要指令。提示应简单明了;对用户来说令人困惑的内容对模型来说也可能是令人困惑的。避免复杂的语言和多余的信息。使用直接的措辞和主动动词清晰地界定期望的操作。有效的动词包括:行动(Act)、分析(Analyze)、分类(Categorize)、归类(Classify)、对比(Contrast)、比较(Compare)、创建(Create)、描述(Describe)、定义(Define)、评估(Evaluate)、提取(Extract)、查找(Find)、生成(Generate)、识别(Identify)、列举(List)、测量(Measure)、组织(Organize)、解析(Parse)、选择(Pick)、预测(Predict)、提供(Provide)、排序(Rank)、推荐(Recommend)、返回(Return)、检索(Retrieve)、重写(Rewrite)、选择(Select)、展示(Show)、排序(Sort)、总结(Summarize)、翻译(Translate)、撰写(Write)。

使用动词:动词的选择是提示的关键工具。动作动词指示预期的操作。与其使用“考虑总结这个”,不如直接指令“总结以下文本”,这样更有效。精准的动词能够引导模型激活与特定任务相关的训练数据和处理流程。

指令优于约束:积极的指令通常比消极的约束更有效。指定期望的操作比说明不该做什么更为优先。虽然约束在安全性或严格格式方面有其作用,但过度依赖可能导致模型专注于避免错误而非实现目标。设计提示时应直接引导模型。积极的指令与人类的指导偏好一致,并减少混淆。

实验与迭代: 提示工程是一个迭代的过程。要找到最有效的提示需要进行多次尝试。首先创建一个草稿,测试它,分析输出结果,识别不足之处,然后优化提示。模型的变体、配置(如温度或top-p参数)以及措辞的微小变化可能会产生不同的结果。记录尝试过程对于学习和改进至关重要。实验与迭代是实现预期性能的必要步骤。

这些原则构成了与语言模型进行有效沟通的基础。通过优先考虑清晰、简洁、行动动词、积极指令以及迭代,一个稳健的框架得以建立,用于应用更高级的提示技术。

基础提示技术

在核心原则的基础上,基础技术为语言模型提供不同层次的信息或示例,以引导其响应。这些方法作为提示工程的初始阶段,适用于广泛的应用场景。

零样本提示

零样本提示是最基本的提示形式,其中语言模型仅接收到指令和输入数据,而没有任何期望的输入-输出对的示例。这完全依赖于模型的预训练能力来理解任务并生成相关的响应。基本上,零样本提示由任务描述和初始文本组成,用于启动过程。

  • 适用场景: 零样本提示通常适用于模型在训练过程中可能已经广泛接触的任务,例如简单的问答、文本补全或对简单文本的基本摘要。这是最快速的尝试方法。
  • 示例:

    将以下英文句子翻译成法语:'Hello, how are you?'

单样本提示

单样本提示是指在实际任务之前,向语言模型提供一个输入及其对应的期望输出示例。这种方法作为初步演示,展示了模型需要复制的模式。其目的是为模型提供一个具体实例,作为模板以有效执行给定任务。

  • 适用场景: 单样本提示适用于输出格式或风格较为特殊或不常见的任务。它为模型提供了一个具体实例进行学习。相比于零样本提示,对于需要特定结构或语气的任务,单样本提示可以提高性能。
  • 示例:

    将以下英文句子翻译成西班牙语:

    英文:'Thank you.'

    西班牙语:'Gracias.'

    英文:'Please.'

    西班牙语:

少样本提示

少样本提示通过提供多个示例(通常为三到五个输入-输出对)增强了单样本提示。这种方法旨在更清晰地展示期望响应的模式,提高模型复制该模式的可能性。通过提供多个示例,少样本提示能够更好地引导模型遵循特定的输出模式。

  • 使用场景: Few-shot 提示特别适用于需要遵循特定格式、风格或展现细微变化的任务。这种方法非常适合分类、基于特定模式的数据提取或以特定风格生成文本的任务,尤其是在零样本或单样本提示无法产生一致结果时。通常建议提供至少三到五个示例,并根据任务复杂性和模型的 token 限制进行调整。
  • 示例质量和多样性的重要性: Few-shot 提示的效果很大程度上取决于所提供示例的质量和多样性。示例应准确、具有代表性,并涵盖模型可能遇到的潜在变化或边界情况。高质量、精心编写的示例至关重要;即使是一个小错误也可能导致模型困惑并生成不理想的输出。包含多样化的示例有助于模型更好地泛化到未见过的输入。
  • 分类任务中混合类别示例: 在使用 Few-shot 提示进行分类任务(模型需要将输入分类到预定义类别中)时,最佳实践是混合不同类别示例的顺序。这可以防止模型可能过度拟合于特定的示例顺序,并确保它能够独立识别每个类别的关键特征,从而在未见数据上表现得更为稳健和具有泛化能力。
  • 向“多样本”学习的演变: 随着现代大型语言模型(如 Gemini)在长上下文建模方面的能力不断增强,它们在利用“多样本”学习方面变得非常高效。这意味着通过在提示中直接包含更多的示例——有时甚至多达数百个——可以实现复杂任务的最佳性能,从而使模型能够学习更复杂的模式。
  • 示例:

    将以下电影评论的情感分类为 POSITIVE(积极)、NEUTRAL(中立)或 NEGATIVE(消极):

    评论:“表演非常出色,故事引人入胜。”

    情感:POSITIVE

    评论:“还可以,没什么特别的。”

    情感:NEUTRAL

    评论:“我觉得情节很混乱,角色也不讨喜。”

    情感:NEGATIVE

    评论:“视觉效果令人惊叹,但对话很弱。”

    情感:

理解何时应用零样本、单样本和 Few-shot 提示技术,并精心设计和组织示例,是提升智能系统有效性的关键。这些基本方法为各种提示策略奠定了基础。

提示结构化

除了提供示例的基本技术外,如何结构化提示对引导语言模型的表现也至关重要。结构化提示包括在提示中使用不同的部分或元素,以清晰有序的方式提供不同类型的信息,例如指令、上下文或示例。这有助于模型正确解析提示,并理解每段文本的具体作用。

系统提示

系统提示为语言模型设定整体的上下文和交互或会话的目的。这包括提供指令或背景信息,以建立规则、角色或整体行为。与具体的用户查询不同,系统提示提供了模型响应的基础性指导。它会影响模型的语气、风格以及整个交互过程中的总体方式。例如,系统提示可以指示模型始终以简洁且有帮助的方式回应,或确保响应适合普通受众。系统提示还可以通过包含指导方针(如保持尊重的语言)来用于安全性和防止不当内容的控制。

此外,为了最大化系统提示的有效性,可以通过基于大型语言模型(LLM)的迭代优化进行自动提示优化。像 Vertex AI Prompt Optimizer 这样的服务能够通过基于用户定义的指标和目标数据系统化地改进提示,从而确保在特定任务中实现最高性能。

  • 示例:

    你是一个乐于助人且无害的 AI 助手。以礼貌和信息丰富的方式回答所有问题。不要生成任何有害、偏见或不适当的内容。

角色提示

角色提示通过分配特定的角色、人物或身份给语言模型,通常与系统或上下文提示结合使用。这涉及指示模型采用与该角色相关的知识、语气和沟通风格。例如,像“充当旅行指南”或“你是一位数据分析专家”这样的提示会引导模型反映所分配角色的视角和专业知识。定义一个角色为语气、风格和专注的专业知识提供了框架,旨在提升输出的质量和相关性。可以进一步指定角色内的期望风格,例如“幽默且鼓舞人心的风格”。

  • 示例:

    充当一位经验丰富的旅行博主。写一个关于罗马最佳隐藏景点的简短、吸引人的段落。

使用分隔符

有效的提示设计需要明确区分指令、上下文、示例和语言模型的输入。可以使用分隔符,例如三重反引号(\`\`\`)、XML 标签(\\, \\)或标记(---),以视觉和程序化方式分隔这些部分。这种实践在提示工程中被广泛使用,可最大限度减少模型的误解,确保清晰地定义每部分提示的角色。

  • 示例:

    \总结以下文章,重点关注作者提出的主要论点。\</instruction>

    \

    [在此插入文章全文]

    \</article>

上下文工程

与静态系统提示不同,上下文工程动态提供任务和对话所需的背景信息。这种不断变化的信息帮助模型理解细微差别、回忆过去的互动并整合相关细节,从而生成扎实的响应并实现更流畅的交流。示例包括之前的对话、相关文档(如检索增强生成)或特定的操作参数。例如,在讨论去日本旅行时,可以基于现有的对话上下文,询问东京适合家庭的三个活动。在智能体系统中,上下文工程是核心智能体行为的基础,例如记忆持久性、决策制定以及跨子任务的协调。具有动态上下文管道的智能体可以在时间上持续目标、调整策略,并与其他智能体或工具无缝协作——这些特性对于长期自主性至关重要。这种方法表明,模型输出的质量更多取决于提供的上下文的丰富性,而非模型架构本身。它标志着从传统提示工程的显著演变,后者主要集中于优化用户即时查询的措辞。上下文工程将其范围扩展到包含多层信息。

这些层包括:

  • 系统提示: 基础指令定义了 AI 的操作参数(例如,“你是一名技术写作者;你的语气必须正式且精确”)。
  • 外部数据:
    • 检索文档: 从知识库中主动获取的信息以支持响应(例如,提取技术规格)。
    • 工具输出: AI 使用外部 API 实时获取数据的结果(例如,查询日历以获取可用性)。
  • 隐式数据: 关键信息,例如用户身份、交互历史和环境状态。整合隐式上下文面临隐私和伦理数据管理相关的挑战。因此,尤其是在企业、医疗保健和金融等领域,针对上下文工程的强大治理至关重要。

核心原则是,即使是先进的模型,在其操作环境视图有限或构造不良的情况下也会表现不佳。这种实践将任务从简单回答问题重新定义为为智能体构建全面的操作图景。例如,一个经过上下文工程设计的智能体可以在响应查询之前整合用户的日历可用性(工具输出)、与电子邮件接收者的专业关系(隐式数据)以及之前会议的笔记(检索文档)。这使得模型能够生成高度相关、个性化且实用的输出。“工程”方面涉及创建强大的管道以在运行时获取和转换这些数据,并建立反馈循环以持续改进上下文质量。

为实现这一目标,可以使用专门的调优系统,例如 Google 的 Vertex AI 提示优化器,在大规模上自动改进流程。通过根据样本输入和预定义指标系统地评估响应,这些工具可以增强模型性能,并在不同模型间调整提示和系统指令,而无需大量手动重写。为优化器提供样本提示、系统指令和模板,可以使其以编程方式优化上下文输入,为实施复杂的上下文工程所需的反馈循环提供结构化方法。

这种结构化方法将简单的 AI 工具与更复杂的、具有上下文感知能力的系统区分开来。它将上下文视为主要组成部分,强调智能体知道什么、何时知道以及如何使用这些信息。这种实践确保模型对用户意图、历史和当前环境有全面的理解。最终,上下文工程是一种关键方法,可将无状态聊天机器人转变为功能强大的、情境感知的系统。

结构化输出

通常,提示的目标不仅仅是获得自由形式的文本响应,而是以特定的机器可读格式提取或生成信息。请求结构化输出,例如 JSON、XML、CSV 或 Markdown 表,是一种重要的结构化技术。通过明确要求以特定格式输出,并可能提供所需结构的模式或示例,可以指导模型以其他系统或应用程序易于解析和使用的方式组织其响应。返回 JSON 对象进行数据提取非常有益,因为它强制模型创建结构,并可以限制幻觉现象。建议对输出格式进行实验,特别是对于数据提取或分类等非创造性任务。

  • 示例:

    从以下文本中提取信息,并以包含键“name”、“address”和“phone_number”的 JSON 对象返回。

    文本:“Contact John Smith at 123 Main St, Anytown, CA or call (555) 123-4567.”

有效利用系统提示、角色分配、上下文信息、分隔符和结构化输出,可以显著提升与语言模型交互的清晰度、控制性和实用性,为开发可靠的智能体系统提供坚实的基础。请求结构化输出对于创建以语言模型输出作为后续系统或处理步骤输入的管道至关重要。

利用 Pydantic 实现面向对象的外观:

一种强大的技术是使用语言模型生成的数据填充 Pydantic 对象实例,从而强制执行结构化输出并增强互操作性。Pydantic 是一个用于数据验证和设置管理的 Python 库,基于 Python 类型注解。通过定义 Pydantic 模型,可以为所需的数据结构创建清晰且可强制执行的模式。这种方法有效地为提示的输出提供了一个面向对象的外观,将原始文本或半结构化数据转换为经过验证的、带有类型提示的 Python 对象。

可以直接使用 model_validate_json 方法将语言模型生成的 JSON 字符串解析为 Pydantic 对象。这种方法特别有用,因为它将解析和验证结合在一个步骤中。

from pydantic import BaseModel, EmailStr, Field, ValidationError
from typing import List, Optional
from datetime import date

# --- Pydantic 模型定义 ---
class User(BaseModel):
    name: str = Field(..., description="用户的全名。")
    email: EmailStr = Field(..., description="用户的电子邮件地址。")
    date_of_birth: Optional[date] = Field(None, description="用户的出生日期。")
    interests: List[str] = Field(default_factory=list, description="用户的兴趣列表。")

# --- 假设的语言模型输出 ---
llm_output_json = """
{
    "name": "Alice Wonderland",
    "email": "alice.w@example.com",
    "date_of_birth": "1995-07-21",
    "interests": [
        "自然语言处理",
        "Python编程",
        "园艺"
    ]
}
"""

# --- 解析和验证 ---
try:
    # 使用 model_validate_json 类方法解析 JSON 字符串。
    # 此单步操作将 JSON 解析并根据 User 模型验证数据。
    user_object = User.model_validate_json(llm_output_json)

    # 现在可以使用一个干净的、类型安全的 Python 对象。
    print("成功创建 User 对象!")
    print(f"姓名: {user_object.name}")
    print(f"电子邮件: {user_object.email}")
    print(f"出生日期: {user_object.date_of_birth}")
    print(f"第一个兴趣: {user_object.interests[0]}")

    # 可以像访问普通 Python 对象的属性一样访问数据。
    # Pydantic 已将 'date_of_birth' 字符串转换为 datetime.date 对象。
    print(f"date_of_birth 的类型: {type(user_object.date_of_birth)}")
except ValidationError as e:
    # 如果 JSON 格式错误或数据与模型的类型不匹配,
    # Pydantic 将抛出 ValidationError。
    print("无法验证语言模型生成的 JSON。")
    print(e)

上述 Python 代码展示了如何使用 Pydantic 库定义数据模型并验证 JSON 数据。代码定义了一个包含姓名、电子邮件、出生日期和兴趣字段的 User 模型,并为每个字段添加了类型提示和描述。随后,代码使用 User 模型的 model_validate_json 方法解析来自大型语言模型(LLM)的假设 JSON 输出。该方法根据模型的结构和类型同时处理 JSON 解析和数据验证。最后,代码从生成的 Python 对象中访问经过验证的数据,并在 JSON 无效时通过 ValidationError 进行错误处理。

对于 XML 数据,可以使用 xmltodict 库将 XML 转换为字典,然后将其传递给 Pydantic 模型进行解析。通过在 Pydantic 模型中使用 Field 的别名,可以无缝映射 XML 通常冗长或属性繁多的结构到对象的字段。

这种方法对于确保基于LLM(大型语言模型)的组件与更大系统的其他部分之间的互操作性至关重要。当LLM的输出被封装在一个Pydantic对象中时,可以可靠地将其传递给其他函数、API或数据处理管道,同时确保数据符合预期的结构和类型。这种在系统组件边界处采用“解析,而非验证”的实践,有助于构建更健壮且易于维护的应用程序。

有效利用系统提示、角色分配、上下文信息、分隔符以及结构化输出,可以显著增强与语言模型交互的清晰度、控制力和实用性,为开发可靠的智能体系统提供坚实的基础。请求结构化输出对于创建以语言模型输出作为后续系统或处理步骤输入的管道至关重要。

提示结构化

除了提供示例的基本技术外,提示的结构化方式在引导语言模型方面也起着关键作用。结构化提示涉及在提示中使用不同的部分或元素,以清晰和有组织的方式提供不同类型的信息,例如指令、上下文或示例。这有助于模型正确解析提示,并理解每段文本的具体角色。

推理与思维过程技术

大型语言模型擅长模式识别和文本生成,但在需要复杂、多步骤推理的任务中往往面临挑战。本附录重点介绍旨在通过鼓励模型揭示其内部思维过程来增强推理能力的技术,特别是改善逻辑推导、数学计算和规划的方法。

思维链(Chain of Thought, CoT)

思维链(CoT)提示技术是一种强大的方法,通过明确提示模型生成中间推理步骤以提高其推理能力。在要求模型给出最终答案时,使用该技术会指示模型“逐步思考”。这一过程类似于人类将问题分解为更小、更易管理的部分并依次解决的方式。

CoT有助于LLM生成更准确的答案,尤其是对于需要某种计算或逻辑推导的任务,在这些任务中,模型可能会遇到困难并产生错误结果。通过生成这些中间步骤,模型更有可能保持正确的轨迹并正确执行必要的操作。

CoT主要有两种变体:

  • 零样本思维链(Zero-Shot CoT): 这种方法仅需在提示中添加短语“让我们逐步思考”(或类似的措辞),而无需提供任何推理过程的示例。令人惊讶的是,对于许多任务,这种简单的添加可以显著提高模型的性能,触发其暴露内部推理过程的能力。

    • 示例(零样本思维链):

      如果一列火车以每小时60英里的速度行驶,行驶了240英里的距离,旅程花了多长时间?让我们逐步思考。
  • 少样本 CoT(Few-Shot CoT):

    这种方法将链式思维(CoT)与少样本提示结合起来。通过提供多个示例,展示输入、逐步推理过程以及最终输出,模型可以更清晰地理解如何进行推理并组织其响应。这通常比零样本 CoT 在处理更复杂任务时表现更好。

    • 示例(少样本 CoT):

      Q: 三个连续整数的和是 36。这些整数是什么?

      A: 设第一个整数为 x。下一个连续整数是 x+1,第三个是 x+2。它们的和为 x + (x+1) + (x+2) \= 3x + 3。我们知道总和是 36,因此 3x + 3 \= 36。两边同时减去 3:3x \= 33。两边同时除以 3:x \= 11。这些整数是 11,11+1=12,11+2=13。这些整数是 11、12 和 13。

      Q: Sarah 有 5 个苹果,她又买了 8 个苹果。她吃了 3 个苹果。她还剩下多少个苹果?让我们一步步思考。

      A: 让我们一步步思考。Sarah 开始时有 5 个苹果。她又买了 8 个,因此她将 8 加到初始数量上:5 + 8 \= 13 个苹果。然后,她吃了 3 个苹果,因此我们从总数中减去 3:13 - 3 \= 10。Sarah 还剩下 10 个苹果。答案是 10。

CoT 有几个优势。它实现起来相对简单,并且在使用现成的大型语言模型(LLM)时非常有效,无需进行额外的微调。一个显著的优点是模型输出的可解释性得到了提高;可以看到模型遵循的推理步骤,这有助于理解模型为何得出某个特定答案,以及在出现错误时进行调试。此外,CoT 似乎增强了提示在不同版本语言模型中的鲁棒性,这意味着当模型更新时性能不太可能下降。主要的缺点是生成推理步骤会增加输出的长度,从而导致更高的 token 使用量,这可能会增加成本和响应时间。

CoT 的最佳实践包括确保最终答案在推理步骤之后呈现,因为推理的生成会影响后续 token 的预测,从而影响答案的生成。此外,对于只有一个正确答案的任务(如数学问题),建议在使用 CoT 时将模型的温度设置为 0(贪婪解码),以确保每一步都能确定性地选择最可能的下一个 token。

自一致性(Self-Consistency)

基于链式思维的理念,自一致性技术旨在通过利用语言模型的概率特性来提高推理的可靠性。与依赖单一贪婪推理路径(如基本 CoT)不同,自一致性会为同一个问题生成多个不同的推理路径,并从中选择最一致的答案。

自一致性包括三个主要步骤:

  1. 生成多样化的推理路径: 使用同一个提示(通常是 CoT 提示)多次发送给 LLM。通过设置较高的温度,模型可以探索不同的推理方法并生成多样化的逐步解释。
  2. 提取答案: 从每个生成的推理路径中提取最终答案。
  3. 选择最常见的答案: 对提取的答案进行多数投票。选择在不同推理路径中出现频率最高的答案作为最终的最一致答案。

这种方法提高了响应的准确性和连贯性,特别适用于存在多种有效推理路径或模型在单次尝试中容易出错的任务。其优势在于提高了答案正确性的概率,整体准确性有所提升。然而,其显著的成本在于需要对同一查询运行多次模型,从而导致计算量和费用大幅增加。

  • 示例(概念性):
    • 提示: “‘所有鸟类都会飞’这一说法是正确还是错误?请解释你的理由。”
    • 模型运行 1(高温度): 论证大多数鸟类会飞,得出结论为“正确”。
    • 模型运行 2(高温度): 论证企鹅和鸵鸟,得出结论为“错误”。
    • 模型运行 3(高温度): 论证鸟类总体情况,简要提及例外情况,得出结论为“正确”。
    • 自一致性结果: 基于多数投票(“正确”出现两次),最终答案为“正确”。(注:更复杂的方法可能会权衡推理质量)。

回溯式提示(Step-Back Prompting)

回溯式提示通过首先要求语言模型考虑与任务相关的一般原则或概念,从而增强其推理能力。模型对这一广泛问题的回答随后被用作解决原始问题的上下文。

这一过程使语言模型能够激活相关的背景知识和更广泛的推理策略。通过关注底层原则或更高层次的抽象,模型能够生成更准确和更有洞察力的答案,减少受表面因素的影响。最初考虑一般因素可以为生成具体的创造性输出提供更强的基础。回溯式提示鼓励批判性思维和知识的应用,有可能通过强调一般原则来减轻偏见。

  • 示例:
    • 提示 1(回溯): “什么因素构成一个好的侦探故事?”
    • 模型回答 1: (列出红鲱鱼、引人入胜的动机、有缺陷的主角、逻辑线索、令人满意的结局等元素)。
    • 提示 2(原始任务 + 回溯上下文): “基于好的侦探故事的关键因素[插入模型回答 1],为一个发生在小镇上的新悬疑小说写一个简短的情节概要。”

思维树(Tree of Thoughts, ToT)

思维树(ToT)是一种扩展链式思维(Chain of Thought)的方法的高级推理技术。它使语言模型能够同时探索多个推理路径,而不是遵循单一的线性进程。这种技术利用树状结构,其中每个节点代表一个“思维”——一个作为中间步骤的连贯语言序列。从每个节点出发,模型可以分支,探索替代的推理路径。

ToT特别适合需要探索、回溯或在得出解决方案之前评估多种可能性的复杂问题。虽然比线性链式思维方法计算需求更高且实现更复杂,但ToT在需要深思熟虑和探索性问题解决的任务中可以取得更优异的结果。它使智能体能够考虑多样化的视角,并通过在“思维树”中调查替代分支来纠正初始错误。

  • 示例(概念性): 对于一个复杂的创意写作任务,例如“根据这些情节点设计三个不同的故事结局”,ToT将允许模型从关键转折点开始探索不同的叙事分支,而不是仅仅生成一个线性延续。

这些推理和思维过程技术对于构建能够处理超越简单信息检索或文本生成的任务的智能体至关重要。通过提示模型暴露其推理过程、考虑多种视角或回溯到一般原则,我们可以显著增强其在智能系统中执行复杂认知任务的能力。

行动与交互技术

智能体具备主动与环境交互的能力,超越了简单的文本生成。这包括使用工具、执行外部功能以及参与观察、推理和行动的迭代循环。本节探讨旨在实现这些主动行为的提示技术。

工具使用 / 函数调用

一个智能体的关键能力是使用外部工具或调用函数来执行超出其内部能力范围的操作。这些操作可能包括网页搜索、数据库访问、发送电子邮件、执行计算或与外部 API 交互。有效的工具使用提示设计需要设计能够指导模型在适当的时间和方法上使用工具的提示。

现代语言模型通常通过针对“函数调用”或“工具使用”进行微调。这使得它们能够理解可用工具的描述,包括工具的用途和参数。在接收到用户请求后,模型可以判断是否需要使用工具,识别适当的工具,并格式化调用所需的参数。模型本身并不直接执行工具操作,而是生成一个结构化的输出,通常是 JSON 格式,指定工具及其参数。一个智能体系统会处理这个输出,执行工具操作,并将工具的结果返回给模型,从而将结果整合到持续的交互中。

  • 示例:

    你可以访问一个天气工具,该工具可以获取指定城市的当前天气。工具名为 get_current_weather,并接受一个参数 city(字符串)。

    用户:伦敦现在的天气怎么样?

    • 预期模型输出(函数调用):

      {  
        "tool_code": "get_current_weather",  
        "tool_name": "get_current_weather",  
        "parameters": {  
          "city": "London"  
        }  
      }
      

ReAct(Reason & Act)

ReAct,即 Reason and Act,是一种提示设计范式,它将“思维链”式的推理与使用工具执行操作的能力相结合,以交替的方式进行。ReAct 模仿了人类的操作方式——我们通过语言进行推理,并采取行动以获取更多信息或朝目标迈进。

ReAct 模式涉及一个循环过程:

  1. 思考(Thought): 模型生成一个思考过程,解释其当前的理解和计划。
  2. 行动(Action): 基于思考,模型决定执行一个操作,通常是使用工具(例如搜索、计算器、API 调用)。它输出工具的名称及所需输入。
  3. 观察(Observation): 智能体系统执行工具操作,并将结果(观察)返回给模型。
  4. 循环继续: 模型基于最新的“观察”生成新的“思考”,从而引发进一步的“行动”和“观察”,直到任务完成,模型输出“最终答案”。

这种交替进行的思考与行动过程使智能体能够动态地收集信息、对工具输出作出反应并优化其方法,从而在需要与动态环境或外部知识源交互的任务中表现得特别有效。

  • 示例(ReAct 交互示例):

    用户:法国的首都是哪里?它的当前人口是多少?

    思考:用户在询问两个信息:法国的首都及其人口。我可以使用搜索工具来获取这些信息。我将首先确认首都,尽管我可能已经知道它。

    行动:Search({"query": "capital of France"})

    观察:巴黎

    思考:好的,首都是巴黎。现在我需要查找巴黎的人口。

    行动:Search({"query": "current population of Paris"})

    观察:2023 年巴黎的估计人口约为 210 万人。

    思考:我已经找到了两个信息,现在可以向用户提供最终答案。

    最终答案:法国的首都是巴黎,2023 年的估计人口约为 210 万人。

这些技术对于构建能够主动与世界互动、检索实时信息并执行需要与外部系统交互的任务的智能体至关重要。

高级技术

除了基础、结构和推理模式之外,还有一些其他提示技术可以进一步增强智能体系统的能力和效率。这些技术包括使用人工智能优化提示、整合外部知识以及根据用户特征定制响应。

自动提示工程(Automatic Prompt Engineering, APE)

鉴于设计有效的提示可能是一个复杂且需要反复迭代的过程,自动提示工程(APE)探索使用语言模型自身来生成、评估和优化提示。该方法旨在自动化提示编写过程,从而在无需大量人工设计提示的情况下提升模型性能。

其核心理念是使用一个“元模型”或流程,根据任务描述生成多个候选提示。这些提示会基于它们在给定输入集上生成的输出质量进行评估(可能使用诸如 BLEU 或 ROUGE 等指标,或者通过人工评估)。表现最佳的提示会被选中,可能进一步优化后用于目标任务。例如,使用大型语言模型(LLM)生成用户查询的变体以训练聊天机器人就是一个实际应用案例。

  • 示例(概念性): 开发者提供了一个描述:“我需要一个提示来提取电子邮件中的日期和发送者。”APE 系统生成了多个候选提示。这些提示在样本电子邮件上进行测试,最终选择能够一致性提取正确信息的提示。

当然,以下是对使用 DSPy 等框架进行程序化提示优化的重新表述和略微扩展的解释:

另一种强大的提示优化技术,尤其是由 DSPy 框架推广的技术,是将提示视为程序化模块,而不是静态文本,并对其进行自动优化。这种方法超越了手动的试错过程,进入了更系统化、数据驱动的方法领域。

该技术的核心依赖于两个关键组件:

  1. 黄金集(Goldset 或高质量数据集): 这是一个高质量的输入和输出对的代表性数据集,用于定义某项任务成功响应的“标准答案”。
  2. 目标函数(Objective Function 或评分指标): 这是一个自动评估 LLM 输出与数据集中对应“黄金”输出的函数,返回一个指示质量、准确性或正确性的得分。

借助这些组件,优化器(例如贝叶斯优化器)可以系统地优化提示。此过程通常涉及两种主要策略,可以单独使用或结合使用:

  • 少样本示例优化(Few-Shot Example Optimization): 优化器会程序化地从黄金集中抽取不同的示例组合,而不是由开发者手动选择少样本提示的示例。然后测试这些组合,以识别最能有效引导模型生成所需输出的示例集。

  • 指令性提示优化(Instructional Prompt Optimization): 在这种方法中,优化器会自动优化提示的核心指令。它使用 LLM 作为“元模型”,迭代地改变和重新措辞提示的文本——调整措辞、语气或结构,以发现哪种表达方式可以从目标函数中获得最高分。

这两种策略的最终目标是最大化目标函数的得分,从而有效地“训练”提示,使其生成的结果始终更接近高质量的黄金集。通过结合这两种方法,系统可以同时优化给模型的指令展示的示例,从而生成针对特定任务高度有效且经过机器优化的提示。

迭代提示 / 优化

这种技术涉及从一个简单的基础提示开始,然后根据模型的初始响应进行迭代优化。如果模型的输出不够理想,可以分析其不足之处并修改提示以解决问题。这更像是一个由人驱动的迭代设计循环,而非自动化流程(如 APE)。

  • 示例:
    • 尝试 1: "为一种新型咖啡机撰写产品描述。"(结果过于普通)。
    • 尝试 2: "为一种新型咖啡机撰写产品描述。突出其速度和易清洁的特点。"(结果有所改善,但缺乏细节)。
    • 尝试 3: "为‘SpeedClean Coffee Pro’撰写产品描述。强调其在2分钟内煮一壶咖啡的能力以及自清洁功能。目标用户为忙碌的职场人士。"(结果更接近预期)。

提供负面示例

虽然“指令优于约束”的原则通常是正确的,但在某些情况下,提供负面示例可能会有所帮助,但需谨慎使用。负面示例展示了模型一个输入和一个不希望的输出,或者一个输入和一个不应该生成的输出。这可以帮助明确边界或防止某些类型的错误响应。

  • 示例:

    生成巴黎热门旅游景点列表。不要包括埃菲尔铁塔。

    不应生成的示例:

    输入:列出巴黎的热门地标。

    输出:埃菲尔铁塔、卢浮宫、巴黎圣母院。

使用类比

通过类比来构建任务有时可以帮助模型理解期望的输出或过程,将其与熟悉的事物联系起来。这在处理创意任务或解释复杂角色时尤其有用。

  • 示例:

    扮演一名“数据厨师”。将原始食材(数据点)加工成一道“总结菜肴”(报告),为商业受众突出关键风味(趋势)。

分解认知 / 任务分解

对于非常复杂的任务,将整体目标分解为更小、更易管理的子任务并分别提示模型处理每个子任务可能更为有效。然后将这些子任务的结果结合起来以实现最终目标。这与提示链和规划相关,但强调问题的有意分解。

  • 示例:撰写研究论文:
    • 提示 1:"生成一篇关于人工智能对就业市场影响的论文的详细提纲。"
    • 提示 2:"根据以下提纲撰写引言部分:[插入提纲引言]。"
    • 提示 3:"根据以下提纲撰写‘对白领工作的影响’部分:[插入提纲部分]。"(对其他部分重复此操作)。
    • 提示 N:"将这些部分合并并撰写结论部分。"

检索增强生成(RAG)

RAG 是一种强大的技术,通过在提示过程中为语言模型提供外部的、最新的或领域特定的信息来增强其能力。当用户提出问题时,系统首先从知识库(例如数据库、一组文档、网络)中检索相关文档或数据。然后将检索到的信息作为上下文包含在提示中,使语言模型能够生成基于外部知识的响应。这减轻了模型产生幻觉的问题,并提供了模型未训练或非常近期的信息访问能力。这是智能体系统在处理动态或专有信息时的重要模式。

  • 示例:
    • 用户查询: "Python库‘X’最新版本有哪些新功能?"
    • 系统操作: 在文档数据库中搜索“Python库 X 最新功能”。
    • 提示给 LLM: "根据以下文档片段:[插入检索到的文本],解释 Python 库‘X’最新版本中的新功能。"

人物角色模式(用户角色):

虽然角色提示为模型分配了一个角色,但人格模式(Persona Pattern)则是描述用户或模型输出的目标受众。这有助于模型根据语言、复杂性、语气以及提供信息的类型来定制其响应。

  • 示例:

    你正在解释量子物理学。目标受众是一名没有该领域基础知识的高中生。请用简单的方式解释,并使用他们可能理解的类比。

    解释量子物理学:[插入基础解释请求]

这些高级和补充技术为提示工程师提供了进一步的工具,以优化模型行为、整合外部信息,并在智能体工作流中为特定用户和任务量身定制交互。

使用 Google Gems

Google 的 AI "Gems"(见图 1)是其大型语言模型架构中的一种用户可配置功能。每个 "Gem" 都是核心 Gemini AI 的一个专门实例,旨在完成特定的、可重复的任务。用户通过提供一组明确的指令来创建一个 Gem,这些指令建立了其操作参数。初始指令集定义了 Gem 的指定用途、响应风格和知识领域。底层模型设计为在整个对话过程中始终遵守这些预定义的指令。

这使得能够创建高度专业化的 AI 智能体,用于特定应用。例如,一个 Gem 可以被配置为仅引用特定编程库的代码解释器。另一个可以被指示分析数据集,生成没有推测性评论的摘要。还有一个 Gem 可以作为翻译工具,遵循特定的正式风格指南。这个过程为人工智能创建了一个持久的、任务特定的上下文。

因此,用户无需在每次新查询时重新建立相同的上下文信息。这种方法减少了对话冗余,提高了任务执行的效率。最终的交互更加专注,生成的输出始终与用户的初始需求保持一致。这一框架允许对通用 AI 模型应用细粒度的、持久的用户指令。最终,Gems 实现了从通用交互到专门预定义 AI 功能的转变。

图 1:Google Gem 使用示例。

图 1:Google Gem 使用示例。

使用 LLM 优化提示(元方法)

我们已经探讨了许多构建有效提示的技术,强调了清晰性、结构性,以及提供上下文或示例。然而,这一过程可能是迭代的,有时也具有挑战性。那么,如果我们能够利用大型语言模型(如 Gemini)的强大功能来帮助我们优化提示呢?这就是使用 LLM 优化提示的本质——一种“元”应用,AI协助改进我们给AI的指令。

这种能力尤其“酷”,因为它代表了一种 AI 自我改进的形式,或者至少是 AI 协助人类改进与 AI 交互的形式。与其完全依赖人类的直觉和反复试验,我们可以利用 LLM 对语言、模式,甚至常见提示问题的理解,来获得改进提示的建议。这使得 LLM 成为提示工程过程中的协作伙伴。

实际操作中如何实现?你可以向语言模型提供一个现有的提示(你希望改进的提示),同时说明你希望它完成的任务,甚至可以提供当前获得的输出示例(以及为什么它未能满足你的期望)。然后,你可以提示 LLM 分析该提示并提出改进建议。

像 Gemini 这样的模型,凭借其强大的推理和语言生成能力,可以分析现有的提示,找出潜在的模糊点、不够具体的地方或措辞效率低下的问题。它可以建议采用我们讨论过的技术,例如添加分隔符、明确所需的输出格式、建议更有效的角色设定,或推荐加入少量示例。

这种元提示方法的好处包括:

  • 加速迭代:比纯手动试错更快地获得改进建议。
  • 发现盲点:LLM可能会发现提示中的模糊性或潜在的误解点,而这些可能是你忽略的。
  • 学习机会:通过观察 LLM 提出的建议,可以更好地了解有效提示的构造方式,提升自己的提示工程技能。
  • 可扩展性:在处理大量提示时,可能自动化部分提示优化过程。

需要注意的是,LLM 的建议并非总是完美的,仍需像手动设计的提示一样进行评估和测试。然而,它提供了一个强大的起点,可以显著简化优化过程。

  • 提示优化示例:

    分析以下语言模型提示,并提出改进建议,以确保能够一致地从新闻文章中提取主要话题和关键实体(人物、组织、地点)。当前的提示有时会遗漏实体或错误地识别主要话题。

    现有提示:

    "总结主要内容,并列出这篇文章中的重要名字和地点:[插入文章文本]"

    改进建议:

在这个例子中,我们使用 LLM 对另一个提示进行批判和优化。这种元层级的交互展示了这些模型的灵活性和强大功能,使我们能够通过优化它们接收到的基本指令来构建更有效的智能体系统。这是一个引人入胜的循环,AI 帮助我们更好地与 AI 进行交流。

针对特定任务的提示

虽然前面讨论的技术具有广泛适用性,但某些任务需要特定的提示考虑。这在代码和多模态输入领域尤为重要。

代码提示

语言模型,尤其是那些经过大量代码数据集训练的模型,可以成为开发者强大的助手。代码提示涉及使用 LLM 来生成、解释、翻译或调试代码。以下是一些常见的使用场景:

  • 编写代码的提示:要求模型根据所需功能的描述生成代码片段或函数。
    • 示例:"写一个 Python 函数,该函数接收一个数字列表并返回平均值。"
  • 解释代码的提示:提供代码片段并要求模型逐行或总结性地解释其功能。
    • 示例:"解释以下 JavaScript 代码片段:[插入代码]。"
  • 翻译代码的提示:要求模型将代码从一种编程语言翻译为另一种语言。
    • 示例:"将以下 Java 代码翻译为 C++:[插入代码]。"
  • 调试和审查代码的提示:提供有错误或需要改进的代码,并要求模型识别问题、提出修复建议或提供重构建议。
    • 示例:"以下 Python 代码出现了 'NameError'。问题是什么,如何修复?[插入代码和错误信息]。"

有效的代码提示通常需要提供足够的上下文,明确指定所需的语言和版本,并清晰描述功能或问题。

多模态提示

虽然本附录及当前大部分的大型语言模型(LLM)交互都以文本为主,但该领域正迅速向多模态模型发展,这些模型能够处理并生成跨不同模态(文本、图像、音频、视频等)的信息。多模态提示涉及使用多种输入组合来引导模型。这意味着使用多种输入格式,而不仅仅是文本。

  • 示例: 提供一张图表的图像,并要求模型解释图表中显示的过程(图像输入 + 文本提示)。或者提供一张图片,并要求模型生成描述性标题(图像输入 + 文本提示 -> 文本输出)。

随着多模态能力变得更加复杂,提示技术也将不断发展,以有效利用这些组合输入和输出。

最佳实践与实验

成为一名熟练的提示工程师是一个需要持续学习和实验的迭代过程。以下是一些值得重申和强调的宝贵最佳实践:

  • 提供示例: 提供一个或少量示例是引导模型的最有效方法之一。
  • 设计简洁: 保持提示简明、清晰、易于理解。避免使用不必要的术语或过于复杂的措辞。
  • 明确输出要求: 清楚地定义模型响应的格式、长度、风格和内容。
  • 使用指令而非约束: 重点告诉模型您希望它做什么,而不是告诉它您不希望它做什么。
  • 控制最大令牌长度: 使用模型配置或明确的提示指令来管理生成输出的长度。
  • 在提示中使用变量: 对于应用中的提示,使用变量使其动态且可重复使用,避免硬编码具体值。
  • 尝试不同的输入格式和写作风格: 尝试以不同的方式措辞您的提示(问题、陈述、指令),并尝试不同的语气或风格,看看哪种方式效果最佳。
  • 对于分类任务的少样本提示,混合类别顺序: 随机化不同类别示例的顺序,以防止过拟合。
  • 适应模型更新: 语言模型会不断更新。准备好在新模型版本上测试现有提示,并进行调整以利用新功能或保持性能。
  • 尝试输出格式: 特别是对于非创意任务,尝试请求结构化输出,例如 JSON 或 XML。
  • 与其他提示工程师共同实验: 与他人合作可以提供不同的视角,并有助于发现更有效的提示。
  • 链式思维(CoT)最佳实践: 记住链式思维的具体实践,例如在推理之后放置答案,并在只有一个正确答案的任务中将温度设置为 0。
  • 记录各种提示尝试: 这对于跟踪哪些方法有效、哪些方法无效以及原因至关重要。维护一个结构化的记录,记录您的提示、配置和结果。
  • 将提示保存在代码库中: 在将提示集成到应用程序时,将它们存储在单独的、组织良好的文件中,以便于维护和版本控制。
  • 依赖自动化测试和评估: 对于生产系统,实施自动化测试和评估程序以监控提示性能,并确保其对新数据的泛化能力。

提示工程是一项通过实践不断提高的技能。通过应用这些原则和技术,并保持系统化的实验和文档记录方法,您可以显著提升构建有效智能体系统的能力。

结论

这个附录全面概述了提示工程,将其重新定义为一种严谨的工程实践,而不是简单的提问行为。其核心目的是展示如何将通用语言模型转化为专门的、可靠的、高效的工具,用于处理特定任务。整个过程始于不可或缺的核心原则,例如清晰、简洁和迭代实验,这些原则是与人工智能进行有效沟通的基石。这些原则至关重要,因为它们能够减少自然语言中的固有模糊性,帮助引导模型的概率输出朝向单一、正确的意图。在此基础上,零样本、单样本和少样本提示等基本技术作为主要方法,通过示例展示预期行为。这些方法提供了不同程度的上下文指导,有效地塑造了模型的响应风格、语气和格式。除了示例之外,通过明确角色、系统级指令以及清晰的分隔符来构建提示,为模型的精细化控制提供了必要的架构层。

在构建自主智能体的背景下,这些技术的重要性尤为突出,它们为复杂的多步骤操作提供了必要的控制和可靠性。为了让智能体有效地创建和执行计划,它必须利用诸如“思维链”(Chain of Thought)和“思维树”(Tree of Thoughts)等高级推理模式。这些复杂的方法促使模型外化其逻辑步骤,系统性地将复杂目标分解为一系列可管理的子任务。整个智能体系统的操作可靠性依赖于每个组件输出的可预测性。这正是为什么请求结构化数据(如 JSON)并使用诸如 Pydantic 等工具进行程序化验证,不仅仅是为了方便,而是实现可靠自动化的绝对必要条件。如果缺乏这种纪律性,智能体的内部认知组件将无法可靠地通信,从而导致自动化工作流中的灾难性失败。最终,这些结构化和推理技术能够成功地将模型的概率文本生成转化为智能体的确定性和可信赖的认知引擎。

此外,这些提示赋予智能体至关重要的能力,使其能够感知并作用于环境,弥合数字思维与现实世界交互之间的差距。以行动为导向的框架,例如 ReAct 和原生函数调用,是智能体的“手”,使其能够使用工具、查询 API 和操作数据。同时,诸如“检索增强生成”(Retrieval Augmented Generation,RAG)以及更广泛的“上下文工程”(Context Engineering)等技术则充当了智能体的“感官”。它们能够主动从外部知识库中检索相关的实时信息,确保智能体的决策基于当前的事实。这一关键能力防止了智能体在真空中运行,仅限于其静态且可能过时的训练数据。因此,掌握提示工程的全方位技术是将通用语言模型从简单的文本生成器提升为真正复杂的智能体的决定性技能,使其能够以自主性、感知力和智能完成复杂任务。

参考文献

以下是一些资源列表,可供进一步阅读和深入探索提示工程技术:

  1. Prompt Engineering, https://www.kaggle.com/whitepaper-prompt-engineering
  2. Chain-of-Thought Prompting Elicits Reasoning in Large Language Models, https://arxiv.org/abs/2201.11903
  3. Self-Consistency Improves Chain of Thought Reasoning in Language Models, https://arxiv.org/pdf/2203.11171
  4. ReAct: Synergizing Reasoning and Acting in Language Models, https://arxiv.org/abs/2210.03629
  5. Tree of Thoughts: Deliberate Problem Solving with Large Language Models, https://arxiv.org/pdf/2305.10601
  6. Take a Step Back: Evoking Reasoning via Abstraction in Large Language Models, https://arxiv.org/abs/2310.06117
  7. DSPy: Programming—not prompting—Foundation Models https://github.com/stanfordnlp/dspy

results matching ""

    No results matching ""