LangChain v0.1.0

LangChain v0.1.0

10 分钟阅读

今天我们激动地宣布发布 langchain 0.1.0,我们的首个稳定版本。它完全向后兼容,同时提供 PythonJavaScript 版本,并通过功能和文档改进了重点。LangChain 的稳定版本有助于我们赢得开发者的信任,并使我们能够系统且安全地发展该库。

介绍

LangChain 已经存在一年多一点了,并且随着它成长为构建 LLM 应用程序的默认框架而发生了很大变化。正如我们 一个月前预览 的那样,我们最近决定对 LangChain 包架构进行重大更改,以便更好地组织项目并加强基础。

具体来说,我们进行了两个大的架构更改:将 langchain-core 分离出来,并将合作伙伴包(分离到 langchain-community独立的合作伙伴包 中)从 langchain 中分离出来。

提醒一下,langchain-core 包含主要的抽象、接口和核心功能。此代码是稳定的,并且在一个多月以来一直遵循更严格的版本控制策略。

然而,langchain 本身仍然停留在 0.0.x 版本。所有版本都使用次要版本 0 带来了一些挑战

  • 用户无法确信更新不会带来破坏性更改
  • 随着我们采取“维护一切”的方法来减少破坏性更改和弃用通知,langchain 变得臃肿且不稳定

然而,从今天发布 langchain 0.1.0 开始,所有未来的版本都将遵循新的版本控制标准。具体来说

  • 对公共 API 的任何破坏性更改都将导致次要版本号(第二个数字)的提升
  • 任何错误修复或新功能都将导致补丁版本号(第三个数字)的提升

我们希望这与之前的架构更改相结合,将

  • 清楚地传达是否进行了破坏性更改,使开发人员能够放心地更新
  • 为我们提供正式弃用和删除旧代码的途径,减少臃肿
  • 更负责任地处理集成(其 SDK 通常像 LangChain 一样快速变化)

即使在我们发布 0.2 版本后,我们也将致力于维护 0.1 的分支,但只会修补关键的错误修复。请参阅本文末尾关于我们计划的更多内容。

在将软件包重新架构为通往稳定 0.1 版本的道路时,我们借此机会与数百名开发人员讨论了他们为什么使用 LangChain 以及他们喜欢它的哪些方面。这些输入指导了我们的方向和重点。我们还利用这个机会使 Python 和 JavaScript 版本在下面概述的核心领域中达到对等。

💡
虽然某些集成和更边缘的链可能是特定于语言的,但核心抽象和关键功能在 Python 和 JavaScript 包中均等地实现。

我们想分享我们听到的内容以及我们不断改进 LangChain 的计划。我们希望分享这些经验教训将提高我们思考和决策的透明度,使其他人能够更好地使用、理解和贡献 LangChain。毕竟,LangChain 的很大一部分是我们的社区——用户群和 2000 多名贡献者——我们希望每个人都加入这段旅程。

第三方集成

人们最喜欢 LangChain 的一点是,我们使其可以轻松地开始在任何堆栈上构建。我们有 近 700 个集成,范围从 LLM 到向量存储,再到代理使用的工具。

💡
LangChain 通常用作将构建 LLM 应用程序所需的所有不同部分连接在一起的“粘合剂”,因此优先考虑强大的集成生态系统对我们来说至关重要。

大约一个月前,我们开始进行一些更改,我们认为这些更改将提高围绕集成的稳健性、稳定性、可扩展性和总体开发人员体验。我们将所有第三方集成拆分到 langchain-community 中——这使我们能够集中进行特定于集成的工作。我们也开始将各个集成拆分到它们自己的包中。到目前为止,我们已经为 大约 10 个包 进行了此操作,包括 OpenAI、Google 和 Mistral。这样做的一个好处是更好的依赖管理 - 以前,所有依赖项都是可选的,这在尝试安装特定版本时导致了一些麻烦。现在,如果集成在它们自己的包中,我们可以更严格地控制其要求的版本,从而更容易安装。另一个好处是版本控制。通常,第三方集成会发生更改,这需要进行破坏性更改。现在,这些更改可以通过独立集成包中的适当版本控制反映在单个集成基础上。

可观测性

构建 LLM 应用程序涉及将非确定性组件置于系统的中心。这些模型通常会输出意外的结果,因此清楚地了解系统中正在发生的事情至关重要。

💡
我们希望使 langchain 尽可能地可观测和可调试,无论是通过架构决策还是我们构建的辅助工具。

我们通过几种方式着手解决这个问题。

我们解决这个问题的主要方法是构建 LangSmith。LangSmith 提供的主要价值主张之一是为您的 LLM 应用程序提供 一流的调试体验。我们记录正在发生的每个步骤、每个步骤的输入、每个步骤的输出、每个步骤花费的时间以及更多数据。我们以用户友好的方式显示这些信息,使您能够识别哪些步骤花费的时间最长,进入游乐场以调试意外的 LLM 响应,跟踪令牌使用情况等等。即使在私人测试版中,对 LangSmith 的需求也已势不可挡,我们正在对可扩展性进行大量投资,以便我们可以在未来几个月内发布公开测试版,然后使其普遍可用。我们还已经支持 企业版本,该版本带有 VPC 内部部署,适用于具有严格数据隐私政策的企业。

我们还通过其他方式解决了可观测性问题。长期以来,我们内置了 verbosedebug 模式,用于在整个管道中进行不同级别的日志记录。我们最近引入了 可视化您创建的链 以及 获取所有使用的提示 的方法。

可组合性

虽然拥有预构建的链来入门很有帮助,但我们经常看到团队突破这些架构,并希望自定义他们的链 - 不仅自定义提示,还自定义编排的不同部分。

💡
在过去的几个月中,我们对 LangChain 表达式语言 (LCEL) 进行了大量投资。这实现了任意序列的组合,为数据工程管道提供了与数据编排工具相同的许多好处(批处理并行化回退)。

它还提供了一些 LLM 工作负载独有的好处 - 主要是 LLM 特定的可观测性(上面已涵盖)和流式传输,将在本文后面介绍。

LCEL 的组件位于 langchain-core 中。我们已经开始为 LangChain 中特定链创建更高级别的入口点。这些将逐步取代预先存在的(现在是“旧版”)链,因为使用 LCEL 构建的链将开箱即用地获得流式传输、易于自定义、可观测性、批处理、重试。我们的目标是使这种过渡无缝衔接。以前您可能做过

ConversationalRetrievalChain.from_llm(llm, …)

我们希望简单地使其成为

create_conversational_retrieval_chain(llm, …)

在幕后,它将创建一个特定的 LCEL 链并返回它。如果您想修改逻辑 - 没问题!因为它全部用 LCEL 编写,所以很容易修改其中的一部分,而无需子类化任何内容或覆盖任何方法。

LangChain 中有很多链,其中很多链被大量使用。在替代构造函数存在并已被使用和充分测试之前,我们不会弃用链的旧版。

流式传输

LLM 有时可能需要一段时间才能响应。重要的是向最终用户展示正在进行的工作,而不是盯着空白屏幕。这可以是来自 LLM 的流式传输令牌的形式,也可以是流式传输中间步骤(如果链或代理运行时间较长)。

我们在这两方面都投入了大量资金。使用 LCEL 构建的所有链都公开了标准 streamastream 方法,并且我们做了很多工作来确保流式传输不仅仅是在 LLM 调用之外(例如,在输出解析器中)。所有链还公开了一个标准 astream_log 方法,该方法流式传输 LCEL 链中的所有步骤。然后可以对其进行过滤,以轻松获取所采取的中间步骤和其他信息。

💡
流式传输(令牌和中间步骤)是大多数 LLM 应用程序的关键 UX 组件,您可以通过 LangChain 免费获得它。

输出解析

LangChain 的主要用例之一是“工具使用”——使用 LLM 调用其他工具。

💡
确保 LLM 以可在下游应用程序中使用的结构化格式返回信息对于使 LLM 能够采取行动至关重要。

我们围绕这一点投入了大量资金来提供良好的开发人员体验,并提出了 输出解析器的概念

执行此操作的主要方法之一是使用 OpenAI 函数调用。我们不仅可以轻松指定输出格式(使用 Pydantic、JSON 模式甚至函数),还可以轻松处理响应。我们还支持几种不同的编码方法(JSONXMLYaml),当您想使用不支持 OpenAI 函数调用的模型并求助于使用提示时。当您求助于使用提示时,您还需要正确的指令来告诉 LLM 如何响应——所有输出解析器都配备了 get_format_instructions 方法来获取这些指令。

我们还对围绕输出解析器的更高级功能进行了投资,例如允许它们在生成部分结果时对其进行流式传输,以改善用户体验。这包括从 JSON、XML 和 CSV 等结构化格式流式传输部分结果。对于输出解析,有时可能会很棘手 - 为了解析 JSON blob,大多数 JSON 解析器都需要完整的 JSON blob。我们的许多输出解析器都包含内置逻辑来执行此部分解析。

检索

我们看到开发人员构建的 主要应用程序类型之一 是与他们的私人数据交互的应用程序。

💡
能够轻松地将您的数据与 LLM 结合使用是 LangChain 非常重要的组成部分。

这通常涉及两个不同的组件 - 摄取(准备数据)和检索(检索数据),我们都已构建了这两个组件。

在摄取方面,摄取的一个重要部分是将您正在处理的文本拆分为块。虽然这看起来很简单,但最好的方法通常是细致入微的,并且通常特定于您正在处理的文档类型。我们有 15 种不同的文本拆分器,其中一些针对特定文档类型进行了优化(例如 HTMLMarkdown),以便为开发人员提供对此过程的最大控制权。但是,相关数据通常在变化,我们的摄取系统专为生产、规模化的应用程序而设计。我们公开了一个 索引 API,允许您重新摄取内容,同时忽略未更改的部分 - 从而节省大量工作负载的时间和成本。

在检索方面,我们投入了更先进的方法,同时使检索更适合生产。我们实施了来自学术界的 高级检索策略(如 FLARE 和 Hyde),创建了我们自己的策略(如 父文档自查询),并改编了一些来自其他行业解决方案的策略(如 多查询 - 源自搜索中常用的查询扩展)。我们还确保支持生产问题,例如 按用户检索 - 这对于您将多个用户的文档存储在一起的任何应用程序都至关重要。

重要的是,虽然 LangChain 提供了构建高级检索系统所需的所有组件,但我们对如何这样做并没有过多的意见。这导致许多其他库在 LangChain 的基础上构建,以提供更具主观性的检索方法 - 例如 EmbedChainGPTResearcher

代理

LangChain 最早为人所知的事情之一是代理工作负载。这可能意味着两件事

  1. 工具使用:让 LLM 调用函数或工具
  2. 推理:如何最好地使 LLM 多次调用工具,以及以什么顺序调用工具(或者根本不调用工具!)

在工具使用方面,我们已经基本涵盖了我们认为至关重要的组件

  1. 与大量第三方工具集成
  2. 构建 LLM 响应以适应这些工具的输入模式的方法
  3. 一种灵活的方式来指定应调用这些工具的自定义方式 (LCEL)

在推理方面,我们有 几种不同的“代理”方法,这些方法在很大程度上可以被认为是 LLM 在循环中运行,每次迭代都决定它需要调用哪个(如果有)工具,然后观察该工具的结果。我们从一开始就加入了 ReAct(一种早期用于执行此操作的提示策略),并迅速添加了许多其他类型,包括使用 OpenAI 函数调用 的类型,使用其 新工具调用 API 的类型,针对对话优化的类型等等。

💡
通过灵活且可扩展的工具支持和高级推理能力,LangChain 已成为使 LLM 能够采取行动的默认方式。

与检索类似,虽然 LangChain 提供了代理的构建块,但我们也看到了几个建立在其之上的更具主观性的框架。一个很好的例子是 CrewAI,它建立在 LangChain 之上,为多代理工作负载提供更简单的界面。

LangChain 0.2

即使我们刚刚发布了 LangChain 0.1,我们已经在考虑 0.2 了。我们最关心的一些事情是

  • 在 LCEL 中重写旧版链(具有更好的流式传输和调试支持)
  • 添加新型链
  • 添加新型代理
  • 改进我们的生产摄取能力
  • 删除旧的和未使用的功能

重要的是,即使我们很高兴删除一些旧的和旧版代码,以使 langchain 更精简和更专注,我们也希望为仍在使用旧版本的人们保持支持。这就是为什么我们将把 0.1 作为稳定分支(修补关键错误修复)维护至少在 0.2 版本发布后的 3 个月。我们计划从今以后的每个稳定版本都这样做。

如果您一直想开始贡献,那么现在是最好的时机。如果您正在寻找开始的地方,我们最近在 GitHub 上添加了 一个良好的入门问题

还有一件事

LangChain v0.1.0 的很大一部分是稳定性和专注于上面概述的核心领域。既然我们已经确定了人们喜欢 LangChain 的领域,我们就可以致力于在那里添加更高级和更完整的工具。

人们喜欢 LangChain 的主要原因之一是它对代理的支持。大多数代理在很大程度上被定义为在某种循环中运行 LLM。到目前为止,我们实现这一目标的唯一方法是使用 AgentExecutor。我们向 AgentExecutor 添加了许多参数和功能,但它仍然只是一种运行循环的方式。

💡
我们很高兴地宣布发布 langgraph,这是一个新的库,允许将语言代理创建为图。

这将允许用户创建更自定义的循环行为。您可以定义显式的计划步骤、显式的反思步骤,或者轻松地硬编码它,以便始终首先调用特定工具。

它受到 PregelApache Beam 的启发。当前公开的界面是受 NetworkX 启发的界面,看起来像

from langgraph.graph import END, Graph

workflow = Graph()

workflow.add_node("agent", agent)
workflow.add_node("tools", execute_tools)

workflow.set_entry_point("agent")

workflow.add_conditional_edges(
    "agent",
    should_continue,
    {
        "continue": "tools",
        "exit": END
    }
)

workflow.add_edge('tools', 'agent')

chain = workflow.compile()

在过去的六个月中,我们一直在为此努力,并与用户进行 Beta 测试。它目前为 OpenGPTs 提供支持。在接下来的几周内,我们将添加更多示例和文档 - 我们对此感到非常兴奋!

在此处试用。

结论

LangChain 随着生态系统发生了重大演变。我们非常感谢我们的社区和用户推动我们并与我们一起构建。通过 0.1 版本,我们花时间了解了您在 LLM 框架中想要和需要什么,并仍然致力于构建它。随着社区的需求不断发展(或者如果我们遗漏了某些内容),我们希望听到您的反馈,以便我们能够解决它。他们说:“千里之行,始于足下。”——或者在我们的例子中,版本 0.1。