1 快速开始
1.1 说明
01.常用信息1
a.介绍
LangChain 是一个基于大型语言模型(LLM)开发应用程序的框架。
b.LangChain 简化了LLM应用程序生命周期的每个阶段:
开发:使用 LangChain 的开源构建模块和组件构建应用程序。使用第三方集成(opens in a new tab)和模板(opens in a new tab)快速上手。
生产化:使用LangSmith检查、监控和评估你的链条,以便你可以持续优化和自信地部署。
部署:使用LangServe(opens in a new tab)将任何链条转变为 API。
c.该框架由以下开源库组成
langchain-core:基本抽象和 LangChain 表达式语言
langchain-community:第三方集成,langchain-openai,langchain-anthropic
-----------------------------------------------------------------------------------------------------
langchain:构成应用程序认知架构的链条、代理和检索策略
langgraph(opens in a new tab):通过将步骤建模为图中的边缘和节点,使用LLMs构建强大且有状态的多角色应用程序
langserve(opens in a new tab):将 LangChain 链条部署为 REST API
-----------------------------------------------------------------------------------------------------
LangSmith:开发人员平台,可让你对LLM应用程序进行调试、测试、评估和监控,并与LangChain无缝集成
02.常用信息2
a.说明
LangChain 是一个用于开发由语言模型驱动的应用程序的框架。
我们相信,最强大和不同的应用程序不仅将通过 API 调用语言模型
-------------------------------------------------------------------------------------------------
数据感知:将语言模型与其他数据源连接在一起。
主动性:允许语言模型与其环境进行交互。
因此,LangChain 框架的设计目标是为了实现这些类型的应用程序。
c.两个主要的价值主张
组件:LangChain 为处理语言模型所需的组件提供模块化的抽象。LangChain 还为所有这些抽象提供了实现的集合。这些组件旨在易于使用,无论您是否使用 LangChain 框架的其余部分。
用例特定链:链可以被看作是以特定方式组装这些组件,以便最好地完成特定用例。这旨在成为一个更高级别的接口,使人们可以轻松地开始特定的用例。这些链也旨在可定制化。
因此,我们将以下文档分为这两个价值主张。在本文档中,我们以高层次和与语言无关的方式介绍组件和用例。有关使用这些组件和解决这些用例的语言特定方式,请参见页面顶部链接的语言特定部分。
1.2 安装
01.正式版
a.命令
pip install langchain
b.说明
这将安装LangChain的最低要求。集成LangChain与各种模型提供程序、数据存储等的价值很大。
默认情况下,安装这些集成所需的依赖项没有安装。您需要单独安装特定集成的依赖项。
02.合集1
a.从源代码安装
如果您想从源代码安装,请通过克隆存储库,并确保目录为PATH/TO/REPO/langchain/libs/langchain运行以下命令:
---
pip install -e .
---
b.LangChain核心
langchain-core包包含LangChain生态系统的基本抽象,以及LangChain表达语言。它会自动被langchain安装,但也可以单独使用。用以下命令安装:
---
pip install langchain-core
---
c.LangChain社区版
langchain-community包包含第三方集成。它会自动被langchain安装,但也可以单独使用。用以下命令安装:
---
pip install langchain-community
---
d.LangChain实验版
langchain-experimental包包含实验性的LangChain代码,用于研究和实验用途。使用以下命令安装:
---
pip install langchain-experimental
---
03.合集2
a.LangGraph
langgraph是一个用于构建具有LLMs、基于LangChain的有状态多参与者应用程序的库。使用以下命令安装:
---
pip install langgraph
---
b.LangServe
LangServe可帮助开发人员将LangChain可运行文件和链部署为RESTAPI。LangServe会自动被LangChainCLI安装。如果未使用LangChainCLI,请使用以下命令安装:
---
pip install "langserve[all]"
---
同时安装客户端和服务器依赖。或者使用pipinstall"langserve[client]"安装客户端代码,使用pipinstall"langserve[server]"安装服务器代码。
c.LangChainCLI
LangChainCLI对于使用LangChain模板和其他LangServe项目非常有用。使用以下命令安装:
---
pip install langchain-cli
---
d.LangSmithSDK
LangSmithSDK会根据LangChain自动安装。如果未使用LangChain,请使用以下命令安装:
---
pip install langsmith
1.3 场景示例
01.应用程序编程接口:API
API(应用程序编程接口)非常强大,因为它们既允许您通过它们执行操作,也可以通过它们查询数据。本页面介绍了 LangChain 中用于处理 API 的所有资源。
---------------------------------------------------------------------------------------------------------
链式操作( Chains )
如果您刚刚开始,且拥有相对较小/简单的API,您应该从链式操作( Chains )开始。链式操作是一系列预定步骤,因此它们非常适合入门,因为它们能够提供更多的控制并让您更好地理解正在发生的事情。
---------------------------------------------------------------------------------------------------------
代理( Agents )
代理更复杂,需要多次查询语言模型以了解如何操作。代理的缺点是您拥有的控制权较少。优点是它们更强大,使您能够在更大或更复杂的API上使用它们。
02.聊天机器人 Chatbots
ChatGPT 以其提供全新的接口——聊天( chat )而席卷了全球。构建聊天机器人需要几个组成部分。
模型 - 您可以使用普通的语言模型或聊天模型构建聊天机器人。重要的是要记住,即使您使用的是聊天模型,API本身是无状态的,这意味着它不会记住先前的交互 - 您必须将它们传递进去。
PromptTemplate(提示模板)- 这将指导您的聊天机器人的行为方式。它们是率性的还是乐于助人的?这些可以用来赋予您的聊天机器人一些个性。
Memory(记忆)- 如上所述,模型本身是无状态的。记忆为聊天机器人带来了一定的状态概念,使其能够记住先前的交互。
将聊天机器人与其他数据源结合使用时,聊天机器人通常非常强大且更具差异化。与"在文档上进行问答"的基本技术相同,也可以在这里使用,使您的聊天机器人能够访问这些数据。
03.评估的方法,Evaluation
评估 LangChain 链式操作和代理可能非常困难。
---------------------------------------------------------------------------------------------------------
这主要有两个原因:
缺乏数据
在开始项目之前,通常很难获得用于评估链式操作和代理的大量数据。
这通常是因为大型语言模型(大多数链式操作和代理的核心)具有出色的小样本和零样本学习能力,
这意味着您几乎总是能够在特定任务(如文本到 SQL、问答等)上开始,而无需大量的示例数据集。
这与传统的机器学习形成鲜明对比,传统机器学习在使用模型之前必须先收集大量数据点。
---------------------------------------------------------------------------------------------------------
缺乏评估指标
大多数链式操作和代理执行的任务往往没有很好的评估指标来评估性能。例如,生成某种形式的文本比评估分类预测或数值预测要复杂得多。
04.提取,Extraction
语言模型实际上非常擅长从非结构化文本中提取结构化信息。这非常有用,因为很多信息都以文本形式存储,但为了在下游使用时更方便,通常需要将其转换为结构化格式。
在这里理解的最有用的概念是 OutputParser(输出解析器)。OutputParser 负责指定语言模型应该以何种模式响应,并将其原始文本输出解析为结构化格式。
在进行提取时,您可以使用 OutputParser 定义要提取的信息的模式。然后,您可以创建一个 PromptTemplate(提示模板),该模板接收原始文本块,并包含提取信息的指令,使其以指定的格式提取信息。
05.个人助理,Personal Assistants
个人助理是一个非常理想的应用场景,因为它结合了 LangChain 的两个核心价值主张(行动执行和个性化数据)。为了构建一个个人助理,您需要了解以下概念:
PromptTemplate(提示模板)- 这将指导您的个人助理的行为方式。它们是率性的还是乐于助人的?这些可以用来赋予您的个人助理一些个性。
Memory(记忆)- 您的个人助理可能需要记住一些事情。它应该能够进行对话(短期记忆),并且可能还需要一些长期记忆的概念。
Tools(工具)- 您的个人助理将通过您提供的工具来展现其特点。它应该知道如何做什么?
Agent(代理)- 您的个人助理将需要理解它应该采取的行动。构建尽可能好的代理将非常重要。
Agent Executor(代理执行器)- 在获得了工具和代理之后,为了将其付诸实践,您需要设置一个环境供代理使用这些工具。这就是代理执行器发挥作用的地方。
06.基于文档的问答,Question Answering Over Documents
虽然LLM非常强大,但它们对于它们未经训练的信息一无所知。如果您想使用LLM来回答它未经训练的文档相关问题,您需要向其提供这些文档的信息。最常用的方法是通过"检索增强生成"( retrieval augmented generation )。
检索增强生成的思想是,在给定一个问题时,首先进行检索步骤以获取任何相关文档。然后将这些文档与原始问题一起传递给语言模型,并让它生成一个回答。然而,为了做到这一点,首先需要将文档以适合进行此类查询的格式呈现。
本页介绍了这两个步骤的高级思想:
(1)将文档摄入到可查询格式中,然后
(2)进行检索增强生成链。
---------------------------------------------------------------------------------------------------------
摄入,Ingestion
为了使用语言模型与数据进行交互,您首先需要将其转换为适合的格式。这种格式可以是索引( Index )。通过将数据放入索引中,可以使后续的步骤更容易与之交互。
有几种类型的索引,但最常见的是向量存储( Vectorstore )。将文档摄入到向量存储中可以按照以下步骤完成:
1.加载文档(使用文档加载器)
2.分割文档(使用文本分割器)
3.为文档创建嵌入(使用文本嵌入模型)
4.将文档和嵌入存储到向量存储中
---------------------------------------------------------------------------------------------------------
生成,Generation
现在我们有了一个索引,如何使用它进行生成呢?可以将此过程分为以下步骤:
1.接收用户提问
2.在索引中查找与问题相关的文档
3.使用问题和任何相关文档构建一个 PromptValue(使用 PromptTemplate )
4.将PromptValue传递给模型
5.获取结果并返回给用户。
07.表格数据查询,Querying Tabular Data
大量的数据和信息存储在表格数据中,无论是 CSV 文件、 Excel 表格还是 SQL 表格。本页面介绍了 LangChain 中用于处理这种格式数据的所有资源。
---------------------------------------------------------------------------------------------------------
文档加载( Document Loading )
如果您的文本数据以表格格式存储,您可能希望将数据加载到文档中,然后像处理其他文本/非结构化数据一样对其进行索引。
为此,您应该使用像 CSVLoader 这样的文档加载器,然后在该数据上创建索引,并进行查询。
---------------------------------------------------------------------------------------------------------
查询( Querying )
如果您有更多的数值型表格数据,或者有大量数据且不想对其进行索引,您也可以直接使用语言模型进行交互。
---------------------------------------------------------------------------------------------------------
链式操作( Chains )
如果您刚刚开始,且拥有相对较小/简单的表格数据,您应该从链式操作( Chains )开始。
链式操作是一系列预定步骤,因此它们非常适合入门,因为它们能够提供更多的控制并让您更好地理解正在发生的事情。
---------------------------------------------------------------------------------------------------------
代理( Agents )
代理更复杂,需要多次查询语言模型以了解如何操作。代理的缺点是您拥有的控制权较少。优点是它们更强大,使您能够在更大的数据库和更复杂的模式上使用它们。
2 核心概念
2.1 代理:agents
00.汇总
有些应用程序不仅需要预定的LLM/其他工具的调用链,还可能需要根据用户的输入构建未知的链条。
在这些类型的链条中,有一个"代理"(agent)可以访问一套工具。根据用户的输入,代理可以决定是否调用这些工具中的任何一个。
-----------------------------------------------------------------------------------------------------
我们将文档拆分为以下几个部分:
工具(Tools):语言模型与其他资源的交互方式。
代理(Agents):驱动决策的语言模型。
工具包(Toolkits):一组工具,当它们一起使用时可以完成特定的任务。
代理执行器(Agent Executor):负责运行带有工具的代理的逻辑。
01.代理执行器,Agent Executor
代理执行器( Agent Executor )是一个代理( Agent )和一组工具( Tools )。
代理执行器负责调用代理,获取动作和动作输入,根据动作引用的工具以及相应的输入调用工具,获取工具的输出,
然后将所有这些信息传递回代理,以获取它应该采取的下一个动作。
代理执行器充当了协调和管理代理与工具之间交互的角色。
它通过调用代理获取动作和动作输入,然后根据动作引用的工具调用相应的工具进行处理。
最后,将工具的输出和其他相关信息传递回代理,以便代理决定下一步应该采取的动作。
代理执行器将代理与工具的使用组织起来,以实现更复杂的任务或问题的解决。
02.代理,Agent
代理( Agent )是围绕模型的封装,它接收用户输入并返回与 “动作 action ”相对应的响应,以及相应的 “动作输入 action input ”。
代理的作用是接收用户的输入,并根据模型的处理逻辑生成相应的响应。这个响应通常包括执行的动作和对应的动作输入,用于进一步指导系统的行为。
代理起到了将用户输入与模型的交互进行封装和管理的作用。
03.工具,Tool
工具(Tool)是围绕函数的具体抽象,使语言模型可以与之进行交互变得简单。具体而言,工具的接口具有单一的文本输入和单一的文本输出。
04.工具包,Toolkits
工具包( Toolkits )是一组工具的集合,可以用于解决特定问题或完成特定任务。
这些工具包是为了一起使用、相互协作以实现更复杂的目标而组织起来的。
使用工具包可以提供更全面、高效的解决方案,因为它们涵盖了解决特定问题所需的各个方面或阶段。
2.2 链:chains
00.汇总
链( Chains )是一个非常通用的概念,它指的是将一系列模块化组件(或其他链)以特定方式组合起来,以实现共同的用例。
最常用的链类型是LLMChain(LLM链),它结合了PromptTemplate(提示模板)、Model(模型)和Guardrails(守卫)来接收用户输入,进行相应的格式化,
将其传递给模型并获取响应,然后验证和修正(如果需要)模型的输出。
01.链,Chain
链(Chain)是对多个独立组件进行端到端封装的一种方式。
02.索引链,Index-related chains
a.说明
这类链用于与索引进行交互。这些链的目的是将自己的数据(存储在索引中)与LLM结合起来。其中最好的例子是对自己的文档进行问答。
其中一个重要部分是了解如何将多个文档传递给语言模型。有几种不同的方法或链来实现这一点。
LangChain 支持其中四种常见的方法,并且我们正在积极寻求包括更多方法,如果你有任何想法,请随时联系我们!
请注意,并没有一种最佳方法-选择使用哪种方法通常非常依赖上下文。按照从简单到复杂的顺序:
b.Stuffing(填充)
Stuffing 是最简单的方法,您只需将所有相关数据作为上下文直接添加到提示中,然后传递给语言模型。LangChain 中的 StuffDocumentsChain 便是采用了这种方法。
优点:只需向LLM发出一次调用。在生成文本时,LLM 可以一次性访问所有数据。
缺点:大多数LLM具有上下文长度限制,对于大型文档(或许多文档),这种方法将不起作用,因为提示的长度将超过上下文长度。
这种方法的主要缺点是它只适用于较小的数据片段。一旦您处理许多数据片段,这种方法就不再可行。接下来的两种方法旨在帮助处理这个问题。
c.Map Reduce(映射-归约)
该方法涉及对每个数据块运行初始提示(对于摘要任务,可以是该块的摘要;对于问答任务,可以是仅基于该块的答案)。然后运行不同的提示来组合所有初始输出。LangChain中实现了这种方法,称为 MapReduceDocumentsChain。
优点:可以扩展到比 StuffDocumentsChain 更大的文档(以及更多的文档)。对各个文档进行的LLM调用是独立的,因此可以并行化处理。
缺点:比 StuffDocumentsChain 需要更多对 LLM 的调用。在最终的组合调用中会丢失一些信息。
d.Refine(优化)
该方法涉及在第一个数据块上运行初始提示,生成一些输出。对于剩余的文档,将该输出与下一个文档一起传递给LLM,要求LLM基于新文档优化输出。
优点:可以获取更多相关的上下文,并且可能比 MapReduceDocumentsChain 更少损失信息。
缺点:比 StuffDocumentsChain 需要更多对LLM的调用。这些调用也不是独立的,这意味着无法像 MapReduceDocumentsChain 那样进行并行化处理。还可能对文档的顺序造成潜在的影响。
e.Map-Rerank(映射-重新排序)
这种方法涉及在每个数据块上运行初始提示,该提示不仅尝试完成任务,还为其答案的确定程度给出一个分数。然后根据这个分数对响应进行排序,返回最高分的响应。
优点:与MapReduceDocumentsChain类似的优点。与MapReduceDocumentsChain相比,需要更少的调用。
缺点:无法在文档之间合并信息。这意味着当您期望在单个文档中有一个简单的单一答案时,这种方法最为有用。
03.LLM链,LLMChain
LLMChain(LLM链)是最常见的链类型。
它由 PromptTemplate(提示模板)、模型(可以是 LLM 或 ChatModel )和可选的输出解析器组成。
该链接受多个输入变量,使用 PromptTemplate 将它们格式化为提示。然后将提示传递给模型。
最后,它使用 OutputParser(如果提供)将LLM的输出解析为最终格式。
04.提示选择器,Prompt Selector
在 LangChain 中,链的一个目标是让人们尽快开始使用特定的用例。这其中一个重要部分是拥有良好的提示。
问题是,对一个模型有效的提示对另一个模型可能效果不佳。我们希望链对所有类型的模型都能够良好工作。
因此,我们没有在链中硬编码默认提示的使用方式,而是引入了 PromptSelector 的概念。PromptSelector 负责根据传入的模型选择一个默认提示。
PromptSelectors 的最常见用例是为 LLM 和 Chat Model 设置不同的默认提示。然而,如果需要,也可以为不同的模型提供商设置不同的默认提示。
2.3 索引:indexes
01.加载文档,Document Loaders
Document Loaders负责加载文档对象列表的类。
02.检索数据,Retriever
一种存储数据的方式,使其可以被语言模型查询。该对象必须提供的唯一接口是get_relevant_texts方法,它接收一个字符串作为输入,并返回一个文档列表。
03.文档拆分,Text Splitters
通常您想将大型文本文档分成更小的块以更好地处理语言模型。TextSplitters 负责将文档拆分成较小的文档。
04.向量存储库,Vectorstore
最常见的索引类型是为每个文档创建数值嵌入(通过嵌入模型(Embedding Model)生成)。
向量存储库(Vector Store)存储文档和相关的嵌入,并提供通过嵌入快速查找相关文档的方法。
2.4 内存:memory
00.汇总
内存(Memory)是在对话过程中存储和检索数据的概念。主要有两种方法:
1.根据输入,获取任何相关的数据。
2.根据输入和输出,相应地更新状态。
---------------------------------------------------------------------------------------------------------
内存主要分为两种类型:短期内存和长期内存。
1.短期内存通常指的是如何在单个对话的上下文中传递数据(通常是先前的聊天消息或其摘要)。
2.长期内存处理的是如何在对话之间获取和更新信息的问题。
01.记录聊天历史,ChatMessageHistory
目前,与语言模型的主要接口是通过聊天界面进行的。ChatMessageHistory类负责记录所有先前的聊天互动。
然后,可以直接将它们传递回模型,以某种方式进行总结,或者进行某种组合。
---------------------------------------------------------------------------------------------------------
ChatMessageHistory提供了两个方法和一个属性。
它提供的两个方法是add_user_message和add_ai_message,用于分别存储来自用户的消息和AI的响应。
它提供的属性是messages属性,用于访问所有先前的消息。
2.5 模型:models
00.汇总
LLMs
首先介绍的是大型语言模型( LLMs )。这些模型以文本字符串作为输入,并返回文本字符串作为输出。
---------------------------------------------------------------------------------------------------------
聊天模型 Chat Models
聊天模型是第二种介绍的模型类型。这些模型通常由语言模型支持,但其 API 更加结构化。具体来说,这些模型以聊天消息列表作为输入,并返回聊天消息。
---------------------------------------------------------------------------------------------------------
文本嵌入模型 Text Embedding Models
第三种介绍的模型类型是文本嵌入模型。这些模型以文本作为输入,并返回浮点数列表。
01.聊天模型,Chat Models
聊天模型接受一个聊天消息列表作为输入,并返回一个聊天消息。
02.语言模型,LLMs
语言模型接受文本作为输入,并返回文本作为输出。
03.文本嵌入模型,Text Embedding Models
文本嵌入模型接受文本作为输入,并以浮点数列表的形式返回该文本的数字表示。
2.6 提示:prompt
00.汇总
PromptValue
表示模型输入的类。
---------------------------------------------------------------------------------------------------------
Prompt Templates
负责构建 PromptValue 的类。
---------------------------------------------------------------------------------------------------------
示例选择器 Example Selectors
在提示中包含示例通常是有用的。这些示例可以硬编码,但如果它们是动态选择的,则通常更有用。
---------------------------------------------------------------------------------------------------------
输出解析器 Output Parsers
语言模型(和聊天模型)输出文本。但是许多时候,您可能想获得比仅文本更有结构化的信息。这就是输出解析器发挥作用的地方。
输出解析器负责(1)指示模型如何格式化输出,(2)将输出解析为所需格式(包括必要时进行重试)。
01.示例选择器,Example Selectors
在提示中包括示例通常是很有用的。这些示例可以硬编码,但如果动态选择,则通常更强大。示例选择器是一种对象,接受用户输入,然后返回要使用的示例列表。
02.输出解析器,Output Parsers
Output parsers(输出解析器)是用于结构化语言模型响应的类。输出解析器必须实现两个主要方法:
get_format_instructions() -> str:一个返回包含语言模型输出格式化指令的字符串的方法。 parse(str) -> Any:一个接受字符串(假设为语言模型的响应)并将其解析为某种结构的方法。 还有一个可选的方法:
parse_with_prompt(str) -> Any:一个接受字符串(假设为语言模型的响应)和提示(假设为生成此响应的提示)的方法,并将其解析为某种结构。在输出解析器希望以某种方式重试或修复输出,并且需要来自提示的信息时,提供提示非常有用。
03.Prompt模板,Prompt Templates
“ PromptValue ”是最终传递给模型的内容。大多数情况下,该值不是硬编码的,而是根据用户输入、其他非静态信息(通常来自多个源)和固定的模板字符串动态创建的。
我们将负责创建“ PromptValue ”的对象称为 PromptTemplate。该对象公开了一种将输入变量作为输入并返回“ PromptValue ”的方法。
04.提示内容,PromptValue
“提示 Prompt”指的是传递给底层模型的内容。LangChain 提供了几种针对提示的抽象,以处理文本数据。对于其他数据类型(例如图像、音频),我们正在努力添加抽象,但还没有完成。
不同的模型可能期望不同的数据格式。在可能的情况下,我们希望允许在不同的模型类型中使用相同的提示。因此,我们有“ PromptValue ”的概念。这是一个类,公开了用于转换为每种模型类型所期望的确切输入类型(目前为文本或 ChatMessages )的方法。
2.7 模式:schema
01.聊天消息,ChatMessages
最终用户与之交互的主要接口是聊天接口。因此,一些模型提供商甚至开始以预期聊天消息的方式提供对底层 API 的访问。
这些消息具有内容字段(通常是文本),并与用户相关联。目前支持的用户为系统、人类和 AI。
---------------------------------------------------------------------------------------------------------
SystemChatMessage
表示应该将什么信息传达给 AI 系统的聊天消息。
---------------------------------------------------------------------------------------------------------
HumanChatMessage
表示来自与 AI 系统交互的人类的信息的聊天消息。
---------------------------------------------------------------------------------------------------------
AIChatMessage
表示来自 AI 系统的信息的聊天消息。
02.文档,Document
一份非结构化数据。由页面内容(数据的内容)和元数据(描述数据属性的辅助信息)组成。
03.例子,Examples
例子是输入/输出对,表示函数的输入和预期输出。它们可以在模型的训练和评估中使用。
这些可以是模型或链的输入/输出。两种类型的示例有不同的用途。模型的示例可用于微调模型。链式的示例可用于评估端到端链式过程,甚至可能训练替换整个链的模型。
04.文本,text
在处理语言模型时,您可以通过文本与其进行交互。作为一种过于简化的描述,很多模型是 “输入文本,输出文本”。因此,LangChain 中的很多接口都围绕文本展开。