文章目录
- 一、Architecture
- 1、langchain-core
- 2、partner-packages
- 3、langchain
- 4、langchain-community
- 5、langgraph
- 6、langserve
- 7、langsmith
- 二、浪链表达语言(LCEL )
- 可运行界面 runnable-interface
- 三、组件 components
- 1、聊天模型 chat-models
- 2、 LLM
- 3、Messages
- HumanMessage
- AIMessage
- 系统消息 SystemMessage
- 功能消息 FunctionMessage
- 工具消息 ToolMessage
- 4、提示模板 Prompt templates
- 1)字符串提示模板 string-prompttemplates
- 2)聊天提示模板 chatprompttemplates
- 3)消息占位符 MessagesPlaceholder
- 5、选择器示例 Example selectors
- 6、输出解析器 Output parsers
- 7、聊天记录 Chat history
- 8、文件 documents
- 9、文件装载机 document-loaders
- 10、文本分割器 text-splitters
- 11、嵌入模型 embedding-models
- 12、矢量存储 Vector stores
- 13、检索器 Retrievers
- 14、工具 Tools
- 15、工具包 Toolkits
- 16、代理 agents
- 17、回调 callbacks
- 回调处理程序 callback-handlers
- 传递回调 passing-callbacks
- 四、techniques
- 1、函数/工具调用 Function/tool calling
- 2、检索 retrieval
- 3、文本分割 text-splitting
本文翻译整理自:https://python.langchain.com/v0.2/docs/concepts/
本节对LangChain的关键部分进行介绍。
一、Architecture
LangChain作为一个框架由许多包组成。
1、langchain-core
该包包含不同组件的基本抽象以及将它们组合在一起的方法。
此处定义了 LLM、向量存储、检索器等核心组件的接口。
这里没有定义第三方集成。依赖性被故意保持得非常轻量。
2、partner-packages
虽然集成的长尾位于 langchain-community
中,但我们将流行的集成 拆分为它们自己的包(例如langchain-openai
,langchain-anthropic
等)。
这样做是为了改善对这些重要集成的支持。
3、langchain
主langchain
包包含构成应用程序认知架构的链、代理和检索策略。
这些不是第三方集成。
这里的所有链、代理和检索策略并不特定于任何一种集成,而是在所有集成中通用。
4、langchain-community
该软件包包含由 LangChain 社区维护的第三方集成。
主要合作伙伴包被分开(见下文)。
这包含各种组件(LLM、向量库、检索器)的所有集成。
此包中的所有依赖项都是可选的,以保持包尽可能轻量。
5、langgraph
https://langchain-ai.github.io/langgraph
langgraph
是一个扩展,langchain
旨在通过将步骤建模为图中的边和节点,使用 LLM 构建健壮且有状态的多角色应用程序。
LangGraph 公开了用于创建常见代理类型的高级接口,以及用于构建更多控制的低级 API。
6、langserve
https://python.langchain.com/v0.2/docs/langserve/
用于将 LangChain 链部署为 REST API 的包。
可以轻松启动并运行生产就绪的 API。
7、langsmith
https://docs.smith.langchain.com/
一个开发者平台,可让您调试、测试、评估和监控 LLM 应用程序。
二、浪链表达语言(LCEL )
LangChain 表达式语言(LCEL)是一种链接 LangChain 组件的声明性方式。
LCEL 从第一天起就被设计为支持将原型投入生产,无需更改代码,从最简单的“提示 + LLM”链到最复杂的链(我们已经看到人们在生产中成功运行了 100 个步骤的 LCEL 链)。
强调一下您可能想要使用 LCEL 的一些原因:
一流的流支持 当您使用 LCEL 构建链时,您可以获得最佳的首次代币时间(直到第一个输出块出现之前经过的时间)。
对于某些连锁店来说,这意味着例如。
我们将令牌直接从 LLM 流式传输到流式输出解析器,然后您会以与 LLM 提供者输出原始令牌相同的速率返回已解析的增量输出块。
异步支持 使用 LCEL 构建的任何链都可以使用同步 API(例如,在原型设计时在 Jupyter 笔记本中)和异步 API(例如,在LangServe服务器中)进行调用。
这使得能够在原型和生产中使用相同的代码,具有出色的性能,并且能够在同一服务器中处理许多并发请求。
优化的并行执行 只要您的 LCEL 链具有可以并行执行的步骤(例如,如果您从多个检索器获取文档),我们就会在同步和异步接口中自动执行此操作,以尽可能减少延迟。
重试和回退 为 LCEL 链的任何部分配置重试和回退。
这是让您的链条在规模上更加可靠的好方法。
我们目前正在努力添加对重试/回退的流支持,以便您可以获得更高的可靠性,而无需任何延迟成本。
访问中间结果 对于更复杂的链,即使在生成最终输出之前访问中间步骤的结果通常也非常有用。
这可以用来让最终用户知道正在发生的事情,甚至只是为了调试您的链。
您可以流式传输中间结果,并且它在每个LangServe服务器上都可用。
输入和输出模式 输入和输出模式为每个 LCEL 链提供从链结构推断出的 Pydantic 和 JSONSchema 模式。
这可用于验证输入和输出,并且是 LangServe 的组成部分。
无缝 LangSmith 追踪 随着您的链条变得越来越复杂,了解每一步到底发生了什么变得越来越重要。
借助 LCEL,所有步骤都会自动记录到LangSmith,以实现最大程度的可观察性和可调试性。
无缝 LangServe 部署 使用 LCEL 创建的任何链都可以使用LangServe轻松部署。
可运行界面 runnable-interface
为了尽可能轻松地创建自定义链,我们实现了 “Runnable” 协议。
许多 LangChain 组件都实现了该Runnable
协议,包括聊天模型、LLM、输出解析器、检索器、提示模板等。
还有一些用于处理可运行对象的有用原语,您可以在下面阅读。
这是一个标准接口,可以轻松定义自定义链并以标准方式调用它们。标准接口包括:
stream
:流回响应块invoke
:在输入上调用链batch
:在输入列表上调用链
这些也有相应的异步方法,应与asyncio 语法一起使用await
以实现并发:
astream
:异步流回响应块ainvoke
:在输入异步上调用链abatch
:异步调用输入列表上的链astream_log
:除了最终响应之外,还实时流回发生的中间步骤astream_events
:链中发生的betalangchain-core
流事件( 0.1.14 中引入)
输入类型和输出类型因组件而异:
Component | Input Type | Output Type |
---|---|---|
Prompt | Dictionary | PromptValue |
ChatModel | Single string, list of chat messages or a PromptValue | ChatMessage |
LLM | Single string, list of chat messages or a PromptValue | String |
OutputParser | The output of an LLM or ChatModel | Depends on the parser |
Retriever | Single string | List of Documents |
Tool | Single string or dictionary, depending on the tool | Depends on the tool |
所有可运行对象都公开输入和输出模式以检查输入和输出:
input_schema
:从 Runnable 结构自动生成的输入 Pydantic 模型output_schema
:根据 Runnable 的结构自动生成的输出 Pydantic 模型
三、组件 components
LangChain 为各种组件提供标准、可扩展的接口和外部集成,这些组件可用于使用 LLM 进行构建。
有些组件是 LangChain 实现的,有些组件我们依赖第三方集成,还有一些则是混合的。
1、聊天模型 chat-models
使用消息序列作为输入并返回聊天消息作为输出(而不是使用纯文本)的语言模型。
这些传统上是较新的模型(通常是较旧的模型LLMs
,请参见上文)。
聊天模型支持为对话消息分配不同的角色,有助于区分来自 AI、用户和系统消息等指令的消息。
虽然底层模型是消息输入、消息输出,但 LangChain 包装器也允许这些模型将字符串作为输入。
这意味着您可以轻松使用聊天模型代替 LLM 。
当字符串作为输入传入时,它会转换为 HumanMessage,然后传递到底层模型。
LangChain 不提供任何 ChatModel,而是依赖第三方集成。
我们在构建 ChatModel 时有一些标准化参数:
model
: 型号名称
ChatModel 还接受特定于该集成的其他参数。
注意:工具调用部分聊天模型针对工具调用进行了微调,并提供了专用的工具调用 API。
一般来说,此类模型在工具调用方面的表现优于非微调模型,建议用于需要工具调用的用例。
有关详细信息,请参阅下文工具调用部分。
2、 LLM
将字符串作为输入 并返回字符串的语言模型。这些都是传统上较旧的型号(通常是较新的型号ChatModels
,请参见下文)。
虽然底层模型是字符串输入、字符串输出,但 LangChain 包装器也允许这些模型将消息作为输入。这使得它们可以与 ChatModel 交互。
当消息作为输入传递时,它们将在传递到底层模型之前在底层被格式化为字符串。
LangChain不提供任何LLM,而是依赖第三方集成。
3、Messages
某些语言模型将消息列表作为输入并返回消息。
有几种不同类型的消息。
所有消息都有role
、content
和response_metadata
属性。
-
role
描述了 WHO 正在传达的信息。LangChain针对不同的角色有不同的消息类别。 -
content
属性描述了消息的内容。这可能是一些不同的事情:- 字符串(大多数模型处理此类内容)
- 字典列表(用于多模式输入,其中字典包含有关该输入类型和该输入位置的信息)
HumanMessage
这代表来自用户的消息。
AIMessage
这代表来自模型的消息。除了content
属性之外,这些消息还具有:
response_metadata
该response_metadata
属性包含有关响应的附加元数据。
这里的数据通常特定于每个模型提供商。
这是可以存储日志概率和令牌使用情况等信息的地方。tool_calls
它们代表语言模型调用工具的决定。
它们作为输出的一部分包含在内AIMessage
。
可以从那里通过酒店访问它们.tool_calls
。
此属性返回字典列表。每个字典都有以下键:
name
:应调用的工具的名称。args
:该工具的参数。id
:该工具调用的 id。
系统消息 SystemMessage
这代表一条系统消息,告诉模型如何行为。
并非每个模型提供商都支持这一点。
功能消息 FunctionMessage
这表示函数调用的结果。
除了 role
和 content
之外, 此消息还有一个name
参数,该参数传达为产生此结果而调用的函数的名称。
工具消息 ToolMessage
这表示工具调用的结果。
这与 FunctionMessage 不同,以便匹配 OpenAIfunction
和tool
消息类型。
除了 role
和content
之外,此消息还有一个tool_call_id
参数,该参数将调用的 id 传递给被调用以产生此结果的工具。
4、提示模板 Prompt templates
提示模板有助于将用户输入和参数转换为语言模型的指令。
这可用于指导模型的响应,帮助其理解上下文并生成相关且连贯的基于语言的输出。
提示模板将字典作为输入,其中每个键代表提示模板中要填写的变量。
提示模板输出 PromptValue。
此 PromptValue 可以传递给 LLM 或 ChatModel,也可以转换为字符串或消息列表。
这个 PromptValue 存在的原因是为了方便在字符串和消息之间切换。
有几种不同类型的提示模板
1)字符串提示模板 string-prompttemplates
这些提示模板用于格式化单个字符串,通常用于更简单的输入。
例如,构建和使用 PromptTemplate 的常见方法如下:
from langchain_core.prompts import PromptTemplateprompt_template = PromptTemplate.from_template("Tell me a joke about {topic}")prompt_template.invoke({"topic": "cats"})
API参考: https://api.python.langchain.com/en/latest/prompts/langchain_core.prompts.prompt.PromptTemplate.html
2)聊天提示模板 chatprompttemplates
这些提示模板用于格式化消息列表。
这些“模板”由模板本身的列表组成。
例如,构造和使用ChatPromptTemplate的常见方法如下:
from langchain_core.prompts import ChatPromptTemplateprompt_template = ChatPromptTemplate.from_messages([("system", "You are a helpful assistant"),("user", "Tell me a joke about {topic}")
])prompt_template.invoke({"topic": "cats"})
API参考: https://api.python.langchain.com/en/latest/prompts/langchain_core.prompts.chat.ChatPromptTemplate.html
在上面的示例中,此 ChatPromptTemplate 在调用时将构造两条消息。
第一个是系统消息,没有要格式化的变量。
第二个是 HumanMessage,将由topic
用户传入的变量进行格式化。
3)消息占位符 MessagesPlaceholder
该提示模板负责在特定位置添加消息列表。
在上面的 ChatPromptTemplate 中,我们看到了如何格式化两条消息,每条消息都是一个字符串。
但是,如果我们希望用户传递一个消息列表并将其放入特定位置该怎么办?这就是您使用 MessagesPlaceholder 的方式。
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.messages import HumanMessageprompt_template = ChatPromptTemplate.from_messages([("system", "You are a helpful assistant"),MessagesPlaceholder("msgs")
])prompt_template.invoke({"msgs": [HumanMessage(content="hi!")]})
API参考:
- 聊天提示模板
- 消息占位符
- 人类讯息
这将产生两个消息的列表,第一个是系统消息,第二个是我们传入的 HumanMessage。
如果我们传入 5 条消息,那么它总共会产生 6 条消息(系统消息加上5 人通过)。
这对于将消息列表放入特定位置非常有用。
在不显式使用该类的情况下完成相同任务的另一种方法MessagesPlaceholder
是:
prompt_template = ChatPromptTemplate.from_messages([("system", "You are a helpful assistant"),("placeholder", "{msgs}") # <-- This is the changed part
])
5、选择器示例 Example selectors
实现更好性能的一种常见提示技术是将示例作为提示的一部分。
这为语言模型提供了其行为方式的具体示例。
有时这些示例被硬编码到提示中,但对于更高级的情况,动态选择它们可能会更好。
示例选择器是负责选择示例并将其格式化为提示的类。
6、输出解析器 Output parsers
注:这里的信息是指从模型获取文本输出的解析器尝试将其解析为更结构化的表示。
越来越多的模型支持函数(或工具)调用,它会自动处理这个问题。
建议使用函数/工具调用而不是输出解析。
请参阅下方 function-tool-calling 文档。
负责获取模型的输出并将其转换为更适合下游任务的格式。
当您使用 LLM 生成结构化数据或规范化聊天模型和 LLM 的输出时很有用。
LangChain 有许多不同类型的输出解析器。
这是 LangChain 支持的输出解析器列表。
下表包含各种信息:
- 名称:输出解析器的名称
- 支持流:输出解析器是否支持流。
- 有格式指令:输出解析器是否有格式指令。
这通常是可用的,除非 (a) 未在提示中指定所需模式,而是在其他参数中指定(如 OpenAI 函数调用),或 (b) 当 OutputParser 包装另一个 OutputParser 时。 - Calls LLM:此输出解析器本身是否调用 LLM。
这通常仅由尝试纠正格式错误的输出的输出解析器来完成。 - 输入类型:预期的输入类型。
大多数输出解析器都可以处理字符串和消息,但有些(如 OpenAI Functions)需要带有特定 kwargs 的消息。 - 输出类型:解析器返回的对象的输出类型。
- 描述:我们对此输出解析器以及何时使用它的评论。
姓名 | 支持流媒体 | 有格式说明 | 致电法学硕士 | 输入类型 | 输出类型 | 描述 |
---|---|---|---|---|---|---|
JSON | ✅ | ✅ | str | Message | JSON 对象 | |
XML | ✅ | ✅ | str | Message | dict | |
CSV | ✅ | ✅ | str | Message | List[str] | |
输出固定 | ✅ | str | Message | |||
错误重试 | ✅ | str | Message | |||
派丹蒂克 | ✅ | str | Message | pydantic.BaseModel | ||
YAML | ✅ | str | Message | pydantic.BaseModel | ||
熊猫数据框 | ✅ | str | Message | dict | ||
枚举 | ✅ | str | Message | Enum | ||
约会时间 | ✅ | str | Message | datetime.datetime | ||
结构化的 | ✅ | str | Message | Dict[str, str] |
7、聊天记录 Chat history
大多数 LLM 申请都有对话界面。
对话的一个重要组成部分是能够引用对话中先前介绍的信息。
至少,对话系统应该能够直接访问过去消息的某些窗口。
的概念ChatHistory
是指LangChain中的一个类,可以用来包装任意链。
这ChatHistory
将跟踪底层链的输入和输出,并将它们作为消息附加到消息数据库中,然后未来的交互将加载这些消息并将它们作为输入的一部分传递到链中。
8、文件 documents
LangChain中的Document对象包含了一些数据的信息。它有两个属性:
page_content: str
:本文档的内容。
目前只是一个字符串。metadata: dict
:与此文档关联的任意元数据。
可以跟踪文档id、文件名等。
9、文件装载机 document-loaders
这些类加载 Document 对象。
LangChain 与各种数据源有数百个集成,可以从以下来源加载数据:Slack、Notion、Google Drive 等。
每个 DocumentLoader 都有自己特定的参数,但它们都可以用相同的方法调用.load
。
示例用例如下:
from langchain_community.document_loaders.csv_loader import CSVLoaderloader = CSVLoader(... # <-- Integration specific parameters here
)
data = loader.load()
API参考 : https://api.python.langchain.com/en/latest/document_loaders/langchain_community.document_loaders.csv_loader.CSVLoader.html
10、文本分割器 text-splitters
加载文档后,您通常会想要对其进行转换以更好地适合您的应用程序。
最简单的例子是,您可能希望将长文档分割成更小的块,以适合模型的上下文窗口。
LangChain 有许多内置的文档转换器,可以轻松地拆分、组合、过滤和以其他方式操作文档。
当您想要处理长文本时,有必要将该文本分割成块。
这听起来很简单,但这里存在很多潜在的复杂性。
理想情况下,您希望将语义相关的文本片段保留在一起。
“语义相关”的含义可能取决于文本的类型。
本笔记本展示了实现此目的的几种方法。
在较高层面上,文本分割器的工作原理如下:
-
将文本分割成小的、具有语义意义的块(通常是句子)。
-
开始将这些小块组合成一个更大的块,直到达到一定的大小(通过某些函数测量)。
-
一旦达到该大小,请将该块设为自己的文本片段,然后开始创建具有一些重叠的新文本块(以保持块之间的上下文)。
这意味着您可以沿着两个不同的轴自定义文本分割器:
- 文本如何分割
- 如何测量块大小
11、嵌入模型 embedding-models
Embeddings 类是设计用于与文本嵌入模型交互的类。
有很多嵌入模型提供者(OpenAI、Cohere、Hugging Face 等)——此类旨在为所有这些提供者提供标准接口。
嵌入创建一段文本的矢量表示。
这很有用,因为它意味着我们可以在向量空间中思考文本,并执行语义搜索之类的操作,在向量空间中查找最相似的文本片段。
LangChain 中的 Embeddings 基类提供了两种方法:一种用于嵌入文档,另一种用于嵌入查询。
前者采用多个文本作为输入,而后者采用单个文本。
将它们作为两种单独方法的原因是,某些嵌入提供程序对文档(要搜索的)与查询(搜索查询本身)有不同的嵌入方法。
12、矢量存储 Vector stores
存储和搜索非结构化数据的最常见方法之一是嵌入它并存储生成的嵌入向量,然后在查询时嵌入非结构化查询并检索与嵌入查询“最相似”的嵌入向量。
矢量存储负责存储嵌入数据并为您执行矢量搜索。
向量存储可以通过执行以下操作转换为检索器接口:
vectorstore = MyVectorStore()
retriever = vectorstore.as_retriever()
13、检索器 Retrievers
检索器是一个接口,它根据非结构化查询返回文档。它比矢量存储更通用。
检索器不需要能够存储文档,只需返回(或检索)它们即可。
检索器可以从矢量存储创建,但也足够广泛,包括 Wikipedia 搜索和Amazon Kendra。
检索器接受字符串查询作为输入,并返回文档列表作为输出。
14、工具 Tools
工具是代理、链或聊天模型/LLM 可以用来与世界交互的接口。
一个工具由以下组件组成:
- 工具名称
- 该工具的功能描述
- 工具输入内容的 JSON 架构
- 要调用的函数
- 工具的结果是否应直接返回给用户(仅与代理相关)
名称、描述和 JSON 模式作为上下文提供给 LLM,允许 LLM 确定如何正确使用该工具。
给定可用工具列表和提示, LLM 可以请求使用适当的参数调用一个或多个工具。
一般来说,在设计聊天模型或 LLM 使用的工具时,请务必记住以下几点:
- 经过针对工具调用进行微调的聊天模型将比未微调的模型更擅长工具调用。
- 未经微调的模型可能根本无法使用工具,尤其是在工具很复杂或需要多次工具调用的情况下。
- 如果工具具有精心选择的名称、描述和 JSON 架构,模型的性能将会更好。
- 对于模型来说,简单的工具通常比较复杂的工具更容易使用。
15、工具包 Toolkits
工具包是旨在一起用于特定任务的工具的集合。他们有方便的装载方法。
所有工具包都公开一个get_tools
返回工具列表的方法。因此,您可以这样做:
# Initialize a toolkit
toolkit = ExampleTookit(...)# Get list of tools
tools = toolkit.get_tools()
16、代理 agents
语言模型本身无法采取行动——它们只是输出文本。
LangChain 的一个重要用例是创建代理。
代理是使用 LLM 作为推理工程师来确定要采取哪些操作以及这些操作的输入应该是什么的系统。
然后,这些操作的结果可以反馈给代理,并确定是否需要更多操作,或者是否可以完成。
LangGraph是LangChain的扩展,专门旨在创建高度可控和可定制的代理。
请查看该文档以更深入地了解代理概念。
LangChain 中有一个遗留代理概念,我们正在逐步弃用:AgentExecutor
。
AgentExecutor 本质上是代理的运行时。
这是一个很好的起点,但是,当您开始拥有更多定制代理时,它不够灵活。
为了解决这个问题,我们将 LangGraph 构建为这种灵活、高度可控的运行时。
如果您仍在使用 AgentExecutor,请不要担心:我们仍然有关于 如何使用 AgentExecutor 的指南。
但是,建议您开始过渡到 LangGraph。
为了帮助实现这一目标,我们整理了一份关于如何做到这一点的过渡指南
17、回调 callbacks
LangChain 提供了一个回调系统,允许您连接到 LLM 申请的各个阶段。
这对于日志记录、监控、流传输和其他任务非常有用。
您可以使用callbacks
API 中提供的参数订阅这些事件。
此参数是处理程序对象的列表,这些对象应实现下面更详细描述的一个或多个方法。
回调处理程序 callback-handlers
CallbackHandlers
是实现该接口的对象CallbackHandler
,该接口对于每个可以订阅的事件都有一个方法。
CallbackManager
当事件被触发时,将在每个处理程序上调用适当的方法。
class BaseCallbackHandler:"""Base callback handler that can be used to handle callbacks from langchain."""def on_llm_start(self, serialized: Dict[str, Any], prompts: List[str], **kwargs: Any) -> Any:"""Run when LLM starts running."""def on_chat_model_start(self, serialized: Dict[str, Any], messages: List[List[BaseMessage]], **kwargs: Any) -> Any:"""Run when Chat Model starts running."""def on_llm_new_token(self, token: str, **kwargs: Any) -> Any:"""Run on new LLM token. Only available when streaming is enabled."""def on_llm_end(self, response: LLMResult, **kwargs: Any) -> Any:"""Run when LLM ends running."""def on_llm_error(self, error: Union[Exception, KeyboardInterrupt], **kwargs: Any) -> Any:"""Run when LLM errors."""def on_chain_start(self, serialized: Dict[str, Any], inputs: Dict[str, Any], **kwargs: Any) -> Any:"""Run when chain starts running."""def on_chain_end(self, outputs: Dict[str, Any], **kwargs: Any) -> Any:"""Run when chain ends running."""def on_chain_error(self, error: Union[Exception, KeyboardInterrupt], **kwargs: Any) -> Any:"""Run when chain errors."""def on_tool_start(self, serialized: Dict[str, Any], input_str: str, **kwargs: Any) -> Any:"""Run when tool starts running."""def on_tool_end(self, output: Any, **kwargs: Any) -> Any:"""Run when tool ends running."""def on_tool_error(self, error: Union[Exception, KeyboardInterrupt], **kwargs: Any) -> Any:"""Run when tool errors."""def on_text(self, text: str, **kwargs: Any) -> Any:"""Run on arbitrary text."""def on_agent_action(self, action: AgentAction, **kwargs: Any) -> Any:"""Run on agent action."""def on_agent_finish(self, finish: AgentFinish, **kwargs: Any) -> Any:"""Run on agent end."""
传递回调 passing-callbacks
该callbacks
属性在整个 API 中的大多数对象(模型、工具、代理等)上都可用,位于两个不同的位置:
- 构造函数回调:在构造函数中定义,例如
ChatAnthropic(callbacks=[handler], tags=['a-tag'])
。
在这种情况下,回调将用于对该对象进行的所有调用,并且仅限于该对象。
例如,如果您使用构造函数回调初始化聊天模型,然后在链中使用它,则只会在调用该模型时调用回调。 - 请求回调:传递到
invoke
用于发出请求的方法中。
在这种情况下,回调将仅用于该特定请求及其包含的所有子请求(例如,对触发模型调用的序列的调用,该模型使用在方法中传递的相同处理程序invoke()
)。
在invoke()
方法中,回调是通过config
参数传递的。
四、techniques
1、函数/工具调用 Function/tool calling
注:我们可以互换使用术语“工具调用(term tool calling)”和“函数调用(function calling)”。
尽管函数调用有时是指单个函数的调用,但我们将所有模型视为可以在每条消息中返回多个工具或函数调用。
工具调用允许模型通过生成与用户定义的模式匹配的输出来响应给定的提示。
虽然名称暗示模型正在执行某些操作,但实际上情况并非如此!该模型提出了工具的参数,实际运行(或不运行)该工具取决于用户 - 例如,如果您想从非结构化文本中提取与某些模式匹配的输出 ,您可以给模型一个“提取”工具,它采用与所需模式匹配的参数,然后将生成的输出视为最终结果。
工具调用包括名称、参数字典和可选标识符。
参数 dict 是结构化的{argument_name: argument_value}
。
许多 LLM 提供商,包括Anthropic、 Cohere、Google、 Mistral、OpenAI等,都支持工具调用功能的变体。
这些功能通常允许向 LLM 发出的请求包含可用的工具及其架构,并允许响应包含对这些工具的调用。
例如,给定一个搜索引擎工具, LLM 可能会通过首先向搜索引擎发出调用来处理查询。
调用LLM的系统可以接收工具调用,执行它,并将输出返回给LLM以告知其响应。
LangChain 包含一套内置工具 ,并支持多种定义您自己的自定义工具的方法。
LangChain提供了标准化的工具调用接口,在不同模型之间保持一致。
标准接口包括:
ChatModel.bind_tools()
:指定模型可以调用哪些工具的方法。AIMessage.tool_calls
:从模型返回的属性AIMessage
,用于访问模型请求的工具调用。
函数/工具调用有两个主要用例:
- 如何从 LLM 返回结构化数据
- 如何使用模型调用工具
2、检索 retrieval
LangChain提供了多种高级检索类型。 下面是完整列表以及以下信息:
名称:检索算法的名称。
索引类型:它依赖哪种索引类型(如果有)。
使用 LLM:此检索方法是否使用 LLM。
何时使用:我们对何时应考虑使用此检索方法的评论。
描述:描述此检索算法正在做什么。
姓名 | 指数类型 | 使用法学硕士学位 | 何时使用 | 描述 |
---|---|---|---|---|
矢量商店 | 矢量商店 | 不 | 如果您刚刚开始并正在寻找快速简单的东西。 | 这是最简单的方法,也是最容易上手的方法。它涉及为每段文本创建嵌入。 |
父文档 | 矢量存储 + 文档存储 | 不 | 如果您的页面有许多较小的不同信息,最好自行索引,但最好一起检索。 | 这涉及到为每个文档的多个块建立索引。然后,您找到嵌入空间中最相似的块,但检索整个父文档并返回它(而不是单个块)。 |
多向量 | 矢量存储 + 文档存储 | 有时在索引期间 | 如果您能够从文档中提取您认为与索引比文本本身更相关的信息。 | 这涉及为每个文档创建多个向量。每个向量都可以通过多种方式创建 - 示例包括文本摘要和假设问题。 |
自我查询 | 矢量商店 | 是的 | 如果用户提出的问题可以通过获取基于元数据而不是与文本的相似性的文档来更好地回答。 | 它使用 LLM 将用户输入转换为两件事:(1) 用于语义查找的字符串,(2) 与其一起使用的元数据文件管理器。这很有用,因为问题通常与文档的元数据(而不是内容本身)有关。 |
上下文压缩 | 任何 | 有时 | 如果您发现检索到的文档包含太多不相关的信息并且分散了法学硕士的注意力。 | 这将后处理步骤置于另一个检索器之上,并仅从检索到的文档中提取最相关的信息。这可以通过嵌入或法学硕士来完成。 |
时间加权向量库 | 矢量商店 | 不 | 如果你的文档有时间戳,并且你想检索最新的时间戳 | 这基于语义相似性(如正常向量检索)和新近度(查看索引文档的时间戳)的组合来获取文档 |
多查询检索器 | 任何 | 是的 | 如果用户提出的问题很复杂并且需要多条不同的信息来回答 | 这使用 LLM 从原始查询生成多个查询。当原始查询需要有关多个主题的信息才能得到正确回答时,这很有用。通过生成多个查询,我们可以为每个查询获取文档。 |
合奏 | 任何 | 不 | 如果您有多种检索方法并想尝试将它们组合起来。 | 这会从多个检索器中获取文档,然后将它们组合起来。 |
3、文本分割 text-splitting
LangChain 提供多种不同类型的text splitters
。这些都包含在langchain-text-splitters
包中。表列:
- 名称:文本分割器的名称
- 类:实现此文本分割器的类
- 拆分:此文本拆分器如何拆分文本
- 添加元数据:此文本拆分器是否添加有关每个块来自何处的元数据。
- 描述:分离器的描述,包括有关何时使用它的建议。
姓名 | 课程 | 分裂 | 添加元数据 | 描述 |
---|---|---|---|---|
递归 | 递归字符文本分割器、递归Json分割器 | 用户定义的字符列表 | 递归地分割文本。这种拆分试图将相关的文本片段保持在一起。这是recommended way 开始分割文本。 | |
超文本标记语言 | HTMLHeaderTextSplitter、HTMLSectionSplitter | HTML 特定字符 | ✅ | 根据 HTML 特定字符分割文本。值得注意的是,这添加了有关该块来自何处的相关信息(基于 HTML) |
降价 | MarkdownHeaderTextSplitter, | Markdown 特定字符 | ✅ | 根据 Markdown 特定字符分割文本。值得注意的是,这添加了有关该块来自何处的相关信息(基于 Markdown) |
代码 | 许多语言 | 代码(Python、JS)特定字符 | 根据特定于编码语言的字符分割文本。有 15 种不同的语言可供选择。 | |
代币 | 许多课程 | 代币 | 拆分标记上的文本。有几种不同的方法来衡量代币。 | |
特点 | 字符文本分割器 | 用户定义的角色 | 根据用户定义的字符拆分文本。 比较简单的方法之一。 | |
语义分块器(实验性) | 语义分块器 | 句子 | 首先对句子进行拆分。 如果语义足够相似,则将相邻的句子合并。 摘自Greg Kamradt | |
集成:AI21语义 | AI21语义文本分割器 | ✅ | 识别形成连贯文本片段的不同主题并沿着这些文本片段进行分割。 |
2024-05-22(三)