LangChain-v0.2文档翻译:3.7、如何在LangChain中串联可运行组件

LangChain表达式语言的一个要点是任何两个可运行组件(runnables)可以被“串联”成序列。前一个可运行组件的 .invoke() 调用的输出会被作为输入传递给下一个可运行组件。这可以通过使用管道操作符(|)或更明确的 .pipe() 方法来完成,两者效果相同。

生成的 RunnableSequence 本身就是一个可运行组件,这意味着它可以像其他任何可运行组件一样被调用、流式传输或进一步串联。以这种方式串联可运行组件的优势包括高效的流式传输(序列将尽可能快地输出结果)以及使用LangSmith等工具进行调试和追踪。

管道操作符:|

为了展示这是如何工作的,让我们通过一个示例来演示。我们将经历LangChain中的一个常见模式:使用提示模板将输入格式化为聊天模型,并最终使用输出解析器将聊天消息输出转换为字符串。

  • OpenAI
# 安装 langchain-openai 库
pip install -qU langchain-openai

# 导入 getpass 和 os 模块
import getpass
import os

# 设置 OPENAI_API_KEY 环境变量
os.environ["OPENAI_API_KEY"] = getpass.getpass()

from langchain_openai import ChatOpenAI

# 创建 ChatOpenAI 模型实例
model = ChatOpenAI(model="gpt-3.5-turbo-0125")
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate

# 从模板创建 ChatPromptTemplate 对象
prompt = ChatPromptTemplate.from_template("tell me a joke about {topic}")

# 串联提示模板、模型和输出解析器
chain = prompt | model | StrOutputParser

# 调用生成的序列
chain.invoke({"topic": "bears"})

提示和模型都是可运行的,并且提示调用的输出类型与聊天模型的输入类型相同,因此我们可以将它们串联在一起。然后我们可以像调用其他任何可运行组件一样调用生成的序列:

# 输出示例
"Here's a bear joke for you:\n\nWhy did the bear dissolve in water?\nBecause it was a polar bear!"

强制转换

我们甚至可以将此链与更多可运行组件结合以创建另一个链。这可能涉及使用其他类型的可运行组件进行一些输入/输出格式化,具体取决于链组件的所需输入和输出。

例如,假设我们想要将生成笑话的链与另一个评估生成的笑话是否有趣的链组合。

我们需要小心如何将输入格式化到下一个链中。在下面的例子中,链中的字典自动解析并转换为 RunnableParallel,它并行运行其所有值,并返回一个包含结果的字典。

这恰好是下一个提示模板所期望的格式。下面是它的实际应用:

# 创建第二个提示模板
analysis_prompt = ChatPromptTemplate.from_template("is this a funny joke? {joke}")

# 组合链
composed_chain = {"joke": chain} | analysis_prompt | model | StrOutputParser

composed_chain.invoke({"topic": "bears"})
# 输出示例
'Haha, that's a clever play on words! Using "polar" to imply the bear dissolved or became polar/polarized when put in water. Not the most hilarious joke ever, but it has a cute, groan-worthy pun that makes it mildly amusing. I appreciate a good pun or wordplay joke.'

函数也将被强制转换为可运行组件,因此您也可以向您的链中添加自定义逻辑。下面的链与之前的逻辑流程相同:

# 使用 lambda 函数组合链
composed_chain_with_lambda = (
    chain
    | (lambda input: {"joke": input})
    | analysis_prompt
    | model
    | StrOutputParser()
)

composed_chain_with_lambda.invoke({"topic": "beets"})
# 输出示例
"Haha, that's a cute and punny joke! I like how it plays on the idea of beets blushing or turning red like someone blushing. Food puns can be quite amusing. While not a total knee-slapper, it's a light-hearted, groan-worthy dad joke that would make me chuckle and shake my head. Simple vegetable humor!"

但是,请记住,像这样使用函数可能会干扰流式传输等操作。有关更多信息,请参见相关部分。

.pipe() 方法

我们也可以使用 .pipe() 方法来组合相同的序列。下面是它的样子:

from langchain_core.runnables import RunnableParallel

# 使用 .pipe() 方法组合链
composed_chain_with_pipe = (
    RunnableParallel({"joke": chain})
    .pipe(analysis_prompt)
    .pipe(model)
    .pipe(StrOutputParser())
)

composed_chain_with_pipe.invoke({"topic": "battlestar galactica"})
# 输出示例
"I cannot reproduce any copyrighted material verbatim, but I can try to analyze the humor in the joke you provided without quoting it directly.\n\nThe joke plays on the idea that the Cylon raiders, who are the antagonists in the Battlestar Galactica universe, failed to locate the human survivors after attacking their home planets (the Twelve Colonies) due to using an outdated and poorly performing operating system (Windows Vista) for their targeting systems.\n\nThe humor stems from the juxtaposition of a futuristic science fiction setting with a relatable real-world frustration – the use of buggy, slow, or unreliable software or technology. It pokes fun at the perceived inadequacies of Windows Vista, which was widely criticized for its performance issues and other problems when it was released.\n\nBy attributing the Cylons' failure to locate the humans to their use of Vista, the joke creates an amusing and unexpected connection between a fictional advanced race of robots and a familiar technological annoyance experienced by many people in the real world.\n\nOverall, the joke relies on incongruity and relatability to generate humor, but without reproducing any copyrighted material directly."

或者缩写形式:

# 缩写形式的 .pipe() 组合链
composed_chain_with_pipe = RunnableParallel({"joke": chain}).pipe(
    analysis_prompt, model, StrOutputParser()
)
  • 流式传输:查看流式传输指南,了解链的流式传输行为

总结
本文介绍了LangChain中如何通过管道操作符 |.pipe() 方法将不同的可运行组件串联起来形成序列。这种机制允许我们将一个组件的输出作为下一个组件的输入,从而创建复杂的处理流程。文章通过示例展示了如何将提示模板、聊天模型和输出解析器串联起来生成笑话,并进一步扩展了这个例子,通过添加自定义逻辑和评估笑话的有趣程度来创建更复杂的链。此外,还讨论了函数如何被转换为可运行组件以及如何使用 RunnableParallel 来并行运行多个组件。

扩展知识

  • LangChain:一个用于构建和运行复杂语言模型链的框架,提供了一系列的工具和接口。
  • 可运行组件(Runnables):LangChain中的组件,可以是模型、提示模板或自定义函数,能够被调用并产生输出。
  • 管道操作符(|)和 .pipe() 方法:用于将多个可运行组件串联起来,形成处理序列。
  • 流式传输(Streaming):一种技术,允许逐步处理数据,而不是一次性处理整个数据集。
  • LangSmith:LangChain提供的工具,用于调试和追踪模型链的执行过程。
  • 输出解析器(Output Parsers):用于将模型的输出转换为特定的格式,例如字符串。
  • 提示模板(Prompt Templates):用于定义向模型提出问题的模板,可以根据不同的输入动态生成提示。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值