引言
在当今的AI与编程领域,结合聊天历史与检索增强生成的ConversationalRetrievalChain是一种强大的工具,能够让开发者实现与文档的“对话”。然而,随着技术的进步,迁移到LCEL实现具有许多优势,包括更清晰的内部结构、方便地返回源文档以及支持流式和异步操作。在本文中,我们将探讨如何从ConversationalRetrievalChain迁移到LCEL,并提供详细的代码示例和潜在挑战的解决方案。
主要内容
为什么迁移到LCEL?
- 更清晰的内部:
ConversationalRetrievalChain隐藏了一个完整的问题重述步骤,而LCEL则提供了更透明的实现,使开发者能够更好地掌控流程。 - 更简便的源文档返回:
LCEL允许更灵活的文档检索和处理。 - 支持流式和异步操作:
LCEL支持更多种类的方法调用,提升了实现的多样性和效率。
LCEL的主要组件
- 历史感知检索器:能够智能地处理聊天历史,并根据需要重述问题。
- 检索链:负责从存储中获取相关的上下文文档。
- 文档组合链:用于将多个文档的内容组合成有意义的答案。
代码示例
以下是如何利用LCEL实现的一个完整示例。
%pip install --upgrade --quiet langchain-community langchain langchain-openai faiss-cpu
import os
from getpass import getpass
os.environ["OPENAI_API_KEY"] = getpass()
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()
from langchain.chains import create_history_aware_retriever, create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_core.prompts import ChatPromptTemplate
# 设置问题重述模板
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)
# 执行链
convo_qa_chain.invoke(
{
"input": "What are autonomous agents?",
"chat_history": [],
}
)
常见问题和解决方案
- API访问问题:由于某些地区的网络限制,开发者可能需要考虑使用API代理服务来提高访问稳定性。
- LLM初始化失败:确保API密钥和必要的库已正确安装和配置。
- 文档加载错误:检查网络连接和文档源的可访问性。
总结与进一步学习资源
通过将ConversationalRetrievalChain迁移到LCEL,开发者可以获得更大的灵活性和功能。推荐进一步阅读以下资源以更深入地理解LCEL:
参考资料
本文所用资料来源于Langchain及其API文档。具体参考文献和资源可在Langchain Documentation中查阅。
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
—END—

1728




被折叠的 条评论
为什么被折叠?



