本文将从Chains的本质、Chains的原理、Chains的应用三个方面,带您一文搞懂 LangChain(五):Chains。Chains
Chains是什么?
Chains 在 LangChain 框架中的核心概念是用于将多个组件及其他 Chains 组合成更复杂功能,通过模块化与复用提高开发效率、代码可读性及可维护性。模块化:提高代码复用性,降低开发复杂性。
可维护性:易于理解和维护,方便修改和扩展。
灵活性:支持不同组合方式,适应多变需求。
Chains Introduction
Chains两种类型的链:通用链和实用链。
通用链和实用链
Chains能干什么?
Chains的灵活性使得我们可以根据具体需求将多个链组合在一起,或者将链与其他功能组件相结合,从而构建出更复杂、更强大的应用程序。
Legacy Chains 是一系列传统的工具链,用于处理和转换数据,执行特定的任务,并在早期的技术环境中提供关键的功能支持。
APIChain:将查询转换为API请求并执行,然后获取响应并传递给另一个语言模型(LLM)以作出响应。
OpenAPIEndpointChain:与APIChain类似,但专为与OpenAPI端点交互而优化。
ConversationalRetrievalChain:用于与文档进行对话。它接收问题和(可选的)先前的对话历史,然后使用LLM和检索器来获取相关文档,并作出响应。
StuffDocumentsChain:将一系列文档格式化为提示,并将其传递给LLM。
ReduceDocumentsChain:通过迭代减少文档来组合它们。它分批处理文档,然后将其传递给LLM,直到所有内容都适合在一个最终的LLM调用中处理。
MapReduceDocumentsChain:首先对每个文档进行LLM调用,然后使用ReduceDocumentsChain来减少它们。
RefineDocumentsChain:通过基于第一个文档生成初始答案,然后循环遍历其余文档来精炼答案。
MapRerankDocumentsChain:对每个文档进行LLM调用,并要求其提供答案和置信度分数。返回置信度最高的答案。
ElasticsearchDatabaseChain:将自然语言问题转换为ElasticSearch查询,执行它,然后总结响应。
LLMMath:将用户问题转换为数学问题并执行它。
LLMCheckerChain:使用第二次LLM调用来验证其初始答案。
LLMSummarizationChecker:使用一系列LLM调用来创建摘要,以确保其准确性。
Legacy Chains
Chains的工作流程:通过定义链构造函数来初始化链,配置所需的组件和可能的其他链,以形成具有特定功能的执行流程。
Chains流程包含以下四个核心步骤:
Chain Constructor(链构造函数):在LangChain中,链构造函数用于初始化链,设定其组件、配置及嵌套的其他链。
Function Calling(函数调用):这指链是否需要调用外部函数,如OpenAI服务,以执行其任务。
Other Tools(其他工具):除LangChain核心组件外,链可能还使用其他工具如数据库、API等以增强其功能。
When to Use(何时使用):这部分提供指导,帮助开发者确定在何种场景或需求下使用特定的LangChain链最为合适。
Chains的工作流程
Chains的架构:Chains作为LangChain的核心组件,通过串联各个逻辑单元,实现了流程控制、数据传递和状态管理,使得复杂的业务逻辑能够高效、有序地执行。
流程控制:Chains通过特定的顺序将逻辑单元串联起来,确保业务流程按照预定的顺序执行。每个逻辑单元在Chains中都被视为一个节点,节点之间的连接形成了完整的业务流程。
数据传递:在Chains中,数据在各个节点之间流动。每个节点接收前一个节点的输出作为输入,并根据业务需求进行处理,然后将结果传递给下一个节点。这种数据传递方式实现了各个逻辑单元之间的无缝衔接。
状态管理:Chains还具备状态管理能力,允许节点在执行过程中修改自身的状态,并根据上一次的状态进行相应的操作。这有助于处理复杂的业务逻辑,提高代码的复用性和可维护性。
LangChain的架构
LangChain Expression Language(LCEL)是一种声明式的方式,可以轻松地组合链。LCEL 从一开始就被设计为支持将原型投入生产,无需任何代码更改,从最简单的“提示+LLM”链到最复杂的链。
Chains的基本案例:prompt + model + output parser
在此链中,用户输入传递到提示模板,然后提示模板输出传递到模型,然后模型输出传递到输出解析器。
基本案例的流程
1. 提示(Prompt):你创建了一个 ChatPromptTemplate 对象,该对象使用给定的模板字符串,并根据提供的输入(在这种情况下是主题)生成完整的提示。当你调用 prompt.invoke({"topic": "ice cream"}) 时,它会返回一个 ChatPromptValue 对象,该对象包含要传递给模型的完整提示。
ChatPromptTemplate
2. 模型(Model):PromptValue
作为输入传递给ChatModel
,该模型处理后输出一个BaseMessage
格式的回复。
ChatModel
如果我们的模型是一个大语言模型(LLM),它将输出一个字符串作为结果。
大语言模型(LLM)
3. 输出解析器(Output Parser):最后,我们将模型输出传递给output_parser
,它是一个BaseOutputParser
,可以接受字符串或BaseMessage
作为输入。其中,StrOutputParser
专门将任何输入简单转换为字符串。
输出解析器(Output Parser)
RAG Search Example:在这个例子中,我们想要运行一个检索增强的生成链,以便在回答问题时添加一些上下文。
RAG Search Example的流程
该流程通过创建一个包含上下文和问题的RunnableParallel对象,将其传递给提示组件以生成PromptValue,然后将该值输入到OpenAI的大型语言模型(LLM)中以生成ChatMessage,最后通过输出解析器将其转换为Python字符串并返回。
1. 创建RunnableParallel对象:首先,创建一个RunnableParallel
对象,它包含两个条目:一个是context
(由检索器获取的文档结果),另一个是question
(用户的原始问题)。为了传递问题,使用RunnablePassthrough
来复制这个条目。
2. 传递给提示组件:将上述步骤中创建的字典传递给提示组件。提示组件接收用户输入的问题和检索到的文档(作为上下文),然后构建一个提示并输出一个PromptValue
。
3. 模型组件评估:模型组件接收生成的提示,并将其传递给OpenAI的大型语言模型(LLM)进行评估。模型生成的输出是一个ChatMessage
对象。
4. 输出解析:最后,output_parser
组件接收一个ChatMessage
对象,并将其转换为Python字符串。这个字符串是从调用方法中返回的最终结果。
RAG Search Example