如何链式运行 Runnable
本指南假设您熟悉以下概念:
关于 LangChain 表达式语言 (LCEL) 的一点是,任何两个 Runnable 都可以被“链接”成序列。前一个 Runnable 的 .invoke() 调用的输出将作为输入传递给下一个 Runnable。这可以通过管道操作符 (|) 或更明确的 .pipe() 方法完成,它们的功能相同。
生成的 RunnableSequence 本身就是一个 Runnable,这意味着它可以像任何其他 Runnable 一样被调用、流式传输或进一步链接。以这种方式链接 Runnable 的优点是高效的流式传输(序列将在可用时立即流式传输输出),以及使用 LangSmith 等工具进行调试和跟踪。
管道操作符:|
为了展示其工作原理,让我们看一个例子。我们将介绍 LangChain 中的一个常见模式:使用 Prompt 模板 将输入格式化为 Chat 模型,最后使用 Output Parser 将聊天消息输出转换为字符串。
pip install -qU "langchain[google-genai]"
import getpass
import os
if not os.environ.get("GOOGLE_API_KEY"):
os.environ["GOOGLE_API_KEY"] = getpass.getpass("Enter API key for Google Gemini: ")
from langchain.chat_models import init_chat_model
model = init_chat_model("gemini-2.0-flash", model_provider="google_genai")
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_template("tell me a joke about {topic}")
chain = prompt | model | StrOutputParser()
Prompt 和模型都是可运行的,并且 Prompt 调用产生的输出类型与 Chat 模型的输入类型相同,因此我们可以将它们链接在一起。然后,我们可以像调用其他 Runnable 一样调用由此产生的序列:
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,它会并行运行所有值,并返回一个包含结果的字典。
这恰好是下一个提示模板所期望的相同格式。以下是其运行效果:
from langchain_core.output_parsers import StrOutputParser
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.'
函数也将被强制转换为可运行对象,因此您也可以在链中添加自定义逻辑。以下链与之前的逻辑流程相同:
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
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."
或者缩写:
composed_chain_with_pipe = RunnableParallel({"joke": chain}).pipe(
analysis_prompt, model, StrOutputParser()
)
相关
- Streaming: 查看流式处理指南,了解链的流式处理行为