评估
好了,既然我们已经掌握了基础知识,现在就要进入中级阶段了。
我们将从一些非常枯燥的内容开始。但这正是区分业余爱好者和专业人士的关键所在:你如何衡量其性能。
有时,评估可以像计算输出正确的次数一样简单。如果我问我的客服聊天机器人我们是否有某种商品库存,它能正确回答吗
但并非一切都那么泾渭分明。让我们来思考一下我们的论文写作智能体。你如何衡量一篇论文是否真的
好
呢?
一种方法是使用第二个大语言模型(LLM)来评判输出结果。让它使用统一的评分标准,按照1到5的等级对每篇文章的质量进行评分。
按回车键或点击以查看全尺寸图像

你可以在组件层面评估你的系统,以确保每个单独的步骤都能正常运行,也可以进行端到端的评估,以判断整个系统的最终质量。
如果你发现系统的运行效果不如预期,第一步是检查中间步骤,这些步骤被称为追踪。这包括代理编写的搜索查询、草稿和思考步骤等内容。如果你仔细查看这些内容,可能会注意到一些模式,比如查询过于笼统,或者修订步骤没有正确传递批评意见。
这些观察结果将成为你的下一次评估或下一次修复。
重要的是,你要立即开始评估,但同时也不要一开始就担心要有一个完美的评估系统。你可以迅速让某些东西运转起来,然后随着时间的推移不断迭代。
内存
既然我们已经搭建了一个简单的系统,并且有了衡量性能的方法,现在是时候真正着手提高性能了。内存是实现这一目标的常见方法。
记忆能让智能体记住哪些方法有效、哪些失败了,以及下次该如何做出不同的行动,从而在每次运行中不断改进。智能体可能有短期记忆,用于在执行任务时记录工作内容。在多智能体系统中,其他智能体可以读取这些记录。智能体完成任务后,可以反思自己的行为,将结果与预期进行比较,找出哪些方面做得好、哪些方面做得不好,并将这些经验教训存储在长期记忆中。
下次运行时,它会加载这些经验教训并加以应用。
这可用于"训练"智能体,类似于监督学习。你可以就智能体的工作给予反馈,这样随着时间的推移,每次运行的质量都会有所提高。我将在本节末尾的演示中展示一个这样的例子。
因此,内存是动态的,每次运行时都会更新。而知识则是你预先加载的静态参考资料,如PDF、CSV、文档或对数据库的访问权限。你只需向代理提供一次,它在需要引用准确信息时就可以从该库中提取。
护栏
一旦我们为智能体配置好任务、知识和记忆,就可以让它大显身手了!对吧?
不完全对。有一个非常重要的步骤我们还没谈到。
由于大语言模型具有非确定性,它们可能会出错。也许它们会写出事实错误的内容,或者格式错误的内容。
为防止出现问题,我们需要为系统设置防护措施。
护栏基本上是代理声称已完成的事情与任务实际最终完成之间的质量关卡。
护栏主要有三种方法,大多数生产系统至少采用两种。
对于输出格式和长度等确定性内容,我们可以直接使用标准代码片段。这些代码片段速度快、成本低,在可能的情况下应优先使用。
按回车键或点击以查看全尺寸图像

有时我们会检查更细微的方面,比如"这个回答是否与来源在事实层面一致?"或者"语气是否积极且专业?"
按回车键或点击以查看全尺寸图像

在这种情况下,我们可以使用另一个大语言模型(LLM)来评判输出结果。如果大语言模型评判结果为"不,此输出失败",它会解释原因。该反馈会被发送回你的智能体,智能体随后进行修订并再次尝试。
最后,有时候你就是需要人来检查工作。
您可以让代理先暂停并请求批准,而不是让代理自动完成并发送结果。您可以提供反馈并要求代理再次尝试。
设计模式
好了,我们已经讲了很多关于如何让系统运行的内容。现在让我们来谈谈如何提高系统的质量。
有四种核心模式能够可靠地提升质量和能力:反思、工具使用、规划和多智能体协作。
让我们从最简单、最有效的方法开始:反思。
反射
简而言之,反思基本上就是指我们不会停留在初稿阶段。
当你使用反思时,模型会生成内容,对其进行评估,然后在需要时进行重写。第二次处理------由一个要求它找出并解决问题的提示引导------几乎总能让结果变得更好。
让我用一封电子邮件给你举个简单的例子。
版本1(初稿):"嘿,咱们下个月见面讨论这个项目。谢谢"
这有什么问题呢?日期含糊不清("下个月"),没有签名,而且"谢谢"显得很突兀。
反思步骤:模型读取v1并发现这些问题------时间线不清晰、缺少审批、语气显得仓促。
版本2(修订版):"嗨,亚历克斯,咱们1月5日至7日期间见个面,讨论一下项目时间表。告诉我你什么时候方便。祝好,玛丽娜"
这篇内容相同,但更简洁、更具体、更专业。
反射在代码中变得非常强大,因为你可以添加外部反馈。你可以编写代码,让一个审查代理对其进行审核,然后实际运行它。这使你能够捕捉错误、测试结果和输出,并将这些反馈给模型。模型可以利用这些具体信息生成更好的版本2。
按回车键或点击以查看全尺寸图像

当你有像JSON这样的结构化输出、像泡茶步骤这样的程序性指令(反思可以发现其中遗漏的步骤)、创造和长篇写作时,反思尤其有用。
特别是,当你能够纳入外部反馈时,反思效果会很好。比如对JSON运行模式验证器,或者在研究任务中检查是否有遗漏的引用。
缺点在于,由于要进行多次处理,它会增加延迟和成本。因此,务必对使用反射和不使用反射的情况都进行测试,以确保它确实有帮助。
工具使用
好了,让我们来谈谈第二种设计模式:工具使用。
核心思想是这样的:你给大语言模型(LLM)提供一个它可以调用的功能菜单。这些功能可以是网络搜索、数据库查询、代码执行、日历访问,或者任何你的应用程序所需要的功能。然后模型会决定何时以及使用哪些工具。
这很重要,因为大语言模型本身只是一个文本生成器。它不知道现在是什么时间,也不了解贵公司的销售数据。它无法执行代码来计算确切答案。
但如果你给它工具,它就能做一些事情,比如搜索网络、查询数据库、写入CRM或运行代码。
所以,如果我问代理"现在几点了?",大语言模型会调用 getCurrentTime() 函数,得到返回结果"3:20 PM",并以此进行回应。
按回车键或点击以查看全尺寸图像

或者我们可以要求它搜索当地餐厅、查询数据库或进行数学计算。在每种情况下,模型都会识别出它需要外部信息或计算,选择合适的工具,并利用结果进行回答。
当你为模型提供多个工具时,它可以将这些工具串联起来使用。例如,假设你正在构建一个日历助手。你已经公开了三个工具:checkCalendar(检查日历)、makeAppointment(创建预约)和deleteAppointment(删除预约)。
用户询问:"安排本周与爱丽丝的会议。"
模型会逐步思考:
-
查看我的日程安排以确认是否有空
-
找一个空闲时段 ------ 看起来周四下午3点可以
-
与爱丽丝在那个时间预约
-
向用户确认返回
按回车键或点击以查看全尺寸图像

这里的关键在于,大语言模型(LLM)会根据从之前工具输出中学到的内容,来选择接下来要调用的工具。这不是一个固定的流程------它是动态的。
好吧,但问题来了:大语言模型(LLMs)只会生成文本,它们不会执行代码。那么,它们如何"调用"函数呢?
实际上他们不会。他们
请求
一个函数调用。
下面是其背后的循环机制:
-
用户发送提示
-
大语言模型查看其可用工具,并决定是否需要使用其中一个
-
如果是,则输出一个特殊请求,如"我想调用getCurrentTime并指定时区为Pacific/Auckland"
-
你的代码接收到该请求,实际运行函数,并获取结果
-
你将该结果作为新的上下文反馈给大语言模型
-
大语言模型(LLM)使用它来完成回答,或者在需要时请求另一个工具
就这么简单。大语言模型(LLM)会请求但实际上并不执行代码。
设计优秀工具
为了让大语言模型(LLM)能够找到并请求工具,我们需要一种统一的方式来定义它们。每个工具都有两个部分:
- 代理的接口。这包括工具名称、何时使用该工具的纯英文描述以及类型化的输入模式。
例如:"ReadWebsiteContent",描述为"获取并返回网页的文本",有一个输入:url(字符串)。
- 以及实现代码。包括你需要的任何内容,如 SQL 查询、身份验证、重试、限流和解析。
代理只能看到接口。所有杂乱的实现细节都被隐藏起来了。
好的工具还会考虑错误处理、自我恢复和速率限制等因素。它们可能会使用缓存来记忆相同输入的结果,以减少延迟、成本和外部 API 负载。并且它们应该支持异步操作,以便在长时间的工具请求完成时,代理(或其他代理)可以继续工作。
工具应像产品一样构建,具备版本控制、完善的文档和充分的测试。维护一个内部的经过审核的工具注册表,包含文档、版本和所有权信息,是很有用的。
将所有这些结合起来,你现在就为你的智能体提供了一种与世界互动的方式。这很棒!但我们需要确保智能体知道在现实世界中需要做什么,这就引出了第三个设计模式:规划。
规划
规划的思路是这样的:与其硬编码一个固定的步骤序列,不如让大语言模型(LLM)来决定做什么以及按什么顺序做。
按回车键或点击以查看全尺寸图像

假设你正在为一家零售店构建一个客服代理。你可以为每种场景硬编码流程:"如果是价格问题,执行 X。如果是退货问题,执行 Y。如果是库存问题,执行 Z。"
但是当有人问了一个你没有预料到的问题时会发生什么?或者当同一个问题需要根据不同的情境采取不同的步骤时又该怎么办?
通过规划,你可以为智能体提供一个包含诸如获取商品描述、检查库存、获取商品价格、处理退货等功能的工具包,并让它自行决定使用哪些工具以及何时使用。
基本循环如下所示:
-
你授予代理访问工具的权限
-
你提示它制定一个计划:"列出回答这个问题的详细步骤"
-
你逐步执行计划------大语言模型选择合适的工具,你运行它,再将结果反馈回去
-
重复操作,直到完成
它基本上就是"计划→行动→观察→继续",只不过是借助你的工具来完成。
一个具体例子:零售太阳镜
用户询问:"有售价低于100美元的圆形太阳镜库存吗?"
代理可能会计划:
步骤1 :使用get_item_descriptions查找圆形镜框步骤2 :对该列表运行check_inventory步骤3 :对库存商品调用get_item_price并筛选出价格低于100美元的商品步骤4:整理答案
你没有预先定义这个确切的配方。大语言模型是从可用工具中选择的它。
现在出现了一个不同的问题:"我想退回我买的金色镜框太阳镜,不是金属镜框的。"
在这种情况下,计划会完全改变:
步骤 1 :识别用户之前的购买记录步骤 2 :匹配金边产品步骤 3 :调用 process_item_return步骤 4:确认结果
要求模型以JSON格式输出结构化计划可能会很有帮助。
按回车键或点击以查看全尺寸图像

或者,你可以让它编写实际的代码,通常是能将整个计划编码的 Python 代码。
按回车键或点击以查看全尺寸图像

规划中需要关注的事项
规划会增加自主性,这意味着它也会增加不可预测性。你需要在权限等方面设置防护栏,对工具调用进行验证,并管理将一个步骤的输出传递到下一个步骤。
如今,规划的最强用例是高度自主的编码系统。该模型将编程任务分解为多个步骤并逐步完成。
对于其他领域,规划绝对是有效的,但更难控制,因为你无法提前知道模型会制定出什么样的计划。不过,相关工具和保障措施正在迅速改进,采用率也在不断提高。
但是,如果你有一个系统,需要同时做很多不同的事情,那该怎么办呢?这就是多智能体协作发挥作用的地方。
多智能体
想想在现实生活中你会如何处理一个复杂的项目。你不会聘请一个超级通才来做所有事情。你会组建一个团队。团队中有擅长各自专业领域的专家,他们会相互交接工作。
多智能体系统借鉴了同样的思维方式。
每个智能体都有明确的角色。每个智能体都专注于自己擅长的领域。由于每一步都有专业化分工,因此输出结果更好。
除了专业化之外,多智能体系统还有其他一些优势:
-
它避免了任何一个智能体拥有巨大的上下文窗口。
-
你可以使用多个大语言模型(LLMs)。你可以混合使用速度更快、成本更低的模型来处理高容量的简单任务,同时保留更大、能力更强的模型用于需要精确性的任务,如制定策略、进行细致的客户回复或长篇写作。这让你在成本和性能两方面都具有灵活性。
-
你可以并行处理工作。
-
如果您有非常耗时的操作,可以将工作拆分,并查看哪些代理在处理什么任务,以帮助用户了解正在发生的事情。
如果您有简单的任务,请跳过多智能体系统。它们可能会拖慢速度,使调试更加困难。
这是因为多智能体系统引入了全新的复杂性层面。如果两个智能体试图修改同一个文件,就可能出现资源冲突,智能体之间存在通信开销,还有复杂的任务依赖关系。此外,还存在诸如 API 速率限制等问题,以及如果一个智能体失败该怎么办------其他智能体是继续执行还是回滚?还有,如何将多个智能体产生的结果整合为一个连贯的输出?
这并非无法管理,但你需要为此进行设计。你需要强大的编排、良好的错误处理,以及明确的代理通信协议。
多智能体系统设计
那么,让我们进一步探讨如何设计这些多智能体系统。让我们以创建营销手册为例,来说明我们的选择。
角色模型
第一步是按角色定义你的代理。每个代理都有明确的工作描述,并且只配备完成该工作所需的工具。
在我们的营销手册中,您可能会看到:
研究人员代理,负责发现市场趋势和竞争对手的动向。该代理可能具备网络搜索、检索工具,也许还有笔记记录功能。
图形设计师代理,使用图像生成、图像处理或代码执行工具创建图表和视觉资产以绘制图表。
以及一位撰写代理,它将调查结果和素材转化为最终文案。这个代理可以仅仅是大语言模型本身,无需外部工具。
按回车键或点击以查看全尺寸图像

你通过为每个智能体设定一个角色来实现它,比如"你是一个专门从事市场分析的研究智能体",并仅为其提供该角色应具备的工具。
一旦你定义了你的代理,你需要决定它们如何进行通信。我们将讨论四种主要模式,从最简单到最复杂。
模式1:顺序
这是最简单且最可预测的方式。每个代理完成其工作后,将输出传递给队列中的下一个代理。
按回车键或点击以查看全尺寸图像

在我们的宣传册中,流程可能是这样的:研究人员完成工作→交接给设计师→设计师完成工作→交接给文案撰写人员→完成。
这就像一条装配线。它易于调试,且时间和成本可预测。
这就是你应该开始的地方。根据你的使用场景,这可能就足够了。
模式2:并行
但顺序执行并非唯一选择。当步骤之间相互独立时,你还可以并行运行代理,这对于减少延迟非常有效。
按回车键或点击以查看全尺寸图像

例如,您的研究员和设计师可以同时在宣传册的不同独立部分开展工作,然后由文案撰写人员整合他们的成果。
这加快了事情的进展,但增加了协调的复杂性。
模式3:单一经理层级
如果您开始涉及更复杂的工作流程,添加一个负责规划和协调的管理代理可能会很有帮助。专业代理完成各自的工作后向管理代理汇报,而不是相互汇报。
按回车键或点击以查看全尺寸图像

这在给予您灵活性的同时,还能保持严格的控制。经理可以重新安排步骤、跳过不需要的内容,或者要求代理重新做工作。它比线性流程更具适应性,同时又不会混乱。
这可能是当今生产环境中多智能体系统里最常见的模式。
对于更复杂的工作流程,您可以拥有更深层次的层级结构,其中一些代理管理自己的子代理。
按回车键或点击以查看全尺寸图像

例如,您的研究员代理可能会协调网络研究员子代理和事实核查子代理。您的撰写员代理可能有风格撰写员和引用核查员在其之下工作。这对非常复杂的任务很有帮助,但当然也会增加一点混乱。
模式4:全对全(自由聊天)
最后,我们有全连接模型,它可能会超级混乱。在这个模型中,任何智能体都可以在任何时候向其他任何智能体发送消息。这种情况在实际生产中很少见,因为它难以预测和控制。每次运行的输出可能会有很大差异。
按回车键或点击以查看全尺寸图像

但它可以用于更具头脑风暴性、创造性或低风险的任务。比如生成广告文案的多个变体,在这种情况下,如果一次运行产生了无用的内容,你可以直接再试一次。
协调陷阱
我们已经多次讨论过协调方面的挑战。以下是两个最常见的陷阱。
首先是冗余工作。多个智能体可能会重复进行相同的搜索或调用相同的工具。这可以通过收紧任务范围并在智能体之间进行明确的分工来解决。
第二,不必要的序列化。将本可并发运行的步骤串联起来会拖慢一切。为解决这个问题,应识别真正独立的任务并异步运行它们,然后仅传递下一步所需的上下文片段。
一般来说,你会希望从最简单的协调方法开始,仅在必要时增加复杂性。
最佳实践
无论你选择哪种模式,在设计系统时,都要牢记以下四个关键的最佳实践:
- 定义接口,而非氛围。
每个代理都需要一个清晰的输入和输出模式。它需要了解诸如:有哪些字段?是什么类型?传递哪些ID或引用?
交接环节比模型更容易出问题。如果研究人员返回的是一个无结构的数据块,而设计师又不知道如何解析,整个系统就会失败。
- 每个代理的范围工具。
只给每个代理提供其实际需要的工具。最小权限访问。
这有助于提高安全性,使系统更易于推理、审计和调试。
- 记录跟踪信息。
保留每一步的工件。每个智能体计划做什么?它使用了哪些提示?它进行了哪些工具调用?返回了什么结果?
当出现故障时,这种跟踪能快速进行错误分析。你可以准确地看到问题出在哪里。
- 评估组件和端到端
你需要两种类型的评估:
组件层面:研究是否相关?图片质量是否高?文案语气是否合适?
端到端:最终的宣传册是否令人满意?是否符合要求?
如果你的端到端评估显示存在问题,但各个组件评估都看起来正常,你就知道这是交接或集成问题。如果某个特定组件评估失败,你就知道该改进哪个代理。