【LangChain】chain = load_qa_chain(llm, chain_type=‘stuff‘) 迁移到 LCEL 链

如果代码中出现 LangChainDeprecationWarning,提示 load_qa_chain 函数及其相关类(如 StuffDocumentsChain)已废弃,推荐根据 chain_type(如 stuffmap_reduce 等)迁移到新的实现。这是 LangChain 0.2.x 及以上版本模块重构的一部分,旨在用更灵活的 LCEL(LangChain Expression Language)替代旧的链类。

本回答基于 LangChain 0.3.x,详细解释警告原因、load_qa_chain 的作用、迁移方法,并提供一个独立示例,展示如何将 load_qa_chain(chain_type='stuff') 迁移到 LCEL 实现,构建一个简单的 RAG 系统。示例将包含文本加载、分割、嵌入生成、Milvus 向量存储和查询。

代码废弃告警:
LangChainDeprecationWarning: This class is deprecated. See the following migration guides for replacements based on chain_type:
stuff: https://python.langchain.com/docs/versions/migrating_chains/stuff_docs_chain
map_reduce: https://python.langchain.com/docs/versions/migrating_chains/map_reduce_chain
refine: https://python.langchain.com/docs/versions/migrating_chains/refine_chain
map_rerank: https://python.langchain.com/docs/versions/migrating_chains/map_rerank_docs_chain
See also guides on retrieval and question-answering here: https://python.langchain.com/docs/how_to/#qa-with-rag
chain = load_qa_chain(llm, chain_type=‘stuff’) ……


警告原因

LangChainDeprecationWarning 表明你使用了已废弃的 load_qa_chain 函数:

from langchain.chains import load_qa_chain
chain = load_qa_chain(llm, chain_type='stuff')  # 废弃

在 LangChain 0.2.x 及以上版本中,load_qa_chain 及其相关链类(如 StuffDocumentsChainMapReduceDocumentsChain)被标记为废弃,推荐使用 LCEL 或其他现代组件构建问答链。

原因

  1. 模块重构:LangChain 鼓励使用 LCEL 替代旧的链类,LCEL 更模块化、可组合,支持复杂逻辑。
  2. 统一接口:LCEL 提供标准化的 Runnable 接口,便于调试和扩展。
  3. 性能优化:LCEL 支持异步、流式处理,优于旧链类的固定模式。
  4. 向后兼容:旧函数暂时有效,但会触发警告,未来版本可能移除。

废弃的 chain_type

  • stuff:将所有文档塞入上下文,适合短文档。
  • map_reduce:分步处理文档,适合长文档。
  • refine:逐个精炼答案,适合需要逐步改进的场景。
  • map_rerank:重新排序文档,适合高精度检索。

load_qa_chain 简介

load_qa_chain 是 LangChain 的一个工厂函数,用于创建基于文档的问答链,根据 chain_type 选择不同的处理逻辑:

  • stuff:将所有文档内容拼接为单一上下文,输入 LLM 回答。
  • map_reduce:对每个文档单独调用 LLM,汇总结果。
  • refine:迭代处理文档,逐步精炼答案。
  • map_rerank:对文档评分并重新排序,选择最佳文档回答。

典型用法(已废弃):

from langchain.chains import load_qa_chain
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4")
chain = load_qa_chain(llm, chain_type="stuff")
answer = chain.run(input_documents=docs, question="问题")

问题

  • stuff 模式对长文档可能超过 LLM 上下文限制。
  • 旧链类缺乏灵活性,难以自定义提示或处理复杂逻辑。
  • 不支持现代功能(如异步、流式)。

迁移方法

根据警告,load_qa_chain(chain_type='stuff') 需迁移到 LCEL 实现。以下是针对 stuff 模式的迁移步骤,参考官方迁移指南(Stuff Documents Chain):

  1. 替换 load_qa_chain

    • 使用 LCEL 组合 ChatPromptTemplateLLMStrOutputParser,手动实现 stuff 逻辑。
    • 将文档和问题格式化为提示,传递给 LLM。
  2. 保留 stuff 逻辑

    • stuff 模式将所有文档拼接为上下文,LCEL 通过 ChatPromptTemplate 实现相同效果。
    • 使用 {context} 占位符包含文档内容,{question} 包含用户问题。
  3. 集成检索器

    • 结合向量存储(如 langchain_milvus.Milvus)的检索器,获取相关文档。
    • 使用 as_retriever 方法生成文档。
  4. 更新依赖

    • 确保使用最新版本:
      pip install --upgrade langchain langchain-openai langchain-milvus pymilvus
      
  5. 自动迁移(可选)

    • 使用 LangChain CLI 检查代码:
      pip install langchain-cli
      langchain migrate
      
    • CLI 可能无法完全替换 load_qa_chain,需手动实现 LCEL。

LCEL 迁移示例:替换 load_qa_chain(chain_type='stuff')

以下是一个独立的 RAG 示例,展示如何将 load_qa_chain(chain_type='stuff') 迁移到 LCEL,使用 langchain_milvus.Milvus 作为向量存储,加载文档、分割、嵌入并回答问题。

准备文件
创建 qa_knowledge.txt

云计算是一种通过互联网提供计算资源(如服务器、存储)的技术。
虚拟化是云计算的基础,允许在单一物理服务器上运行多个虚拟机。
容器化是另一种技术,使用 Docker 等工具提供轻量级隔离。

代码

import os
os.environ["OPENAI_API_KEY"] = "Your OpenAI API Key"

from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_milvus import Milvus
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import TextLoader

# 加载文档
loader = TextLoader(file_path="qa_knowledge.txt", encoding="utf-8")
documents = loader.load()

# 分割文档
splitter = RecursiveCharacterTextSplitter(
    chunk_size=100,
    chunk_overlap=20,
    separators=["\n\n", "\n", " ", ""]
)
split_documents = splitter.split_documents(documents)

# 创建 Milvus 向量存储
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = Milvus.from_documents(
    documents=split_documents,
    embedding=embeddings,
    connection_args={"uri": "http://localhost:19530"},
    collection_name="cloud_knowledge",
    drop_old=True
)

# 初始化 LLM
llm = ChatOpenAI(temperature=0, model="gpt-4")

# 提示模板(模拟 stuff 模式)
prompt = ChatPromptTemplate.from_template(
    """根据以下上下文回答问题:
上下文:{context}
问题:{question}
回答:"""
)

# 格式化文档函数
def format_docs(docs):
    return "\n\n".join(doc.page_content for doc in docs)

# 创建 LCEL 链(替换 load_qa_chain chain_type='stuff')
rag_chain = (
    {
        "context": vectorstore.as_retriever(search_kwargs={"k": 2}) | format_docs,
        "question": RunnablePassthrough()
    }
    | prompt
    | llm
    | StrOutputParser()
)

# 调用链
print("RAG 链输出:")
response = rag_chain.invoke("什么是云计算?")
print(response)
response = rag_chain.invoke("它依赖哪些技术?")
print(response)

输出示例

RAG 链输出:
云计算是一种通过互联网提供计算资源(如服务器、存储)的技术。
云计算依赖技术,如虚拟化和容器化。
代码说明
  1. 文档加载与分割
    • TextLoader 加载 qa_knowledge.txt
    • RecursiveCharacterTextSplitter 分割为 100 字符块,chunk_overlap=20
  2. 向量存储
    • Milvus.from_documents 创建 cloud_knowledge 集合,存储嵌入。
  3. LCEL 链(替换 stuff
    • vectorstore.as_retriever 检索 2 个相关文档。
    • format_docs 拼接文档内容,模拟 stuff 模式。
    • prompt 包含 {context}(拼接的文档)和 {question}
    • llmgpt-4)生成答案,StrOutputParser 提取文本。
  4. 独立性
    • 示例聚焦云计算主题,独立于之前上下文。

运行要求

  • Milvus 服务运行(localhost:19530)。
  • qa_knowledge.txt 存在,编码为 utf-8
  • OpenAI API 密钥有效。
迁移要点
  • 旧代码(废弃):
    from langchain.chains import load_qa_chain
    chain = load_qa_chain(llm, chain_type="stuff")
    answer = chain.run(input_documents=docs, question="问题")
    
  • 新代码(LCEL):
    • 使用 ChatPromptTemplate 定义提示。
    • format_docs 拼接文档,替代 stuff 的文档合并。
    • LCEL 链通过 | 组合组件,替代 run 方法。
  • 优势
    • LCEL 更灵活,可自定义提示、异步支持。
    • 更容易调试(打印中间结果)。

注意事项

  1. API 密钥
    • 使用 .env 文件:
      from dotenv import load_dotenv
      load_dotenv()
      
    • 确保密钥支持 text-embedding-3-smallgpt-4
  2. 依赖
    • 安装:
      pip install --upgrade langchain langchain-openai langchain-milvus pymilvus
      
  3. Milvus 配置
    • 验证服务:
      docker ps  # 检查 Milvus 容器
      
    • 非本地部署:
      connection_args=connection_args={"uri": "http://your-milvus-host:your-port"}
      
  4. 性能优化
    • 调整 chunk_size(500-1000)、search_kwargs={"k": 3}
    • 限制文档长度,避免超过 LLM 上下文:
      def format_docs(docs):
          return "\n\n".join(doc.page_content[:200] for doc in docs)  # 截断每文档
      
  5. 错误调试
    • 检查 Milvus 连接:from pymilvus import connections; connections.connect(uri="http://localhost:19530")
    • 设置 langchain.debug = True 查看 LCEL 链日志。

常见问题

Q1:如何迁移其他 chain_type(如 map_reduce)?
A:参考官方指南:

  • map_reduce:使用 LCEL 的 MapReduceDocumentsChain 或自定义 map-reduce 逻辑(指南)。
  • refine:使用 RefineDocumentsChain 或 LCEL 迭代处理(指南)。
  • map_rerank:使用 MapRerankDocumentsChain 或 LCEL 排序(指南)。

Q2:LCEL 比 load_qa_chain 有何优势?
A:LCEL 更模块化,支持异步、流式、自定义提示,且调试更透明。

Q3:如何处理长文档?
A:增加 chunk_size(如 1000),或截断文档:

def format_docs(docs):
    return "\n\n".join(doc.page_content[:500] for doc in docs)

Q4:可以添加对话历史吗?
A:使用 RunnableWithMessageHistory

from langchain_core.runnables import RunnableWithMessageHistory
from langchain_community.chat_message_histories import ChatMessageHistory

总结

LangChainDeprecationWarning 提示 load_qa_chain(chain_type='stuff') 已废弃,需迁移到 LCEL。LCEL 通过 ChatPromptTemplateformat_docsRunnable 组合实现 stuff 模式,替代旧链。示例代码展示了使用 TextLoaderRecursiveCharacterTextSplitterlangchain_milvus.Milvus 和 LCEL 构建 RAG 系统,处理云计算主题查询。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

彬彬侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值