了解如何使用 AWS SageMaker JumpStart 基础模型构建和部署使用工具的 LLM 代理


大型语言模型 (LLM) 代理是扩展独立 LLM 功能的程序,具有 1) 访问外部工具(API、函数、Webhook、插件等)的能力,以及 2) 能够自行规划和执行任务的能力。 - 指导时尚。通常,法学硕士需要与其他软件、数据库或 API 交互才能完成复杂的任务。例如,安排会议的管理聊天机器人需要访问员工的日历和电子邮件。通过使用工具,LLM 代理可以变得更加强大,但代价是增加了复杂性。

在本文中,我们介绍 LLM 代理并演示如何使用 Amazon SageMaker JumpStart 和 AWS Lambda 构建和部署电子商务 LLM 代理。代理将使用工具来提供新功能,例如回答有关退货的问题(“我的退货吗? rtn001 已处理吗?”)并提供有关订单的最新信息(“您能告诉我订单是否 123456 已发货?”)。这些新功能要求法学硕士从多个数据源获取数据(命令, 回报)并执行检索增强生成(RAG)。

为了给 LLM 代理提供动力,我们使用 果馅饼-UL2 模型部署为 SageMaker 终端节点,并使用使用 AWS Lambda 构建的数据检索工具。该代理随后可以与 Amazon Lex 集成,并用作网站或 AWS Connect 内的聊天机器人。我们在这篇文章的最后列出了将 LLM 代理部署到生产环境之前需要考虑的事项。为了获得构建 LLM 代理的完全托管体验,AWS 还提供了 Amazon Bedrock 功能的代理(预览版)。

LLM代理架构的简要概述

LLM 代理是使用 LLM 来决定何时以及如何根据需要使用工具来完成复杂任务的程序。借助工具和任务规划能力,LLM代理可以与外部系统交互并克服LLM的传统局限性,例如知识切断、幻觉和不精确的计算。工具可以采用多种形式,例如 API 调用、Python 函数或基于 Webhook 的插件。例如,法学硕士可以使用“检索插件”来获取相关上下文并执行 RAG。

那么对于法学硕士来说选择工具和计划任务意味着什么?有很多方法(例如 反应, MRKL, 工具成型机, 拥抱GPT, 和 变压器代理s) 将法学硕士与工具结合使用,并且进步正在迅速发生。但一种简单的方法是向 LLM 提示一系列工具,并要求其确定 1) 是否需要某个工具来满足用户查询,如果需要,2) 选择适当的工具。此类提示通常类似于以下示例,并且可能包含少量示例,以提高法学硕士选择正确工具的可靠性。

'''您的任务是选择一个工具来回答用户问题。您可以使用以下工具。 search:在常见问题解答中搜索答案 order:订购商品 noop:不需要工具 {few shot Examples} 问题:{input} 工具:'''

更复杂的方法涉及使用专门的 LLM,可以直接解码“API 调用”或“工具使用”,例如 大猩猩法学硕士。这种经过微调的法学硕士在 API 规范数据集上进行训练,以根据指令识别和预测 API 调用。通常,这些 LLM 需要一些有关可用工具的元数据(其输入参数的描述、yaml 或 JSON 架构)才能输出工具调用。 Amazon Bedrock 和 OpenAI函数调用。请注意,法学硕士通常需要足够大和复杂才能显示工具选择能力。

典型的LLM代理架构

假设选择了任务规划和工具选择机制,典型的 LLM 代理程序按以下顺序工作:

  1. 用户请求 – 该程序接受用户输入,例如“我的订单在哪里 123456?”来自一些客户端应用程序。
  2. 计划下一步行动并选择要使用的工具 – 接下来,程序使用提示让 LLM 生成下一个操作,例如,“使用以下命令查找订单表” 订单API”。系统会提示法学硕士建议一个工具名称,例如 订单API 来自可用工具及其描述的预定义列表。或者,可以指示 LLM 直接生成带有输入参数的 API 调用,例如 订单API(12345).
    1. 请注意,下一步操作可能涉及也可能不涉及使用工具或 API。如果没有,法学硕士将响应用户输入,而不包含工具中的附加上下文,或者只是返回预设的响应,例如“我无法回答这个问题”。
  3. 解析工具请求 – 接下来,我们需要解析并验证法学硕士建议的工具/操作预测。需要进行验证,以确保工具名称、API 和请求参数不会出现幻觉,并确保根据规范正确调用工具。此解析可能需要单独的 LLM 调用。
  4. 调用工具 – 一旦确保有效的工具名称和参数,我们就调用该工具。这可以是 HTTP 请求、函数调用等。
  5. 解析输出 – 该工具的响应可能需要额外处理。例如,API 调用可能会产生很长的 JSON 响应,其中只有部分字段是 LLM 感兴趣的。以干净、标准化的格式提取信息可以帮助法学硕士更可靠地解释结果。
  6. 解释输出 – 给定工具的输出,再次提示法学硕士理解它并决定是否可以向用户生成最终答案或是否需要其他操作。
  7. 终止或继续步骤 2 – 如果出现错误或超时,则返回最终答案或默认答案。

不同的代理框架以不同的方式执行前面的程序流程。例如, 反应 将工具选择和最终答案生成合并到单个提示中,而不是使用单独的提示进行工具选择和答案生成。此外,该逻辑可以单遍运行,也可以在 while 语句(“代理循环”)中运行,当生成最终答案、引发异常或发生超时时终止。保持不变的是,代理使用 LLM 作为核心来协调规划和工具调用,直到任务终止。接下来,我们展示如何使用 AWS 服务实现简单的代理循环。

解决方案概述

在这篇博文中,我们实现了一个电子商务支持 LLM 代理,它提供了两种由工具支持的功能:

  • 退货状态检索工具 – 回答有关退货状态的问题,例如“我的退货发生了什么情况” rtn001?”
  • 订单状态检索工具 – 跟踪订单状态,例如“我的订单状态如何 123456?”

代理有效地使用 LLM 作为查询路由器。给定一个查询(“订单状态是什么? 123456?”),选择适当的检索工具来跨多个数据源(即退货和订单)进行查询。我们通过让法学硕士在多个检索工具中进行选择来完成查询路由,这些工具负责与数据源交互并获取上下文。这扩展了简单的 RAG 模式,该模式假定单个数据源。

两种检索工具都是采用 id (订单号 或者 返回ID)作为输入,从数据源获取 JSON 对象,并将 JSON 转换为适合 LLM 使用的人类友好表示字符串。现实场景中的数据源可能是高度可扩展的 NoSQL 数据库,例如 DynamoDB,但该解决方案使用简单的 Python 字典 带有用于演示目的的示例数据。

通过添加检索工具并相应修改提示,可以向代理添加其他功能。该代理可以作为独立服务进行测试,该服务通过 HTTP 与任何 UI 集成,这可以使用 Amazon Lex 轻松完成。

解决方案概述

以下是有关关键组件的一些其他详细信息:

  1. LLM 推理终点 – 代理项目的核心是法学硕士。我们将使用 SageMaker JumpStart 基础模型中心轻松部署 果馅饼-UL2 模型。 SageMaker JumpStart 可以轻松地将 LLM 推理端点部署到专用 SageMaker 实例。
  2. 代理协调器 – 代理协调器协调 LLM、工具和客户端应用程序之间的交互。对于我们的解决方案,我们使用 AWS Lambda 函数来驱动此流程,并使用以下函数作为辅助函数。
    • 任务(工具)规划器 – 任务规划者使用法学硕士建议以下之一:1) 返回查询,2) 订单查询,或 3) 无工具。我们仅使用即时工程,并且 果馅饼-UL2 模型按原样进行,无需微调。
    • 工具解析器 – 工具解析器确保任务规划器的工具建议有效。值得注意的是,我们确保单个 订单号 或者 返回ID 可以解析。否则,我们将使用默认消息进行响应。
    • 工具调度员 – 工具调度程序使用有效参数调用工具(Lambda 函数)。
    • 输出解析器 – 输出解析器清理 JSON 中的相关项并将其提取为人类可读的字符串。此任务由每个检索工具以及编排器内完成。
    • 输出解释器 – 输出解释器的职责是 1) 解释工具调用的输出,2) 确定是否可以满足用户请求或是否需要额外的步骤。如果是后者,则单独生成最终响应并将其返回给用户。

现在,让我们更深入地了解关键组件:代理协调器、任务规划器和工具调度器。

代理协调器

以下是代理协调器 Lambda 函数内代理循环的缩写版本。该循环使用辅助函数,例如 任务规划器 或者 工具解析器,将任务模块化。这里的循环被设计为最多运行两次,以防止 LLM 陷入不必要的长时间循环。

#.. imports ..
MAX_LOOP_COUNT = 2 # stop the agent loop after up to 2 iterations
# ... helper function definitions ...
def agent_handler(event):
    user_input = event["query"]
    print(f"user input: {user_input}") 
    
    final_generation = ""
    is_task_complete = False
    loop_count = 0 

    # start of agent loop
    while not is_task_complete and loop_count < MAX_LOOP_COUNT:
        tool_prediction = task_planner(user_input)
        print(f"tool_prediction: {tool_prediction}")  
        
        tool_name, tool_input, tool_output, error_msg = None, None, "", ""

        try:
            tool_name, tool_input = tool_parser(tool_prediction, user_input)
            print(f"tool name: {tool_name}") 
            print(f"tool input: {tool_input}") 
        except Exception as e:
            error_msg = str(e)
            print(f"tool parse error: {error_msg}")  
    
        if tool_name is not None: # if a valid tool is selected and parsed 
            raw_tool_output = tool_dispatch(tool_name, tool_input)
            tool_status, tool_output = output_parser(raw_tool_output)
            print(f"tool status: {tool_status}")  

            if tool_status == 200:
                is_task_complete, final_generation = output_interpreter(user_input, tool_output) 
            else:
                final_generation = tool_output
        else: # if no valid tool was selected and parsed, either return the default msg or error msg
            final_generation = DEFAULT_RESPONSES.NO_TOOL_FEEDBACK if error_msg == "" else error_msg
    
        loop_count += 1

    return {
        'statusCode': 200,
        'body': final_generation
    }

任务规划器(工具预测)

代理协调器使用 任务计划员 根据用户输入预测检索工具。对于我们的 LLM 代理,我们将简单地使用提示工程和少量提示来教 LLM 在上下文中执行此任务。更复杂的代理可以使用微调的 LLM 进行工具预测,这超出了本文的范围。提示如下:

tool_selection_prompt_template = """ 您的任务是选择适当的工具来满足用户输入。如果不需要工具,则选择“no_tool” 可用的工具有: returns_inquiry:有关特定退货状态的信息数据库,无论是待处理、已处理、 order_inquiry:有关特定订单状态的信息,例如发货状态、产品、金额等。 no_tool:不需要工具来回答用户输入。您可以建议多个工具,以逗号分隔。示例: user: "你们的营业时间是几点?” 工具:no_tool 用户:“订单 12345 发货了吗?” 工具:order_inquiry 用户:“退货 ret812 处理了吗?” 工具:returns_inquiry 用户:“退货订单还有多少天?” 工具: returns_inquiry 用户:“订单 38745 的订单总数是多少?” tool: order_inquiry 用户:“我可以根据商店政策退回订单 38756 吗?” tool: order_inquiry 用户:“嗨” tool: no_tool 用户:“你是 AI ?" tool: no_tool user: "天气怎么样?" tool: no_tool user: "订单 12347 的退款状态是什么?" tool: order_inquiry user: "return ret172 的退款状态是什么?" tool: returns_inquiry 用户输入: {} 工具: ”””

工具调度员

工具调度机制的工作原理是 如果别的 根据工具名称调用适当的 Lambda 函数的逻辑。以下是 工具调度 辅助函数的实现。它用于内部 代理人 循环并返回来自工具 Lambda 函数的原始响应,然后由 输出解析器 功能。


def tool_dispatch(tool_name, tool_input):
    #...
     
    tool_response = None 

    if tool_name == "returns_inquiry":
        tool_response = lambda_client.invoke(
            FunctionName=RETURNS_DB_TOOL_LAMBDA,
            InvocationType="RequestResponse",
            Payload=json.dumps({
              "returnId": tool_input  
            })
        )
    elif tool_name == "order_inquiry":
        tool_response = lambda_client.invoke(
            FunctionName=ORDERS_DB_TOOL_LAMBDA,
            InvocationType="RequestResponse",
            Payload=json.dumps({
                "orderId": tool_input
            })
        )
    else:
        raise ValueError("Invalid tool invocation")
        
    return tool_response

部署解决方案

重要先决条件 – 要开始部署,您需要满足以下先决条件:

  • 通过可以启动 AWS CloudFormation 堆栈的用户访问 AWS 管理控制台
  • 熟悉导航 AWS Lambda亚马逊莱克斯 控制台
  • 果馅饼-UL2 需要一个单一的 ml.g5.12xlarge 用于部署,这可能需要通过支持票证增加资源限制。在我们的示例中,我们使用 美国东部1 作为区域,因此请确保增加服务配额(如果需要) 美国东部1.

使用 CloudFormation 进行部署 – 您可以将解决方案部署到 美国东部1 单击下面的按钮:

启动堆栈

部署该解决方案大约需要 20 分钟,并将创建一个 LLMAgentStack 堆栈,其中:

  • 使用部署 SageMaker 端点 果馅饼-UL2 来自 SageMaker JumpStart 的模型;
  • 部署三个 Lambda 函数: LLMA代理编曲家, LLMAgent退货工具, LLMAgent订单工具;和
  • 部署一个 AWS 莱克斯 可用于测试代理的机器人: Sagemaker-Jumpstart-Flan-LLM-Agent-Fallback-Bot.

测试解决方案

该堆栈部署了一个名为 Amazon Lex 的机器人 Sagemaker-Jumpstart-Flan-LLM-Agent-Fallback-Bot。该机器人可用于端到端测试代理。这里有一份额外的综合指南,用于通过 Lambda 集成测试 AWS Amazon Lex 机器人以及集成如何在高级别上工作。但简而言之,Amazon Lex 机器人是一种资源,可提供快速 UI 来与我们构建的 Lambda 函数内运行的 LLM 代理聊天(LLMA代理编曲家).

要考虑的示例测试用例如下:

  • 有效订单查询 (例如,“订购的商品是 123456?”)
    • 订单“123456”是有效订单,因此我们应该期待一个合理的答案(例如“Herbal Handsoap”)
  • 有效退货查询 退货(例如,“我什么时候回来 rtn003 处理?”)
    • 我们应该期待关于退货状态的合理答复。
  • 与退货或订单无关 (例如,“苏格兰现在的天气怎么样?”)
    • 与退货或订单无关的问题,因此应返回默认答案(“抱歉,我无法回答该问题。”)
  • 无效订单查询 (例如,“订购的商品是 383833?”)
    • 订单数据集中不存在 ID 383832,因此我们应该优雅地失败(例如,“未找到订单。请检查您的订单 ID。”)
  • 退货查询无效 (例如,“我什么时候回来 rtn123 处理?”)
    • 同样,id rtn123 返回数据集中不存在,因此应该正常失败。
  • 不相关退货查询 (例如,“退货的影响是什么? rtn001 世界和平?”)
    • 这个问题虽然似乎与有效订单有关,但实际上是无关紧要的。 LLM 用于过滤上下文不相关的问题。

要自行运行这些测试,请参阅以下说明。

  1. 在 Amazon Lex 控制台上 (AWS 控制台 > Amazon Lex),导航到名为的机器人 Sagemaker-Jumpstart-Flan-LLM-Agent-Fallback-Bot。该机器人已配置为调用 LLMA代理编曲家 Lambda 函数每当 回退意图 被触发。
  2. 在导航窗格中,选择 意图.
    意图导航
  3. 选择 建造 在右上角
    lex 机器人开始构建
  4. 4. 等待构建过程完成。完成后,您会收到一条成功消息,如以下屏幕截图所示。
    构建完成状态
  5. 通过输入测试用例来测试机器人。
    ML 15042 机器人屏幕截图调整大小

清理

为了避免额外费用,请按照以下步骤删除我们的解决方案创建的资源:

  • AWS 云形成 控制台,选择名为的堆栈 LLMAgentStack (或您选择的自定义名称)。
  • 选择 删除
  • 检查堆栈是否已从 CloudFormation 控制台删除。

重要的: 仔细检查堆栈是否已成功删除,确保 果馅饼-UL2 推理端点被删除。

  • 要检查,请访问 AWS 控制台 > Sagemaker > 终端节点 > 推理 页。
  • 该页面应列出所有活动端点。
  • 确保 sm-jumpstart-flan-bot-端点 不存在,如下面的屏幕截图所示。

贤者清理

生产注意事项

将 LLM 代理部署到生产环境需要采取额外的步骤来确保可靠性、性能和可维护性。以下是在生产中部署代理之前的一些注意事项:

  • 选择 LLM 模型来为代理循环提供动力: 对于本文中讨论的解决方案,我们使用了 果馅饼-UL2 模型无需微调即可执行任务规划或工具选择。在实践中,使用经过微调以直接输出工具或 API 请求的 LLM 可以提高可靠性和性能,并简化开发。我们可以在工具选择任务上微调 LLM,或者使用直接解码工具标记的模型,例如 Toolformer。
    • 使用微调模型还可以简化代理可用工具的添加、删除和更新。使用仅基于提示的方法,更新工具需要修改代理协调器内的每个提示,例如用于任务规划、工具解析和工具调度的提示。这可能很麻烦,并且如果在 LLM 上下文中提供太多工具,性能可能会下降。
  • 可靠性和性能: LLM 代理可能不可靠,尤其是对于无法在几个循环内完成的复杂任务。添加输出验证、重试、将 LLM 的输出结构化为 JSON 或 yaml,以及强制超时以为陷入循环的 LLM 提供逃生通道,可以增强可靠性。

结论

在这篇文章中,我们探讨了如何使用低级提示工程、AWS Lambda 函数和 SageMaker JumpStart 作为构建块,构建一个可以从头开始利用多种工具的 LLM 代理。我们详细讨论了 LLM 代理的架构和代理循环。本博文中介绍的概念和解决方案架构可能适合使用少量预定义工具集的代理。我们还讨论了在生产中使用代理的几种策略。预览版的 Agents for Bedrock 还提供了用于构建代理的托管体验,并具有对代理工具调用的本机支持。


关于作者

黄约翰黄约翰 是 AWS 的生成式 AI 架构师,特别关注大型语言模型 (LLM) 应用程序、向量数据库和生成式 AI 产品策略。他热衷于帮助公司进行人工智能/机器学习产品开发,以及法学硕士代理人和副驾驶的未来。在加入 AWS 之前,他曾担任 Alexa 的产品经理,帮助将对话式 AI 引入移动设备,同时也是摩根士丹利的衍生品交易员。他拥有斯坦福大学计算机科学学士学位。



来源链接

发表评论

您的电子邮件地址不会被公开。 必需的地方已做标记 *

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

zh_CNChinese