langchain base

This commit is contained in:
estom
2024-06-19 23:31:45 +08:00
parent b002270ab2
commit f4b423fefb

View File

@@ -1,19 +1,119 @@
## 架构
## 架构原理
### 是什么
* LangChain Python 和 JavaScript 库。包含了各种组件的接口和集成,一个基本的运行时,用于将这些组件组合成链和代理,以及现成的链和代理的实现。
LangChain 模板:一系列易于部署的参考架构,用于各种任务。
LangServe一个用于将 LangChain 链部署为 REST API 的库。
LangSmith一个开发者平台让你可以调试、测试、评估和监控基于任何 LLM 框架构建的链,并且与 LangChain 无缝集成。
langgraph(opens in a new tab)通过将步骤建模为图中的边缘和节点使用LLMs构建强大且有状态的多角色应用程序。
LangChain 是一个用于开发由语言模型驱动的应用程序的框架。它使得应用程序能够:
具有上下文感知能力:将语言模型连接到上下文来源(提示指令,少量的示例,需要回应的内容等)
具有推理能力:依赖语言模型进行推理(根据提供的上下文如何回答,采取什么行动等)
### 核心组件
![alt text](image/image.png)
* LangChain 库Python 和 JavaScript 库。包含了各种组件的接口和集成,一个基本的运行时,用于将这些组件组合成链和代理,以及现成的链和代理的实现。
* LangChain 模板:一系列易于部署的参考架构,用于各种任务。
* LangServe一个用于将 LangChain 链部署为 REST API 的库。
* LangSmith一个开发者平台让你可以调试、测试、评估和监控基于任何 LLM 框架构建的链,并且与 LangChain 无缝集成。
* langgraph(opens in a new tab)通过将步骤建模为图中的边缘和节点使用LLMs构建强大且有状态的多角色应用程序。
![alt text](image/image-1.png)
![alt text](image/image-2.png)
## 概念组成
### 1 Agent 代理
可以简单的理解为它可以动态的帮我们选择和调用Chain或者已有的工具执行过程可以参考下面这张图
![alt text](image/image-2.png)
* 代理( Agent )是围绕模型的封装,它接收用户输入并返回与 “动作 action ”相对应的响应,以及相应的 “动作输入 action input ”。代理的作用是接收用户的输入,并根据模型的处理逻辑生成相应的响应。这个响应通常包括执行的动作和对应的动作输入,用于进一步指导系统的行为。代理起到了将用户输入与模型的交互进行封装和管理的作用。
* 代理执行器( Agent Executor )是一个代理( Agent )和一组工具( Tools )。代理执行器负责调用代理,获取动作和动作输入,根据动作引用的工具以及相应的输入调用工具,获取工具的输出,然后将所有这些信息传递回代理,以获取它应该采取的下一个动作。代理执行器充当了协调和管理代理与工具之间交互的角色。
* 工具Tool是围绕函数的具体抽象使语言模型可以与之进行交互变得简单。具体而言工具的接口具有单一的文本输入和单一的文本输出。
* 工具包( Toolkits )是一组工具的集合,可以用于解决特定问题或完成特定任务。这些工具包是为了一起使用、相互协作以实现更复杂的目标而组织起来的。使用工具包可以提供更全面、高效的解决方案,因为它们涵盖了解决特定问题所需的各个方面或阶段。
### 2 Chain 链
我们可以把 Chain 理解为任务。一个 Chain 就是一个任务,当然也可以像链条一样,一个一个的执行多个链。
*Chain是对多个独立组件进行端到端封装的一种方式。
#### 索引链
这类链用于与索引进行交互。这些链的目的是将自己的数据存储在索引中与LLM结合起来。其中最好的例子是对自己的文档进行问答。
其中一个重要部分是了解如何将多个文档传递给语言模型。有几种不同的方法或链来实现这一点。
LangChain 支持其中四种常见的方法,并且我们正在积极寻求包括更多方法,如果你有任何想法,请随时联系我们!请注意,并没有一种最佳方法-选择使用哪种方法通常非常依赖上下文。按照从简单到复杂的顺序:
* Stuffing填充Stuffing 是最简单的方法您只需将所有相关数据作为上下文直接添加到提示中然后传递给语言模型。LangChain 中的 StuffDocumentsChain 便是采用了这种方法。这种方法的主要缺点是它只适用于较小的数据片段。一旦您处理许多数据片段,这种方法就不再可行。接下来的两种方法旨在帮助处理这个问题。
* 优点: 只需向LLM发出一次调用。在生成文本时LLM 可以一次性访问所有数据。
* 缺点: 大多数LLM具有上下文长度限制对于大型文档或许多文档这种方法将不起作用因为提示的长度将超过上下文长度。
* Map Reduce映射-归约该方法涉及对每个数据块运行初始提示对于摘要任务可以是该块的摘要对于问答任务可以是仅基于该块的答案。然后运行不同的提示来组合所有初始输出。LangChain中实现了这种方法称为 MapReduceDocumentsChain。
* 优点: 可以扩展到比 StuffDocumentsChain 更大的文档以及更多的文档。对各个文档进行的LLM调用是独立的因此可以并行化处理。
* 缺点: 比 StuffDocumentsChain 需要更多对 LLM 的调用。在最终的组合调用中会丢失一些信息。
* Refine优化该方法涉及在第一个数据块上运行初始提示生成一些输出。对于剩余的文档将该输出与下一个文档一起传递给LLM要求LLM基于新文档优化输出。
* 优点: 可以获取更多相关的上下文,并且可能比 MapReduceDocumentsChain 更少损失信息。
* 缺点: 比 StuffDocumentsChain 需要更多对LLM的调用。这些调用也不是独立的这意味着无法像 MapReduceDocumentsChain 那样进行并行化处理。还可能对文档的顺序造成潜在的影响。
* Map-Rerank映射-重新排序)这种方法涉及在每个数据块上运行初始提示,该提示不仅尝试完成任务,还为其答案的确定程度给出一个分数。然后根据这个分数对响应进行排序,返回最高分的响应。
* 优点: 与MapReduceDocumentsChain类似的优点。与MapReduceDocumentsChain相比需要更少的调用。
* 缺点: 无法在文档之间合并信息。这意味着当您期望在单个文档中有一个简单的单一答案时,这种方法最为有用。
#### LLMChainLLM链
由 PromptTemplate提示模板、模型可以是 LLM 或 ChatModel )和可选的输出解析器组成。该链接受多个输入变量,使用 PromptTemplate 将它们格式化为提示。然后将提示传递给模型。最后,它使用 OutputParser如果提供将LLM的输出解析为最终格式。
#### 提示选择器 Prompt Selector
在 LangChain 中,链的一个目标是让人们尽快开始使用特定的用例。这其中一个重要部分是拥有良好的提示。
问题是,对一个模型有效的提示对另一个模型可能效果不佳。我们希望链对所有类型的模型都能够良好工作。因此,我们没有在链中硬编码默认提示的使用方式,而是引入了 PromptSelector 的概念。PromptSelector 负责根据传入的模型选择一个默认提示。
PromptSelectors 的最常见用例是为 LLM 和 Chat Model 设置不同的默认提示。然而,如果需要,也可以为不同的模型提供商设置不同的默认提示。
### 3 模型Model
* LLMs。首先介绍的是大型语言模型 LLMs )。这些模型以文本字符串作为输入,并返回文本字符串作为输出。
* 聊天模型 Chat Models聊天模型是第二种介绍的模型类型。这些模型通常由语言模型支持但其 API 更加结构化。具体来说,这些模型以聊天消息列表作为输入,并返回聊天消息。
* 文本嵌入模型 Text Embedding Models。第三种介绍的模型类型是文本嵌入模型。这些模型以文本作为输入并返回浮点数列表。
### 4 提示词Prompt
现在编写模型的新方法是通过提示。 "提示" 指的是模型的输入。这个输入通常不是硬编码的而是通常由多个组件构成的。PromptTemplate 负责构建这个输入。LangChain 提供了多个类和函数,使构建和使用提示更加容易。
* PromptValue。表示模型输入的类。
* Prompt Templates负责构建 PromptValue 的类。
* 示例选择器 Example Selectors在提示中包含示例通常是有用的。这些示例可以硬编码但如果它们是动态选择的则通常更有用。
* 输出解析器 Output Parsers语言模型和聊天模型输出文本。但是许多时候您可能想获得比仅文本更有结构化的信息。这就是输出解析器发挥作用的地方。输出解析器负责1指示模型如何格式化输出2将输出解析为所需格式包括必要时进行重试
### 5 文档和索引INDEX
* Loader 加载器。顾名思义,这个就是从指定源进行加载数据的。比如:文件夹 DirectoryLoader、Azure 存储 AzureBlobStorageContainerLoader、CSV文件 CSVLoader、印象笔记 EverNoteLoader、Google网盘 GoogleDriveLoader、任意的网页 UnstructuredHTMLLoader、PDF PyPDFLoader、S3 S3DirectoryLoader或 S3FileLoader、Youtube YoutubeLoader 等。
* Document 文档。当使用 Loader 加载器读取到数据源后,数据源需要转换成 Document 文档对象后,后续才能进行使用。
* 检索数据 Retriever/一种存储数据的方式使其可以被语言模型查询。该对象必须提供的唯一接口是get_relevant_texts方法它接收一个字符串作为输入并返回一个文档列表。
* 文档拆分 Text Splitters.通常您想将大型文本文档分成更小的块以更好地处理语言模型。TextSplitters 负责将文档拆分成较小的文档。
* Vector Stores 向量数据库。因为数据相关性搜索其实是向量运算。所以需要将我们的加载进来的数据 Document 文档对象进行向量化,才能进行向量运算搜索。转换成向量也很简单,只需要我们把数据存储到对应的向量数据库中即可完成向量的转换。
* Embedding 嵌入。用于衡量文本的相关性,这个也是 OpenAI API 能实现构建自己知识库的关键所在。它相比 fine-tuning 最大的优势就是,不用进行训练,并且可以实时添加新的内容,而不用加一次新的内容就训练一次,并且各方面成本要比 fine-tuning 低很多。
### 6 Memory 内存
内存Memory是在对话过程中存储和检索数据的概念。主要有两种方法
* 根据输入,获取任何相关的数据。
* 根据输入和输出,相应地更新状态。
内存主要分为两种类型:短期内存和长期内存。
短期内存通常指的是如何在单个对话的上下文中传递数据(通常是先前的聊天消息或其摘要)。
长期内存处理的是如何在对话之间获取和更新信息的问题。
* 记录聊天历史 ChatMessageHistory。目前与语言模型的主要接口是通过聊天界面进行的。ChatMessageHistory类负责记录所有先前的聊天互动。然后可以直接将它们传递回模型以某种方式进行总结或者进行某种组合。ChatMessageHistory提供了两个方法和一个属性。它提供的两个方法是add_user_message和add_ai_message用于分别存储来自用户的消息和AI的响应。它提供的属性是messages属性用于访问所有先前的消息。
### 7 模式Schema
* 聊天消息 ChatMessages最终用户与之交互的主要接口是聊天接口。因此一些模型提供商甚至开始以预期聊天消息的方式提供对底层 API 的访问。这些消息具有内容字段(通常是文本),并与用户相关联。目前支持的用户为系统、人类和 AI。
* SystemChatMessage表示应该将什么信息传达给 AI 系统的聊天消息。
* HumanChatMessage表示来自与 AI 系统交互的人类的信息的聊天消息。
* AIChatMessage表示来自 AI 系统的信息的聊天消息。
* 例子 Examples。例子是输入/输出对,表示函数的输入和预期输出。它们可以在模型的训练和评估中使用。这些可以是模型或链的输入/输出。两种类型的示例有不同的用途。模型的示例可用于微调模型。链式的示例可用于评估端到端链式过程,甚至可能训练替换整个链的模型。
* 文本 text。在处理语言模型时您可以通过文本与其进行交互。作为一种过于简化的描述很多模型是 “输入文本输出文本”。因此LangChain 中的很多接口都围绕文本展开。