How We Deployed our Multi-Agent Flow to LangGraph Cloud

我们如何将多代理流程部署到 LangGraph Cloud

阅读这篇客座博客文章,了解如何通过 React 和 LangGraph Cloud 创建 LangGraph 多代理流程。

5 分钟阅读

注意:这是一篇由 Fiverr 技术主管 Elisha Kramer 撰写的客座博客文章。他也是 Assaf Elovic 领导的 gpt-researcher Github 顶级项目的贡献者之一。

在体验了新的 LangGraph Cloud 功能后,我们非常兴奋,不得不写一篇关于它的文章。下面,我们将展示我们如何部署 LangGraph Cloud Host 并从 GPT Researcher 前端 (NextJS) 查询它。

什么是 GPT Researcher?

GPT Researcher 是一个开源的自主代理,旨在对各种任务进行全面的在线研究。该开源项目在过去一年中越来越受欢迎,拥有超过 1.3 万颗星和 4 千多名开发人员的社区。

GPT Researcher 也随着时间的推移不断发展,最初是一个成功的 RAG 实现,现在使用带有流行的 LangGraph 框架的多代理。

但仍然缺少一块。GPT Researcher 还没有一个顶级的前端应用程序,仍然基于简单的 HTML 和 CSS 构建。我们很高兴推出我们最新的客户端,它使用 NextJS 构建,旨在提供最佳的研究体验!在此处查看演示

LangGraph 如何融入其中?

当我们开始尝试构建能够通过问题进行推理的上下文感知 AI 代理时,我们发现了 LangChain 库和 LangGraph。

具体来说,我们对 LangGraph 的概念着迷:一个框架,可以使我们构建复杂的多代理流程,其中 AI 代理与其他代理协调,带来他们独特的视角并审查彼此的工作。

事实证明,LangGraph 非常适合!并且能够轻松地将我们的新前端连接到基于云的 GPT Researcher 版本,这听起来好得令人难以置信。

什么是 LangGraph Cloud?

LangGraph Cloud Host 背后的概念与 GraphQL API Server 背后的概念非常相似。

GraphQL API 服务器

  • 可以帮助抽象化对数据库的访问
  • 可以利用服务器语言的任何库

同样,LangGraph API 服务器也可以

  • 抽象化对 LangGraph 的访问
  • 利用 LangGraph 中使用的任何 pip 包

本质上,您正在部署一个 Python 服务器,其中内置了 LangGraph。在您进行此操作时,您会免费获得很多东西;以下是 LangGraph Cloud Host 上自动公开的 API 端点,以实现轻松的任务触发和图编辑。

我们部署了什么?

在我们的案例中,大部分工作是由 GPT-Researcher 的创始人 Assaf 完成的,当时他构建了一个利用 LangGraph 的多代理工作流程。(随意阅读这篇早期文章中的冒险经历:如何使用多代理协作构建终极 AI 自动化。)

一旦使用 LangGraph 构建了该多代理流程,就为未来的一些轻松胜利奠定了基础。几周后,Harrison(LangChain 的 CEO)介入并创建了一个拉取请求,使我们能够轻松部署 Assaf 预构建的 LangGraph:这是 GPT Researcher PR

该 PR 的美妙之处在于,它使我们的 GPT-Researcher LangGraph 可以轻松地通过 API 调用进行部署、编辑和使用自定义参数触发。哇!只需 4 个更改的文件即可从我们的开发环境转变为可扩展的生产就绪服务!

查询 LangGraph API 服务器

我花了一段时间才完全理解前 2 个步骤的简单性。触发多代理 LLM 工作流程不可能如此简单...对吧?

事实证明,就是这么简单。

在 Assaf 和 Harrison 代码的基础上,我们所需要做的就是以下步骤。

步骤 1:观看 Harrison 的部署教程

步骤 2:通过 LangSmith GUI 的“Deployments”选项卡部署我们的自定义 LangGraph。

在我们的案例中,我选择了我的 GPT Researcher 项目 fork,并指向 GPT Researcher multi_agents 目录中的 langgraph.json 配置文件(见下文)

步骤 3:将我的环境变量添加到我的 LangGraph Cloud 部署中。

这些应该足够了

请注意,在上面的屏幕截图中,LangGraph Cloud 将自动为我创建一个“Tracing Project”。

这意味着我们可以获得与 MVP 多代理流程相同的 LangSmith 跟踪优势。以下是它的外观

这是您获得的功能 - 一个强大的工具,用于

  • 使用户能够可视化和检查后端数据流
  • 质量保证调试 - 即,我们的 AI 流程的输入或输出在哪些方面可以改进

步骤 4:查询新部署的 LangGraph。

这是一个 React 代码示例


import { getHost } from '../../helpers/getHost';
import { Client } from "@langchain/langgraph-sdk";
import { task } from '../../config/task';


export async function startLanggraphResearch(newQuestion, report_source) {
   // Update the task query with the new question
   task.task.query = newQuestion;
   task.task.source = report_source;
   const host = getHost({purpose: 'langgraph-gui'});
   const client = new Client({apiUrl: host});
    // List all assistants
   const assistants = await client.assistants.search({
     metadata: null,
     offset: 0,
     limit: 10,
   });
   
   const agent = assistants[0];
    // Start a new thread
   const thread = await client.threads.create();
    // Start a streaming run
   const input = task;
    const streamResponse = client.runs.stream(
     thread["thread_id"],
     agent["assistant_id"],
     {
       input,
     },
   );


   return {streamResponse, host, thread_id: thread["thread_id"]};
}

在文件顶部导入的 task 对象可以被视为我们的 API 请求对象。它实际上与 Assaf 的 LangGraph 使用的 task.json 文件 完全相同。

getHost 函数返回 localhost:8123(对于 langgraph-cli 服务)或我们部署到的 LangGraph Cloud 服务器的域名。

这就是全部内容。上面的代码使我们能够在 LangGraph 服务器上触发运行 - 这在 LangSmith 用户界面上是完全可观察的!以下是上述代码的延续,它向用户显示 LangGraph 状态(每个任务)的状态,因为我们的多代理流程按部就班地运行

     const langsmithGuiLink = `https://smith.langchain.com/studio/thread/${thread_id}?baseUrl=${host}`;

     let previousChunk = null;

     for await (const chunk of streamResponse) {
       console.log(chunk);
       if (chunk.data.report != null && chunk.data.report != "Full report content here") {
         setOrderedData((prevOrder) => [...prevOrder, { ...chunk.data, output: chunk.data.report, type: 'report' }]);
         setLoading(false);
       } else if (previousChunk) {
         const differences = findDifferences(previousChunk, chunk);
         setOrderedData((prevOrder) => [...prevOrder, { type: 'differences', content: 'differences', output: JSON.stringify(differences) }]);
       }
       previousChunk = chunk;
     }
   }

请注意,在早期的代码片段中,我们使用了 client.runs.stream 方法。

这意味着 LangGraph API 服务器将以块的形式向我们反馈更新。这些块可以包含:当前正在运行的作业的更新状态或我们的 Python 脚本在已部署的 LangGraph 服务器上遇到的任何自定义错误。

在我们的案例中,我们希望向用户展示 LangGraph API 作业的自定义逐场记录 - 因此,我们还添加了一个 findDifferences 函数,其作用是计算两个 JavaScript 对象之间的差异。

如果 Graph 完成报告,则该报告将显示给用户。

如果 Graph 实时进行了一些字段编辑,则 Graph 中的这些差异将显示给用户。

总结

在这篇博文中,我们展示了如何通过 React 和 LangGraph Cloud 触发我们的 LangGraph 多代理流程。这些流程模仿人类推理,使其非常复杂。但是,正如上面的演练所示,一个优雅的 API 简化了流程,并使一切都轻松就位。