代理系统设计模式

GenAI 代理将 GenAI 模型的智能与用于数据检索、外部作用和其他功能的工具相结合。 本页逐步讲解代理设计:

  • 构建代理系统的具体示例说明了如何协调模型和工具调用的流动。
  • 代理系统的设计模式 构成了复杂性和自主性的连续性,从确定性链到可以做出动态决策的单代理系统,到协调多个专用代理的多代理体系结构。
  • 实践建议部分 提供有关选择正确设计以及开发代理、测试和迁移到生产的建议。

代理严重依赖用于收集信息和采取外部作的工具。 有关工具的更多背景信息,请参阅 “工具”。

代理系统示例

具体来说,想要了解代理系统的一个例子,可以考虑呼叫中心的 GenAI 代理与客户的互动:

客户与 GenAI 应用的交互流程图。

客户提出请求:“你能帮我退回最后一个订单吗?

  1. 原因和计划:鉴于查询的意图,代理“打算”:“查找用户最近的订单并检查我们的退货政策”。
  2. 查找信息 (数据智能):代理查询订单数据库以检索相关顺序并引用策略文档。
  3. 原因:代理检查该顺序是否适合返回窗口。
    • 可选的人工介入: 代理核实其他规则:如果项目属于特定类别或超出正常退货时限,请转交给人工处理。
  4. :代理触发退货过程并生成发货标签。
  5. 原因:客服代表会生成对客户的响应。

AI 代理响应客户:“完成! 下面是发货标签...”

这些步骤在 人工 呼叫中心环境中是自然而然的。 在代理系统的上下文中,LLM 会“推理”,而系统则调用专用工具或数据源来填写详细信息。

代理系统使用的工具和数据源。

复杂性级别:从 LLM 到代理系统

GenAI 应用可以由一系列系统提供支持,从简单的 LLM 调用到复杂的多代理系统。 生成任何 AI 驱动的应用程序时,请简单起见。 在真正需要代理行为时引入更复杂的代理行为,以提高灵活性或模型驱动的决策。 确定性链为定义完善的任务提供可预测的基于规则的流。 更多的代理方法提供了更大的灵活性和潜力,但它们带来了额外的复杂性和潜在延迟成本。

设计模式 何时使用 优点 缺点
LLM + 提示
  • 一般问题和答案
  • 短期使用的快速原型
  • 非常简单
  • 易于创建
  • 最少定制化
确定性链
  • 定义完善的任务
  • 静态管道,如基本 RAG
  • 无需进行实时决策
  • Simple
  • 易于审核
  • 死板
  • 需要更改代码才能适应
单代理系统
  • 处理同一领域中中等到复杂的查询
  • 某些动态性决策无需多个专门代理带来的开销
  • 灵活
  • 比多代理更简单
  • 良好的“默认”
  • 可预测性较低
  • 注意防范重复或不正确的工具调用
多代理系统
  • 大型或跨职能域
  • 具有不同逻辑或对话上下文的多个“专家”代理
  • 高度模块化
  • 适用于大规模领域
  • 复杂的协调工作
  • 更难跟踪和调试

马赛克 AI 代理框架 与这些模式无关,因此,随着应用程序需求的增长,可以轻松开始简单并朝着更高级别的自动化和自主发展。

若要详细了解代理系统背后的理论,请参阅 Databricks 创始人的博客文章:

LLM 和提示

最简单的设计具有独立的 LLM 或其他 GenAI 模型,该模型根据来自大量训练数据集的知识响应提示。 此设计适用于简单查询或泛型查询,但通常与实际业务数据断开连接。 可以通过提供系统提示和自定义说明或嵌入的数据来自定义行为。

LLM 对用户做出响应

确定性链(硬编码步骤)

确定性链使用工具调用增强 GenAI 模型,但开发人员定义调用的工具或模型、顺序和参数。 LLM 不决定调用哪些工具,或调用的顺序。 系统遵循所有请求的预定义工作流或“链”,使其高度可预测。

例如,一个确定性的检索增强生成(RAG)链可能始终:

  1. 从向量索引中检索 top-k 结果,以查找与用户请求相关的上下文。
  2. 通过将用户请求与检索到的上下文相结合来增强提示。
  3. 通过将扩充提示发送到 LLM 来生成响应。

基本 RAG 链示意图

何时使用

  • 这适用于具有可预测工作流的明确定义任务。
  • 当一致性和审核是首要任务时。
  • 如果想要通过避免多次 LLM 调用以做出编排决策来最大程度地减少延迟。

优点:

  • 最高可预测性和可审核性。
  • 通常具有较低延迟(LLM 调用用于编排的次数更少)。
  • 更易于测试和验证。

注意事项:

  • 处理各种或意外请求的灵活性有限。
  • 随着逻辑分支的增长,可能会变得复杂且难以维护。
  • 可能需要进行重大重构才能适应新功能。

单代理系统

单代理系统具有一个 LLM,用于协调一个协调的逻辑流。 LLM 自适应决定使用哪些工具、何时进行更多 LLM 调用以及何时停止。 此方法支持动态上下文感知决策。

单代理系统可以:

  1. 接收请求,例如用户查询,以及任何相关的上下文信息,如对话历史记录。
  2. 分析如何做出最佳响应,并选择是否调用工具以获取外部数据或采取行动。
  3. 如果需要,请重复调用 LLM 或工具,直到达到目标或满足特定条件,例如接收有效数据或解决错误。
  4. 将工具输出集成到对话中。
  5. 返回一个连贯的回应作为输出。

例如,技术支持助理代理可能会按如下所示进行调整:

  • 如果用户提出一个简单的问题(“我们的返回策略是什么?”),代理可能会直接从 LLM 的知识做出响应。
  • 如果用户想要其订单状态,代理可能会调用函数 lookup_order(customer_id, order_id)。 如果该工具使用“无效订单号”进行响应,代理可以重试或提示用户输入正确的 ID,继续,直到提供最终答案。

AI 代理合理化计划,并使用工具执行该计划。

何时使用

  • 你期望多样化的用户查询,但仍在一个统一的领域或产品范畴内。
  • 某些查询或条件可以保证工具的使用,例如确定何时提取客户数据。
  • 需要比确定性链更具灵活性,但不需要针对不同的任务使用单独的专用代理。

优点:

  • 代理可以通过选择要调用的工具(如果有)来适应新的或意外的查询。
  • 代理可以循环遍历重复的 LLM 调用或工具调用来优化结果 - 无需完全多代理设置。
  • 这种设计模式通常是企业用例的甜蜜点-比多代理设置更容易调试,同时仍允许动态逻辑和有限自治。

注意事项:

  • 与硬编码链相比,你必须防范重复或无效的工具调用。 无限循环可能发生在任何工具调用方案中,因此设置迭代限制或超时。
  • 如果应用程序跨越了完全不同的子域(例如财务、开发运维、营销等),单个代理可能会由于功能需求过多而变得笨拙或超载。
  • 你仍然需要精心设计的提示和约束来使代理保持专注和相关。
  • 代理是一个连续性;提供模型来控制系统行为的自由度越多,应用程序就越具有代理性。 在实践中,大多数生产系统仔细限制代理的自主性,以确保合规性和可预测性,例如,要求人工批准风险作。

多代理系统

多代理系统涉及两个或多个专门代理,这些代理交换消息或协作处理任务。 每个代理都有自己的域或任务专业知识、上下文和可能不同的工具集。 单独的“协调器”或“AI 主管”将请求定向到相应的代理,或决定何时将请求从一个代理移交给另一个代理。 监督器可以是另一个 LLM 或规则驱动的路由器。

协调器管理多个 AI 代理。

例如,客户助理可能有委托给专用代理的主管:

  • 购物助手:帮助客户搜索产品,并提供有关评论的优缺点的建议
  • 客户支持代理:处理反馈、退货和发货

何时使用

  • 你有不同的问题领域或技能集,如编码代理或财务代理。
  • 每个代理都需要访问会话历史记录或特定于域的提示。
  • 你有这么多工具,将它们全部拟合到一个代理的架构是不切实际的;每个代理都可以拥有子集。
  • 你想要在专门的智能体之间实现反思、评论或来回协作。

优点:

  • 这种模块化方法意味着每个代理都可以由单独的团队开发或维护,专门处理窄域。
  • 可以处理单个代理难以一致管理的大型复杂企业工作流。
  • 促进高级多步骤或多透视推理 - 例如,一个生成答案的代理,另一个代理验证答案。

注意事项:

  • 需要一种策略来在代理之间进行路由,并处理跨多个终结点的日志记录、跟踪和调试的开销。
  • 如果你有许多子代理和工具,则确定哪个代理有权访问哪些数据或 API 可能会变得复杂。
  • 如果未仔细约束,代理可以无限期地在相互之间推卸任务,而不解决任务。 单代理工具调用中也存在无限循环风险,但多代理设置增加了另一层调试复杂性。

实用建议

如果你的用例适合Agent Bricks的产品/服务,请从那个有指导的简单选项开始。

如果需要构建自定义代理系统,则 Azure Databricks 和 马赛克 AI 代理框架 与所选的任何模式无关,因此在应用程序增长时可以轻松改进设计模式。 请考虑以下用于开发稳定且可维护的代理系统的最佳做法:

  1. 简单开始: 如果只需要简单的链条,确定性链可以快速构建。
  2. 逐渐添加复杂性: 由于需要更多动态查询或灵活的数据源,请使用工具调用迁移到单代理系统。 如果你有明显的域或任务、多个聊天上下文或大型工具集,请考虑使用多代理系统。
  3. 组合模式: 在实践中,许多实际代理系统将模式组合在一起。 例如,大多数确定性链可以有一个步骤,其中 LLM 可以根据需要动态调用某些 API。

开发指南

  • 提示和工具
    • 保持提示清晰和最少,以避免矛盾的说明,分散信息,减少幻觉。
    • 仅提供代理所需的工具和上下文,而不是一组未绑定的 API 或大型无关上下文。 在设计过程中选择工具方法
  • 日志记录和可观测性
    • 使用 MLflow 跟踪为每个用户请求、代理计划和工具调用实现详细的日志记录。
    • 安全地存储日志,并注意对话数据中的个人身份信息(PII)。 考虑 用于自动化的数据分类

测试和迭代指南

  • 评估
  • 错误处理和回退逻辑
    • 规划应对工具或 LLM 故障。 超时、格式不正确的响应或空结果可能会中断工作流。 在高级功能失败时,包括重试策略、回退逻辑或更简单的回退链。
  • 迭代改进
    • 预期会随着时间的推移优化提示和代理逻辑。 使用 MLflow 提示注册表进行提示的版本更改,并使用 MLflow 应用版本跟踪进行应用的版本跟踪。 版本管理将简化操作,并允许回滚和比较。
    • 收集评估数据并定义指标时,请考虑更多的自动化优化方法,例如 MLflow 提示优化

生产指南

  • 模型更新和版本锁定
    • 当提供程序在后台更新模型时,LLM 行为可能会改变。 使用版本固定和频繁的回归测试来确保代理逻辑保持可靠且稳定。
  • 延迟和成本优化
    • 每增加一个额外的 LLM 或工具调用都会增加令牌消耗和响应时间。 尽可能合并步骤或缓存重复查询,以保持性能和成本可管理。
  • 安全和沙盒技术
    • 如果代理可以更新记录或运行代码,请对这些操作进行沙盒处理,或在必要时强制实施人工审批。 这在企业或受监管的环境中至关重要,以避免意外的伤害。 Unity Catalog函数 使生产环境具备沙盒执行功能。
    • 有关工具选项的更多指导,请参阅 “选择工具方法 ”。

通过遵循这些准则,可以缓解许多最常见的故障模式,例如工具错误调用、偏移 LLM 性能或意外成本峰值,以及构建更可靠、可缩放的代理系统。