老铁们,今天我们来讨论一下在使用LangChain时,如何向链的状态中添加值。这个技术点其实不难,特别是在需要在链的各个步骤之间传递数据的时候,它简直就是一波相当丝滑的操作。
技术背景介绍
在LangChain中,处理复杂的数据流程时,往往需要将数据以某种形式保存在链的状态中。而LangChain提供的LangChain Expression Language (LCEL)为我们提供了一种优雅的方式来实现这一点。通过RunnablePassthrough.assign()方法,我们可以在不更改现有状态的情况下,将新的键值对添加到链的状态中。
原理深度解析
说白了就是这么个原理,RunnablePassthrough.assign()方法会接受一个输入值,并将传递给assign函数的额外参数添加到该输入值中。这在创建字典的过程中非常有用,尤其是当你需要为后续步骤准备输入时。
实战代码演示
下面是一个简单的示例,展示了如何使用RunnablePassthrough.assign():
%pip install --upgrade --quiet langchain langchain-openai
import os
from getpass import getpass
os.environ["OPENAI_API_KEY"] = getpass()
from langchain_core.runnables import RunnableParallel, RunnablePassthrough
runnable = RunnableParallel(
extra=RunnablePassthrough.assign(mult=lambda x: x["num"] * 3),
modified=lambda x: x["num"] + 1,
)
result = runnable.invoke({"num": 1})
print(result)
执行结果是:
{'extra': {'num': 1, 'mult': 3}, 'modified': 2}
代码解析
- 输入为
{"num": 1},并通过RunnableParallel传递。 RunnablePassthrough.assign()会保留原始输入,并添加一个新的键mult,值通过lambda函数计算为3。- 同时,
modified键通过lambda函数被设置为2。
这一套操作可以说是相当丝滑。
优化建议分享
在实际应用中,建议使用代理服务来提高系统的整体稳定性和可靠性。同时在开发时,尽量保持代码的简洁性,这有助于后续的维护和扩展。
补充说明和总结
这个方法的一个方便之处在于,它可以让值在可用时立即传递。比如在一个检索链中,我们可以通过RunnablePassthrough.assign()来立即返回来源文档。
from langchain_community.vectorstores import FAISS
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
# 创建检索器和生成链
vectorstore = FAISS.from_texts(["harrison worked at kensho"], embedding=OpenAIEmbeddings())
retriever = vectorstore.as_retriever()
template = """Answer the question based only on the following context:
{context}
Question: {question}
"""
prompt = ChatPromptTemplate.from_template(template)
model = ChatOpenAI()
generation_chain = prompt | model | StrOutputParser()
retrieval_chain = {
"context": retriever,
"question": RunnablePassthrough(),
} | RunnablePassthrough.assign(output=generation_chain)
stream = retrieval_chain.stream("where did harrison work?")
for chunk in stream:
print(chunk)
结果解析
- 首先,原始问题
"where did harrison work?"立即被传递。 - 接下来是上下文
"harrison worked at kensho"。 - 最后,生成链的输出以流的形式传递。
今天的技术分享就到这里,希望对大家有帮助。开发过程中遇到问题也可以在评论区交流~
—END—

被折叠的 条评论
为什么被折叠?



