LangChain学习笔记
介绍
LangChain是一个用于开发由大型语言模型(LLM)驱动的应用程序的框架。
LangChain简化了LLM应用程序生命周期的每个阶段:
- 开发:使用LangChain的开源组件和第三方集成构建您的应用程序。使用LangGraph构建具有顶级流式传输和人类参与支持的状态化代理。
- 生产化:使用LangSmith检查、监控和评估您的应用程序,从而能够持续优化并放心部署。
- 部署:通过LangGraph平台,将您的 LangGraph 应用程序转化为生产就绪的 API 和助手
LangChain 实现了针对大型语言模型及相关技术(如嵌入模型和向量存储)的标准接口,并与数百个提供商进行了集成。
构成
LangChain框架由多个开源库组成。
- langchain-core:聊天模型和其他组件的基本抽象。
- Integration packages (e.g. langchain-openai, langchain-anthropic, etc.):已被拆分为轻量级包,由LangChain团队和集成开发人员共同维护。
- langchain:Chains,angents,retrieval构成应用程序架构
- langchain-community:社区维护的第三方集成
- langgraph:用于将LangChain组件组合到具有持久性、流式传输和其他关键功能的生产就绪应用程序中。
https://python.langchain.com/svg/langchain_stack_112024.svg
聊天模型
大型语言模型(LLM)是先进的机器学习模型,在广泛的语言相关任务中表现出色,如文本生成、翻译、摘要、问答等,而不需要对每个场景进行特定任务的微调。
现代LLM通常通过聊天模型界面访问,该界面将消息列表作为输入,并返回消息作为输出。
最新一代聊天模式提供了额外的功能:
工具调用(tool calling)
许多流行的聊天模型都提供一个称为API的原生工具。此API允许开发人员构建丰富的应用程序,使LLM能够与外部服务、API和数据库交互。工具调用还可以用于从非结构化数据中提取结构化信息,并执行各种其他任务。
概述
许多人工智能应用程序直接与人类交互。在这些情况下,模型用自然语言进行响应是合适的。但是,如果我们希望模型也与系统(如数据库或API)直接交互,那么情况又如何呢?这些系统通常具有特定的输入模式;例如,API通常具有所需的有效载荷结构。这种需求激发了工具调用的概念。您可以使用工具调用来请求与特定模式匹配的模型响应。
https://python.langchain.com/assets/images/tool_calling_concept-552a73031228ff9144c7d59f26dedbbf.png
关键概念
- 工具创建:使用@Tool装饰器创建工具。工具是函数与其模式之间的关联
- 工具绑定:工具需要连接到支持工具调用的模型。这使模型能够感知工具和工具所需的相关输入模式。
- 工具调用:在适当的时候,模型可以决定调用工具,并确保其响应符合工具的输入模式。
- 工具执行:可以使用模型提供的参数执行工具。
推荐用法
此伪代码说明了使用工具调用的推荐工作流程。创建的工具以列表形式传递给.bind_tools()方法。这个模型可以像往常一样被调用。如果进行了工具调用,模型的响应将包含工具调用参数。工具调用参数可以直接传递给工具。
# Tool creation
tools = [my_tool]
# Tool binding
model_with_tools = model.bind_tools(tools)
# Tool calling
response = model_with_tools.invoke(user_input)
工具创建
创建工具的推荐方法是使用@tool装饰器。
from langchain_core.tools import tool
@tool
def multiply(a: int, b: int) -> int:
"""Multiply a and b."""
return a * b
工具绑定
要理解的核心概念是,LangChain提供了一个标准化的接口,用于将工具连接到模型。.bind_tools()方法可用于指定模型可调用的工具。
model_with_tools = model.bind_tools(tools_list)
举个例子,让我们把一个函数multiply作为一个工具绑定到一个支持工具调用的模型上。
def multiply(a: int, b: int) -> int:
"""Multiply a and b.
Args:
a: first int
b: second int
"""
return a * b
llm_with_tools = tool_calling_model.bind_tools([multiply])
工具调用
https://python.langchain.com/assets/images/tool_call_example-2348b869f9a5d0d2a45dfbe614c177a4.png
工具调用的一个关键原则是,模型根据输入的相关性决定何时使用工具。模型并不总是需要调用工具。例如,给定一个无关的输入,模型不会调用该工具:
result = llm_with_tools.invoke("Hello world!")
结果将是一个包含模型自然语言响应的AIMessage(例如,“Hello!”)。但是,如果我们传递与工具相关的输入,模型应该选择调用它:
result = llm_with_tools.invoke("What is 2 multiplied by 3?")
如前所述,输出结果将是一条AIMessage。但是,如果调用了该工具,则结果将具有tool_calls属性。此属性包括执行工具所需的一切,包括工具名称和输入参数:
result.tool_calls
{'name': 'multiply', 'args': {'a': 2, 'b': 3}, 'id': 'xxx', 'type': 'tool_call'}
工具执行
Tool executionTools实现了Runnable接口,着可以直接调用它们(例如Tool.inquire(args))。
LangGraph提供预构建的组件(例如ToolNode),这些组件通常会代表用户调用工具。
最佳实践
在设计模型使用的工具时,重要的是要记住:
- 具有显式工具调用API的模型在工具调用方面比非微调模型更好。
- 如果工具有精心选择的名称和描述,模型的性能会更好。
- 简单、范围小的工具比复杂的工具更容易让模型使用。
- 要求模型从大量工具中进行选择对模型来说是一个挑战。
结构化输出 (Structured output)
一种使聊天模型以结构化格式响应的技术,例如与给定模式匹配的JSON。
概述
对于许多应用程序,如聊天机器人,模型需要以自然语言直接响应用户。然而,在某些情况下,我们需要模型以结构化格式输出。例如,我们可能希望将模型输出存储在数据库中,并确保输出符合数据库模式。这种需求激发了结构化输出的概念,其中可以指示模型以特定的输出结构进行响应。
https://python.langchain.com/assets/images/structured_output-2c42953cee807dedd6e96f3e1db17f69.png
关键概念
- 结构定义:输出结构固定为该结构,可以通过多种方式定义
- 返回结构化输出:模型被赋予此结构,并被指示返回符合它的输出。
推荐用法
此伪代码说明了使用结构化输出时的推荐工作流程。LangChain提供了一个带有_structured_output()的方法,可以自动将模式绑定到模型并解析输出。此辅助函数可用于支持结构化输出的所有模型提供程序。
# 定义结构
schema = {"foo": "bar"}
# 绑定该结构至模型
model_with_structure = model.with_structured_output(schema)
# 调用模型以生成与模式匹配的结构化输出
structured_output = model_with_structure.invoke(user_input)
结构定义
核心概念是,模型响应的输出结构需要以某种方式表示。虽然你可以使用的对象类型取决于你使用的模型,但在Python中,通常允许或推荐使用常见类型的对象进行结构化输出。
结构化输出最简单、最常见的格式是类似JSON的结构,在Python中可以表示为字典(dict)或列表(list)。当工具需要原始、灵活且开销最小的结构化数据时,JSON对象(或Python中的字典)通常直接使用。
{
"answer": "The answer to the user's question",
"followup_question": "A followup question the user could ask"
}
第二个例子,Pydantic对于定义结构化输出模式特别有用,因为它提供了类型提示和验证。下面是一个Pydantic模式的示例:
from pydantic import BaseModel, Field
class ResponseFormatter(BaseModel):
"""Always use this tool to structure your response to the user."""
answer: str = Field(description="The answer to the user's question")
followup_question: str = Field(description="A followup question the user could ask")
结构化输出
定义了结构后,我们需要一种方法来指示模型使用它。虽然一种方法是在提示中包含此模式,并很好地要求模型使用它,但不建议这样做。有几种更强大的方法可以利用模型提供程序的API中的本机功能。
使用工具调用
工具调用涉及将工具绑定到模型,在适当的时候,模型可以决定调用此工具并确保其响应符合工具的模式。考虑到这一点,中心概念很简单:只需将我们的模式绑定到模型作为工具!下面是一个使用上面定义的ResponseFormatter模式的示例:
from langchain_openai import ChatOpenAI
model = ChatOpenAI(model="gpt-4o", temperature=0)
# Bind responseformatter schema as a tool to the model
model_with_tools = model.bind_tools([ResponseFormatter])
# Invoke the model
ai_msg = model_with_tools.invoke("What is the powerhouse of the cell?")
工具调用的参数已经提取为字典。这个字典可以选择性地解析为Pydantic对象,与我们最初的ResponseFormatter模式相匹配。
# Get the tool call arguments
ai_msg.tool_calls[0]["args"]
{'answer': "The powerhouse of the cell is the mitochondrion. Mitochondria are organelles that generate most of the cell's supply of adenosine triphosphate (ATP), which is used as a source of chemical energy.",
'followup_question': 'What is the function of ATP in the cell?'}
# Parse the dictionary into a pydantic object
pydantic_object = ResponseFormatter.model_validate(ai_msg.tool_calls[0]["args"])
JSON模式
除了工具调用,一些模型提供程序还支持一种名为JSON模式的功能。这支持JSON模式定义作为输入,并强制模型生成符合要求的JSON输出。您可以在此处找到支持JSON模式的模型提供程序表。以下是一个如何在OpenAI中使用JSON模式的示例:
from langchain_openai import ChatOpenAI
model = ChatOpenAI(model="gpt-4o").with_structured_output(method="json_mode")
ai_msg = model.invoke("Return a JSON object with key 'random_ints' and a value of 10 random ints in [0-99]")
ai_msg
{'random_ints': [45, 67, 12, 34, 89, 23, 78, 56, 90, 11]}
结构化输出方法
使用上述方法生成结构化输出时存在一些挑战:
- 当使用工具调用时,需要将工具调用参数从字典解析回原始模式
- 此外,当我们想要强制执行结构化输出时,需要指示模型始终使用该工具,灵活性差。
- 当使用JSON模式时,需要将输出解析为JSON对象。
考虑到这些挑战,LangChain提供了一个辅助函数(With_structured_output())来简化流程。
这既将模式作为工具绑定到模型,又将输出解析为指定的输出模式。
# Bind the schema to the model
model_with_structure = model.with_structured_output(ResponseFormatter)
# Invoke the model
structured_output = model_with_structure.invoke("What is the powerhouse of the cell?")
# Get back the pydantic object
structured_output
ResponseFormatter(answer="The powerhouse of the cell is the mitochondrion. Mitochondria are organelles that generate most of the cell's supply of adenosine triphosphate (ATP), which is used as a source of chemical energy.", followup_question='What is the function of ATP in the cell?')
多模态(Multimodality)
处理文本以外的数据的能力;例如,图像、音频和视频。
概述
多模态是指处理不同形式的数据的能力,如文本、音频、图像和视频。多模态可以出现在各种组件中,使模型和系统能够无缝处理和处理这些数据类型的混合。
- 聊天模型(Chat Models):理论上,这些可以接受和生成多模式输入和输出,处理各种数据类型,如文本、图像、音频和视频。
- 向量化模型(Embedding Models):向量化模型可以表示多模态内容,将各种形式的数据(如文本、图像和音频)嵌入向量空间。
- 向量存储(Vector Stores):向量存储可以在表示多模态数据的嵌入上进行搜索,从而能够跨不同类型的信息进行检索。
Chat Models中的多模态
多模态仍然相对较新且不太常见,模型提供商尚未对定义API的“最佳”方式进行标准化。因此,LangChain的多模式抽象是轻量级和灵活的,旨在适应不同模型提供者的API和交互模式,但并没有跨模型标准化。
如何使用多模态
支持哪种多模态
Input
一些模型可以接受多模式输入,如图像、音频、视频或文件。支持的多模式输入类型取决于模型提供者。例如,谷歌的Gemini支持PDF等文档作为输入。
大多数支持多模式输入的聊天模型也接受OpenAI内容块格式的这些值。到目前为止,这仅限于图像输入。对于像Gemini这样支持视频和其他字节输入的模型,API还支持本机特定于模型的表示。
将多模式输入传递给聊天模型的要点是使用指定类型和相应数据的内容块。例如,要将图像传递给聊天模型:
from langchain_core.messages import HumanMessage
message = HumanMessage(
content=[
{"type": "text", "text": "describe the weather in this image"},
{"type": "image_url", "image_url": {"url": image_url}},
],
)
response = model.invoke([message])
Outputs
截止2024年10月,几乎没有流行的聊天模型支持多模式输出。
唯一的例外是OpenAI的聊天模型(gpt-4o-audio-preview),它可以生成音频输出
多模式输出将作为AIMessage响应对象的一部分出现。
有关如何使用多模式输出的更多信息,请参阅ChatOpenAI。ChatOpenAI | 🦜️🔗 LangChain
Tools
目前,没有聊天模型被设计为直接处理工具调用请求或ToolMessage结果中的多模式数据。
然而,聊天模型可以通过调用具有多模式数据引用(例如URL)的工具,而不是数据本身,轻松地与多模式数据交互。例如,任何能够调用工具的模型都可以配备下载和处理图像、音频或视频的工具。
Embeddings Models中的多模态
向量化是用于相似性搜索和检索等任务的数据的矢量表示
LangChain中使用的当前向量化接口完全针对基于文本的数据进行了优化,不适用于多模式数据
随着涉及多模式搜索和检索任务的用例变得越来越普遍,希望扩展嵌入接口以适应其他数据类型,如图像、音频和视频。
Vector stores中的多模态
向量存储是用于存储和检索嵌入的数据库,通常用于搜索和检索任务。与向量化类似,向量存储目前针对基于文本的数据进行了优化。
随着涉及多模式搜索和检索任务的用例变得越来越普遍,希望扩展向量存储接口,以适应图像、音频和视频等其他数据类型。
特征
LangChain提供了一个一致的接口,用于处理来自不同提供商的聊天模型,同时提供了额外的功能,用于监控、调试和优化使用LLM的应用程序的性能。
- 与许多聊天模型(例如,Anthropic、OpenAI、Ollama、Microsoft Azure、Google Vertex、Amazon Bedrock、Hugging Face、Cohere、Groq)集成。
- 使用LangChain的消息格式或OpenAI格式。Messages | 🦜️🔗 LangChain
- 标准工具调用API:用于将工具绑定到模型、访问模型发出的工具调用请求以及将工具结果发送回模型的标准接口。Tool calling | 🦜️🔗 LangChain
- 通过with_structured_output方法构造输出的标准API。Structured outputs | 🦜️🔗 LangChain
- 提供对异步编程、高效批处理、丰富的流式API的支持Async programming with langchain | 🦜️🔗 LangChainRunnable interface | 🦜️🔗 LangChainStreaming | 🦜️🔗 LangChain
- 与LangSmith集成,用于监控和调试基于LLM的生产级应用程序。Get started with LangSmith | 🦜️🛠️ LangSmith
- 其他功能,如标准化token使用、速率限制、缓存等。Messages | 🦜️🔗 LangChainChat models | 🦜️🔗 LangChainChat models | 🦜️🔗 LangChain
集成
LangChain有许多聊天模型集成,允许您使用来自不同提供商的各种模型。
这些集成有两种类型:
- 官方模型:这些是LangChain和/或模型提供商官方支持的模型。您可以在langchain-<provider>包中找到这些模型。
- 社区模型:有些模型主要由社区贡献和支持。您可以在langchain社区包中找到这些模型。
LangChain聊天模型的命名有一个约定,即在类名前加上“chat”前缀(例如,ChatOllama、ChatAnthropic、ChatOpenAI等)。
请查看聊天模型集成以获取支持的模型列表。Chat models | 🦜️🔗 LangChain
注意:名称中不包含前缀“Chat”或名称中包含后缀“LLM”的型号通常是指不遵循聊天模型接口的旧型号,而是使用一个以字符串为输入并返回字符串作为输出的接口。
接口
LangChain聊天模型实现了BaseChatModel接口。由于BaseChatModel还实现了Runnable接口,聊天模型支持标准流接口、异步编程、优化批处理等。有关更多详细信息,请参阅Runnable接口。BaseChatModel — 🦜🔗 LangChain documentationRunnable interface | 🦜️🔗 LangChainStreaming | 🦜️🔗 LangChainAsync programming with langchain | 🦜️🔗 LangChainRunnable interface | 🦜️🔗 LangChain
聊天模型的许多关键方法都以消息作为输入,以返回消息作为输出。Messages | 🦜️🔗 LangChain
聊天模型提供了一组可用于配置模型的标准参数。这些参数通常用于控制模型的行为
关键方法
聊天模型的关键方法有:BaseChatModel — 🦜🔗 LangChain documentation
- invoke:与聊天模型交互的主要方法。它以消息列表作为输入,并返回消息列表作为输出。
- stream:一种允许您在生成聊天模型时流式传输其输出的方法。
- batch:一种方法,允许您将多个请求批处理到一个聊天模型中,以实现更高效的处理。
- bind_tools:允许将工具绑定到聊天模型,以便在模型的执行上下文中使用。
- with_structured_output:结构化输出。
输入和输出
现代LLM通常通过聊天模型界面访问,该界面将消息作为输入,并将消息作为输出返回。消息通常与角色(例如,“系统”、“人”、“助理”)和一个或多个包含文本或潜在多模式数据(例如,图像、音频、视频)的内容块相关联。
LangChain支持两种消息格式与聊天模型交互:
- LangChain消息格式:LangChain自己的消息格式,默认使用,由LangChain内部使用。
- OpenAI消息格式:OpenAI的消息格式。
标准参数
许多聊天模型都有可用于配置模型的标准化参数:
| 参数 | 描述 |
| model | 要使用的特定AI模型的名称或标识符(例如,“gpt-3.5-turbo”或“gpt-4”) |
| temperature | 控制模型输出的随机性。较高的值(例如1.0)使响应更具创造性,而较低的值(如0.0)使其更具确定性和专注性。 |
| timeout | 取消请求之前等待模型响应的最长时间(秒)。确保请求不会无限期挂起。 |
| max_tokens | 限制响应中标记(单词和标点符号)的总数。这控制了输出的长度 |
| stop | 指定停止序列,指示模型何时应停止生成令牌。例如,可以使用特定的字符串来表示响应的结束。 |
| max_retries | 如果由于网络超时或速率限制等问题导致请求失败,系统将尝试重新发送请求的最大次数。 |
| api_key | 与模型提供程序进行身份验证所需的API密钥。这通常在注册访问模型时发出。 |
| base_url | 发送请求的API终结点的URL。这通常由模型的提供者提供,对于指导请求是必要的。 |
| rate_limiter | 可选的BaseRateLimiter,用于分隔请求以避免超过速率限制。 |
需要注意的一些重要事项:
- 标准参数仅适用于公开具有预期功能的参数的模型提供程序。例如,一些提供程序不公开最大输出令牌的配置,因此这些提供程序不支持max_tokens。
- 目前,标准参数仅在具有自己的集成包的集成上强制执行(例如langchain openai、langchain anthropic等),而在langchain社区的模型上则没有强制执行
聊天模型还接受特定于该集成的其他参数。要查找聊天模型支持的所有参数,请访问该模型各自的API参考。
工具调用
聊天模型可以调用工具来执行任务,例如从数据库获取数据、发出API请求或运行自定义代码。
结构化输出
可以请求聊天模型以特定格式(例如JSON或匹配特定模式)进行响应。此功能对于信息提取任务非常有用。请在结构化输出指南中阅读更多关于该技术的信息。
多模态
大型语言模型(LLM)不仅限于处理文本。它们还可以用于处理其他类型的数据,如图像、音频和视频。这被称为多模态。目前,只有一些LLM支持多模态输入,几乎没有一个支持多模态输出。
上下文窗口
聊天模型的上下文窗口是指模型一次可以处理的输入序列的最大大小。虽然现代LLM的上下文窗口相当大,但它们仍然存在一个限制,开发人员在使用聊天模型时必须牢记这一点。
如果输入超出上下文窗口,模型可能无法处理整个输入,并可能引发错误。在会话应用程序中,这一点尤为重要,因为上下文窗口决定了模型在整个会话中可以“记住”多少信息。开发人员通常需要在上下文窗口中管理输入,以保持连贯的对话,而不会超出限制。有关在对话中处理内存的更多详细信息,请参阅内存。Memory
输入的大小以tokens来衡量,令牌是模型使用的处理单位。
限速
许多聊天模型对给定时间段内可以发出的请求数量施加了限制。
如果达到速率限制,通常会收到来自提供商的速率限制错误响应,并且需要等待才能发出更多请求。
有几个选项可以处理利率限制:
- 通过间隔请求来避免达到速率限制:聊天模型接受可以在初始化期间提供的rate_limiter参数。此参数用于控制向模型提供者发出请求的速率。在对模型进行基准测试以评估其性能时,将请求间隔开来是一种特别有用的策略。How to handle rate limits | 🦜️🔗 LangChain
- 尝试从速率限制错误中恢复:如果您收到速率限制错误,您可以在重试请求之前等待一定时间。每次出现速率限制错误时,等待时间都会增加。聊天模型有一个max_retrys参数,可用于控制重试次数。Chat models | 🦜️🔗 LangChain
- 回退到另一种聊天模型:如果你在一种聊天模型上达到了速率限制,你可以切换到另一个不受速率限制的聊天模型。
缓存
聊天模型API可能很慢,因此一个自然的问题是是否缓存以前对话的结果。理论上,缓存可以通过减少向模型提供者发出的请求数量来帮助提高性能。在实践中,缓存聊天模型响应是一个复杂的问题,应该谨慎处理。
原因是,如果依赖于将确切的输入缓存到模型中,则在对话中的第一次或第二次交互后不太可能获得缓存命中。例如,你认为多个对话以完全相同的信息开始的可能性有多大?那完全相同的三条信息呢?
另一种方法是使用语义缓存,根据输入的含义而不是确切的输入本身缓存响应。这在某些情况下可能有效,但在其他情况下无效。
语义缓存在应用程序的关键路径上引入了对另一个模型的依赖(例如,语义缓存可能依赖于向量化模型将文本转换为向量表示),并且不能保证准确捕捉输入的含义。Embedding models | 🦜️🔗 LangChain
然而,在某些情况下,缓存聊天模型响应可能是有益的。例如,如果您有一个用于回答常见问题的聊天模型,缓存响应可以帮助减少模型提供者的负载、成本并缩短响应时间。
How to cache chat model responses | 🦜️🔗 LangChain
相关资源(引用)
如何使用聊天模式指南:操作指南How-to guides | 🦜️🔗 LangChain
支持的聊天模式列表:聊天模式集成Chat models | 🦜️🔗 LangChain
Messages
概览
消息是聊天模式中的通信单位。它们用于表示聊天模型的输入和输出,以及可能与对话相关的任何其他上下文或元数据。
每条消息都有一个角色(例如,“用户”、“助理”)和内容(例如,文本、多模态数据),以及根据聊天模型而有所不同的附加元数据。
LangChain提供了一种跨聊天模型使用的统一消息格式,允许用户使用不同的聊天模型,而无需担心每个模型提供商使用的消息格式的具体细节。
消息里面有什么?
消息通常由以下信息组成:
- Role:消息的角色(例如,“user”、“assistant”)
- Content:消息的内容(例如,文本、多模态数据)
- 其他元数据:id、name、token和其他特定于模型的元数据。
Role
角色用于区分对话中不同类型的消息,并帮助聊天模型理解如何响应给定的消息序列。
| Role | Description |
| system | 用于告诉聊天模型如何表现并提供额外的上下文。并非所有聊天模型都支持。 |
| user | 表示与模型交互的用户的输入,通常以文本或其他交互式输入的形式。 |
| assistant | 表示来自模型的响应,其中可以包括文本或调用工具的请求。 |
| tool | 一种消息,用于在检索到外部数据或处理后将工具调用的结果传递回模型。与支持工具调用的聊天模型一起使用。 |
| function(legacy) | 这是一个遗留角色,对应于OpenAI的遗留功能调用API。应该使用tool角色。 |
Content
表示多模式数据(如图像、音频、视频)的消息文本或字典列表的内容。内容的确切格式可能因不同的聊天模式提供商而异。
目前,大多数聊天模型支持文本作为主要内容类型,一些模型还支持多模式数据。然而,大多数聊天模型对多模式数据的支持仍然有限。
有关更多信息,请参阅:SystemMessage、HumanMessage、AIMessage、Multimodality
Other Message Data
根据聊天模式提供商的不同,消息可能包括其他数据,例如:
- ID:消息的可选唯一标识符。
- Name:一个可选的名称属性,允许区分具有相同角色的不同实体/说话者。并非所有模型都支持此功能!
- Metadata:有关消息的其他信息,如时间戳、token使用情况等。
- ToolCalls:模型请求调用一个或多个工具Tool calling | 🦜️🔗 LangChain
会话结构
聊天模型中的消息序列应遵循特定的结构,以确保聊天模型能够生成有效的响应。
SystemMessage
SystemMessage用于引导AI模型的行为并提供额外的上下文,例如指示模型采用特定的角色或设置对话的基调(例如,“这是一个关于烹饪的对话”)。
不同的聊天模型可能通过以下方式之一支持系统消息:
- 通过“system”消息角色:在这种情况下,系统消息作为消息序列的一部分包含在内,角色明确设置为“系统”
- 通过单独的系统指令API参数:系统指令不是作为消息包含,而是通过专用的API参数传递。
- 不支持系统消息:某些模型根本不支持系统信息。
大多数主要的聊天模型提供商通过聊天消息或单独的API参数支持系统指令。LangChain将根据提供商的能力自动进行调整。如果提供者为系统指令支持单独的API参数,LangChain将提取系统消息的内容并通过该参数传递。
如果提供者不支持系统消息,在大多数情况下,LangChain将尝试将系统消息的内容合并到HumanMessage中,或者在不可能的情况下引发异常。然而,这种行为尚未在所有实现中得到一致执行,如果使用不太流行的聊天模型实现(例如,来自langchain社区包的实现),建议查看该模型的具体文档。
HumanMessage
HumanMessage对应于“user”角色。人工消息表示与模型交互的用户的输入。
1、文本(Text Content)
大多数聊天模型都希望用户输入以文本的形式出现。
from langchain_core.messages import HumanMessage
model.invoke([HumanMessage(content="Hello, how are you?")])
2、多模态(Multi-modal Content)
一些聊天模式接受多模态输入,如图像、音频、视频或PDF等文件。
AIMessage
AIMessage用于表示具有“assitant”角色的消息。这是来自模型的响应,其中可以包括文本或调用工具的请求。它还可以包括其他媒体类型,如图像、音频或视频,尽管目前这种情况仍然不常见。
from langchain_core.messages import HumanMessage
ai_message = model.invoke([HumanMessage("Tell me a joke")])
ai_message # <-- AIMessage
AIMessage具有以下属性。标准化的属性是LangChain试图在不同的聊天模型提供商之间标准化的。原始字段特定于模型提供者,可能会有所不同。
| Attribute | Standardized/Raw | Description |
| content | Raw | 通常是字符串,但也可以是内容块列表。详见内容。 |
| tool_calls | Standardized | 与消息关联的工具调用。Tool calling | 🦜️🔗 LangChain |
| invalid_tool_calls | Standardized | 带有与消息相关的解析错误的工具调用Tool calling | 🦜️🔗 LangChain |
| usage_metadata | Standardized |
消息的使用元数据,如token计数. Tokens | 🦜️🔗 LangChainUsageMetadata — 🦜🔗 LangChain documentation |
| id | Standardized | 消息的可选唯一标识符,最好由创建消息的提供者/模型提供。 |
| response_metadata | Raw | 响应元数据,例如响应头、logprobs、token计数。 |
AIMessage的content属性表示聊天模型生成的响应。
Content为:
- 文本:几乎所有聊天模式的标准。
- 词典列表:每个字典代表一个内容块,并与一个类型相关联,1:Anthropic在调用工具时用于显示思考过程。2:OpenAI用于音频输出。请查看多模态内容以获取更多信息
AIMessageChunk
在生成聊天模型的响应时,通常会对其进行流式传输,因此用户可以实时查看响应,而无需等待整个响应生成后再显示。
它是从聊天模型的stream、astream和astream_events方法返回的。
例如:
for chunk in model.stream([HumanMessage("what color is the sky?")]):
print(chunk)
AIMessageChunk遵循与AIMessage几乎相同的结构,但使用不同的ToolCallChunk,以便能够以标准化的方式流式传输工具调用。
AIMessageChunks支持+运算符将它们合并为单个AIMessage。当您想向用户显示最终响应时,这很有用。
ai_message = chunk1 + chunk2 + chunk3 + ...
ToolMessage
这表示一条角色为“tool”的消息,其中包含调用工具的结果。除了角色和内容外,此消息还包括:
- tool_call_id字段,它将调用的id传递给被调用以产生此结果的工具
- artifact字段,可用于传递工具执行的任意工件,这些对跟踪有用,但不应发送到模型。
RemoveMessage
这是一种特殊的消息类型,与任何角色都不对应。它用于在LangGraph中管理聊天历史记录。
(Legacy) FunctionMessage
这是一种遗留消息类型,对应于OpenAI的遗留功能调用API。应该使用ToolMessage来对应于更新的工具调用API。
Memory
记忆是一种认知功能,它允许人们存储、检索和使用信息来理解他们的现在和未来。想想和一个忘记你告诉他们的一切、需要不断重复的同事一起工作的沮丧吧!随着人工智能代理承担涉及大量用户交互的更复杂的任务,为它们配备内存对于效率和用户满意度同样至关重要。有了记忆,代理可以从反馈中学习并适应用户的偏好。本指南涵盖了基于回忆范围的两种类型的记忆:
短期记忆或线程范围内存可以随时从与用户的单个会话线程中调用。LangGraph将短期记忆作为代理状态的一部分进行管理。使用检查指针将状态持久化到数据库中,以便可以随时恢复线程。当调用图形或完成一个步骤时,短期记忆会更新,并在每个步骤开始时读取状态。
长期记忆在会话线程之间共享。它可以在任何时间和任何线程中被调用。记忆的作用域是任何自定义命名空间,而不仅仅是单个线程ID。LangGraph提供存储(参考文档),让您保存和调用长期记忆。Persistence
https://langchain-ai.github.io/langgraph/concepts/img/memory/short-vs-long.png
短期记忆
短期记忆让您的应用程序记住单个线程或对话中的先前交互。一个线程在会话中组织多个交互,类似于电子邮件在单个对话中对消息进行分组的方式。
LangGraph将短期内存作为代理状态的一部分进行管理,并通过线程范围的检查点进行持久化。此状态通常可以包括对话历史以及其他有状态的数据,如上传的文件、检索到的文档或生成的工件。通过将这些存储在图的状态中,机器人可以访问给定对话的完整上下文,同时保持不同线程之间的分离。
管理长对话历史
长期记忆
「智能机器人开发者大赛」官方平台,致力于为开发者和参赛选手提供赛事技术指导、行业标准解读及团队实战案例解析;聚焦智能机器人开发全栈技术闭环,助力开发者攻克技术瓶颈,促进软硬件集成、场景应用及商业化落地的深度研讨。 加入智能机器人开发者社区iRobot Developer,与全球极客并肩突破技术边界,定义机器人开发的未来范式!
更多推荐



所有评论(0)