附录A:高级提示技术
引言:提示技术概述
提示,与语言模型交互的主要界面,是指构建输入以引导模型生成期望输出的过程。这包括构建请求、提供相关上下文、指定输出格式以及展示预期的响应类型。设计良好的提示可以最大化语言模型的能力,从而产生准确、相关和富有创意的响应。相比之下,设计不佳的提示可能导致模糊、不相关或错误的输出。
提示工程的目标是持续地从语言模型中获取高质量的反应。这需要了解模型的能力和局限性,并有效地传达预期目标。它涉及到通过学习如何最佳地指导它来与AI进行沟通的专长开发。
本附录详细介绍了各种超越基本交互方法的提示技术。它探讨了构建复杂请求、增强模型推理能力、控制输出格式以及整合外部信息的方法。这些技术适用于构建从简单聊天机器人到复杂多智能体系统等各种应用,并可以提高智能体应用的性能和可靠性。
智能体模式,即构建智能系统的架构结构,在主要章节中进行了详细阐述。这些模式定义了智能体如何规划、使用工具、管理记忆以及协作。这些智能体系统的有效性取决于它们与语言模型进行有意义交互的能力。
核心提示原则
语言模型有效提示的核心原则:
有效的提示建立在指导与语言模型沟通的基本原则上,这些原则适用于各种模型和任务复杂度。掌握这些原则对于持续生成有用且准确的结果至关重要。
清晰与明确性:指令应当清晰且精确。语言模型会解读模式;多种解释可能导致意外响应。定义任务、期望的输出格式以及任何限制或要求。避免使用模糊的语言或假设。不充分的提示会导致模糊和不准确的响应,阻碍有意义的输出。
简洁性:虽然明确性至关重要,但不应以牺牲简洁性为代价。指令应直接明了。不必要的文字或复杂的句子结构可能会混淆模型或掩盖主要指令。提示应简单明了;对用户来说难以理解的内容很可能对模型也是如此。避免使用复杂的语言和冗余信息。使用直接的表达方式和主动语态,以清楚地界定所需的行为。有效的动词包括:行动(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)以及细微的措辞变化都可能产生不同的结果。记录尝试对于学习和改进至关重要。实验和迭代是实现预期性能的必要手段。
这些原则构成了与语言模型有效沟通的基础。通过优先考虑清晰度、简洁性、行动动词、积极指令和迭代,建立了一个强大的框架,用于应用更高级的提示技术。
基本提示技巧
基于核心原则,基础技术为语言模型提供不同层次的信息或示例,以指导其回答。这些方法在提示工程中作为初始阶段,适用于广泛的应用范围。
零样本提示
零样本提示是最基本的提示形式,其中语言模型在没有任何期望输入输出对示例的情况下,被提供指令和输入数据。它完全依赖于模型的预训练来理解任务并生成相关响应。本质上,零样本提示由任务描述和初始文本组成,以开始这个过程。
何时使用: 零样本提示通常适用于模型在训练过程中很可能已经广泛接触过的任务,例如简单的问答、文本补全或对直接文本的基本摘要。这是首先尝试的最快方法。 示例: 您好,您好吗?
一次性提示
一次性提示涉及在展示实际任务之前,向语言模型提供单个输入示例及其对应的期望输出。这种方法作为初始演示,用以说明模型预期复制的模式。其目的是为模型提供一个具体的实例,使其能够作为模板,有效地执行给定任务。
何时使用: 当所需的输出格式或风格特定或较为少见时,单次提示非常有用。它为模型提供了一个具体的实例进行学习。对于需要特定结构或语调的任务,与零次提示相比,它可以提高性能。 示例: 将以下英文句子翻译成西班牙语: 谢谢。 西班牙语:'谢谢。'
西班牙语: 请。
少量样本提示
少量样本提示通过提供几个输入-输出对的示例来增强单次提示,通常为三到五个。这旨在展示更清晰的预期响应模式,提高模型复制此模式以对新输入进行响应的可能性。此方法提供多个示例,以引导模型遵循特定的输出模式。
- 适用场景: 少样本提示在需要遵循特定格式、风格或展现细微变化的输出任务中特别有效。它非常适合分类、具有特定模式的 数据提取或生成特定风格的文本等任务,尤其是在零样本或单样本提示无法产生一致结果时。通常情况下,使用至少三个到五个示例是一个经验法则,具体应根据任务复杂度和模型令牌限制进行调整。
- 示例质量和多样性的重要性: 少样本提示的有效性高度依赖于提供的示例的质量和多样性。示例应当准确、代表任务特点,并涵盖模型可能遇到的潜在变化或边缘情况。高质量的、撰写良好的示例至关重要;即使是微小的错误也可能使模型困惑,并导致不期望的输出。包括多样化的示例有助于模型更好地泛化到未见过的输入。
- 在分类示例中混合类别: 当使用少量样本提示进行分类任务(模型需要将输入分类到预定义的类别中)时,将不同类别的示例顺序混合是一种最佳实践。这可以防止模型可能过度拟合到特定示例序列,并确保模型学会独立识别每个类别的关键特征,从而在未见过的数据上实现更稳健和可泛化的性能。
- 向“多轮”学习的进化:随着现代LLM(大型语言模型)如Gemini在长上下文建模方面的增强,它们在利用“多轮”学习方面变得越来越高效。这意味着,通过在提示中包含更多的示例——有时甚至达到数百个——现在可以实现复杂任务的优化性能,从而使模型能够学习更复杂的模式。
示例: 请将以下电影评论分类为积极(POSITIVE)、中性(NEUTRAL)或消极(NEGATIVE):
评论:“表演出色,故事引人入胜。” 情感:积极
评论:“还可以,没什么特别的。” 情感:中性
评论:“我觉得剧情让人困惑,人物也不讨人喜欢。” 情感:负面
评论:“视觉效果令人惊叹,但对话较弱。” 情感:
理解何时应用零样本、单样本和少样本提示技术,以及精心构思和组织示例,对于提高智能体系统的有效性至关重要。这些基本方法构成了各种提示策略的基础。
结构化提示
在提供示例的基本技巧之外,你如何构建提示对引导语言模型起着至关重要的作用。构建提示涉及在提示中使用不同的部分或元素,以清晰有序的方式提供不同类型的信息,例如指令、上下文或示例。这有助于模型正确解析提示并理解每段文本的特定角色。
系统提示
系统提示为语言模型设定整体上下文和目的,定义其在交互或会话中的预期行为。这包括提供指令或背景信息,以建立规则、角色或整体行为。与特定用户查询不同,系统提示为模型的响应提供基础性指导。它影响模型在整个交互过程中的语气、风格和一般方法。例如,系统提示可以指示模型始终以简洁和有帮助的方式响应,或确保响应适合一般受众。系统提示还通过包括保持尊重性语言等指南,用于安全和毒性控制。
此外,为了最大限度地提高其有效性,系统提示可以通过基于LLM的迭代优化进行自动提示优化。例如,Vertex AI Prompt Optimizer这类服务通过根据用户定义的指标和目标数据进行系统性地改进提示,确保给定任务达到最高性能。
示例: 您是一位有益且无害的人工智能助手。请以礼貌和富有信息性的方式回答所有查询。不要生成有害、有偏见或不适当的内容。
角色提示
角色提示将特定的角色、人物或身份分配给语言模型,通常与系统或上下文提示结合使用。这涉及到指导模型采用与该角色相关的知识、语气和沟通风格。例如,如“扮演旅行指南”或“你是一位数据分析师专家”这样的提示,引导模型反映所分配角色的视角和专业知识。定义一个角色为语气、风格和专注的专业知识提供了一个框架,旨在提高输出的质量和相关性。在角色内也可以指定期望的风格,例如,“幽默且鼓舞人心的风格”。
示例: 作为一名经验丰富的旅行博主,我想向大家介绍罗马隐藏的瑰宝——那座位于宁静小巷深处,充满历史韵味的古老建筑。这里不仅保存着丰富的艺术珍品,更让人沉醉于那份静谧与时光的交错,仿佛穿越时空,回到了那个辉煌的年代。🏰🎨
使用分隔符
有效的提示涉及对指令、上下文、示例和语言模型输入的清晰区分。可以使用分隔符,如三重反引号(````),XML标签(
示例:*
<指令>总结以下文章,着重于作者提出的核心论点。</指令>
文章内容未提供,无法进行翻译。请提供需要翻译的英文文档内容。
[在此处插入文章全文]
</article>
上下文工程
上下文工程与静态系统提示不同,它动态地提供对任务和对话至关重要的背景信息。这些不断变化的信息有助于模型把握细微差别,回忆过去的交互,并整合相关细节,从而实现基于现实的回答和更流畅的交流。例如,包括之前的对话、相关文档(如在检索增强生成中),或特定的操作参数。例如,在讨论去日本旅行时,可能会要求提供东京的三个适合家庭的活动,利用现有的对话上下文。在智能体系统中,上下文工程是核心智能体行为(如记忆持久性、决策和子任务间的协调)的基础。具有动态上下文管道的智能体可以持续目标,调整策略,并与其他智能体或工具无缝协作——这些品质对于长期自主性至关重要。这种方法认为,模型输出的质量更多地取决于提供上下文的丰富程度,而不是模型架构。这标志着从传统的提示工程到重大转变,传统的提示工程主要关注优化即时用户查询的措辞。上下文工程扩大了其范围,包括多个层次的信息。
这些层包括:
- 系统提示: 定义AI操作参数的基本指令(例如:“你是一位技术文档编写者;你的语气必须正式且精确”)。
- 外部数据:
- 检索到的文档:从知识库中主动获取的信息,用于提供响应(例如,提取技术规范)。
- 工具输出: 智能体使用外部API获取实时数据(例如,查询日历以获取可用性)的结果。
- 隐式数据: 关键信息,如用户身份、交互历史和环境状态。引入隐式上下文会带来与隐私和道德数据管理相关的挑战。因此,对于上下文工程来说,强大的治理至关重要,尤其是在企业、医疗和金融等产业中。
核心原则是,即使是最先进的模型,如果对其操作环境的理解有限或构建不当,也会表现不佳。这种做法将任务从仅仅回答问题转变为为智能体构建全面的操作图景。例如,一个经过上下文工程化的智能体会整合用户的日程安排(工具输出)、与电子邮件收件人的专业关系(隐含数据)以及之前会议的笔记(检索到的文档)在回答查询之前。这使模型能够生成高度相关、个性化且具有实际应用价值的输出。所谓的“工程化”方面,包括创建健壮的管道在运行时获取和转换这些数据,并建立反馈循环以持续提升上下文质量。
为了实现这一点,可以采用专门的调优系统,例如谷歌的Vertex AI提示优化器,以大规模自动化改进过程。通过系统地评估响应与样本输入和预定义指标,这些工具可以提升模型性能,并在不同模型之间调整提示和系统指令,而无需进行大量的手动重写。向优化器提供样本提示、系统指令和模板,它就可以程序化地优化上下文输入,为复杂的上下文工程提供一种结构化的反馈循环实现方法。 这种结构化方法将基础的人工智能工具与更复杂、具有情境意识的系统区分开来。它将情境视为一个主要组成部分,强调智能体知道什么、何时知道以及如何使用这些信息。这种做法确保模型对用户的意图、历史和当前环境有全面的理解。最终,情境工程是将无状态的聊天机器人转变为高度能干、情境感知系统的关键方法。
结构化输出
通常,提示的目标不仅仅是获取自由形式的文本响应,而是提取或生成特定、机器可读的格式信息。请求结构化输出,如JSON、XML、CSV或Markdown表格,是一种关键的构建技术。通过明确要求以特定格式输出,并可能提供模式或所需结构的示例,您可以引导模型以易于解析和使用的方式组织其响应。对于数据提取,返回JSON对象是有益的,因为它迫使模型创建结构,并可以限制幻觉。对于非创造性任务,如数据提取或分类,建议尝试不同的输出格式。
示例: 从以下文本中提取以下信息,并以JSON对象的形式返回,键为"name"、"address"和"phone_number"。
{
"name": "John Doe",
"address": "123 Main Street, Anytown, USA",
"phone_number": "(555) 123-4567"
}
文本:请联系约翰·史密斯,地址为加州Anytown市123主街,或拨打联系电话(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模型中使用字段别名,您可以无缝地将XML中通常冗长或属性密集的结构映射到对象的字段上。
这种方法对于确保基于LLM的组件与更大系统其他部分的互操作性至关重要。当一个LLM的输出被封装在Pydantic对象中时,它可以被可靠地传递到其他函数、API或数据处理管道,确保数据符合预期的结构和类型。在系统组件边界处采用“解析而非验证”的实践,有助于构建更健壮和易于维护的应用程序。
有效地利用系统提示、角色分配、上下文信息、分隔符和结构化输出,可以显著提高与语言模型交互的清晰度、控制力和实用性,为开发可靠的智能体系统奠定坚实基础。请求结构化输出对于创建语言模型输出作为后续系统或处理步骤输入的管道至关重要。
在提供示例的基本技巧之外,您如何构建提示在引导语言模型方面起着至关重要的作用。构建提示涉及在提示中使用不同的部分或元素,以清晰有序的方式提供不同类型的信息,例如指令、上下文或示例。这有助于模型正确解析提示并理解每段文本的特定作用。
推理与思维过程技巧
大型语言模型在模式识别和文本生成方面表现出色,但往往在需要复杂、多步骤推理的任务中面临挑战。本附录重点关注旨在通过鼓励模型揭示其内部思维过程来增强这些推理能力的技巧。具体而言,它涉及提高逻辑推理、数学计算和规划的方法。
思维链(CoT)
思维链(CoT)提示技术是一种通过明确提示模型在得出最终答案之前生成中间推理步骤,从而提高语言模型推理能力的方法。您不是仅仅要求模型给出结果,而是指导模型“一步步思考”。这个过程与人类将问题分解为更小、更易于管理的部分并按顺序解决的方式相似。
CoT帮助LLM生成更准确的答案,尤其是对于需要某种形式计算或逻辑推理的任务,在这些任务中,模型可能会遇到困难并产生错误的结果。通过生成这些中间步骤,模型更有可能保持正确的方向并正确执行必要的操作。
CoT主要有两种变体:
- 零样本CoT(Zero-Shot CoT):这涉及在提示中简单地添加“让我们一步步思考”(或类似的表达)而不提供任何推理过程的示例。令人惊讶的是,对于许多任务来说,这个简单的添加可以通过触发模型暴露其内部推理轨迹的能力,显著提高模型的表现。
-
示例(零样本CoT): If a train travels at 60 miles per hour and covers a distance of 240 miles, how long did the journey take? Let's think step by step.
-
少样本CoT(Few-Shot CoT):这结合了CoT(概念到文本)与少样本提示。您向模型提供多个示例,其中展示了输入、逐步推理过程以及最终输出。这为模型提供了一个更清晰的模板,说明如何进行推理和构建其响应结构,通常比零样本CoT在更复杂的任务上获得更好的结果。
-
示例(少样本CoT): Q: The sum of three consecutive integers is 36. What are the integers?
A: Let the first integer be x. The next consecutive integer is x+1, and the third is x+2. The sum is x + (x+1) + (x+2) \= 3x + 3. We know the sum is 36, so 3x + 3 \= 36. Subtract 3 from both sides: 3x \= 33. Divide by 3: x \= 11. The integers are 11, 11+1=12, and 11+2=13. The integers are 11, 12, and 13.Q: Sarah has 5 apples, and she buys 8 more. She eats 3 apples. How many apples does she have left? Let's think step by step.
A: Let's think step by step. Sarah starts with 5 apples. She buys 8 more, so she adds 8 to her initial amount: 5 + 8 \= 13 apples. Then, she eats 3 apples, so we subtract 3 from the total: 13 - 3 \= 10. Sarah has 10 apples left. The answer is 10.
CoT具有多个优势。它相对容易实现,并且无需微调即可与现成的LLM高度有效。一个显著的好处是提高了模型输出的可解释性;您可以查看其遵循的推理步骤,这有助于理解为什么得出特定答案,并在出现问题时进行调试。此外,CoT似乎提高了不同版本语言模型提示的鲁棒性,这意味着当模型更新时,性能不太可能下降。主要缺点是生成推理步骤会增加输出的长度,导致更高的token使用量,这可能会增加成本和响应时间。
CoT的最佳实践包括确保在推理步骤之后呈现最终答案,因为推理的生成会影响答案后续标记的预测。此外,对于只有一个正确答案的任务(如数学问题),在应用CoT时建议将模型的温度设置为0(贪婪解码),以确保在每一步都确定性地选择最可能的下一个标记。
自我一致性
基于思维链的概念,自洽性技术旨在通过利用语言模型的概率性质来提高推理的可靠性。与基本思维链不同,自洽性技术不是依赖于单一的贪婪推理路径,而是为同一问题生成多个不同的推理路径,然后从中选择最一致的答案。
自洽性包含三个主要步骤:
- 生成多样化的推理路径: 相同的提示(通常是CoT提示)被发送给LLM多次。通过使用更高的温度设置,模型被鼓励探索不同的推理方法,并生成多样化的逐步解释。
- 提取答案: 最终答案从每个生成的推理路径中提取出来。
- 选择最常见的答案: 对提取出的答案进行多数投票。在多种推理路径中出现频率最高的答案被选为最终、最一致的答案。
这种方法提高了响应的准确性和连贯性,尤其是在存在多个有效推理路径或模型可能在单次尝试中容易出错的任务中。其优势是给出了答案正确性的伪概率可能性,从而提高了整体准确率。然而,显著的代价是需要对同一查询多次运行模型,导致计算和成本大幅增加。
示例(概念性): * 提示: “'所有鸟类都能飞'这个说法是真的还是假的?请解释你的推理。” * 模型运行1(高温): 关于大多数鸟类飞行的原因,得出结论为真实。 * 模型运行 2(高温): 关于企鹅和鸵鸟的原因,结论为错误。 * 模型运行3(高温): 关于鸟类的普遍原因,简要提及例外,结论为真。 * 自我一致性结果: 基于多数投票(True出现两次),最终答案是“True”。(注意:更复杂的方法会考虑推理质量)。
步骤回退提示
回溯提示通过首先要求语言模型考虑与任务相关的通用原则或概念,从而增强推理能力。然后,将对此更广泛问题的回答用作解决原始问题的上下文。
此过程允许语言模型激活相关的背景知识和更广泛的推理策略。通过关注基本原理或更高层次的抽象,模型可以生成更准确、更有洞察力的答案,减少受表面元素的影响。最初考虑一般因素可以为生成具体的创意输出提供更坚实的基础。回溯提示鼓励批判性思维和知识的应用,通过强调一般原则,可能有助于减轻偏见。
示例: * 提示1(回顾步骤): “哪些关键因素构成了一个好侦探故事?” * 模型响应1: (列出元素如转移注意力、强烈的动机、有缺陷的主角、逻辑线索、令人满意的结局)。 * 提示2(原始任务 + 回溯上下文): "结合优秀侦探故事的关键因素[插入模型响应1],为一个小镇背景的新悬疑小说撰写一个简短的情节摘要。"
思维树(ToT)
思维树(ToT)是一种高级推理技术,它扩展了思维链方法。该技术使语言模型能够同时探索多个推理路径,而不是遵循单一的线性进展。这种技术利用树状结构,其中每个节点代表一个“思维”——作为中间步骤的连贯语言序列。从每个节点出发,模型可以分支扩展,探索不同的推理路线。
ToT特别适用于需要探索、回溯或评估多种可能性以得出解决方案的复杂问题。虽然比线性思维链方法在计算上要求更高且实现更为复杂,但ToT在需要深思熟虑和探索性解决问题的任务上可以取得更优异的结果。它允许智能体考虑不同的观点,并通过在“思维树”中调查替代分支来从初始错误中恢复。
示例(概念性):对于像“根据这些情节点为故事发展三个不同的可能结局”这样的复杂创意写作任务,ToT将允许模型从关键转折点探索不同的叙事分支,而不仅仅是生成一条线性的延续。
这些推理和思维过程技术对于构建能够处理超越简单信息检索或文本生成的任务的智能体至关重要。通过提示模型展示其推理过程、考虑多个视角或退回到一般原则,我们可以显著提升它们在智能体系统中执行复杂认知任务的能力。
动作与交互技术
智能体具备与周围环境积极互动的能力,而不仅仅是生成文本。这包括使用工具、执行外部函数以及参与观察、推理和行动的迭代循环。本节将探讨旨在实现这些主动行为的提示技术。
工具使用 / 函数调用
智能体的一项关键能力是使用外部工具或调用函数来执行超出其内部能力范围的动作。这些动作可能包括网络搜索、数据库访问、发送电子邮件、执行计算或与外部API交互。有效提示工具使用的设计涉及制定指令,指导模型在何时以及如何使用工具。
现代语言模型通常会进行“函数调用”或“工具使用”的微调。这使得它们能够理解对可用工具的描述,包括其目的和参数。在接收到用户请求后,模型可以确定是否需要使用工具,识别合适的工具,并格式化调用该工具所需的参数。模型不会直接执行工具。相反,它生成一个结构化输出,通常是JSON格式,指定工具及其参数。然后,一个智能体系统处理这个输出,执行工具,并将工具的结果反馈给模型,将其整合到当前的交互中。
示例: 您可以使用一个获取指定城市当前天气的工具。该工具名为 'get_current_weather',并接受一个 'city' 参数(字符串)。
用户:伦敦现在的天气怎么样?
- 预期模型输出(函数调用):
{
"tool_code": "get_current_weather",
"tool_name": "get_current_weather",
"parameters": {
"city": "London"
}
}
ReAct(推理与行动)
ReAct,即“推理与行动”,是一种将思维链式推理与使用工具执行行动的能力相结合的提示范式。ReAct模拟了人类的行为方式——我们通过言语进行推理,并通过采取行动来收集更多信息或朝着目标迈进。
ReAct模式涉及一个循环:
思考过程:该模型生成一个思考过程,解释其当前的理解和计划。 2. 动作:基于思考,模型决定执行一个动作,通常使用一个工具(例如,搜索、计算器、API调用)。它输出工具的名称和所需的输入。 3. 观察结果: 智能体系统执行工具并提供结果(观察结果)回传给模型。 4. 循环继续,模型根据最新的“观察”生成一个新的“思考”,进而导致进一步的“行动”和“观察”,直到任务完成,模型输出“最终答案”。
这种思考和行动交织的过程允许智能体动态地收集信息、对工具输出做出反应,并优化其方法,使其特别适用于需要与动态环境或外部知识源交互的任务。
示例(说明性ReAct跟踪): 用户:法国的首都是哪里?目前的人口是多少?
思考:用户询问了两条信息:法国的首都及其人口。我可以使用搜索工具来查找这些信息。我将首先确认首都,尽管我可能已经知道了。 操作:搜索({"查询": "法国首都"}) 观察:巴黎
想法:好的,首都是巴黎。现在我需要找到巴黎的人口。 操作:搜索({"查询": "巴黎当前人口"}) 观察:据估计,2023年巴黎的人口约为210万人。
思考:我已经找到了这两条信息。我现在可以给出用户的最终答案了。 最终答案:法国的首都是巴黎,其2023年的人口估计约为210万人。
这些技术对于构建能够积极与世界互动、检索实时信息以及执行需要与外部系统交互的任务的智能体至关重要。
高级技术
除了基础、结构和推理模式之外,还有其他几种提示技术可以进一步提升智能体系统的能力和效率。这些技术包括利用AI优化提示、整合外部知识以及根据用户特征定制响应。
自动提示工程(APE)
认识到制定有效的提示可能是一个复杂且迭代的过程,自动提示工程(APE)探索使用语言模型自身来生成、评估和优化提示。这种方法旨在自动化提示编写过程,有望在不需要大量人工努力进行提示设计的情况下,提升模型性能。
总体思路是拥有一个“元模型”或一个过程,它接受一个任务描述并生成多个候选提示。然后根据这些提示在给定输入集上产生的输出质量(可能使用BLEU或ROUGE等指标,或人工评估)来评估它们。表现最佳的提示可以被选中,可能进一步优化,并用于目标任务。使用大型语言模型(LLM)生成用户查询的变体以训练聊天机器人就是一个例子。
示例(概念性):一位开发者提供描述:“我需要一个可以提取电子邮件中的日期和发送者的提示。”APE系统生成几个候选提示。这些提示在样本电子邮件上进行测试,并选择能够持续提取正确信息的提示。
当然。以下是使用DSPy等框架进行程序化提示优化的重新表述和略微扩展的解释:
另一种强大的提示优化技术,特别是由DSPy框架所推崇,是将提示视为不是静态文本,而是可以自动优化的程序模块。这种方法超越了手动试错,进入了一种更系统、数据驱动的方法论。
这项技术的核心依赖于两个关键组件:
- 高质数据集(或优质数据集):这是一组具有代表性的高质量输入-输出对。它作为“真实情况”定义了针对特定任务的成功响应应具备的特征。
- 目标函数(或评分指标): 这是一个自动评估LLM输出与数据集中相应“黄金”输出的函数。它返回一个分数,表示响应的质量、准确性或正确性。
使用这些组件,一个优化器,例如贝叶斯优化器,会系统地细化提示。这个过程通常涉及两种主要策略,这些策略可以单独使用或协同使用:
-
少样本示例优化: 与开发者手动选择少样本提示的示例不同,优化器会从金集中程序性地采样不同组合的示例。然后,它测试这些组合,以确定最有效地引导模型生成所需输出的特定示例集。
-
指令提示优化: 在这种方法中,优化器会自动细化提示的核心指令。它使用一个LLM(大型语言模型)作为“元模型”,通过迭代变异和重新措辞提示文本——调整措辞、语气或结构——来发现哪种措辞能从目标函数中获得最高的分数。
两种策略的最终目标都是最大化目标函数的得分,有效地“训练”提示词以产生结果,这些结果始终更接近高质量的金集。通过结合这两种方法,系统可以同时优化对模型给出的指令以及展示给它的示例,从而产生一个高度有效且稳健的提示词,该提示词针对特定任务进行了机器优化。
迭代提示/细化
这种技术涉及从一个简单、基本的提示开始,然后根据模型最初的响应进行迭代优化。如果模型的输出并不完全正确,您会分析其不足之处,并修改提示以解决这些问题。这更侧重于由人类驱动的迭代设计循环,而不是自动化过程(如APE)。
- 示例:
- 尝试1: “为一种新型咖啡机撰写产品描述。”(结果过于泛泛)。
- 尝试2: “为一种新型咖啡机撰写产品描述。突出其速度和清洁的便捷性。”(结果较好,但缺乏细节)。
- 尝试3: “为'SpeedClean Coffee Pro'撰写产品描述。强调其能在2分钟内煮好一壶咖啡以及其自清洁功能。针对忙碌的专业人士。”(结果更接近预期)。
提供负例
尽管“指令优于约束”的原则通常成立,但在某些情况下,提供负面示例可能会有所帮助,尽管使用时需要谨慎。负面示例向模型展示一个输入和一个不希望的输出,或者一个输入和一个不应该生成的输出。这有助于明确边界或防止特定类型的错误响应。
示例: 生成一份巴黎热门旅游景点列表,不包括埃菲尔铁塔。
示例:以下为不应该做的事情: 输入:列出巴黎的著名地标。 输出:埃菲尔铁塔,卢浮宫,巴黎圣母院大教堂。
使用类比
使用类比来设定任务有时可以帮助模型通过将其与熟悉的事物联系起来,理解所需的输出或过程。这对于创意任务或解释复杂角色特别有用。
示例: 扮演一位“数据厨师”。将原始食材(数据点)加工成一份“总结大餐”(报告),为商业受众突出关键风味(趋势)。
分解认知
对于非常复杂的任务,将整体目标分解成更小、更易于管理的子任务,并对每个子任务分别提示模型,可以非常有效。然后,将这些子任务的结果结合起来,以实现最终结果。这与提示链和规划有关,但强调了对问题的有意分解。
示例: 编写一篇研究论文: * 提示1: "生成一份关于人工智能对就业市场影响的论文详细提纲。" * 提示2:“根据以下大纲撰写引言部分:[插入大纲引言]。” * 提示3:“根据以下大纲撰写‘对白领工作的影响’部分:[插入大纲章节]。”(对其他章节重复此操作)。 * 提示 N: "合并这些部分并撰写一个结论。"
检索增强生成(RAG)
RAG是一种强大的技术,通过在提示过程中让语言模型访问外部、最新或特定领域的知识来增强其功能。当用户提出问题时,系统首先从知识库(例如,数据库、文档集合、网络)中检索相关文档或数据。然后,检索到的信息被包含在提示中作为上下文,使语言模型能够生成基于该外部知识的响应。这有助于减轻诸如幻觉等问题,并提供模型未训练或非常新的信息访问。这对于需要处理动态或专有信息的智能体系统来说是一个关键模式。
示例: * 用户查询: "Python库'X'的最新版本有哪些新特性?" * 系统操作: 在文档数据库中搜索“Python库X最新功能”。 * 提示给LLM: "根据以下文档片段:[插入检索到的文本],解释Python库'X'最新版本中的新特性。"
角色模式(用户角色):
在角色提示中,将一个角色分配给模型,而人格模式则涉及描述模型的输出针对的用户或目标受众。这有助于模型根据语言、复杂度、语气以及提供的信息类型来调整其响应。
示例: 你在解释量子物理学。目标受众是没有任何先验知识的中学学生。请用他们可能理解的类比简单解释。
解释量子物理:[请插入基本解释请求]
这些高级和补充技术为智能体工作流中模型行为优化、集成外部信息和针对特定用户和任务定制交互提供了更多工具。
使用谷歌Gem
谷歌的AI“宝石”(见图1)是其大型语言模型架构中的一个用户可配置功能。每个“宝石”都是核心Gemini AI的专用实例,针对特定、可重复的任务进行定制。用户通过向其提供一组明确的指令来创建一个“宝石”,这些指令确立了其操作参数。这个初始指令集定义了宝石的指定用途、响应风格和知识领域。底层模型旨在在整个对话过程中始终如一地遵守这些预先定义的指令。
这允许创建高度专业化的AI智能体,用于特定应用。例如,一个Gem可以被配置为仅引用特定编程库的代码解释器。另一个可以被指示分析数据集,生成不带推测性评论的摘要。另一个Gem可能作为遵循特定正式风格指南的翻译器。这个过程为人工智能创建了一个持久、特定任务的上下文。
因此,用户无需在每个新查询中重新建立相同的环境信息。这种方法减少了对话冗余,并提高了任务执行的效率。产生的交互更加专注,输出的结果始终与用户的初始需求保持一致。该框架允许将细粒度、持久化的用户指令应用于通用AI模型。最终,Gems使得从通用交互转向专门、预定义的AI功能成为可能。

图1:Google Gem使用示例。
使用大型语言模型(LLM)优化提示(Meta方法)
我们探索了多种构建有效提示的技术,强调清晰度、结构,并提供上下文或示例。然而,这个过程可能是迭代的,有时也颇具挑战性。如果我们能够利用像Gemini这样的大型语言模型的力量来帮助我们改进提示,那会怎么样呢?这就是使用LLM进行提示优化的本质——一种“元”应用,其中AI帮助优化提供给AI的指令。
这种能力特别“酷”,因为它代表了一种人工智能自我提升的形式,或者至少是人工智能辅助的人类在与人工智能互动中的提升。我们不再仅仅依赖人类的直觉和试错,而是可以利用LLM对语言、模式和甚至常见提示陷阱的理解,获得改进提示的建议。它将LLM转变为提示工程过程中的协作伙伴。
在实际操作中,这是如何工作的?您可以向语言模型提供一个现有的提示,您希望改进它,同时提供您希望模型完成的任务,甚至可以提供目前得到的输出示例(以及为什么它没有达到您的期望)。然后,您提示LLM分析该提示并提出改进建议。
类似Gemini这样的模型,凭借其强大的推理和语言生成能力,可以分析您现有的提示,找出潜在的模糊性、缺乏具体性或表达不高效的问题。它可以建议采用我们讨论过的技术,例如添加分隔符、明确所需的输出格式、建议更有效的角色,或推荐包含少量示例。
这种元提示方法的好处包括:
- 加速迭代: 比纯手工试错更快地获得改进建议。
- 识别盲点:大型语言模型(LLM)可能会发现您在提示中忽略的歧义或潜在误解。
- 学习机会: 通过观察LLM提出的建议类型,您可以了解更多关于什么使提示有效,并提高您自己的提示工程技能。
- 可扩展性: 可能在提示优化过程中自动化部分流程,尤其是在处理大量提示时。
需要注意的是,LLM的建议并不总是完美的,应该像任何手动编写的提示一样进行评估和测试。然而,它提供了一个强大的起点,并且可以显著简化细化过程。
示例细化提示: 分析以下针对语言模型的提示,并提出改进方法,以确保从新闻文章中持续提取主要主题和关键实体(人物、组织、地点)。当前的提示有时会遗漏实体或错误地识别主要主题。
现有提示: 总结本文的主要观点,并列出重要的人物和地点:[插入文章文本]
改进建议:
在这个例子中,我们使用LLM来批评和提升另一个提示。这种元级交互展示了这些模型的灵活性和强大功能,使我们能够通过首先优化它们接收的基本指令来构建更有效的智能体系统。这是一个令人着迷的循环,其中AI帮助我们更好地与AI交流。
提示特定任务
尽管迄今为止讨论的技术具有广泛的适用性,但某些任务会从特定的提示考虑中受益。这些考虑在代码和多模态输入领域尤为重要。
代码提示
语言模型,尤其是那些在大型代码数据集上训练的模型,可以成为开发者的强大助手。代码提示涉及使用大型语言模型(LLM)来生成、解释、翻译或调试代码。存在各种用例:
- 编写代码的提示词: 要求模型根据所需功能的描述生成代码片段或函数。
- 示例: "编写一个Python函数,该函数接收一个数字列表并返回平均值。"
- 解释代码的提示词: 提供一段代码片段,并要求模型逐行或以摘要形式解释其功能。
- 示例: "解释以下JavaScript代码片段:[插入代码]."
- 代码翻译提示: 要求模型将一种编程语言翻译成另一种编程语言。
- 示例: "将以下Java代码翻译为C++:[插入代码]."
- 用于调试和审查代码的提示: 提供存在错误或可改进的代码,并要求模型识别问题、提出修复建议或提供重构建议。
示例: "以下Python代码抛出了'NameError'错误。问题出在哪里?我该如何修复它?(请插入代码和错误追踪信息。)"
有效的代码提示通常需要提供充足的前置信息,明确指定所需的语言和版本,并对功能或问题表述清晰。
多模态提示
尽管本附录和当前许多大型语言模型(LLM)交互的焦点是文本的,但该领域正迅速向多模态模型发展,这些模型能够处理和生成跨不同模态(文本、图像、音频、视频等)的信息。多模态提示涉及使用多种输入来引导模型。这指的是使用多种输入格式,而不仅仅是文本。
示例: 提供一张图表的图片并要求模型解释图表中展示的过程(图像输入 + 文本提示)。或者提供一张图片并要求模型生成描述性的标题(图像输入 + 文本提示 -> 文本输出)。
随着多模态能力的日益复杂,提示技术将不断进化,以有效地利用这些结合的输入和输出。
最佳实践与实验
成为一名熟练的提示工程师是一个需要持续学习和实验的迭代过程。以下一些有价值的最佳实践值得反复强调和重视:
- 提供示例: 提供一个或几个示例是引导模型最有效的方法之一。
- 以简洁设计: 保持你的提示简洁、清晰且易于理解。避免使用不必要的行话或过于复杂的措辞。
- 明确输出要求: 明确定义模型响应的期望格式、长度、风格和内容。
- 以使用说明而非限制为主: 专注于告诉模型你想让它做什么,而不是不希望它做什么。
- 控制最大令牌长度: 使用模型配置或显式的提示指令来管理生成输出的长度。
- 在提示中使用变量: 对于在应用程序中使用的提示,使用变量使它们动态且可重复使用,避免硬编码特定值。
- 尝试不同的输入格式和写作风格: 尝试以不同的方式表述你的提示(问题、陈述、指令),并实验不同的语气或风格,以查看哪种方式能获得最佳结果。对于具有分类任务的少样本提示,混合不同类别的示例顺序以防止过拟合。
- 适应模型更新: 语言模型不断进行更新。请准备好在新的模型版本上测试现有的提示,并调整它们以利用新功能或保持性能。
- 尝试输出格式实验: 尤其是非创造性任务,可以尝试请求结构化输出,例如JSON或XML。
- 与其他提示工程师一起进行实验: 与他人合作可以提供不同的视角,并有助于发现更有效的提示。
- CoT最佳实践: 记住关于思维链的一些特定实践,例如将答案放在推理之后,以及对于只有一个正确答案的任务,将温度设置为0。
- 记录各种提示尝试: 这对于跟踪什么有效、什么无效以及原因至关重要。保持对您的提示、配置和结果的有序记录。
- 在代码库中保存提示词: 当将提示词集成到应用程序中时,将它们存储在单独且组织良好的文件中,以便于维护和版本控制。
- 依赖自动化测试和评估: 对于生产系统,实施自动化测试和评估流程,以监控提示性能并确保对新数据的泛化。
提示工程是一项随着实践而提高的技能。通过应用这些原则和技术,并保持对实验和文档的系统化方法,您可以显著提升构建有效智能体系统的能力。
结论
本附录提供了一个关于提示的全面概述,将其重新定义为一种纪律性的工程实践,而不仅仅是提问的行为。其核心目的是展示如何将通用语言模型转化为针对特定任务的专用、可靠且高度强大的工具。这一旅程始于不可协商的核心原则,如清晰、简洁和迭代实验,这些是有效与人工智能沟通的基石。这些原则至关重要,因为它们减少了自然语言中固有的歧义,有助于引导模型的概率输出指向单一、正确的意图。在此基础上,零样本、单样本和少样本提示等基本技术作为通过示例展示预期行为的主要方法。这些方法提供不同级别的上下文指导,有力地塑造了模型的响应风格、语气和格式。除了示例之外,通过明确的角色、系统级指令和清晰的分隔符来构建提示,为对模型进行精细控制提供了必要的架构层。
在构建自主智能体的背景下,这些技术的意义变得至关重要,因为它们提供了复杂、多步骤操作所必需的控制和可靠性。为了有效地创建和执行计划,智能体必须利用诸如思维链和思维树等高级推理模式。这些复杂的方法迫使模型将逻辑步骤外部化,系统地分解复杂目标为一系列可管理的子任务。整个智能体系统的运行可靠性取决于每个组件输出的可预测性。这正是为什么请求结构化数据如JSON,并使用Pydantic等工具进行程序性验证,不仅仅是一种便利,而是实现稳健自动化绝对必要的。没有这种纪律,智能体的内部认知组件无法可靠地沟通,导致自动化工作流程中的灾难性故障。最终,这些结构和推理技术成功地将模型的不确定性文本生成转化为智能体可确定和值得信赖的认知引擎。
此外,这些提示使得智能体具备了感知和对其环境做出反应的关键能力,弥合了数字思维与现实世界互动之间的差距。以ReAct和原生函数调用为导向的框架是智能体的关键机制,充当其双手,使其能够使用工具、查询API以及操作数据。与此同时,检索增强生成(RAG)技术和更广泛的领域——上下文工程,充当智能体的感官。它们能够主动从外部知识库中检索相关、实时的信息,确保智能体的决策基于当前的事实和现实。这种关键能力防止了智能体在真空状态下运作,否则它将仅限于其静态且可能过时的训练数据。因此,掌握这一完整的提示范围是提升通用语言模型从简单文本生成器到真正复杂智能体的决定性技能,使其能够自主、有意识、智能地执行复杂任务。
参考文献
以下是一份关于进一步阅读和深入探索提示工程技术的资源列表: