第03课-Agent构建指南


文档摘要

目录 什么是智能体? 何时应该构建智能体? 智能体设计基础 防护措施 结论 引言 大型语言模型处理复杂、多步骤任务的能力日益增强。推理、多模态和工具使用方面的进展催生了一类新的由大语言模型驱动的系统,即智能体。 本指南专为探索如何构建首个智能体的产品和工程团队而设计,将众多客户部署中的见解提炼为实用且可行的最佳实践。它涵盖了识别有前景用例的框架、设计智能体逻辑和编排的清晰模式,以及确保智能体安全、可预测且高效运行的最佳实践。 阅读本指南后,您将具备自信开启首个智能体构建所需的基础知识。 什么是智能体? 传统软件使用户能够简化和自动化工作流程,而智能体则能够在高度自主的情况下代表用户执行相同的工作流程。 智能体是代表您独立完成任务的系统。

目录

  • 什么是智能体?
  • 何时应该构建智能体?
  • 智能体设计基础
  • 防护措施
  • 结论

引言

大型语言模型处理复杂、多步骤任务的能力日益增强。推理、多模态和工具使用方面的进展催生了一类新的由大语言模型驱动的系统,即智能体。

本指南专为探索如何构建首个智能体的产品和工程团队而设计,将众多客户部署中的见解提炼为实用且可行的最佳实践。它涵盖了识别有前景用例的框架、设计智能体逻辑和编排的清晰模式,以及确保智能体安全、可预测且高效运行的最佳实践。

阅读本指南后,您将具备自信开启首个智能体构建所需的基础知识。

什么是智能体?

传统软件使用户能够简化和自动化工作流程,而智能体则能够在高度自主的情况下代表用户执行相同的工作流程。

智能体是代表您独立完成任务的系统。工作流程是为实现用户目标而必须执行的一系列步骤,无论是解决客户服务问题、预订餐厅、提交代码更改还是生成报告。

集成了大语言模型但未利用其控制工作流程执行的应用程序(如简单聊天机器人、单轮大语言模型或情感分类器)不属于智能体。

更具体地说,智能体具备以下核心特征,使其能够可靠且一致地代表用户行事:

  1. 利用大语言模型管理工作流程执行并做出决策:它能识别工作流程何时完成,必要时可主动纠正行动。若出现故障,它可以停止执行并将控制权交回给用户。
  2. 可访问各种工具与外部系统交互:既能收集上下文信息,也能采取行动,并根据工作流程的当前状态动态选择合适的工具,且始终在明确定义的防护措施范围内运行。

何时应该构建智能体?

构建智能体需要重新思考系统如何做出决策以及处理复杂性。与传统自动化不同,智能体特别适用于传统确定性和基于规则的方法难以奏效的工作流程。

以支付欺诈分析为例。传统的规则引擎就像一个清单,根据预设标准标记交易。相比之下,大语言模型智能体的功能更像一位经验丰富的调查员,评估上下文、考虑微妙模式,即使未违反明确规则也能识别可疑活动。这种细致入微的推理能力正是智能体有效管理复杂、模糊情况的关键所在。

在评估智能体能够增加价值的领域时,优先考虑那些此前难以实现自动化的工作流程,尤其是传统方法遭遇阻碍的流程:

序号 类型 描述
01 复杂决策 涉及细致判断、例外情况或上下文敏感决策的工作流程,例如客户服务工作流程中的退款审批。
02 难以维护的规则 因规则集广泛且复杂而变得难以处理的系统,更新成本高昂或容易出错,例如进行供应商安全审查。
03 严重依赖非结构化数据 涉及解释自然语言、从文档中提取含义或与用户进行对话交互的场景,例如处理家庭保险理赔。

在致力于构建智能体之前,请确认您的用例能够清晰满足这些标准。否则,确定性解决方案可能就已足够。

智能体设计基础

智能体最基本的形式由三个核心组件组成:

序号 组件 描述
01 模型 为智能体的推理和决策提供动力的大语言模型
02 工具 智能体可用于采取行动的外部函数或应用程序编程接口
03 指令 定义智能体行为的明确指南和防护措施

以下是使用 OpenAI 的智能体软件开发工具包(SDK)时在代码中的呈现方式。您也可以使用您喜欢的库或直接从零开始实现相同的概念。

weather_agent = Agent( name="Weather agent", instructions="You are a helpful agent who can talk to users about the weather.", tools=[get_weather], )

选择模型

不同的模型在任务复杂性、延迟和成本方面各有优劣。正如我们将在接下来关于“编排”的部分中看到的,您可能需要考虑为工作流程中的不同任务使用多种模型。

并非每个任务都需要最强大的模型。简单的检索或意图分类任务可以由较小、速度更快的模型处理,而诸如决定是否批准退款等更困难的任务可能得益于更强大的模型。

一种有效的方法是使用每个任务最强大的模型构建智能体原型,以建立性能基线。从那里开始,尝试替换为较小的模型,看看它们是否仍能取得可接受的结果。这样,您不会过早限制智能体的能力,并且可以诊断较小模型在哪些方面成功或失败。

总之,选择模型的原则很简单:

  1. 建立评估以确定性能基线。
  2. 专注于使用可用的最佳模型达到您的准确性目标。
  3. 尽可能用较小的模型替换较大的模型,以优化成本和延迟。

您可以在此处找到选择 OpenAI 模型的综合指南。

定义工具

工具通过使用底层应用程序或系统的应用程序编程接口来扩展智能体的能力。对于没有应用程序编程接口的遗留系统,智能体可以依靠计算机使用模型通过网页和应用程序用户界面直接与这些应用程序和系统进行交互,就像人类一样。

每个工具都应该有一个标准化的定义,在工具和智能体之间实现灵活的多对多关系。文档完善、经过全面测试且可重复使用的工具可以提高可发现性,简化版本管理,并防止冗余定义。

一般来说,智能体需要三种类型的工具:

  • 编排:智能体本身可以作为其他智能体的工具,详见“编排”部分的“管理器模式”。
  • 退款智能体、研究智能体、写作智能体

例如,以下是在使用智能体软件开发工具包时,如何为上述定义的智能体配备一系列工具:

from agents import Agent, WebSearchTool, function_tool @function_tool def save_results(output): db.insert({"output": output, "timestamp": datetime.time()}) return "File saved" search_agent = Agent( name="Search agent", instructions="Help the user search the internet and save results if asked.", tools=[WebSearchTool(), save_results], )

随着所需工具数量的增加,可以考虑将任务分配给多个智能体(详见“编排”)。

配置指令

高质量的指令对于任何由大语言模型驱动的应用程序都至关重要,对于智能体尤其关键。清晰的指令可以减少歧义,改善智能体的决策,从而使工作流程执行更顺畅,错误更少。

智能体指令的最佳实践

  • 使用现有文档创建大语言模型友好的例程:在创建例程时,可以使用现有的操作程序、支持脚本或政策文档。例如,在客户服务中,例程可以大致对应知识库中的各个文章。
  • 促使智能体分解任务:从密集的资源中提供更小、更清晰的步骤,有助于最大限度地减少歧义,帮助模型更好地遵循指令。
  • 定义明确的行动:确保例程中的每个步骤都对应一个特定的行动或输出。例如,一个步骤可能指示智能体向用户询问订单号,或调用应用程序编程接口检索账户详细信息。明确行动(甚至是面向用户消息的措辞)可以减少解释错误的空间。
  • 捕捉边缘情况:现实世界的交互通常会产生决策点,例如当用户提供不完整信息或提出意外问题时如何继续。一个强大的例程会预见到常见的变化,并包括如何通过条件步骤或分支来处理这些情况的指令,例如在缺少必需信息时的替代步骤。

您可以使用先进的模型,如 o1 或 o3 - mini,从现有文档中自动生成指令。以下是说明此方法的示例提示:

“你是为大语言模型智能体编写指令的专家。将以下帮助中心文档转换为清晰的指令集,以编号列表形式编写。文档将是大语言模型遵循的政策。确保没有歧义,并且指令是作为给智能体的指示编写的。要转换的帮助中心文档如下{{help_center_doc}}”

编排

有了基础组件后,您可以考虑编排模式,以使智能体有效地执行工作流程。

虽然立即构建具有复杂架构的完全自主智能体很诱人,但客户通常通过渐进式方法取得更大的成功。

一般来说,编排模式分为两类:

  1. 单智能体系统:单个配备适当工具和指令的模型以循环方式执行工作流程。
  2. 多智能体系统:工作流程的执行分布在多个协调的智能体之间。

让我们详细探讨每种模式。

单智能体系统

单个智能体可以通过逐步添加工具来处理许多任务,使复杂性易于管理,并简化评估和维护。每个新工具都扩展了其能力,而无需过早地协调多个智能体。

输入 -> 智能体 -> 输出 指令 工具 防护措施 钩子

每种编排方法都需要“运行”的概念,通常实现为一个循环,使智能体能够运行,直到达到退出条件。常见的退出条件包括工具调用、特定的结构化输出、错误或达到最大轮数。

例如,在智能体软件开发工具包中,使用 Runner.run() 方法启动智能体,该方法会循环遍历大语言模型,直到满足以下任一条件:

  1. 调用了最终输出工具,由特定的输出类型定义。
  2. 模型返回的响应不包含任何工具调用(例如,直接的用户消息)。

示例用法:

Agents.run(agent, [UserMessage("What's the capital of the USA?")])

这个 while 循环的概念是智能体功能的核心。在多智能体系统中,正如您接下来将看到的,您可以在智能体之间进行一系列工具调用和交接,但允许模型运行多个步骤,直到满足退出条件。

在不切换到多智能体框架的情况下管理复杂性的一种有效策略是使用提示模板。与其为不同的用例维护大量单独的提示,不如使用一个灵活的基础提示,接受策略变量。这种模板方法可以轻松适应各种上下文,显著简化维护和评估。当出现新的用例时,您可以更新变量,而不是重写整个工作流程。

“你是一名呼叫中心智能体。你正在与{{user_first_name}}互动,他已经是会员{{user_tenure}}。用户最常见的投诉是关于{{user_complaint_categories}}。向用户打招呼,感谢他们成为忠实客户,并回答用户可能提出的任何问题!”

何时考虑创建多个智能体

我们的一般建议是首先最大化单个智能体的能力。更多的智能体可以直观地分离概念,但可能会引入额外的复杂性和开销,因此通常一个配备工具的智能体就足够了。

对于许多复杂的工作流程,将提示和工具分配到多个智能体上可以提高性能和可扩展性。当您的智能体无法遵循复杂的指令或始终选择错误的工具时,您可能需要进一步划分系统并引入更多不同的智能体。

划分智能体的实用指南包括:

类型 描述
复杂逻辑 当提示包含许多条件语句(多个 if - then - else 分支),并且提示模板难以扩展时,可以考虑将每个逻辑段划分到单独的智能体中。
工具过载 问题不仅仅在于工具的数量,还在于它们的相似性或重叠性。一些实现可以成功管理 15 个以上定义明确、不同的工具,而另一些则在处理不到 10 个重叠工具时遇到困难。如果通过提供描述性名称、清晰的参数和详细的描述来提高工具的清晰度仍无法提高性能,则可以使用多个智能体。

多智能体系统

虽然多智能体系统可以针对特定的工作流程和要求以多种方式进行设计,但我们与客户的经验突出了两个广泛适用的类别:

类型 描述
管理器(智能体作为工具) 一个中央“管理器”智能体通过工具调用协调多个专门的智能体,每个智能体处理特定的任务或领域。
去中心化(智能体之间交接) 多个智能体作为对等体运行,根据各自的专长相互交接任务。

多智能体系统可以建模为图,智能体表示为节点。在管理器模式中,边表示工具调用,而在去中心化模式中,边表示在智能体之间转移执行的交接。

无论采用哪种编排模式,相同的原则都适用:保持组件灵活、可组合,并由清晰、结构良好的提示驱动。

管理器模式

管理器模式使中央大语言模型(“管理器”)能够通过工具调用无缝编排一组专门的智能体。管理器不会失去上下文或控制权,而是在正确的时间将任务智能地委托给合适的智能体,并轻松地将结果整合为一个连贯的交互。这确保了流畅、统一的用户体验,并且专门的功能始终按需可用。

此模式非常适合您只希望一个智能体控制工作流程执行并与用户交互的工作流程。

例如,以下是如何在智能体软件开发工具包中实现此模式:

from agents import Agent, Runner manager_agent = Agent( name="manager_agent", instructions=( "You are a translation agent. You use the tools given to you to translate." "If asked for multiple translations, you call the relevant tools." ), tools=[ spanish_agent.as_tool( tool_name="translate_to_spanish", tool_description="Translate the user's message to Spanish" ), french_agent.as_tool( tool_name="translate_to_french", tool_description="Translate the user's message to French" ), italian_agent.as_tool( tool_name="translate_to_italian", tool_description="Translate the user's message to Italian" ), ] ) async def main(): msg = input("Translate 'hello' to Spanish, French and Italian for me!") orchestrator_output = await Runner.run(manager_agent, msg) for message in orchestrator_output.new_messages: print(f" - {message.content}")

声明式与非声明式图:一些框架是声明式的,要求开发人员通过由节点(智能体)和边(确定性或动态交接)组成的图预先明确定义工作流程中的每个分支、循环和条件。虽然这有助于视觉上的清晰,但随着工作流程变得更加动态和复杂,这种方法可能会很快变得繁琐且具有挑战性,通常需要学习专门的领域特定语言。

相比之下,智能体软件开发工具包采用了更灵活、以代码优先的方法。开发人员可以使用熟悉的编程结构直接表达工作流程逻辑,而无需预先定义整个图,从而实现更动态和适应性强的智能体编排。

去中心化模式

在去中心化模式中,智能体可以将工作流程的执行“交接”给彼此。交接是一种单向转移,允许一个智能体将任务委托给另一个智能体。在智能体软件开发工具包中,交接是一种工具或函数。如果一个智能体调用交接函数,我们会立即在被交接的新智能体上开始执行,同时转移最新的对话状态。

此模式涉及使用多个平等的智能体,其中一个智能体可以直接将工作流程的控制权交给另一个智能体。当您不需要单个智能体保持中央控制或整合,而是允许每个智能体根据需要接管执行并与用户交互时,这种模式是最佳选择。

例如,以下是如何使用智能体软件开发工具包为处理销售和支持的客户服务工作流程实现去中心化模式:

from agents import Agent, Runner technical_support_agent = Agent( name="Technical Support Agent", instructions=( "You provide expert assistance with resolving technical issues, " "system outages, or product troubleshooting." ), tools=[search_knowledge_base] ) sales_assistant_agent = Agent( name="Sales Assistant Agent", instructions=( "You help enterprise clients browse the product catalog, recommend " "suitable solutions, and facilitate purchase transactions." ), tools=[initiate_purchase_order] ) order_management_agent = Agent( name="Order Management Agent", instructions=( "You assist clients with inquiries regarding order tracking, " "delivery schedules, and processing returns or refunds." ), tools=[track_order_status, initiate_refund_process] ) triage_agent = Agent( name="Triage Agent", instructions="You act as the first point of contact, assessing customer " "queries and directing them promptly to the correct specialized agent.", handoffs=[technical_support_agent, sales_assistant_agent, order_management_agent] ) await Runner.run(triage_agent, input("Could you please provide an update on the delivery timeline for our recent purchase?"))

在上述示例中,初始用户消息被发送到 triage_agent。识别到输入涉及最近的购买后,triage_agent 会调用交接给 order_management_agent,将控制权转移给它。

这种模式对于诸如对话分类等场景特别有效,或者在任何您希望专门的智能体完全接管某些任务而无需原始智能体继续参与的情况下。可选地,您可以为第二个智能体配备交回给原始智能体的功能,以便在必要时再次转移控制权。

防护措施

设计良好的防护措施有助于管理数据隐私风险(例如,防止系统提示泄露)或声誉风险(例如,确保模型行为符合品牌形象)。您可以设置针对已识别用例风险的防护措施,并在发现新漏洞时添加更多防护措施。防护措施是任何基于大语言模型部署的关键组成部分,但应与强大的身份验证和授权协议、严格的访问控制以及标准的软件安全措施相结合。

可以将防护措施视为一种分层防御机制。虽然单个防护措施不太可能提供足够的保护,但结合使用多个专门的防护措施可以创建更强大的安全网。以下是一些常见的防护措施类别及其实现方式:

输入验证

在将用户输入传递给智能体之前对其进行验证,确保输入符合预期的格式和内容标准。例如,限制输入长度,防止恶意用户发送超长文本以触发缓冲区溢出或其他漏洞。同时,检查输入中是否包含敏感信息或潜在的恶意指令,如 SQL 注入或代码注入的尝试。可以使用正则表达式或预定义的模式匹配来识别和拒绝不符合要求的输入。

输出过滤

对智能体生成的输出进行审查,以防止敏感信息泄露或不适当内容的呈现。例如,如果智能体正在处理客户数据,确保输出中不包含客户的信用卡号码、社会安全号码等敏感信息。可以通过查找和屏蔽特定的敏感数据模式来实现这一点。此外,检查输出是否包含违反公司政策、道德准则或法律规定的内容,如歧视性语言、仇恨言论等。如果检测到此类内容,对输出进行修改或阻止其发送给用户。

工具调用控制

由于智能体可以调用外部工具和系统,需要严格控制哪些工具可以被调用以及在何种条件下调用。为每个工具定义明确的权限和访问规则,确保智能体只能在授权的情况下使用工具。例如,限制智能体对某些关键系统操作的访问,如删除重要文件或执行系统级命令。可以通过在工具定义中设置权限标志,并在智能体尝试调用工具时进行权限检查来实现这一点。

模型响应监控

持续监控智能体从大语言模型接收到的响应,以检测异常行为或潜在的风险。例如,如果模型返回的响应格式异常、语义混乱或与预期的任务不相关,这可能表明模型出现故障或受到攻击。可以使用机器学习模型或基于规则的系统来分析模型响应,识别异常模式并采取相应的措施,如重新请求响应、暂停智能体操作或通知管理员。

上下文管理

仔细管理智能体的上下文信息,避免上下文泄露或被恶意利用。确保在不同用户会话之间正确隔离上下文,防止一个用户的信息被另一个用户获取。同时,限制上下文的保留时间,在不再需要时及时清除敏感的上下文数据。例如,如果智能体在处理用户的金融交易时存储了相关的上下文信息,在交易完成后应立即删除这些信息,以降低数据泄露的风险。

安全培训与意识

对参与智能体开发、部署和维护的团队成员进行安全培训,提高他们对潜在风险和安全最佳实践的认识。确保团队成员了解如何识别和防范常见的安全威胁,如网络攻击、数据泄露等。定期进行安全意识培训和演练,使团队成员能够及时应对安全事件,并遵循安全政策和流程。

通过实施这些防护措施,可以显著提高智能体系统的安全性和可靠性,保护用户数据和企业声誉。然而,安全是一个持续的过程,需要不断监测、评估和更新防护措施,以应对不断变化的威胁环境。

结论

构建智能体是一个令人兴奋且具有变革性的领域,为自动化复杂工作流程和提供创新的用户体验开辟了新的可能性。通过理解智能体的核心组件、设计基础、编排模式以及实施有效的防护措施,您可以自信地踏上构建首个智能体的旅程。

从定义明确的用例开始,逐步构建和测试您的智能体,不断改进和优化其性能。随着经验的积累,可以探索更复杂的编排模式和功能扩展,以满足不断增长的业务需求。

请记住,智能体的成功不仅取决于技术实现,还在于与用户需求和业务目标的紧密结合。始终以用户为中心进行设计,确保智能体能够可靠、安全且高效地代表用户完成任务。

在这个快速发展的领域中,持续学习和紧跟最新的研究与实践是保持领先的关键。我们希望本指南为您提供了构建智能体的坚实基础,并期待看到您创造的创新解决方案。


发布者: 作者: 转发
评论区 (0)
U