如果代码中出现 LangChainDeprecationWarning
,提示 load_qa_chain
函数及其相关类(如 StuffDocumentsChain
)已废弃,推荐根据 chain_type
(如 stuff
、map_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 onchain_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
及其相关链类(如 StuffDocumentsChain
、MapReduceDocumentsChain
)被标记为废弃,推荐使用 LCEL 或其他现代组件构建问答链。
原因:
- 模块重构:LangChain 鼓励使用 LCEL 替代旧的链类,LCEL 更模块化、可组合,支持复杂逻辑。
- 统一接口:LCEL 提供标准化的
Runnable
接口,便于调试和扩展。 - 性能优化:LCEL 支持异步、流式处理,优于旧链类的固定模式。
- 向后兼容:旧函数暂时有效,但会触发警告,未来版本可能移除。
废弃的 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):
-
替换
load_qa_chain
:- 使用 LCEL 组合
ChatPromptTemplate
、LLM
和StrOutputParser
,手动实现stuff
逻辑。 - 将文档和问题格式化为提示,传递给 LLM。
- 使用 LCEL 组合
-
保留
stuff
逻辑:stuff
模式将所有文档拼接为上下文,LCEL 通过ChatPromptTemplate
实现相同效果。- 使用
{context}
占位符包含文档内容,{question}
包含用户问题。
-
集成检索器:
- 结合向量存储(如
langchain_milvus.Milvus
)的检索器,获取相关文档。 - 使用
as_retriever
方法生成文档。
- 结合向量存储(如
-
更新依赖:
- 确保使用最新版本:
pip install --upgrade langchain langchain-openai langchain-milvus pymilvus
- 确保使用最新版本:
-
自动迁移(可选):
- 使用 LangChain CLI 检查代码:
pip install langchain-cli langchain migrate
- CLI 可能无法完全替换
load_qa_chain
,需手动实现 LCEL。
- 使用 LangChain CLI 检查代码:
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 链输出:
云计算是一种通过互联网提供计算资源(如服务器、存储)的技术。
云计算依赖技术,如虚拟化和容器化。
代码说明
- 文档加载与分割:
TextLoader
加载qa_knowledge.txt
。RecursiveCharacterTextSplitter
分割为 100 字符块,chunk_overlap=20
。
- 向量存储:
Milvus.from_documents
创建cloud_knowledge
集合,存储嵌入。
- LCEL 链(替换
stuff
):vectorstore.as_retriever
检索 2 个相关文档。format_docs
拼接文档内容,模拟stuff
模式。prompt
包含{context}
(拼接的文档)和{question}
。llm
(gpt-4
)生成答案,StrOutputParser
提取文本。
- 独立性:
- 示例聚焦云计算主题,独立于之前上下文。
运行要求:
- 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 更灵活,可自定义提示、异步支持。
- 更容易调试(打印中间结果)。
注意事项
- API 密钥:
- 使用
.env
文件:from dotenv import load_dotenv load_dotenv()
- 确保密钥支持
text-embedding-3-small
和gpt-4
。
- 使用
- 依赖:
- 安装:
pip install --upgrade langchain langchain-openai langchain-milvus pymilvus
- 安装:
- Milvus 配置:
- 验证服务:
docker ps # 检查 Milvus 容器
- 非本地部署:
connection_args=connection_args={"uri": "http://your-milvus-host:your-port"}
- 验证服务:
- 性能优化:
- 调整
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) # 截断每文档
- 调整
- 错误调试:
- 检查 Milvus 连接:
from pymilvus import connections; connections.connect(uri="http://localhost:19530")
。 - 设置
langchain.debug = True
查看 LCEL 链日志。
- 检查 Milvus 连接:
常见问题
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 通过 ChatPromptTemplate
、format_docs
和 Runnable
组合实现 stuff
模式,替代旧链。示例代码展示了使用 TextLoader
、RecursiveCharacterTextSplitter
、langchain_milvus.Milvus
和 LCEL 构建 RAG 系统,处理云计算主题查询。