引言
在现代在线应用中,检索增强生成(Retrieval-Augmented Generation, RAG)技术已经成为一种强大的工具。它通过结合检索和生成模型来回答用户问题,提高了响应的准确性和可靠性。本文将展示如何使用本地组件来构建一个RAG应用,确保数据隐私并优化性能。
主要内容
设置Ollama
首先,我们需要配置Ollama。详细的安装步骤可以参考他们的GitHub仓库,以下是简要步骤:
- 下载并运行Ollama桌面应用。
- 从命令行中选择模型并拉取。例如,拉取通用模型
llama3.1:8b:
ollama pull llama3.1:8b
- 拉取文本嵌入模型
nomic-embed-text:
ollama pull nomic-embed-text
- 启动应用后,所有模型将自动在
localhost:11434上运行。
安装必要的包
我们需要安装一些包来处理本地嵌入、向量存储和推理。
# 文档加载、检索方法和文本分割工具
pip install -qU langchain langchain_community
# 本地向量存储(使用Chroma)
pip install -qU langchain_chroma
# 本地推理和嵌入(使用Ollama)
pip install -qU langchain_ollama
加载并分割文档
我们将以Lilian Weng关于智能体的博客文章为例,加载并分割文档。
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import WebBaseLoader
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)
初始化向量存储
使用nomic-embed-text模型初始化向量存储。
from langchain_chroma import Chroma
from langchain_ollama import OllamaEmbeddings
local_embeddings = OllamaEmbeddings(model="nomic-embed-text")
vectorstore = Chroma.from_documents(documents=all_splits, embedding=local_embeddings)
代码示例
我们可以测试相似度搜索来验证向量存储是否工作正常。
question = "What are the approaches to Task Decomposition?"
docs = vectorstore.similarity_search(question)
print(docs[0].page_content)
设置并测试模型
我们将使用llama3.1:8b模型,并进行一个简单的推理测试。
from langchain_ollama import ChatOllama
model = ChatOllama(model="llama3.1:8b")
response_message = model.invoke("Simulate a rap battle between Stephen Colbert and John Oliver")
print(response_message.content)
创建总结链
我们可以通过传递检索到的文档和简单的提示来创建总结链。
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_template("Summarize the main themes in these retrieved docs: {docs}")
def format_docs(docs):
return "\n\n".join(doc.page_content for doc in docs)
chain = {"docs": format_docs} | prompt | model | StrOutputParser()
question = "What are the approaches to Task Decomposition?"
docs = vectorstore.similarity_search(question)
chain.invoke(docs)
问答功能
我们还可以设置一个简单的问答链,从向量存储中检索文档并回答问题。
from langchain_core.runnables import RunnablePassthrough
RAG_TEMPLATE = """
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, just say that you don't know. Use three sentences maximum and keep the answer concise.
<context>
{context}
</context>
Answer the following question:
{question}"""
rag_prompt = ChatPromptTemplate.from_template(RAG_TEMPLATE)
chain = (
RunnablePassthrough.assign(context=lambda input: format_docs(input["context"]))
| rag_prompt
| model
| StrOutputParser()
)
question = "What are the approaches to Task Decomposition?"
docs = vectorstore.similarity_search(question)
chain.invoke({"context": docs, "question": question})
常见问题和解决方案
- 模型下载失败:访问受限地区可能需要使用API代理服务提高访问稳定性,确保能够顺利下载所需模型。
- 硬件性能问题:选择合适的模型以匹配你的硬件能力,不同模型对硬件的要求不同。
- 文档加载失败:检查文档源地址和网络连接,确保能够正常访问文档。
总结和进一步学习资源
通过这篇文章,我们演示了如何使用本地组件构建一个高效的RAG应用,从文档加载、向量存储初始化到问答与总结链的搭建。RAG是一个深刻的主题,以下资源可以帮助你进一步深入了解:
参考资料
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---