智能体设计模式-附录 A:高级提示词技巧

133 阅读47分钟

英文原地址:Appendix A: Advanced Prompting Techniques

提示词入门

提示(Prompting)是与语言模型交互的主要接口,即通过精心构造输入来引导模型生成期望输出的过程。这包括组织请求、提供相关上下文、指定输出格式,以及示范预期的响应类型。设计良好的提示可以最大化语言模型的潜力,产生准确、相关且富有创意的回答。相反,设计不佳的提示会导致含糊不清、不相关或错误的输出。

提示工程的目标是持续从语言模型中引出高质量的回应。这需要理解模型的能力与局限,并有效传达预期目标。它涉及通过学习如何最佳地指示 AI,从而发展与其沟通的专业能力。

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

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

核心提示词原则

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

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

清晰与具体: 指令应当明确且精确。语言模型基于模式进行解释;多重解释可能导致非预期的回应。定义任务、期望的输出格式,以及任何限制或要求。避免模糊语言或假设。提示不足会产生含糊且不准确的回答,妨碍生成有意义的输出。

简洁: 在确保具体性的同时不应牺牲简洁性。指令应当直截了当。多余措辞或复杂句式可能使模型困惑或掩盖主要指令。提示应简明;对用户造成困惑的内容对模型也可能造成困惑。避免复杂语言与冗余信息。使用直接措辞和主动动词清晰界定期望动作。有效动词包括: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。

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

指令优于约束: 正向指令通常比负向约束更有效。明确所需动作优于列出不该做的事。尽管约束在安全或严格格式化方面有其作用,过度依赖可能使模型聚焦于回避而非目标。以能够直接引导模型的方式来构建提示。正向指令符合人类的指导偏好并可减少困惑。

实验与迭代: 提示工程是一个迭代过程。识别最有效的提示需要多次尝试。从草稿开始,进行测试,分析输出,找出不足,并优化提示。模型的变体、配置(如 temperature 或 top-p)以及措辞的细微变化都可能产生不同结果。记录尝试对于学习与改进至关重要。为达到期望的性能,实验与迭代必不可少。

这些原则构成了与语言模型进行有效沟通的基础。通过优先考虑清晰、简洁、行动动词、正向指令和迭代,就能为应用更高级的提示技术建立一个稳固框架。

基础提示词技巧

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

零样本提示(Zero-Shot Prompting)

零样本提示是最基础的提示形式,向语言模型提供指令和输入数据,但不提供所需输入-输出对的任何示例。它完全依赖模型的预训练来理解任务并生成相关响应。本质上,零样本提示由任务描述和用于启动流程的初始文本组成。

适用场景: 当任务在模型训练中可能被大量接触过时,零样本提示通常已足够,例如简单的问答、文本补全,或对结构简单文本的基本摘要。这是最先尝试的最快方法。

示例:

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

单样本提示(One-Shot Prompting)

单样本提示是在呈现实际任务之前,向语言模型提供一个输入及其对应期望输出的示例。该方法作为初始演示,用以展示模型应当复现的模式。其目的在于为模型提供一个可用作模板的具体实例,以有效执行给定任务。

适用场景: 当期望的输出格式或风格较为特定或不常见时,单样本提示非常有用。它为模型提供了可学习的具体实例。对于需要特定结构或语气的任务,它相比零样本能提高表现。

示例:

将以下英文句子翻译成西班牙语:
英语:'Thank you.'
西班牙语:'Gracias.'

英语:'Please.'
西班牙语:

少样本提示(Few-Shot Prompting)

少样本提示在单样本提示的基础上提供若干示例,通常为三到五个输入-输出对。这旨在展示更清晰的期望响应模式,提高模型在新输入上复现该模式的可能性。该方法通过多个示例引导模型遵循特定的输出模式。

适用场景: 当目标输出需要遵循特定格式、风格或呈现细微差异时,少样本提示特别有效。它非常适合分类、具有特定模式的数据抽取,或以特定风格生成文本,尤其是在零样本或单样本无法产生一致结果时。一般经验法则是至少使用三到五个示例,并根据任务复杂度和模型的 token 限制进行调整。

示例质量与多样性的重要性: 少样本提示的有效性高度依赖于所提供示例的质量与多样性。示例应准确、能代表任务,并覆盖模型可能遇到的潜在变体或边界情形。高质量、书写良好的示例至关重要;即便是小错误也会混淆模型,导致不期望的输出。纳入多样化示例有助于模型更好地泛化到未见过的输入。

在分类示例中打乱类别顺序: 当将少样本提示用于分类任务(模型需要将输入归类到预先定义的类别)时,最佳实践是打乱来自不同类别的示例顺序。这样可防止模型对特定示例序列过拟合,并确保其能够独立识别各类别的关键特征,从而在未见数据上获得更稳健、可泛化的表现。

演进到“Many-Shot”学习: 随着现代 LLMs(如 Gemini)在长上下文建模方面变得更强,它们在利用“Many-Shot”学习上愈发高效。这意味着,对于复杂任务,现可通过在提示中直接包含数量更大的示例——有时甚至达数百个——来实现最佳表现,使模型得以学习更为复杂的模式。

示例:

将以下影评的情感分类为 POSITIVE、NEUTRAL 或 NEGATIVE:

评论:“表演十分出色,剧情引人入胜。”
情感:POSITIVE

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

评论:“我觉得情节令人困惑,角色也不讨喜。”
情感: NEGATIVE

评论:“画面视觉效果惊艳,但对白较为薄弱。”
情感:

理解何时应用零样本、单样本和少样本提示技术,并谨慎地设计和组织示例,对于提升智能体系统的有效性至关重要。这些基本方法为各种提示策略奠定了基础。

结构化提示词(Structuring Prompts)

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

系统提示(System Prompting)

系统提示为语言模型设定整体上下文和目标,定义其在一次交互或会话中的预期行为。这涉及提供建立规则、人物设定或整体行为的指令或背景信息。与具体的用户查询不同,系统提示为模型的回答提供基础性指导方针。它会在整个交互过程中影响模型的语气、风格和总体方法。例如,系统提示可以指示模型始终以简洁且有帮助的方式回应,或确保回答适合普通受众。系统提示还通过包含诸如保持尊重语言等准则,用于安全与有害性控制。

此外,为了最大化其效果,系统提示可以通过基于 LLM 的迭代优化进行自动提示优化。诸如 Vertex AI Prompt Optimizer 等服务通过依据用户定义的指标和目标数据系统性改进提示,从而确保针对特定任务获得尽可能高的性能。

示例:

你是一名乐于助人且无害的 AI 助手。以礼貌且信息丰富的方式回应所有查询。不要生成有害、带偏见或不当的内容。

角色提示(Role Prompting)

角色提示为语言模型分配特定的角色、人物或身份,通常与系统或情境提示结合使用。这涉及指示模型采用与该角色相关的知识、语气和沟通风格。例如,“充当旅行向导”或“你是一名资深数据分析师”等提示,引导模型体现所分配角色的视角与专业知识。定义角色为语气、风格和聚焦的专业性提供框架,旨在提升输出的质量与相关性。还可以在角色中指定期望的风格,例如“幽默且鼓舞人心的风格”。

示例:

充当经验丰富的旅行博主。写一段简短而吸引人的文字,介绍罗马最值得一去的隐藏宝地。

使用分隔符(Using Delimiters)

有效的提示应清晰地区分对语言模型的指令、上下文、示例和输入。可以使用分隔符(例如三重反引号(```)、XML 标签(<instruction>、<context>)或标记(---))在视觉和程序上将这些部分分开。这一在提示工程中广泛使用的做法可最大限度减少模型的误解,确保明确每个提示部分的角色。

示例:

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

<article>
[在此插入文章的全文]
</article>

上下文工程(Contextual Enginnering)

与静态的系统提示不同,Context engineering(上下文工程)动态提供对任务和对话至关重要的背景信息。这些不断变化的信息帮助模型把握细微差别、回忆过往交互并整合相关细节,从而产生更有依据的回复与更顺畅的交流。示例包括先前的对话、相关文档(如检索增强生成中的文档),或特定的运行参数。举例来说,当讨论日本旅行时,可以在现有对话上下文的基础上,请求“三项适合家庭的东京活动建议”。在具备智能体能力的系统中,上下文工程对记忆持久化、决策制定以及跨子任务协同等核心智能体行为至关重要。拥有动态上下文管线的智能体能够在较长时间跨度内维持目标、调整策略,并与其他智能体或工具无缝协作——这些能力是长期自主性的关键。该方法论认为,模型输出质量更多取决于所提供上下文的丰富度,而非模型本身的架构。这标志着从传统提示工程的重大演进——后者主要聚焦于优化用户即时提问的措辞。上下文工程将范围拓展到包含多层信息。

这些层包括:

  • 系统提示(System prompts): 定义 AI 运行参数的基础性指令(例如:“You are a technical writer; your tone must be formal and precise”)。
  • 外部数据(External data):
    • 检索文档(Retrieved documents):为生成回答而主动从知识库获取的信息(例如:拉取技术规格)。
    • 工具输出(Tool outputs):AI 通过外部 API 获取的实时数据结果(例如:查询日历以获取可用时间)。
  • 隐藏数据(Implicit data): 关键信息,如用户身份、交互历史与环境状态。纳入隐式上下文会带来与隐私与伦理数据管理相关的挑战。因此,在企业、医疗与金融等领域,上下文工程尤需健全的治理。

核心原则是,即使是先进模型,在对其运行环境的视角受限或构建不当时也会表现不佳。这一实践将任务从“仅回答问题”重构为“为智能体构建全面的运行图景”。例如,一个经过上下文工程的智能体会在回答查询前,整合用户日历可用性(工具输出)、与邮件收件人的职业关系(隐式数据)以及先前会议的笔记(检索文档)。这使模型能够生成高度相关、个性化且切实有用的输出。“工程”层面涉及在运行时构建健壮的管线以获取和转换这些数据,并建立反馈回路以持续提升上下文质量。

为实现这一点,可以使用专门的调优系统,如 Google 的 Vertex AI prompt optimizer,以规模化自动改进过程。通过依据样例输入与预定义指标对响应进行系统性评估,这些工具能够提升模型表现,并在不同模型间自适应地调整提示与系统指令,而无需大量手工重写。向优化器提供示例提示、系统指令与模板,便可使其以编程方式优化上下文输入,为实施面向复杂上下文工程所需的反馈回路提供结构化方法。

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

结构化输出(Structured Output)

通常,提示的目标不仅是获得自由形式的文本响应,而是以特定的、机器可读的格式提取或生成信息。请求结构化输出(如 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 构建面向对象的外观层: 一种强大的技术是使用 LLM 生成的数据来填充 Pydantic 对象实例,从而强制执行结构化输出并增强互操作性。Pydantic 是一个使用 Python 类型注解进行数据验证与配置管理的 Python 库。通过定义 Pydantic 模型,你可以为所需的数据结构创建清晰且可强制执行的模式。该方法有效地为提示的输出提供了一个面向对象的外观层,将原始文本或半结构化数据转换为经过验证、带类型提示的 Python 对象。

你可以使用 model_validate_json 方法将来自 LLM 的 JSON 字符串直接解析为 Pydantic 对象。这尤其有用,因为它将解析与验证合并为单步操作。

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

# --- Pydantic Model Definition (from above) ---
class User(BaseModel):
   name: str = Field(..., description="The full name of the user.")
   email: EmailStr = Field(..., description="The user's email address.")
   date_of_birth: Optional[date] = Field(None, description="The user's date of birth.")
   interests: List[str] = Field(default_factory=list, description="A list of the user's interests.")

# --- Hypothetical LLM Output ---
llm_output_json = """
{
   "name": "Alice Wonderland",
   "email": "alice.w@example.com",
   "date_of_birth": "1995-07-21",
   "interests": [
       "Natural Language Processing",
       "Python Programming",
       "Gardening"
   ]
}
"""

# --- Parsing and Validation ---
try:
   # Use the model_validate_json class method to parse the JSON string.
   # This single step parses the JSON and validates the data against the User model.
   user_object = User.model_validate_json(llm_output_json)

   # Now you can work with a clean, type-safe Python object.
   print("Successfully created User object!")
   print(f"Name: {user_object.name}")
   print(f"Email: {user_object.email}")
   print(f"Date of Birth: {user_object.date_of_birth}")
   print(f"First Interest: {user_object.interests[0]}")

   # You can access the data like any other Python object attribute.
   # Pydantic has already converted the 'date_of_birth' string to a datetime.date object.
   print(f"Type of date_of_birth: {type(user_object.date_of_birth)}")


except ValidationError as e:
   # If the JSON is malformed or the data doesn't match the model's types,
   # Pydantic will raise a ValidationError.
   print("Failed to validate JSON from LLM.")
   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 或数据处理流水线。在系统组件边界处践行“解析,而非验证”的实践,将带来更健壮、可维护的应用。

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

超越基本示例提供方法的提示结构化 在编写提示时,结构化方式在引导语言模型方面至关重要。结构化是指在提示中使用不同的部分或元素,以清晰、有条理的方式提供不同类型的信息,如指令、上下文或示例。这有助于模型正确解析提示,并理解每段文本各自的作用。

推理与思维过程技巧(Reasoning and Thought Process Techniques)

大型语言模型擅长模式识别和文本生成,但在需要复杂、多步推理的任务中常会面临挑战。本附录聚焦于通过鼓励模型显式展示其内部思考过程来增强推理能力的技术,特别针对提升逻辑推断、数学计算和规划等方面的方法。

思维链(Chain of Thought )

Chain of Thought(CoT)提示技术是一种强有力的方法,通过明确引导模型在得出最终答案前先生成中间推理步骤,从而提升语言模型的推理能力。与其仅仅询问结果,不如指示模型“逐步思考”。这一过程类似于人类将问题拆解为更小、更易处理的部分并按顺序逐一解决。

CoT 有助于 LLM 生成更准确的答案,尤其适用于需要某种计算或逻辑推理的任务——在这些任务中,模型否则可能会出现困难并产出错误结果。通过生成这些中间步骤,模型更可能保持思路一致,正确完成必要的操作。

CoT 主要有两种变体:

1. Zero-Shot CoT: 这仅需在提示中加入“让我们一步一步地思考。”(或类似表述),而不提供任何推理过程的示例。令人惊讶的是,对于许多任务,这一简单添加就能显著提升模型表现,因为它会触发模型显式展示其内部推理轨迹的能力。

如果一列火车以每小时 60 英里的速度行驶并覆盖了 240 英里的距离,这次旅程花了多长时间?让我们一步一步地思考。

2. Few-Shot 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 有几个优势。它实现成本相对较低,并且无需微调即可在现成的 LLMs 上非常有效。一个显著的好处是模型输出的可解释性增强;你可以看到它所遵循的推理步骤,这有助于理解它为何得到特定答案,并在出现问题时进行调试。此外,CoT 似乎还能提高提示在不同版本语言模型之间的稳健性,这意味着当模型更新时性能不太可能下降。主要缺点是生成推理步骤会增加输出长度,导致更高的 token 使用量,从而增加成本和响应时间。

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

Self-Consistency

在 Chain of Thought 的理念之上,Self-Consistency 技术旨在利用语言模型的概率特性来提高推理的可靠性。与依赖单一贪心推理路径(如基础 CoT)不同,Self-Consistency 为同一问题生成多条多样化的推理路径,然后从中选出最一致的答案。

Self-Consistency 包含三个主要步骤:

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

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

示例(概念性):

  • 提示: “‘所有鸟都会飞’这句话是真还是假?请解释你的理由。”
  • 模型运行 1(高温度): 基于大多数鸟会飞进行推理,结论为真。
  • 模型运行 2(高温度): 基于企鹅和鸵鸟进行推理,结论为假。
  • 模型运行 3(高温度): 从鸟类总体进行推理,简要提到例外,结论为真。
  • Self-Consistency 结果: 基于多数投票(“真”出现两次),最终答案为“真”。(注意:更复杂的方法会对推理质量进行加权)

Step-Back Prompting

Step-back 提示通过先让语言模型考虑与任务相关的一般原则或概念,再处理具体细节,从而增强推理能力。对这一更广泛问题的回答随后作为解决原始问题的上下文。

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

示例:

  • 提示 1(Step-Back): “一部优秀的侦探故事由哪些关键要素构成?”
  • 模型回应 1: (列出诸如“障眼法”“引人入胜的动机”“有缺陷的主角”“合乎逻辑的线索”“令人满意的结局”等要素)。
  • 提示 2(原始任务 + 退一步的上下文): “使用优秀侦探小说的关键要素[在此插入 Model Response 1],为一部以小镇为背景的新悬疑小说写一个简短的情节摘要。”

思维树(Tree of Thoughts)

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

ToT 尤其适用于需要探索、回溯或在得出结论前评估多种可能性的复杂问题。虽然相比线性的链式思维方法,它在计算上更昂贵、实现更复杂,但在需要深思熟虑与探索式问题解决的任务上,ToT 能取得更优结果。它允许智能体考虑多元视角,并通过在“思维树”中探索替代分支,从初始错误中潜在地恢复。

示例(概念性):

对于诸如“基于这些情节点为一个故事开发三种不同的可能结局”这样的复杂创意写作任务,ToT 将允许模型从关键转折点出发,探索不同的叙事分支,而不是仅生成一条线性的续写。

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

行动与交互技巧(Action and Interaction Techniques)

智能体具备主动与环境互动的能力,不仅限于生成文本。这包括使用工具、执行外部函数,以及参与观察—推理—行动的迭代循环。本节探讨旨在启用这些主动行为的提示技术。

工具使用(Tool Use) / 函数调用(Function Calling)

对于智能体来说,一个关键能力是使用外部工具或调用函数来执行超出其内部能力范围的操作。这些操作可能包括网页搜索、数据库访问、发送电子邮件、进行计算或与外部 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”的缩写,是一种提示范式,将类似思维链(Chain of Thought)的推理与使用工具执行操作的能力以交错方式结合。ReAct 模仿人类的工作方式——我们进行语言化推理,并采取行动以获取更多信息或朝着目标前进。

ReAct 模式包含一个循环:

  1. 思考(Thought): 模型生成思考过程,说明其当前理解和计划。
  2. 行动(Action): 基于思考,模型决定执行一个动作,通常使用某个工具(例如 Search、Calculator、API 调用)。它会输出工具名称以及所需的输入。
  3. 观察(Observation): 智能体系统执行该工具,并将结果(Observation)反馈给模型。
  4. 该循环继续进行,模型基于最新的“Observation”生成新的“Thought”,从而引发进一步的“Actions”和“Observations”,直至任务完成,模型输出“Final Answer”。

示例(用于说明的 ReAct 轨迹):

用户: 法国的首都是什么,以及它目前的人口是多少?

思考: 用户在询问两条信息:法国的首都以及其人口。我可以使用搜索工具来获取这些信息。我将先确认首都,尽管我大概率已经知道。
行动:Search({"query": "法国的首都"})
观察:巴黎

思考: 好的,首都是 Paris。现在我需要查找 Paris 的人口。
行动: Search({"query": "巴黎当前人口"})
观察: 2023年巴黎的人口估计约为210万人。

思考: 我已经找到了两条信息。现在我可以向用户提供最终答案。
最终回答: 法国的首都是 Paris,2023 年其估计人口约为 210 万人。

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

高级技巧

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

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

鉴于打造有效提示可能是一个复杂且迭代的过程,自动提示工程(APE)探索使用语言模型本身来生成、评估和优化提示。该方法旨在自动化提示撰写流程,有望在无需大量人工提示设计投入的情况下提升模型表现。

其一般思路是使用一个“元模型”或流程,接收任务描述并生成多个候选提示。随后依据这些提示在给定输入集上产生的输出质量进行评估(可使用诸如 BLEU 或 ROUGE 等指标,或进行人工评估)。表现最佳的提示将被选中,并可进一步精炼,用于目标任务。使用 LLM 为训练聊天机器人生成用户查询的多样化变体就是一个例子。

示例(概念性): 开发者提供描述:“我需要一个能从电子邮件中抽取日期和发件人的提示。”APE 系统生成若干候选提示。将其在示例邮件上测试,持续准确抽取正确信息的提示被选用。

当然。下面是对使用诸如 DSPy 等框架进行程序化提示优化的改写并略作扩展的解释:

另一种强大的提示优化技术(由 DSPy 框架特别倡导)是将提示视为可自动优化的程序化模块,而非静态文本。该方法超越了手工反复试错,转向更加系统化、数据驱动的方法论。

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

  • 黄金集(Goldset,或高质量数据集): 这是具有代表性的高质量输入-输出配对集合。它作为“基准真值”,定义了给定任务下成功响应的标准。
  • 目标函数(Objective Function,或评分度量): 这是一个将 LLM 的输出与数据集中对应的“黄金”输出进行自动评估的函数。它返回一个分数,用以指示响应的质量、准确性或正确性。

基于这些组件,优化器(如贝叶斯优化器)会系统地精炼提示。该过程通常涉及两种主要策略,可单独使用或协同配合:

  • 少样本示例优化: 与其由开发者手动为少样本提示选择示例,不如由优化器以编程方式从 goldset 中抽样不同的示例组合。随后对这些组合进行测试,以识别最能有效引导模型生成期望输出的特定示例集合。
  • 指令式提示优化: 在这种方法中,优化器会自动优化提示的核心指令。它使用 LLM 作为“元模型”,迭代地变异和改写提示文本——调整措辞、语气或结构——以发现哪种表述能从目标函数中获得最高分数。

这两种策略的最终目标都是最大化目标函数的得分,从而有效地“训练”提示,使其产出的结果持续更接近高质量的 goldset。通过结合这两种方法,系统可以同时优化应向模型给出的指令以及应展示的示例,从而得到一个针对特定任务进行机器优化的高效且稳健的提示。

迭代式提示/改进

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

示例:

尝试 1:“为一种新型咖啡机撰写产品描述。”(结果过于泛泛)。
尝试 2:“为一种新型咖啡机撰写产品描述。突出其速度快与易清洁的特点。”(结果更好,但缺乏细节)。
尝试 3:“为‘SpeedClean Coffee Pro’撰写产品描述。强调其在 2 分钟内即可煮好一壶咖啡以及其自清洁循环的能力。目标受众为忙碌的职场人士。”(结果更接近期望)。

提供负面示例

虽然“指令优于约束”的原则通常成立,但在某些情况下,谨慎地提供负面示例会有帮助。负面示例展示一个输入和一个不期望的输出,或一个输入与一个不应被生成的输出。这有助于明确边界或防止特定类型的错误响应。

示例:

生成一份巴黎热门旅游景点清单。不要包含埃菲尔铁塔。

不要这样做的示例:
输入:列出巴黎的著名地标。
输出:埃菲尔铁塔、卢浮宫、巴黎圣母院。

使用类比

通过将任务用类比来表述,可以把期望的输出或过程与熟悉的事物联系起来,帮助模型理解。这对创意类任务或解释复杂角色特别有用。

示例:

扮演一位“数据厨师”。将原材料(数据点)烹制成一份“总结菜肴”(报告),为商业受众突出关键风味(趋势)。

分解认知 / 任务分解

对于非常复杂的任务,将整体目标拆分为更小、更易管理的子任务,并分别对每个子任务进行提示会更有效。随后将子任务的结果组合起来以实现最终目标。这与提示链与规划相关,但强调对问题的有意识分解。

示例(撰写一篇研究论文):

为一篇关于 AI 对就业市场影响的论文生成详细提纲。
根据此提纲撰写引言部分:[插入引言提纲]。
根据此提纲撰写‘对白领工作的影响’部分:[插入章节提纲]。
[对其他章节重复此操作]
将这些部分合并并撰写结论。

检索增强生成(RAG)

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

示例:

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

人物设定模式(用户画像)

虽然角色提示是为模型指定一个人格,但人物设定模式是描述模型输出所面向的用户或目标受众。这有助于模型在语言、复杂度、语气以及提供信息的类型方面进行定制化。

示例:

你正在向一名没有任何相关基础的高中生解释量子物理。请用简单的方式讲解,并使用他们容易理解的类比。
解释量子物理:[插入基础解释请求]

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

使用 Google Gems

Google 的 AI “Gems”(见图 1)是在其大型语言模型架构中的用户可配置功能。每个 “Gem” 都是核心 Gemini AI 的一个专门实例,针对特定、可重复的任务进行定制。用户通过提供一组明确的指令来创建一个 Gem,从而确立其运行参数。这个初始指令集定义了 Gem 的指定目标、响应风格和知识领域。底层模型被设计为在整个对话过程中始终如一地遵循这些预定义指令。

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

因此,用户无需在每个新查询中反复建立相同的上下文信息。这种方法减少了对话冗余,并提高了任务执行效率。由此产生的交互更为聚焦,输出也能始终与用户最初的要求保持一致。该框架允许对通用型 AI 模型施加细粒度、持久的用户指令。最终,Gems 实现了从通用交互向专业化、预定义 AI 功能的转变。

图 1:Google Gem 用法示例。 unknown.png

使用 LLMs 优化提示词(元方法)

我们已经探讨了大量打造高效提示的技巧,强调清晰性、结构化,以及提供上下文或示例。然而,这个过程可能是迭代的,有时也较为困难。如果我们能利用大型语言模型(如 Gemini)的强大能力来帮助改进我们的提示,会怎样?这正是使用 LLMs 进行提示优化的本质——一种“元”应用,让 AI 协助优化给予 AI 的指令。

这种能力之所以特别“酷”,是因为它体现了一种 AI 自我改进,或至少是 AI 辅助的人类在与 AI 交互中的改进。我们不必仅靠人类的直觉和反复试错,而是可以利用 LLM 对语言、模式、以及常见提示陷阱的理解,来获得使提示更优的建议。它让 LLM 成为提示工程过程中的协作伙伴。

这在实践中如何运作?你可以向语言模型提供一个你正在尝试改进的现有提示,以及你希望它完成的任务,甚至可以提供你目前得到的输出示例(以及它为何达不到你的预期)。然后,你再提示 LLM 分析该提示并提出改进建议。

像 Gemini 这样具有强大推理和语言生成能力的模型,可以分析你现有的提示中潜在的歧义、缺乏具体性或措辞低效之处。它可以建议加入我们已讨论的技巧,例如添加分隔符、澄清期望的输出格式、提出更有效的人设,或建议包含少量示例(few-shot)。

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

  • 加速迭代: 比纯粹的手动试错更快地获得改进建议。
  • 盲点识别: LLM 可能会发现你在提示词中忽略的歧义或潜在的误解。
  • 学习机会: 通过观察 LLM 给出的建议类型,你可以更深入地了解有效提示词的要素,并提升自己的提示工程能力。
  • 可扩展性: 在处理大量提示词时,能够潜在地将提示优化流程的部分环节实现自动化。

需要注意的是,LLM 的建议并非总是完美的,和手动设计的提示一样,需要进行评估与测试。然而,它能提供一个有力的起点,并显著简化优化迭代过程。

用于优化的示例提示词:

请分析以下用于语言模型的提示词,并提出改进方法,使其能够稳定地从新闻文章中提取主旨和关键实体(人物、组织、地点)。当前提示词有时会漏掉实体或错误判定主旨。

现有提示词:
总结本文的要点,并列出文章中的重要人名和地名:[插入文章全文]

改进建议:

在这个例子中,我们让 LLM 批判并增强另一个提示词。这种元层面的交互展示了这些模型的灵活性与强大能力:通过先优化它们接收的基础指令,我们可以构建更高效的智能体系统。这是一个引人入胜的循环——AI 帮助我们更好地与 AI 对话。

为特定任务进行提示

尽管目前讨论的技术具有广泛适用性,但某些任务需要特定的提示考虑,尤其是在代码与多模态输入领域。

代码提示

语言模型,尤其是那些在大型代码数据集上训练的模型,可以成为开发者的强大助手。用于代码的提示涉及使用 LLMs 来生成、解释、翻译或调试代码。存在多种用例:

  • 用于编写代码的提示: 根据所需功能的描述,请求模型生成代码片段或函数。
    • 示例: “编写一个 Python 函数,接收一个数字列表并返回平均值。”
  • 用于解释代码的提示: 提供一段代码,并要求模型逐行或以摘要形式解释其作用。
    • 示例: “解释以下 JavaScript 代码片段:[插入代码]。”
  • 用于翻译代码的提示: 请求模型将一种编程语言的代码翻译为另一种。
    • 示例: “将以下 Java 代码翻译为 C++:[插入代码]。”
  • 用于调试和审查代码的提示: 提供存在错误或有改进空间的代码,并请求模型定位问题、提出修复建议或提供重构建议。
    • 示例: “以下 Python 代码抛出 ‘NameError’。问题出在哪里?如何修复?[插入代码和回溯]。”

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

多模态提示

尽管本附录和当前大量的 LLM 交互以文本为主,但该领域正迅速迈向能够在不同模态(文本、图像、音频、视频等)间处理与生成信息的多模态模型。多模态提示涉及使用多种输入来引导模型。这指的是使用多种输入格式,而不仅仅是文本。

示例:

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

随着多模态能力日益成熟,提示技术也会不断演进,以更有效地利用这些组合的输入和输出。

最佳实践与实验

成为一名熟练的提示工程师是一个迭代过程,涉及持续学习与实验。以下几条宝贵的最佳实践值得重申与强调:

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

提示工程是一项通过实践不断精进的技能。通过应用这些原则与技术,并保持系统化的实验与文档化方法,你可以显著提升构建高效自主体系统的能力。

总结

本附录提供了关于提示工程的全面概览,将其重新定位为一种有纪律的工程实践,而非简单的提问行为。其核心目的是展示如何将通用语言模型转化为面向特定任务的专业、可靠且高能力的工具。旅程始于不可妥协的核心原则,如清晰、简洁与迭代实验,它们是与 AI 高效沟通的基石。这些原则之所以关键,是因为它们能减少自然语言固有的歧义,帮助将模型的概率性输出引导至单一、正确的意图。在此基础上,零样本、单样本与少样本提示等基础技术,是通过示例展示期望行为的主要方法。这些方法提供不同层次的上下文引导,有力地塑造模型的回应风格、语气与格式。除了示例之外,使用明确的角色设定、系统级指令与清晰分隔符来结构化提示,为对模型进行精细化控制提供了必要的架构层。

在构建自主智能体的语境中,这些技术的重要性尤为凸显,因为它们为复杂的多步骤操作提供所需的可控性与可靠性。要使智能体有效地制定并执行计划,它必须利用链式思维(Chain of Thought)与树式思维(Tree of Thoughts)等高级推理模式。这些复杂方法促使模型将逻辑步骤外显,系统性地将复杂目标拆解为一系列可管理的子任务。整个自主体系统的运行可靠性取决于各组件输出的可预测性。正因如此,请求 JSON 等结构化数据,并使用诸如 Pydantic 的工具进行程序化校验,不仅是便利,更是实现稳健自动化的绝对必要条件。缺乏这种纪律性,智能体的内部认知组件将无法可靠通信,从而在自动化流程中导致灾难性失败。最终,这些结构化与推理技术,正是将模型的概率性文本生成转化为确定且可信的智能体“认知引擎”的关键。

此外,这些提示赋予智能体感知并作用于其环境的关键能力,架起了数字思维与现实交互之间的桥梁。像 ReAct 与原生函数调用这样的行动导向框架,充当智能体的“双手”,使其能够使用工具、查询 API 并操控数据。与此并行,检索增强生成(Retrieval Augmented Generation,RAG)及更广义的上下文工程则充当智能体的“感官”。它们主动从外部知识库检索相关的实时信息,确保智能体的决策以当前、事实的现实为基础。这一关键能力防止智能体在真空中运作,避免其局限于静态且可能过时的训练数据。因此,掌握完整谱系的提示技术,便是将通用语言模型从简单的文本生成器,提升为真正复杂的智能体的决定性技能,使其具备自主性、感知力与智能,能够胜任复杂任务。

参考资料

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