大型语言模型(LLM)是代理的认知核心。为了有效指挥这个核心,需要编写有效的指令,这些指令通常被称为“提示”。这些指令是您向代理的LLM传达任务、目标和操作指南的主要方式。就像给一个人明确的指引一样,向您的代理提供精确的指令对于它有效执行并达到预期成果非常必要。清晰沟通的重要性您提供给LLM代理的指令质量直接影响其行为及其行动的成功。模糊或不明确的指令很可能导致不可预测或不正确的结果。相反,精心编写的指令能引导LLM产生预期的回应和行为。这是使用LLM时的一个基本方面:它们本身并不知道您的具体意图;您必须通过提示来清晰表达。可以将LLM视为一位知识渊博、能力极强的助手,尽管如此,它仍需要精确的指示。它能编写、总结、翻译,甚至推理,但前提是它要明白您要求它做什么。设计和完善这些指令的做法通常被称为“提示工程”。虽然“工程”对于初学者来说可能听起来有些复杂,但它的核心在于清晰的沟通。有效指令的组成要素虽然具体的表述可能有所不同,但好的LLM代理指令通常具有几个共同的特点。理解这些要素将帮助您更有效地指导您的代理。清晰定义任务: 确切说明您希望代理做什么。模糊性是良好表现的大敌。不要说:“告诉我关于日程安排的事。”试试:“为一名修习数学、历史和编程三门课程的学生生成一份每周学习计划。该计划应在周一至周五上午9点到下午5点之间分配学习时间段。”指定所需输出格式(如果适用): 如果您需要特定结构的信息,请明确说明。这对于需要解析LLM输出的代理非常有用。不要说:“列出电动汽车的优缺点。”试试:“列出电动汽车的优缺点。以JSON对象形式提供答案,包含两个键:“pros”和“cons”。每个键应包含一个字符串列表,其中每个字符串代表一个优点或一个缺点。”提供背景信息: 向LLM提供执行任务所需的任何背景信息。如果没有足够的背景信息,LLM可能会做出不正确的判断。如果要求总结,请提供要总结的文本。如果要求编写代码,请指定编程语言和任何相关的库。示例:“您是Python编程助手。编写一个Python函数,该函数接受一个数字列表并返回它们的总和。函数应命名为calculate_sum。这是一个示例输入列表:[1, 2, 3]。”设置限制或边界: 如果代理必须遵循某些限制或规则,请将其包含在指令中。这有助于缩小可能性范围,并引导LLM产生预期的结果。“为一款新咖啡机编写产品描述。描述应不超过100字。”“将以下英文句子翻译成法文,使用正式的‘vous’而非非正式的‘tu’:‘How are you today?’”分配角色(可选但通常有益): 您可以要求LLM扮演特定角色或采用特定风格。这可以在很大程度上影响其回应的语气、风格和信息类型。“您是一位友好且鼓励人的健身教练。提供三个可以在办公桌前做的简单运动。”“扮演一位严谨的历史学家。描述第一次世界大战的主要原因,侧重于政治联盟。”让我们来看一下指令如何从您的意图流向代理的行动:digraph G { rankdir=TB; bgcolor="transparent"; node [shape=box, style="filled,rounded", fontname="sans-serif", margin=0.25, fillcolor="#e9ecef", color="#adb5bd"]; edge [fontname="sans-serif", color="#495057", fontsize=10]; subgraph cluster_user_input { label = "用户意图与编写"; style = "filled"; color = "#dee2e6"; bgcolor = "#f8f9fa"; UserGoal [label="1. 用户目标\n(例如,从文本中提取电子邮件地址)", shape=ellipse, fillcolor="#a5d8ff", color="#1c7ed6"]; Instruction [label="2. 编写的指令(提示)\n'您是数据提取专家。\n您的任务是找出所提供文本中\n所有的电子邮件地址。仅返回\n电子邮件地址列表,每个地址\n占一行。'", fillcolor="#b2f2bb", color="#37b24d", shape=parallelogram]; UserGoal -> Instruction [label="被制定为"]; } subgraph cluster_agent_core { label = "代理的内部处理"; style = "filled"; color = "#dee2e6"; bgcolor = "#f8f9fa"; LLM [label="3. 大型语言模型\n(代理的认知核心)", fillcolor="#ffec99", color="#f59f00"]; ProcessedOutput [label="4. LLM解释指令\n并生成回应\n(例如,“user@example.com\ntest@domain.org”)", fillcolor="#fcc2d7", color="#d6336c", shape=parallelogram]; LLM -> ProcessedOutput [label="处理并产生"]; } Instruction -> LLM [label="被发送到", lhead=cluster_agent_core, minlen=2]; AgentAction [label="5. 代理的行动/最终输出\n(例如,显示列表或用于\n后续任务)", shape=ellipse, fillcolor="#ffc078", color="#f76707"]; ProcessedOutput -> AgentAction [label="作为其依据"]; }该图显示了从用户目标到编写指令的路径,该指令随后由LLM解释。LLM的输出进而指导代理的最终行动。代理指令的基本结构对于初学者来说,采用一种简单、结构化的方法来编写指令会非常有益。这并非一个每次都必须遵循的僵化模板,而是一个有用的起始点:角色(人物设定): 清晰说明LLM应扮演的角色或人物设定。示例:“您是一位有益的烹饪助手。”任务/目标: 描述LLM需要完成的具体行动或目标。示例:“您的任务是根据我提供的食材列表推荐食谱。”背景/输入数据(如果有的话): 提供任何必要的信息、数据或背景。示例:“我有的食材是鸡肉、西兰花和米饭。”限制/输出格式: 指定任何限制、规则或对回应的期望格式。示例:“食谱应为一道主菜,准备时间少于45分钟,并以步骤列表的形式呈现。不要推荐需要烤箱的食谱。”将所有要素整合到一个简单任务中:假设我们希望代理识别句子中提到的编程语言。角色: “您是专注于软件开发的文本分析专家。”任务: “您的主要任务是识别并列出我提供的文本中提及的所有编程语言。”输入数据: “文本是:‘我正在学习Python进行网页开发,但我也有一些Java和JavaScript的经验。’”输出格式: “返回编程语言列表,每个语言占一行。如果未找到编程语言,则返回确切的短语‘未识别到编程语言。’”馈送给LLM的完整指令(提示)将是: “您是专注于软件开发的文本分析专家。您的主要任务是识别并列出我提供的文本中提及的所有编程语言。文本是:‘我正在学习Python进行网页开发,但我也有一些Java和JavaScript的经验。’返回编程语言列表,每个语言占一行。如果未找到编程语言,则返回确切的短语‘未识别到编程语言。’”有了这份清晰且结构化的指令,LLM就能够很好地产生预期的输出:Python Java JavaScript迭代:实现有效提示的途径很少能在第一次尝试时就写出完美的指令,特别是随着任务变得更加复杂。编写有效的指令通常是一个迭代过程:起草初始指令: 基于您对任务和上述要素的最佳理解。测试指令: 将其提供给您的代理(如果您是独立试验提示,也可以直接提供给LLM界面),并仔细观察输出。分析结果:代理是否正确执行了任务?输出是否为期望的格式?LLM是否似乎误解了指令的任何部分?是否存在任何意想不到的行为或错误?完善指令: 修改您的提示以解决发现的任何不足之处。这可能涉及使其更具体、添加或澄清背景、调整限制,或重新措辞可能模糊的部分。重复该过程: 继续测试和完善指令,直到代理始终按预期行事并可靠地产生所需的结果。这种起草、测试、分析和完善的循环是开发任何LLM驱动应用程序的基本组成部分,包括代理。如果您的最初提示没有立即产生完美结果,请不要气馁。每次迭代都能帮助您更好地理解LLM如何解释指令,并让您更接近一个能有效且可靠地指导代理的指令。掌握编写指令的艺术是构建有能力的LLM代理的一项基本技能。当我们后续章节中考察代理的其他组成部分,例如工具和内存时,您会看到这些指令如何演变以整合这些附加功能。这使得代理能够执行日益复杂的行动序列,所有这些都由您精心编写的提示所引发的“思考”所指导。