首页 >后端开发 >Python教程 >指南:如何为 SRE 团队构建 AI 代理

指南:如何为 SRE 团队构建 AI 代理

DDD
DDD原创
2024-11-10 09:21:021041浏览

背景

Aptible AI 的工程团队在过去约 4 个月内构建了一个 AI 代理,以帮助我们的 SRE 团队调查和解决生产问题。因为我们已经与许多早期测试人员和设计合作伙伴进行了交谈,他们正在为类似的目的构建自己的代理,所以我们决定编写一个指南来解释我们使用自己的代理所做的事情以及如何构建一个你自己。

本指南的内容

在以下分步教程中,我们将向您展示如何:

  1. 在 Chainlit 中设置代理
  2. 将您的代理连接到 LLM(在本例中为 gpt-4o)
  3. 让您的代理更快并添加实时“打字”(类似于 ChatGPT)
  4. 赋予您的代理个性和专业性
  5. 让您的代理能够搜索文件集合
  6. 将您的代理与外部工具集成(在本例中为 PagerDuty)

但首先,有一些注意事项和专业提示。

注意事项和专业提示

已经有一个工具可以做到这一点吗?

注意事项:如果你不需要构建新的东西,那么你就不应该。有这样的。许多。市场上的工具。根据您的具体用例,您也许能够找到适合您的一个。

Aptible 搜索和最终开发我们自己的事件响应的动力是我们与知识孤岛作斗争,并且每当我们遇到特定系统的问题时都倾向于依赖三到四个主题专家。

因此,我们开始使用名为 Danswer 的开源工具来改进信息检索(类似于其流行的商业竞争对手 Glean)。它直接插入 Slack,可以从各种信息源检索自然语言问题的答案。问题是它仅限于索引数据(即,只有我们的文档和聊天历史记录)。

⚒️ 我们构建的:我们需要的是一个可以与我们所有其他系统(不仅仅是文档和 Slack)集成的工具。我们需要检索日志和指标、应用程序运行状况,并在事件结束后生成报告和事后分析。因此,我们设计了一个人工智能代理,它本质上是建立在一系列集成的基础上的,可以让您连接实时数据和索引数据。稍后会详细介绍!

专业提示:在决定构建自己的产品之前,请先了解一下已有的产品。一个很好的起点可能是从 Reddit 众包想法(查看这个帖子)或查看一些开源工具(如果您正在专门寻找事件响应工具,那么 github 是一个很好的起点) )。还有一长串开源 AI 代理可供您明天开始使用。

您的整合策略是什么?

注意事项:如上所述,这里最大的考虑因素是:您需要您的代理访问哪些类型的信息?您也许可以简单地通过 API 将其与第三方提供商集成,但如果您需要集成更具体地满足您的需求,那么您需要更加仔细地考虑集成的工作方式。

通过在开始构建之前仔细考虑需要集成的内容,您将在以后避免一些头痛。您是否需要代理能够执行自定义脚本来查询数据库?您是否需要实时检索日志和指标?您将如何设计代理来检索该信息?它会返回源链接吗?它会返回一大堆您仍然需要手动筛选的日志行,还是能够推断出异常可能在哪里?

⚒️ 我们构建的内容: Aptible AI 的核心是建立在一系列集成之上。集成不仅仅是与第三方提供商的连接,它还是我们团队使用该提供商的独特配置的集合。例如,Aptible AI 支持同一提供商的多个集成,因为我们可能希望以不同的方式使用该提供商。不同的团队使用 Datadog 的方式不同,关注不同的指标或使用不同的标签,因此每个团队都可以按照自己需要的方式使用与同一工具的集成。

Aptible AI 支持一系列常见的 SRE 工具,包括:

  • 聊天和其他高度同步的通信
  • 文档和其他知识库
  • 可观测性
  • 警报

这些集成的实际实现符合可定制性的三个类别之一:

对于初学者来说,您有一个不需要自定义的基本集成(PagerDuty 就是一个例子)。由于它只是从 PagerDuty 中提取数据并将其添加到 AI 上下文中,因此每个利用 PagerDuty 集成的团队都以相同的方式使用它。

接下来,我们有更多可定制的集成(如之前的 Datadog 示例),这些集成构建在通用 InfluxDB 集成之上,但针对查找容器指标和查找重启活动的特定用例进行了定制。

最后,有一些完全自定义的工具可能对 Aptible 之外的任何人都没有意义(这里的一个例子是我们为应用程序获取容器的集成)。这些完全特定于我们运行基础设施的方式,可以通过轻量级 PubSub 接口或基于 Websocket 的“安全”代理来实现。

专业提示:少即是多!如果你给模型太多的工具可供选择,它可能会开始选择不正确的工具并使自己感到困惑。下一节将详细介绍

这么多款式,如何挑选呢?

注意事项:这是模型的问题……每天都会出现新的模型,在选择模型时需要记住几个注意事项(主要与您的特定用例有关)。您应该自行托管吗?您需要您的代理是对话式的还是基于任务的,或者两者兼而有之?它将执行简单还是复杂的任务?您需要实时性能吗?

我们没有必要遍历所有存在的模型,因为内容已经遍布各处(如果您想深入了解,这是一个很好的资源),但我们可以遍历我们所做的决定在构建 Aptible AI 时要做的事情以及我们考虑的选项。

这是一个棘手的过程,因为你无法真正避免权衡。如果你需要你的 Agent 来执行复杂的任务,那么你就必须在速度和成本上做出一些牺牲。

模型的大小、功能和架构在很大程度上取决于任务是否需要简单的分类或高度复杂的推理和交互。如果简单,一个更小的、轻量级的模型(如决策树、随机森林或简单的神经网络)就足够了。如果更复杂,那么您可以考虑更强大的模型,例如 GPT-4、BERT 或类似的基于 Transformer 的架构。

如果您选择自托管以避免安全问题,您可能不得不牺牲特性和功能,因为您的自托管版本将落后于托管选项。

如果您需要您的代理接受特定领域知识的培训,那么您需要策划或创建自己的数据集以进行微调。看看您是否可以使用已经在大型数据集上训练过的预训练模型来避免数据质量问题(尽管这可能是不可能的,具体取决于您需要代理访问的数据)。

⚒️ 我们构建的内容:我们目前正在将 GPT-4o 用于 Aptible AI,因为我们相信它最有可能为我们提供最高质量的答案。但是,我们认识到使用 Aptible AI 的客户可能希望使用自己的模型(包括自托管模型)。因此,我们在构建时牢记这一点。

专业提示:您的代理的聪明程度取决于您提供的信息。法学硕士需要帮助了解如何以及何时使用您提供的信息,如果您不向其提供如何解释信息的说明,它只会编造一些东西。预先花费真正的精力来整理您提供给法学硕士的信息!

提示技巧又如何呢?

注意事项:您可能会想要检索尽可能多的数据(文档、Slack 对话、代码存储库、问题跟踪器等),将其全部扔到 RAG 应用程序中* * 并向它提问。但根据我们的经验,几乎总是会出现太多噪音,以至于无法发挥作用。这就是快速工程的用武之地。

我们已经提到过这一点,但提示工程是这里难题的关键部分(有关提示技术的详细概述,请查看此内容)。你的即时工程越好,你的特工就会越好。

就上下文而言,以下是我们在构建 Aptible AI 时(随着时间的推移)考虑的一些内容:

零次提示:这是大多数人在与 ChatGPT 交谈时所做的;他们只是问一个问题然后得到答复。如果反应不好,那么他们只是以不同的方式提出问题。

少量提示:这是稍微有经验的人在与 ChatGPT 交谈时所做的事情;他们向它提出一个问题,并提供他们想要的输出的示例。您可以使用零次和/或几次提示来执行底层模型已经知道如何执行的非常简单的任务。

检索增强生成(RAG):这是一种允许模型检索额外上下文并用它来回答问题的技术。这对于人工智能驱动的文档搜索特别有用(另请参阅:Glean 和 Danswer)。

ReAct:该技术允许代理以迭代方式产生“想法”并采取“行动”来解决问题,最类似于人类推理。 ReAct 非常适合中等复杂的问题,例如通过文档和工具实时导航参考以撰写答案。

需要记住的重要一点是,您可以混合搭配这些技术(接下来我们将介绍多代理方法)。这就是我们所做的......

⚒️ 我们构建的:因为 Aptible AI 具有多代理结构(稍后详细介绍),所以我们根据任务/问题的复杂性实现了 ReAct 和 RAG 的混合。

Guide: How to build an AI Agent for SRE Teams

因此,当您向人工智能提出问题时,我们会将所有集成(以及如何使用它们的说明)交给人工智能。然后,人工智能根据其可用的信息决定调用哪些工具。每次集成调用后,人工智能可以选择确定它有足够的信息来提供答案,或者确定其他集成是相关的并且可能会产生其他信息。

在整个过程中,我们试图通过几种不同的机制帮助人工智能更好地决定要利用哪些集成:

针对集成的广泛提示工程,以确保真正清楚何时以及如何使用每个集成,以及如何解释输出。

我们构建了一个自我评估系统,要求人工智能对集成响应的价值进行自我评估。即使人工智能在调用集成时做出了愚蠢的决定(或提供了错误的输入),如果您要求它自我评估集成的输出是否有用,它通常也能够在事后认识到这一点。然后我们可以用它来影响特定输出对响应的影响程度。如果人工智能持续做出错误的决定,我们也可以阻止它继续进行。

我们根据过去的经验实施了朴素贝叶斯。例如,如果大多数时候您调用集成 A,然后调用 B,并且这会产生有用的结果,那么继续这样做可能会很有用。代理还可以使用诸如与之前的类似事件进行比较之类的方法来进一步缩小集成的有用范围以及在特定场景中何时有用的范围。

专业提示:为了避免听起来正确但实际上并非如此的无意义答案,请务必退后一步,考虑对于您尝试使用人工智能解决的问题,最有用的信息通常来自哪里– 然后基于此设计你的代理。

多代理还是单代理?

注意事项: 多代理方法变得越来越流行,但根据您的用例,它们可能很复杂并且可能没有必要。让一个代理团队使用不同的技术一起工作来解决复杂的问题是非常有用的。

例如,如果您在 Slack 中向机器人询问一个与您的特定基础设施无关的问题(也许您只是想知道谁赢得了 1995 年世界职业棒球大赛),您可以拥有一个基于零样本构建的代理提示您只需充当与您的 Slack(或您拥有的任何地方)集成的 ChatGPT。

但是,如果您的问题或需求很复杂,那么拥有一个代理团队基本上就像您的小研究团队一样,以智能的方式收集和分析来自不同来源的数据会很有用。

⚒️ 我们构建的内容: Aptible AI 使用多代理方法,从确定需要解决什么类型的问题或任务的代理代理开始。

专业提示:重构为多代理方法比重构更容易!因此,在开始以这种方式构建代理之前,请确保您需要它。

Guide: How to build an AI Agent for SRE Teams

不能忘记安全...

注意事项:这是我们与 Aptible AI 早期用户聊天时经常出现的一个话题。大多数工程团队在实施新工具时最终都必须面对他们的安全团队,确保数据安全至关重要(特别是如果您在高度监管的行业中工作)。因此,您要做的第一件事就是了解组织的 AI 安全策略,然后您可以采取一些措施来防止潜在的数据泄露或外部威胁。

⚒️ 我们构建的内容: 对于初学者,我们使用的模型不训练我们的数据。我们仍在围绕客户对安全的需求进行大量探索,无论是自托管还是其他!请继续关注。

专业提示: 请谨慎对待您授予 AI 访问权限或包含在提示中的数据,尤其是不应与最终用户共享该数据的情况下!如果您需要包含不可预测的数据(例如日志),请考虑使用像 Nightfall 这样的工具,以确保传递给 LLM 和最终用户的内容得到清理

哦,当然,它必须可用!

注意事项:您打算如何使用您的代理?它需要有 UI 吗?它会在整个组织中使用吗?

当涉及到机器人的用户体验时,您可能不需要花时间重新发明轮子。 Chainlit、Gradio 和 Streamlit 等框架为您提供了开箱即用的工具,用于构建用户界面和/或与 Slack 等其他工作流程工具集成。使用这些工具之一开始,这样您就可以专注于从您的代理那里获得好的答案!

⚒️ 我们构建的: 因为我们的 Agent 是专门为事件响应而构建的,并且因为我们在 Slack 中处理事件,所以我们主要使用 Slack 作为我们的 UI。不过,它有其局限性,因此我们尽力解决这些问题(即,机器人不是通过模仿 ChatGPT 中的打字来显示代理正在响应,而是用“?”表情符号对 Slack 中的问题做出反应)。我们还设计了一个用于配置、报告、审核和分析的 Web UI。

专业提示: 请确保您的 LLM 代码尽可能解耦,以便在需要时可以轻松重构为另一个 UX。

好吧,让我们继续理论讨论模型、技术和框架!是时候开始动手构建您自己的代理了。

动手实验室:构建您自己的 AI 代理

1. 设置 Chainlit 应用程序

在我们深入研究构建 AI 的无尽兔子洞之前,我们将通过建立 Chainlit,一个用于构建对话助理界面的流行框架来为成功做好准备。

为什么选择Chainlit?

Chainlit 提供了一组用于建模对话交互的自以为是的构建块(例如线程、消息和步骤),以及用于与 LLM 交互的类似 ChatGPT 的用户界面。

它还提供与 Slack 和 Teams 等流行聊天工具的开箱即用集成,以及与 React 和 FastAPI 等流行工具接口的库,因此您可以根据需要将其构建到更大的应用程序中.

简而言之:Chainlit 将为我们消除大量脚手架和繁琐的工作,以便我们可以专注于开发 AI 助手并获取用户的反馈,而不是摆弄 UI 和配置。

目标

在本实验结束时,您将拥有一个可以运行的 Chainlit 应用程序,它可以简单地回显您所说的内容。我们将在下一篇文章中讨论人工智能集成。

先决条件

在我们开始之前,您需要进行一些设置:

  1. 一个有效的 Python 3.12 环境。我们建议使用 pyenv。
  2. Python 包管理器。我们将使用诗歌,但你可以使用任何你觉得舒服的东西。

设置完成后,继续。

项目设置

首先,设置您的项目,并将 chainlit 添加为依赖项:

mkdir roger
cd roger
poetry init --no-interaction
poetry add chainlit

Chainlit 样板文件

接下来,在项目的根目录中创建一个 app.py 文件,其中包含以下内容:

import chainlit as cl


@cl.on_message
async def handle_message(message: cl.Message) -> None:
    # Echo the message back to the user.
    await cl.Message(
        content=f"Received: {message.content}",
    ).send()

上面的代码是向Chainlit注册handle_message函数,这样每当收到消息时,这个函数就会运行。

目前,我们的函数只是将消息回显给用户,并以“已接收:”为前缀。

尝试一下

最后,旋转起来!当您进行更改时,您可以使用 --watch 热重新加载代码。

poetry run chainlit run app.py --watch

运行此命令将启动您的 Chainlit 应用程序并将浏览器打开到其 UI,您可以在其中发送消息并获取响应:

Guide: How to build an AI Agent for SRE Teams

2. 通过连接法学硕士让您的申请更加智能

通过我们的 Chainlit 应用程序支架,我们可以将其连接到 LLM,以便我们可以与其交谈并获得类似人类的响应。

为了简单起见,我们将使用 OpenAI 的托管 gpt-4o 模型,但使用其他提供程序只是语法问题。

目标

在本文结束时,您将能够提示 gpt-4o 模型并获得响应,类似于与 ChatGPT 交互的方式。我们还将确保机器人维护对话上下文,以便您可以提出后续问题。

先决条件

开始之前,您需要:

一个 OpenAI 帐户和一个 API 密钥

配置 OpenAI API 客户端

首先,我们将配置一个 API 客户端以与 OpenAI 的 API 进行交互。将以下代码添加到 app.py 的顶部:

mkdir roger
cd roger
poetry init --no-interaction
poetry add chainlit

向 LLM 发送消息

接下来,我们需要更新我们的handle_message函数来将用户的消息发送到OpenAI并获得响应,而不是仅仅回显它。将您的handle_message 函数替换为以下函数:

import chainlit as cl


@cl.on_message
async def handle_message(message: cl.Message) -> None:
    # Echo the message back to the user.
    await cl.Message(
        content=f"Received: {message.content}",
    ).send()

尝试一下

现在,如果您运行应用程序(或者使用 --watch 标志让它运行),您将能够提出问题并获得响应。

Guide: How to build an AI Agent for SRE Teams

治愈健忘症

如果您玩过一些游戏并提出了后续问题,您可能会注意到机器人不会“记住”您谈论过的任何内容。例如:

Guide: How to build an AI Agent for SRE Teams

发生这种情况是因为每次我们发送消息时,我们只向 LLM 发送一条消息,默认情况下没有“对话”的概念。

为了治愈这种健忘症,我们需要在每次发送新消息时发送对话中的所有消息。

Chainlit 通过提供 cl.chat_context.to_openai() 帮助器让我们轻松实现这一点,它以 OpenAI(和大多数其他提供商)期望的格式方便地为我们提供迄今为止交换的所有消息。

更新你的handle_message函数以将历史消息添加到最新消息之前:

poetry run chainlit run app.py --watch

现在我们可以提出后续问题了!

Guide: How to build an AI Agent for SRE Teams

3. 更快的反馈?️

完成第 1 部分的前几个步骤后,您可能已经注意到,当您提出需要长时间答复的问题时,在看到任何内容之前会出现延迟。

这可能会导致糟糕的用户体验(尤其是在第 3 部分的后面,当我们开始添加长时间运行的工具调用时),所以让我们解决这个问题。

目标

在此步骤结束时,您将能够实时看到您的机器人“输入”内容,类似于 ChatGPT。

流式传输

为了获得实时消息更新,我们需要更新我们的实现以使用“流”。基本上,每当我们收到一条消息时,我们都会立即回复一条空消息,使用 LLM 启动一个流,并在每次从流中收到新的响应块时更新我们的空消息。

这听起来可能很复杂,但其实非常简单!更新你的handle_message函数如下:

mkdir roger
cd roger
poetry init --no-interaction
poetry add chainlit

?‍? 所以,这是迄今为止的完整代码:

import chainlit as cl


@cl.on_message
async def handle_message(message: cl.Message) -> None:
    # Echo the message back to the user.
    await cl.Message(
        content=f"Received: {message.content}",
    ).send()

尝试一下

现在,当您提出问题时,您应该会看到您的机器人实时“打字”!

Guide: How to build an AI Agent for SRE Teams

4. 赋予您的代理专业化和个性?‍♂️

至此,我们已经构建了 ChatGPT 的轻量级克隆。这很酷,但我们真正想要的是一个能够帮助我们执行特定任务的助手:在这种情况下,我们希望它能够像 SRE 一样解决事件问题。

为了实现这一目标,我们首先将代理重构为自定义 OpenAI 助手,这将使我们能够控制系统提示(以及让 LLM 能够访问文件搜索和函数调用等工具,我们稍后会介绍)。

目标

到这一步结束时,您将把您的机器人重构为自定义“助手”,并自定义其系统提示以赋予其自己的“个性”。您的代码还将使用“线程”,它将使用 OpenAI API 保存消息,而不必每次收到新消息时都发送所有消息。

创建助手和线程

创建助手很简单:我们只需要调用 OpenAI Assistants API 即可。但是,我们只想在应用程序启动时执行一次此操作,因此我们不能将该 API 调用放在handle_message 函数中。

相反,我们将使用另一个 Chainlit 钩子 - on_chat_start,它只会在应用程序首次启动时运行一次 - 来设置我们的助手。

将其添加到您的 app.py:

poetry run chainlit run app.py --watch

注意:技术上可以通过在handle_message的消息历史记录中提供初始系统类型消息来为助手提供自定义系统提示。然而,我们正在重构一个具有自定义指令的助手,因为它解锁了我们将在不久的将来使用的其他几个功能。

重构消息处理以使用助手

现在我们有了一个用于对话的助手和一个线程,我们可以重构我们的消息处理程序来使用它们。

首先,我们需要一个 AssistantEventHandler 来告诉我们的新 Assistant 对象如何处理对话期间发生的各种事件。

将以下内容添加到您的 app.py:

import os
from openai import AsyncOpenAI


##
# Settings
#
try:
    OPENAI_API_KEY = os.environ["OPENAI_API_KEY"]
except KeyError as ex:
    raise LookupError(f"Missing required environment variable: {ex}")


client = AsyncOpenAI(api_key=OPENAI_API_KEY)


# ...

现在,我们只需要调整我们的handle_message函数就可以使用我们所有的新玩具了!将您的handle_message函数更新为以下内容:

# ...


@cl.on_message
async def handle_message(message: cl.Message) -> None:
    # Retrieve the response from the LLM
    response = await client.chat.completions.create(
        messages=[{"content": message.content, "role": "user"}],
        model="gpt-4o",
    )


    await cl.Message(content=response.choices[0].message.content).send()

?‍? 现在这是迄今为止的完整代码:

mkdir roger
cd roger
poetry init --no-interaction
poetry add chainlit

5. 授予您的代理访问您文档的权限

现在我们正在使用助手和线程,我们可以开始自定义行为。首先,我们将授予 Google 助理访问一些内部文档的权限,以便它可以提供更适合我们的用例的响应。

目标

在本节结束时,您的机器人将能够在响应提示时搜索文件集合(例如,您的 SRE 运行手册和其他内部文档)。

为了简单起见,我们将其实现为一个充满文件的文件夹,这些文件上传到矢量存储并提供给我们的助手。

创建矢量存储

我们需要做的第一件事是创建一个矢量存储并将其提供给我们的助手。

首先,更新我们的handle_chat_start函数的开头以包含以下内容:

import chainlit as cl


@cl.on_message
async def handle_message(message: cl.Message) -> None:
    # Echo the message back to the user.
    await cl.Message(
        content=f"Received: {message.content}",
    ).send()

接下来,更新对 client.beta.assistants.update() 的调用,以使助手能够访问矢量存储并启用 file_search 工具。

poetry run chainlit run app.py --watch

上传文档

最后,我们需要上传我们希望助手在回答提示时参考的文档。

首先,我们需要创建一个文件夹来放置文档:

import os
from openai import AsyncOpenAI


##
# Settings
#
try:
    OPENAI_API_KEY = os.environ["OPENAI_API_KEY"]
except KeyError as ex:
    raise LookupError(f"Missing required environment variable: {ex}")


client = AsyncOpenAI(api_key=OPENAI_API_KEY)


# ...

接下来,我们将收集文档并将其放入该文件夹中。出于测试目的,我已将以下虚假文档添加到我的文件夹中:

# ...


@cl.on_message
async def handle_message(message: cl.Message) -> None:
    # Retrieve the response from the LLM
    response = await client.chat.completions.create(
        messages=[{"content": message.content, "role": "user"}],
        model="gpt-4o",
    )


    await cl.Message(content=response.choices[0].message.content).send()

最后,我们将更新 handle_chat_start 函数,以自动将文档上传到我们之前创建的矢量存储中。在我们创建矢量存储的位置之后添加以下代码:

# ...


@cl.on_message
async def handle_message(message: cl.Message) -> None:
    # Retrieve the response from the LLM
    response = await client.chat.completions.create(
        messages=[
            # Prepend all previous messages to maintain the conversation.
            *cl.chat_context.to_openai(),
                {"content": message.content, "role": "user"}
            ],
        model="gpt-4o",
    )


    await cl.Message(content=response.choices[0].message.content).send()

ℹ️ 注意: 目前,我们仅支持 .md 文件,但 OpenAI 支持许多不同的文件类型,因此请随意将 glob 模式更新为对您的用例有意义的任何内容!

这将自动上传 ./docs 文件夹中的所有文件并将它们添加到我们的矢量存储中。

添加指标

文件搜索有时可能需要一段时间,尤其是对于较大的数据集。在这些情况下,您可能想让用户知道发生了什么,这样他们就不会感到沮丧。

幸运的是,Chainlit 通过提供 Step 类让这一切变得简单,我们可以用它来告诉用户后台正在发生什么事情。我们可以将 Step 类与我们之前构建的 MessageEventHandler 结合使用,并在任何调用工具时添加指示器。

将以下内容添加到您的 MessageEventHandler:

# ...
@cl.on_message
async def handle_message(message: cl.Message) -> None:
    # Send an empty initial message that we can update with a streaming
    # response.
    message = cl.Message(content="")
    await message.send()

    # Stream the response from the LLM
    stream = await client.chat.completions.create(
        messages=[
            # Prepend all previous messages to maintain the conversation.
            *cl.chat_context.to_openai(),
                {"content": message.content, "role": "user"}
            ],
        model="gpt-4o",
        stream=True,
    )
    # Update the existing (initially-empty) message with new content
    # from each "chunk" in the stream.
    async for chunk in stream:
        if token := chunk.choices[0].delta.content:
            await message.stream_token(token)
    # Send a final update to let the message know it's complete.
    await message.update()

尝试一下

现在您已经上传了一些自己的文档,请尝试提出一些更具体于您的用例的问题,看看您会得到什么!

对于我们的测试用例,当被问及客户数据库上的高 CPU 利用率时,它正确引用了我们的运行手册:

Guide: How to build an AI Agent for SRE Teams

?‍? 作为参考,这是迄今为止的完整代码:

mkdir roger
cd roger
poetry init --no-interaction
poetry add chainlit

6. 将您的代理连接到外部工具

我们的代理现在可以从我们精选的内部文档中检索数据,如果您有良好的文档,这将非常有用。然而,事件管理中的大量时间通常花在调查文档未涵盖的事情上:扫描警报、读取日志、解释指标等。

对于这些事情,我们希望让我们的助手能够调用外部 API - 更广泛地说,执行我们定义的函数 - 以便它可以根据需要收集更多上下文。

为此,我们将利用模型的“函数调用”功能来执行我们定义的函数。

目标

在本节结束时,您将让您的机器人能够在回答提示时使用外部工具(一个假的 PagerDuty 工具)来检索信息。

定义(假)工具

首先,让我们向 app.py 添加一个名为 get_pagerduty_alert_details 的新函数。

import chainlit as cl


@cl.on_message
async def handle_message(message: cl.Message) -> None:
    # Echo the message back to the user.
    await cl.Message(
        content=f"Received: {message.content}",
    ).send()

告诉 LLM 如何使用它

接下来,我们需要告诉LLM如何调用我们的工具。 OpenAI 需要 JSONSchema 格式的工具定义。

更新对 client.beta.assistants.update() 的调用,以在我们已有的 file_search 工具之后包含新的工具定义。

poetry run chainlit run app.py --watch

更新消息处理程序以处理工具调用

我们的 MessageEventHandler 目前处理来回消息事件,但调用工具需要一些特殊处理。

在响应您的提示时,LLM 将决定应调用哪些工具(如果有),并在响应负载中返回一个或多个“工具调用”定义,并告诉您该响应“需要采取行动”。为了实际执行该函数,我们需要处理这些“需要操作”响应。

我们可以通过更新 MessageEventHandler 类来实现 on_event 方法,以及用于执行函数调用并将结果添加到正在运行的线程的新的 handle_requires_action 方法来实现此目的:

import os
from openai import AsyncOpenAI


##
# Settings
#
try:
    OPENAI_API_KEY = os.environ["OPENAI_API_KEY"]
except KeyError as ex:
    raise LookupError(f"Missing required environment variable: {ex}")


client = AsyncOpenAI(api_key=OPENAI_API_KEY)


# ...

调整提示

提醒法学硕士应该在适用时尝试使用您提供的工具通常会很有帮助。在提示符末尾添加如下一行:

使用提供的工具收集有关事件的其他背景信息(如果适用)。

尝试一下

配置好工具后,您将能够在提示中包含 PagerDuty 链接,LLM 将在回答之前使用这些工具收集上下文:

Guide: How to build an AI Agent for SRE Teams

?‍? 完整代码如下:

mkdir roger
cd roger
poetry init --no-interaction
poetry add chainlit

总结

现在您已经准备好为您的 SRE 团队构建一个有用的 AI 代理了!如果您对本指南中介绍的任何内容有任何疑问,请联系我们,我们将很乐意为您提供帮助。同时,如果有任何遗漏或您想学习任何其他与 AI Agent 相关的内容,请告诉我们!

如果您想亲自尝试 Aptible AI 而不是构建自己的 Agent,可以访问 www.aptible.ai 进行注册。

以上是指南:如何为 SRE 团队构建 AI 代理的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn