# 从ConversationalRetrievalChain迁移到LCEL的全面指南
## 引言
在现代对话系统中,`ConversationalRetrievalChain`一直被视为一种强大的工具,它结合了检索增强生成和聊天记录,提供了与文档进行“对话”的能力。但随着技术的进步,切换到LCEL(LangChain Enhanced Learning)实现会带来更清晰的内部结构、更好的文档返回以及流媒体和异步操作等支持。在这篇文章中,我们将探讨迁移的过程、必要的步骤以及相关的代码示例。
## 主要内容
### 为什么选择LCEL?
1. **清晰的内部结构**:`ConversationalRetrievalChain`包含一个隐藏的重新措辞步骤,而LCEL则提供了更加透明的实现。
2. **更容易返回源文档**:通过LCEL,开发者可以更容易地追溯和返回源文档。
3. **支持流媒体和异步操作**:这是现代应用程序中非常重要的功能,LCEL对此有良好的支持。
### 准备工作
在开始之前,你需要安装一些Python库:
```bash
%pip install --upgrade --quiet langchain-community langchain langchain-openai faiss-cpu
你还需要确保你有一个有效的OpenAI API密钥。
import os
from getpass import getpass
os.environ["OPENAI_API_KEY"] = getpass() # 获取API密钥
加载和处理文档
使用langchain的库,我们可以加载和处理文档:
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 = ChatOpenAI()
代码示例
以下是如何使用LCEL重建对话检索链的代码示例:
from langchain.chains import create_history_aware_retriever, create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
condense_question_system_template = (
"Given a chat history and the latest user question "
"which might reference context in the chat history, "
"formulate a standalone question which can be understood "
"without the chat history. Do NOT answer the question, "
"just reformulate it if needed and otherwise return it as is."
)
condense_question_prompt = ChatPromptTemplate.from_messages(
[
("system", condense_question_system_template),
("placeholder", "{chat_history}"),
("human", "{input}"),
]
)
history_aware_retriever = create_history_aware_retriever(
llm, vectorstore.as_retriever(), condense_question_prompt
)
system_prompt = (
"You are an assistant for question-answering tasks. "
"Use the following pieces of retrieved context to answer "
"the question. If you don't know the answer, say that you "
"don't know. Use three sentences maximum and keep the "
"answer concise."
"\n\n"
"{context}"
)
qa_prompt = ChatPromptTemplate.from_messages(
[
("system", system_prompt),
("placeholder", "{chat_history}"),
("human", "{input}"),
]
)
qa_chain = create_stuff_documents_chain(llm, qa_prompt)
convo_qa_chain = create_retrieval_chain(history_aware_retriever, qa_chain)
response = convo_qa_chain.invoke(
{
"input": "What are autonomous agents?",
"chat_history": [],
}
)
print(response['answer'])
# 使用API代理服务提高访问稳定性
常见问题和解决方案
- API访问问题:由于某些地区的网络限制,开发者可能需要考虑使用API代理服务来提高访问稳定性。
- 模型响应时间:确保使用异步方法来减少延迟,特别是在高并发场景下。
总结和进一步学习资源
迁移到LCEL提供了许多优势,包括更清晰的内部结构和更强大的功能支持。有关LCEL的更多信息,可以参阅LangChain官方文档.
参考资料
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---