迁移到LCEL:提升自然语言问答体验的优势和实践
引言
随着人工智能技术的发展,基于检索增强生成(Retrieval-Augmented Generation, RAG)的自然语言问答系统变得越来越流行。这些系统能够通过检索相关信息并结合生成模型来回答复杂问题。本文旨在介绍从传统的RetrievalQA迁移到LangChain Enhanced Library (LCEL)的优势和实践方法。
主要内容
1. LCEL的优势
Migrating from the traditional RetrievalQA to LCEL offers several benefits:
- 更易自定义:在RetrievalQA中,提示和文档的格式化只能通过特定参数进行配置,而LCEL提供了更灵活的自定义选项。
- 更容易返回源文档:LCEL使得返回源文档的过程变得更加简单和直观。
- 支持可运行方法:LCEL支持流式和异步操作,提升了问答系统的响应性能。
2. 环境设置和数据加载
我们将使用相同的数据加载代码,将Lilian Weng关于自治代理的博客文章加载到本地向量存储中:
%pip install --upgrade --quiet langchain-community langchain langchain-openai faiss-cpu
import os
from getpass import getpass
os.environ["OPENAI_API_KEY"] = getpass() # 输入你的OpenAI API键
# 加载文档
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import WebBaseLoader
from langchain_community.vectorstores import FAISS
from langchain_openai.chat_models import ChatOpenAI
from langchain_openai.embeddings import OpenAIEmbeddings
loader = WebBaseLoader("https://lilianweng.github.io/posts/2023-06-23-agent/")
data = loader.load()
# 拆分文档
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=0)
all_splits = text_splitter.split_documents(data)
# 存储拆分后的文档
vectorstore = FAISS.from_documents(documents=all_splits, embedding=OpenAIEmbeddings())
# 使用LLM
llm = ChatOpenAI()
3. 基于RetrievalQA的实现
在迁移到LCEL之前,让我们先回顾一下传统的RetrievalQA实现:
from langchain import hub
from langchain.chains import RetrievalQA
# 获取提示模板
prompt = hub.pull("rlm/rag-prompt")
qa_chain = RetrievalQA.from_llm(
llm, retriever=vectorstore.as_retriever(), prompt=prompt
)
result = qa_chain("What are autonomous agents?")
print(result)
4. 基于LCEL的实现
LCEL实现更加灵活且支持更丰富的功能:
from langchain import hub
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
# 获取提示模板
prompt = hub.pull("rlm/rag-prompt")
# 格式化文档函数
def format_docs(docs):
return "\n\n".join(doc.page_content for doc in docs)
qa_chain = (
{
"context": vectorstore.as_retriever() | format_docs,
"question": RunnablePassthrough(),
}
| prompt
| llm
| StrOutputParser()
)
result = qa_chain.invoke("What are autonomous agents?")
print(result)
5. 使用高层次函数简化实现
LCEL提供了高层次的函数,进一步简化实现过程:
from langchain import hub
from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
# 获取提示模板
retrieval_qa_chat_prompt = hub.pull("langchain-ai/retrieval-qa-chat")
combine_docs_chain = create_stuff_documents_chain(llm, retrieval_qa_chat_prompt)
rag_chain = create_retrieval_chain(vectorstore.as_retriever(), combine_docs_chain)
result = rag_chain.invoke({"input": "What are autonomous agents?"})
print(result)
常见问题和解决方案
-
网络访问限制问题:在某些地区,访问API服务时可能会遇到网络限制问题。开发者可以考虑使用API代理服务来提高访问稳定性。示例如下:
# 使用API代理服务提高访问稳定性 os.environ["OPENAI_API_KEY"] = "your_api_proxy_key" -
文档格式化问题:确保文档格式化时不丢失重要信息,可以通过调试和日志记录来识别和解决问题。
总结和进一步学习资源
迁移到LCEL不仅提升了自然语言问答的自定义能力和性能,还提供了更丰富的功能支持。对于希望进一步提升系统能力的开发者,可以参考以下资源:
参考资料
- LangChain Documentation - smith.langchain.com/
- Lilian Weng's Blog Post - lilianweng.github.io/posts/2023-…
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---