3-Langchain工作流编排和LCEL

LCEL 介绍

LangChain 表达语言(LCEL) 是一种声明式方法,可以轻松组合链条。

  • LCEL 从第一天设计时就目的在于支持将原型置于生产中,无需更改代码,无论是最简单的“提示+LLM”链还是最复杂的链(我们见过成功在生产中运行带有数百步骤的LCEL链)。以下是你可能想使用LCEL的几个原因的亮点:

  • 一流的流处理支持 当你使用LCEL构建链时,你可以获得尽可能短的首个令牌时间(直到输出的第一个块出来的时间)。对于一些链来说,这意味着我们可以从LLM直接将令牌流式传输到流式输出解析器,您将以与LLM提供程序输出原始令牌的速率相同的速率获得解析的增量输出块。

  • 异步支持 使用LCEL构建的任何链既可以使用同步API(例如在原型设计时的Jupyter笔记本中)调用,也可以使用异步API(例如在LangServe服务器上)调用。这使得您可以在原型和生产环境中使用相同的代码,具有良好的性能,并能够在同一个服务器上处理许多并发请求。

  • 优化的并行执行 只要您的LCEL链有可以并行执行的步骤(例如,如果您从多个提取器中获取文档),我们会自动执行它,无论是同步接口还是异步接口,以获得最小的延迟。

  • 重试和回退 为LCEL链的任何部分配置重试和回退。这是使您的链在大规模环境中更加可靠的好方法。我们目前正在添加重试/回退的流处理支持,这样您就可以在不牺牲延迟的情况下获得更高的可靠性。

  • 访问中间结果 对于更复杂的链,访问中间步骤的结果通常非常有用,即使在最终输出产生之前。这可以用于让最终用户知道发生了什么,甚至只是用于调试链。您可以流式传输中间结果,在每个LangServe服务器上都可以使用。

  • 输入和输出模式 输入和输出模式根据链的结构推断出每个LCEL链的Pydantic和JSONSchema模式。这可以用于验证输入和输出,并且是LangServe的一个重要组成部分。

  • 无缝的LangSmith跟踪 随着链条变得越来越复杂,了解每个步骤发生的具体情况变得越来越重要。 在LCEL中,所有步骤都自动记录到LangSmith,以实现最大的可观察性和可调试性。

  • 无缝的LangServe部署(opens in a new tab) 使用LCEL创建的任何链都可以轻松部署使用LangServe(opens in a new tab)。

  • 基本元素 除了可与LCEL一起使用的各种组件之外,LangChain还包括各种基本元素,这些元素有助于传递和格式化数据、绑定参数、调用自定义逻辑等等。

接口(Interface)

为了尽可能简化创建自定义链的过程,我们实现了一个 “Runnable”(opens in a new tab) 协议。许多 LangChain 组件都实现了 Runnable 协议,包括聊天模型、LLMs、输出解析器、检索器、提示模板等。此外,还有几个有用的原语用于处理 Runnable,您可以在 这个部分 中详细了解它们。
这是一个标准接口,使得定义自定义链以及以标准方式调用它们变得容易。 标准接口包括:

  • stream:以流的方式返回响应的块
  • invoke:对输入调用链
  • batch:对输入列表调用链

这些方法还有对应的异步方法,应使用 asyncio(opens in a new tab) 的 await 语法进行并发操作:

  • astream:以异步流的方式返回响应的块
  • ainvoke:异步调用链对输入
  • abatch:异步调用链对输入列表
  • astream_log:以异步流的方式返回中间步骤的响应,以及最终响应
  • astream_events:beta 在链中事件发生时流式传输事件(langchain-core 0.1.14中引入)

输入类型和输出类型因组件而异:
在这里插入图片描述
所有 Runnable 都公开了输入和输出的 模式 以检查输入和输出:

  • input_schema:从 Runnable 结构动态生成的输入 Pydantic 模型
  • output_schema:从 Runnable 结构动态生成的输出 Pydantic 模型
    让我们来看看这些方法。为此,我们将创建一个超级简单的 PromptTemplate + ChatModel 链

在这里插入图片描述

from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
 
model = ChatOpenAI()
prompt = ChatPromptTemplate.from_template("tell me a joke about {topic}")
chain = prompt | model

输出schema

# The input schema of the chain is the input schema of its first part, the prompt.
# chain.input_schema.schema() v2.0 已经废弃
print(chain.input_schema.model_json_schema())
# {'properties': {'topic': {'title': 'Topic', 'type': 'string'}}, 'required': ['topic'], 'title': 'PromptInput', 'type': 'object'}
print("============================")
print(prompt.input_schema.model_json_schema())

print("============================")
print(model.input_schema.model_json_schema())
print("============================")
print(chain.output_schema.model_json_schema())
{
   'properties': {
   'topic': {
   'title': 'Topic', 'type': 'string'}}, 'required': ['topic'], 'title': 'PromptInput', 'type': 'object'}
============================
{
   'properties': {
   'topic': {
   'title': 'Topic', 'type': 'string'}}, 'required': ['topic'], 'title': 'PromptInput', 'type': 'object'}
============================
{
   '$defs': {
   'AIMessage': {
   'additionalProperties': True, 'description': 'Message from an AI.\n\nAIMessage is returned from a chat model as a response to a prompt.\n\nThis message represents the output of the model and consists of both\nthe raw output as returned by the model together standardized fields\n(e.g., tool calls, usage metadata) added by the LangChain framework.', 'properties': {
   'content': {
   'anyOf': [{
   'type': 'string'}, {
   'items': {
   'anyOf': [{
   'type': 'string'}, {
   'type': 'object'}]}, 'type': 'array'}], 'title': 'Content'}, 'additional_kwargs': {
   'title': 'Additional Kwargs', 'type': 'object'}, 'response_metadata': {
   'title': 'Response Metadata', 'type': 'object'}, 'type': {
   'const': 'ai', 'default': 'ai', 'title': 'Type', 'type': 'string'}, 'name': {
   'anyOf': [{
   'type': 'string'}, {
   'type': 'null'}], 'default': None, 'title': 'Name'}, 'id': {
   'anyOf': [{
   'type': 'string'}, {
   'type': 'null'}], 'default': None, 'title': 'Id'}, 'example': {
   'default': False, 'title': 'Example', 'type': 'boolean'}, 'tool_calls': {
   'default': [], 'items': {
   '$ref': '#/$defs/ToolCall'}, 'title': 'Tool Calls', 'type': 'array'}, 'invalid_tool_calls': {
   'default': [], 'items': {
   '$ref': '#/$defs/InvalidToolCall'}, 'title': 'Invalid Tool Calls', 'type': 'array'}, 'usage_metadata': {
   'anyOf': [{
   '$ref': '#/$defs/UsageMetadata'}, {
   'type': 'null'}], 'default': None}}, 'required': ['content'], 'title': 'AIMessage', 'type': 'object'}, 'AIMessageChunk': {
   'additionalProperties': True, 'description': 'Message chunk from an AI.', 'properties': {
   'content': {
   'anyOf': [{
   'type': 'string'}, {
   'items': {
   'anyOf': [{
   'type': 'string'}, {
   'type': 'object'}]}, 'type': 'array'}], 'title': 'Content'}, 'additional_kwargs': {
   'title': 'Additional Kwargs', 'type': 'object'}, 'response_metadata': {
   'title': 'Response Metadata', 'type': 'object'}, 'type': {
   'const': 'AIMessageChunk', 'default': 'AIMessageChunk', 'title': 'Type', 'type': 'string'}, 'name': {
   'anyOf': [{
   'type': 'string'}, {
   'type': 'null'}], 'default': None, 'title': 'Name'}, 'id': {
   'anyOf': [{
   'type': 'string'}, {
   'type': 'null'}], 'default': None, 'title': 'Id'}, 'example': {
   'default': False, 'title': 'Example', 'type': 'boolean'}, 'tool_calls': {
   'default': [], 'items': {
   '$ref': '#/$defs/ToolCall'}, 'title': 'Tool Calls', 'type': 'array'}, 'invalid_tool_calls': {
   'default': [], 'items': {
   '$ref': '#/$defs/InvalidToolCall'}, 'title': 'Invalid Tool Calls', 'type': 'array'}, 'usage_metadata': {
   'anyOf': [{
   '$ref': '#/$defs/UsageMetadata'}, {
   'type': 'null'}], 'default': None}, 'tool_call_chunks': {
   'default': [], 'items': {
   '$ref': '#/$defs/ToolCallChunk'}, 'title': 'Tool Call Chunks', 'type': 'array'}}, 'required': ['content'], 'title': 'AIMessageChunk', 'type': 'object'}, 'ChatMessage': {
   'additionalProperties': True, 'description': 'Message that can be assigned an arbitrary speaker (i.e. role).', 'properties': {
   'content': {
   'anyOf': [{
   'type': 'string'}, {
   'items': {
   'anyOf': [{
   'type': 'string'}, {
   'type': 'object'}]}, 'type': 'array'}], 'title': 'Content'}, 'additional_kwargs': {
   'title': 'Additional Kwargs', 'type': 'object'}, 'response_metadata': {
   'title': 'Response Metadata', 'type': 'object'}, 'type': {
   'const': 'chat', 'default': 'chat', 'title': 'Type', 'type': 'string'}, 'name': {
   'anyOf': [{
   'type': 'string'}, {
   'type': 'null'}], 'default': None, 'title': 'Name'}, 'id': {
   'anyOf': [{
   'type': 'string'}, {
   'type': 'null'}], 'default': None, 'title': 'Id'}, 'role': {
   'title': 'Role', 'type': 'string'}}, 'required': ['content', 'role'], 'title': 'ChatMessage', 'type': 'object'}, 'ChatMessageChunk': {
   'additionalProperties': True, 'description': 'Chat Message chunk.', 'properties': {
   'content': {
   'anyOf': [{
   'type': 'string'}, {
   'items': {
   'anyOf': [{
   'type': 'string'}, {
   'type': 'object'}]}, 'type': 'array'}], 'title': 'Content'}, 'additional_kwargs': {
   'title': 'Additional Kwargs', 'type': 'object'}, 'response_metadata': {
   'title': 'Response Metadata', 'type': 'object'}, 'type': {
   'const': 'ChatMessageChunk', 'default': 'ChatMessageChunk', 'title': 'Type', 'type': 'string'}, 'name': {
   'anyOf': [{
   'type': 'string'}, {
   'type': 'null'}], 'default': None, 'title': 'Name'}, 'id': {
   'anyOf': [{
   'type': 'string'}, {
   'type': 'null'}], 'default': None, 'title': 'Id'}, 'role': {
   'title': 'Role', 'type': 'string'}}, 'required': ['content', 'role'], 'title': 'ChatMessageChunk', 'type': 'object'}, 'ChatPromptValueConcrete': {
   'description': 'Chat prompt value which explicitly lists out the message types it accepts.\nFor use in external schemas.', 'properties': {
   'messages': {
   'items': {
   'oneOf': [{
   '$ref': '#/$defs/AIMessage'}, {
   '$ref': '#/$defs/HumanMessage'}, {
   '$ref': '#/$defs/ChatMessage'}, {
   '$ref': '#/$defs/SystemMessage'}, {
   '$ref': '#/$defs/FunctionMessage'}, {
   '$ref': '#/$defs/ToolMessage'}, {
   '$ref': '#/$defs/AIMessageChunk'}, {
   '$ref': '#/$defs/HumanMessageChunk'}, {
   '$ref': '#/$defs/ChatMessageChunk'}, {
   '$ref': '#/$defs/SystemMessageChunk'}, {
   '$ref': '#/$defs/FunctionMessageChunk'}, {
   '$ref': '#/$defs/ToolMessageChunk'}]}, 'title': 'Messages', 'type': 'array'}, 'type': {
   'const': 'ChatPromptValueConcrete', 'default': 'ChatPromptValueConcrete', 'title': 'Type', 'type': 'string'}}, 'required': ['messages'], 'title': 'ChatPromptValueConcrete', 'type': 'object'}, 'FunctionMessage': {
   'additionalProperties': True, 'description': 'Message for passing the result of executing a tool back to a model.\n\nFunctionMessage are an older version of the ToolMessage schema, and\ndo not contain the tool_call_id field.\n\nThe tool_call_id field is used to associate the tool call request with the\ntool call response. This is useful in situations where a chat model is able\nto request multiple tool calls in parallel.', 'properties': {
   'content': {
   'anyOf': [{
   'type': 'string'}, {
   'items': {
   'anyOf': [{
   'type': 'string'}, {
   'type': 'object'}]}, 'type': 'array'}], 'title': 'Content'}, 'additional_kwargs': {
   'title': 'Additional Kwargs', 'type': 'object'}, 'response_metadata': {
   'title': 'Response Metadata', 'type': 'object'}, 'type': {
   'const': 'function', 'default': 'function', 'title': 'Type', 'type': 'string'}, 'name': {
   'title': 'Name', 'type': 'string'}, 'id': {
   'anyOf': [{
   'type': 'string'}, {
   'type': 'null'}], 'default': None, 'title': 'Id'}}, 'required': ['content', 'name'], 'title': 'FunctionMessage', 'type': 'object'}, 'FunctionMessageChunk': {
   'additionalProperties': True, 'description': 'Function Message chunk.', 'properties': {
   'content': {
   'anyOf': [{
   'type': 'string'}, {
   'items': {
   'anyOf': [{
   'type': 'string'}, {
   'type': 'object'}]}, 'type': 'array'}], 'title': 'Content'}, 'additional_kwargs': {
   'title': 'Additional Kwargs', 'type': 'object'}, 'response_metadata': {
   'title': 'Response Metadata', 'type': 'object'}, 'type': {
   'const': 'FunctionMessageChunk', 'default': 'FunctionMessageChunk', 'title': 'Type', 'type': 'string'}, 'name': {
   'title': 'Name', 'type': 'string'}, 'id': {
   'anyOf': [{
   'type': 'string'}, {
   'type': 'null'}], 'default': None, 'title': 'Id'}}, 'required': ['content', 'name'], 'title': 'FunctionMessageChunk', 'type': 'object'}, 'HumanMessage': {
   'additionalProperties': True, 'description': 'Message from a human.\n\nHumanMessages are messages that are passed in from a human to the model.\n\nExample:\n\n    .. code-block:: python\n\n        from langchain_core.messages import HumanMessage, SystemMessage\n\n        messages = [\n            SystemMessage(\n                content="You are a helpful assistant! Your name is Bob."\n            ),\n            HumanMessage(\n                content="What is your name?"\n            )\n        ]\n\n        # Instantiate a chat model and invoke it with the messages\n        model = ...\n        print(model.invoke(messages))', 'properties': {
   'content': {
   'anyOf': [{
   'type': 'string'}, {
   'items': {
   'anyOf': [{
   'type': 'string'}, {
   'type': 'object'}]}, 'type': 'array'}], 'title': 'Content'}, 'additional_kwargs': {
   'title': 'Additional Kwargs', 'type': 'object'}, 'response_metadata': {
   'title': 'Response Metadata', 'type': 'object'}, 'type': {
   'const': 'human', 'default': 'human', 'title': 'Type', 'type': 'string'}, 'name': {
   'anyOf': [{
   'type': 'string'}, {
   'type': 'null'}], 'default': None, 'title': 'Name'}, 'id': {
   'anyOf': [{
   'type': 'string'}, {
   'type': 'null'}], 'default': None, 'title': 'Id'}, 'example': {
   'default': False, 'title': 'Example', 'type': 'boolean'}}, 'required': ['content'], 'title': 'HumanMessage', 'type': 'object'}, 'HumanMessageChunk': {
   'additionalProperties': True, 'description': 'Human Message chunk.', 'properties': {
   'content': {
   'anyOf': [{
   'type': 'string'}, {
   'items': {
   'anyOf': [{
   'type': 'string'}, {
   'type': 'object'}]}, 'type': 'array'}], 'title': 'Content'}, 'additional_kwargs': {
   'title': 'Additional Kwargs', 'type': 'object'}, 'response_metadata': {
   'title': 'Response Metadata', 'type': 'object'}, 'type': {
   'const': 'HumanMessageChunk', 'default': 'HumanMessageChunk', 'title': 'Type', 'type': 'string'}, 'name': {
   'anyOf': [{
   'type': 'string'}, {
   'type': 'null'}], 'default': None, 'title': 'Name'}, 'id': {
   'anyOf': [{
   'type': 'string'}, {
   'type': 'null'}], 'default': None, 'title': 'Id'}, 'example': {
   'default': False, 'title': 'Example', 'type': 'boolean'}}, 'required': ['content'], 'title': 'HumanMessageChunk', 'type': 'object'}, 'InputTokenDetails'
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值