OpenGPTs 是什么呢?不久前,在 OpenAI 开发日推出的 OpenGPTs:一种可能的开源 GPT 商店形态。它由 LangGraph 的一个早期版本驱动, LangGraph 是 LangChain 的一个扩展,旨在构建作为图(graphs)的代理。两周之前发布的 LangGraph,上周末又将 OpenGPTs 更新为完全使用 LangGraph(还新增了一些功能)。
在这篇博客中,我们将讨论:
- 消息图 MessageGraph:OpenGPTs 所运行的一种特殊图
- 认知架构 Cognitive architectures:OpenGPTs 支持的三种不同类型的认知架构,以及它们的区别
- 持久性 Persistence:如何通过 LangGraph 检查点在 OpenGPTs 中加入持久性
- 配置 Configuration:如何使用 LangChain 原始模型配置所有这些不同的机器人
- 新模型 Configuration:支持的新模型
- 新工具 New tools:支持的新工具
- astream_events:如何使用这种新方法来流式传输令牌和中间步骤
消息图 MessageGraph
OpenGPTs 运行在 MessageGraph 上,它是在 LangGraph 中引入的一种特殊图。这个图特殊的地方在于,每个节点都接受一个消息列表,并返回要添加到消息列表的消息。这种"消息传递"有几个有趣的点:
- 它与新的"聊天完成"模型的 I/O 密切相关,其接受一个消息列表并返回一个消息
- 消息传递是分布式系统中常见的通信方式
- 这种方式可以更容易地可视化正在进行的工作,因为每个工作单元的类型都是常见的
- 它与 OpenAI 引入的助手 API 密切相关(其中消息添加到线程上)
- 它在概念上似乎可以扩展到多代理系统(每个代理只将消息添加到消息列表)
通过使用 MessageGraph,我们对创建的代理的输入和输出做了假设,但显著的是,我们对这些代理的认知架构没有做任何假设。正如我们下面看到的,这可以支持各种各样的认知架构。
认知架构 Cognitive architectures
作为对 OpenGPTs 的这次更新的一部分,用户创建机器人时可以选择以下三种不同的认知架构。
- 助手(Assistants):这些可以分配任意数量的工具,使用 LLM 决定何时使用它们
- RAG:这些配备了一个略取器(retriever)
- 聊天机器人(ChatBot):这些只是由一个自定义的系统消息参数化
助手(Assistants)
助手可以分配任意数量的工具,并使用 LLM 决定何时使用它们。这使得它们成为最灵活的选择,但是,它们在模型较少的情况下工作得不是很好,并且可能不那么可靠。
当创建一个助手时,要指定一些事情。 首先,你选择要使用的语言模型。目前可供使用的只有几种语言模型:GPT-3.5、GPT-4、Claude和Gemini。 其次,你选择要使用的工具。这些可以是预定义的工具,也可以是从上传的文件构建的检索器,你可以选择你想要的任何数量。 然后,可以将认知架构看作是一个循环。首先,LLM 被调用,以确定要采取什么样的行动(如果有的话)。如果决定采取行动,那么执行这些行动并返回循环。如果没有决定采取任何行动,那么 LLM 的响应就是结束循环。
这可以是一个非常强大而灵活的架构。这可能与我们人类的操作方式最接近。然而,这些可能并不总是非常可靠,一般只有在性能更强的模型中才有效(即使是在这些模型中,他们也可能出错)。因此,我们可以看一些更简单的架构。
RAG
GPT 商店的一个大案例是上传文件并使机器人了解这些文件。如果我们制作一个更专注于这个用例的架构,会是什么样的结果呢?
我们添加了一个 RAG 机器人 - 一个以获取为中心的 GPT,具有简单的架构。首先,检索一套文件。然后,这些文件在系统消息中传递给语言模型,以便语言模型可以作出回应。
与助手相比,它的结构更紧密(但功能更少)。它总是会寻找一些东西,如果你知道你想寻找一些东西,这是好的,但如果用户只是试图进行正常对话,可能会有些浪费。并且重要的是,这个架构只会查找一次东西 - 所以如果它没有找到正确的结果,就会产生糟糕的结果(与助手相比,后者可能决定再次查找东西)。
尽管这是一个更简单的架构,它有几个好处。首先,因为它更简单,所以它可以很好地使用各种各样的模型(包括大量的开源模型)。其次,如果你有一个用例,你不需要助手的灵活性(例如,你知道用户每次都会查找信息),那么它可以更专注。第三,与下面的最终架构相比,它可以使用外部知识。
聊天机器人 (ChatBot)
最后的架构非常简单 - 只是对语言模型的调用,由一个系统消息参数化。这使得 GPT 可以扮演不同的角色和人物。肯定地说,它明显比助手或 RAGBot(它们可以访问外部数据或计算的来源)要弱得多。但是,它仍然有价值!大多数受欢迎的 GPT 最终都只是系统消息,尽管在很大程度上只是系统消息,CharacterAI也做得非常成功。
持久性 (Persistence)
从一开始,OpenGPTs 就需要有持久性,特别是聊天消息的持久性。与其为此构建一个特别的解决方案,不如将此功能作为 LangGraph 的一部分加入。具体来说,当创建一个图时,可以传递一个 CheckPoint 对象。然后,每次调用一个节点,这个检查点对象将保存当前图的状态。
对于 OpenGPT,我们创建了一个 RedisCheckPointer,它将结果保存到 Redis。目前,这种持久性只是用于显示过去对话的消息,但我们很快就会以更高级的方式使用这种持久性。
配置
OpenGPTs 的另一个需求是配置。我们需要用户能够选择使用哪种 LLM,哪种系统消息,哪种工具等。我们还需要保存该配置,以便他们将来可以再次使用该聊天机器人。
LangChain 的一个被低估的特性是可以将某些字段标记为可配置的。你可以对任何链的字段进行此操作,然后在运行时传入配置选项。
这使我们能够以模块化和一致的方式轻松完成配置。首先,我们将不同的字段标记为可配置的,为了支持不同的架构,我们甚至给整个链提供了可配置的替代方案。然后,当用户创建一个 GPT 时,我们会保存配置。最后,与该 GPT 进行聊天时,我们将使用保存的配置来调用链。
查看 OpenGPT 源代码可以找到如何执行此操作的一些高级示例,但是请记住,所有的 LangChain 对象都可以这样做!
新模型
随着此次更新,还希望引入一些新模型。首先,我们集成了 Google 的 Gemini 模型。这个模型效果非常好,支持函数调用,因此我们将其添加为助手的一个选项。 添加了 Mixtral(通过 Fireworks)作为 ChatBot 和 RAGBot 的一种选项。在这些较简单的架构下,它的工作效果非常好! 同时还更新了 OpenAI 代理,改为使用工具调用而不是函数调用。
新工具
引入了一个新工具 - Robocorp 的 Action Server。Robocorp 的 Action Server 是定义和运行任意 Python 函数作为工具的一种简单方法。因此,即使这只是单一的工具,也可以用它来定义许多不同的工具!
请留意我们在本周后期深入研究这一点。
astream_events
值得一提的是,我们正在使用新 astream_events 方法轻松地将所有事件(新令牌以及函数调用和函数结果)流回并向用户显示。我们对这个流进行了一些过滤,以获取相关的消息或消息块,然后在用户界面中对它们进行漂亮的呈现。