吴恩达 LLM Agent 工作流 Prompt 设计详解与实战指南
在深入研究和实测吴恩达提出的四种 Agentic 工作流过程中,我测试了包括反思(Reflection)、工具调用(Tool Use)、规划(Planning)以及多智能体(Multi-Agent)在内的多种框架。通过对这些框架中 Prompt 设计的深入学习与实践,我对大模型代理的工作机制有了更为深刻的认识。
核心原则:对于特定的任务来说,不存在万能的 Prompt,只存在一些通用的模式。要完成特定任务,必须结合该任务特有的 Example(示例)。此外,你需要通过强烈的指令引导(如使用 MUST、奖励机制等措辞)来强化模型的遵循度,这能显著提升大模型对指令的执行力。
如果你希望更好地达成目标,务必提供高质量的 Example。在测试各个框架的过程中,我发现没有任何一个成功的案例不包含 Example。虽然网上也有介绍 Zero Shot(零样本)的 Prompt 方法,例如经典的 Let's think step by step,但在面对稍微复杂点的任务时,它往往力不从心。它仅能做到分步思考,而非步步为营的严密推理。
一个精心设计且针对特定任务的 Prompt,大体需要包含以下几个关键部分:
- 解决任务的方法:明确告诉模型如何处理问题。
- 任务的输入和输出:定义清晰的数据边界。
- 任务的 Example:提供 3 到 5 个左右的典型样例,这是 Few-Shot 学习的核心。
- 任务的历史纪录:如果有的话,用于上下文记忆或反思。
- 用户输入的问题:当前的具体查询。
以下将详细解析四种 LLM Agentic 工作流的 Prompt 设计思路及最佳实践。
1. 规划 Prompt 设计案例
ReAct (Reasoning + Acting)
ReAct 提供了一种更易于人类理解、诊断和控制的决策和推理过程。它的典型流程可以用一个有趣的循环来描述:思考(Thought)→ 行动(Action)→ 观察(Observation),简称 TAO 循环。
- 思考(Thought):首先,面对一个问题,我们需要进行深入的思考。这个思考过程是关于如何定义问题、确定解决问题所需的关键信息和推理步骤。
- 行动(Action):确定了思考的方向后,接下来就是行动的时刻。根据我们的思考,采取相应的措施或执行特定的任务,以期望推动问题向解决的方向发展。
- 观察(Observation):行动之后,我们必须仔细观察结果。这一步是检验我们的行动是否有效,是否接近了问题的答案。
通过循环迭代以上流程,模型能够逐步逼近正确答案。这种结构有效地减少了幻觉,因为每一步行动都基于上一步的观察结果。
Prompt 设计要点:
Prompt 设计需包含说明解决问题的方法、输入和输出、样例和用户问题。以下是一个典型的 ReAct Prompt 模板:
用交替进行的"思考、行动、观察"三个步骤来解决问答任务。思考可以对当前情况进行推理,而行动必须是以下三种类型:
(1) Search[entity],在维基百科上搜索确切的实体,并返回第一个段落(如果存在)。如果不存在,将返回一些相似的实体以供搜索。
(2) Lookup[keyword],在上一次成功通过 Search 找到的段落中返回包含关键字的下一句。
(3) Finish[answer],返回答案并结束任务。
你可以采取必要的步骤。确保你的回应必须严格遵循上述格式,尤其是行动必须是以上三种类型之一。
以下是一些参考示例:
问题:科罗拉多造山运动东部地区的海拔范围是多少?
思考 1: 我需要搜索科罗拉多造山运动,找到科罗拉多造山运动东部地区的范围,然后找到该地区的海拔范围。
行动 1: 搜索 [科罗拉多造山运动]
观察 1: 科罗拉多造山运动是科罗拉多州及周边地区的一次造山运动(造山运动)。
思考 2: 它没有提到东部地区。所以我需要查找东部地区的信息。
...
(例子结束)
Question:{question}
{scratchpad}
CoT (Chain of Thought)
想让模型按照思维链这样的方式思考,你一定要给它 Example,并且针对特定的任务。我们看 Reflexion 框架中如何设计的 CoT 式 Prompt:
COT_AGENT_REFLECT_INSTRUCTION = """通过思考来解决问答任务,然后用你的答案完成任务。
思考可以推理当前情况。Finish[answer] 返回答案并完成任务。你将获得一些背景信息,你应该利用这些信息来帮助你回答问题。
以下是一些示例::
{examples}
(END OF EXAMPLES)
相关背景:{context}
问题:{question}{scratchpad}"""
Example 示例:
COT = """相关背景:尼罗河是世界上最长的河流,长度约为 6,650 公里(4,132 英里)。它流经东北非的十一国,包括埃及、苏丹和乌干干。
问题:世界上最长的河流是什么?
思考:这个问题询问世界上最长的河流,根据提供的背景信息,我知道是尼罗河。
行动:完成 [尼罗河]
..."""
CoT 的核心在于强制模型展示推理路径,这对于复杂逻辑任务至关重要。通过 Few-Shot 示例,模型可以学习到推理的模式和深度。
2. 反思 Prompt 设计案例
反思或者说精炼,是一种在现有问答基础上更进一步地指导模型进行自我优化和排除错误答案的过程。Reflexion 框架中设计的 Prompt 如下,让它能够根据历史纪录逐步排除选项,修正之前的错误。
Prompt 设计
你是一个能够通过自我反思来改进的高级推理代理。你将获得之前的推理测试流程,在之前的测试中你尝试访问 Docstore API 并回答了问题。由于你猜错了答案(使用了 Finish[<answer>]),或者用完了设定的推理步骤数,你未能成功回答问题。诊断失败的可能原因,并制定一个新的、简明的高级计划,旨在减轻同样的失败。要求必须使用完整的语句来回复。
这里有一些例子:
{examples}
之前的尝试:
问题:{question}{scratchpad}
反思:
Example 示例
之前的尝试:
问题:《罗马议定书》由三位总理签署,其中一位被暗杀是作为什么的一部分?
思考 1: 我需要搜索《罗马议定书》,找到这三位总理
...
行动 3: 完成 [第二次世界大战]
反思:我搜索了参与签署的一位总理,然后试图立即回答。我应该搜索每位总理,然后查看每位总理的'死亡'信息,以获取更多信息后再回答。
通过引入反思机制,Agent 不再是一次性生成答案,而是具备了纠错能力。这在处理高难度事实性问题时尤为有效,因为它允许模型从过去的失败中学习,调整策略。
3. 工具调用 Prompt 设计案例
如果你有大量的工具函数可能会被调用,但你显然无法将所有 Tools 发给 LLM,这可能会超过大模型的 Token 限制。你要怎么处理呢?一个简单的方法是采用分组,尽量将类似的函数组合到一起,然后再选择。
文章中有讨论,HuggingGPT 使用 HuggingFace 的模型进行推理任务。要知道在当时 HuggingFace 上有大约 673 个模型,其接口和任务描述大约 2765000 个字符,我们是不可能给它一次上传到 LLM 的。好在,HuggingFace 的模型是分类,分为 19 个类别,其中 15 个 NLP 任务类型,2 个 Audio 任务类型,3 个 CV 的任务类型。
关于任务描述的 Prompt 设计,通常包含了那句神奇的 Think step by step,以确保模型按顺序解析依赖关系:
任务必须从以下选项中选择:'token-classification'、'text2text-generation'、'summarization'、'translation'、'question-answering'、'conversational'、'text-generation'、'sentence-similarity'、'tabular-classification'、'object-detection'、'image-classification'、'image-to-image'、'image-to-text'、'text-to-image'、'text-to-video'、'visual-question-answering'、'document-question-answering'、'image-segmentation'、'depth-estimation'、'text-to-speech'、'automatic-speech-recognition'、'audio-to-audio'、'audio-classification'、'canny-control'、'hed-control'、'mlsd-control'、'normal-control'、'openpose-control'、'canny-text-to-image'、'depth-text-to-image'、'hed-text-to-image'、'mlsd-text-to-image'、'normal-text-to-image'、'openpose-text-to-image'、'seg-text-to-image'。可能存在多个相同类型的任务。逐步思考解决用户请求所需的所有任务。解析出尽可能少的任务,同时确保能够解决用户请求。注意任务之间的依赖关系和顺序。如果无法解析用户输入,你需要回复空 JSON [],否则必须直接返回 JSON。
参数完整性检查:
另外,在使用工具调用时候,由于大模型有时候会捏造参数,你一定要在 Prompt 中提示它不要捏造任何参数,如果未提供,请求用户提供,这需要针对不同模型多次尝试优化。可以在 System Prompt 中加入约束:
注意:严禁编造参数值。如果必要参数缺失,请明确指出需要用户补充,而不是自行填充默认值。
这种约束能有效减少因幻觉导致的工具调用失败。
4. 多智能体 Prompt 设计
多智能体为何有效,大概源于人类的分工合作思想。Prompt 如果设定过多的不同任务,很可能会导致大模型无法准确跟随指令,因此给不同的智能体设计专用的 Prompt 就能让它们工作的更高效。
合作使我们能够知道比我们自己所能知道的更多。它赋予我们不同的思维方式,让我们接触到原本无法获得的信息,并在我们共同努力实现共同目标的过程中将想法结合起来。
在多智能体系统中,通常包含以下几种角色:
- Manager/Planner:负责拆解任务,分配子任务给其他 Agent。
- Worker:负责执行具体的子任务,如搜索、计算、写作。
- Reviewer/Critic:负责审查 Worker 的输出,提出改进意见。
每个角色的 Prompt 都需要高度定制化。例如,Review Agent 的 Prompt 应侧重于批判性思维和标准对齐,而 Worker Agent 的 Prompt 应侧重于执行效率和准确性。
总结与最佳实践
综上所述,构建高效的 LLM Agent 系统,Prompt 工程是关键。以下是几点核心建议:
- 示例驱动:永远不要忽视 Example 的作用。Few-Shot 学习能显著提升模型在特定领域的表现。
- 结构化输出:明确指定输出的格式(如 JSON、Markdown 表格),便于后续程序解析。
- 思维链引导:对于复杂任务,强制模型展示推理过程(CoT/ReAct),能大幅降低逻辑错误率。
- 自我反思:引入反思机制,让模型有机会修正错误,提高最终结果的准确率。
- 工具管理:合理组织工具描述,避免 Token 溢出,并加强参数校验以防幻觉。
- 角色分离:在多智能体架构中,清晰的职责划分和专用 Prompt 是协作高效的基础。
通过灵活运用上述设计模式,开发者可以构建出更加智能、可靠且可控的 AI Agent 应用。