本文共 3661 字,大约阅读时间需要 12 分钟。
随着人工智能技术的不断发展,问答系统的构建已经成为一种高效的解决方案。通过结合检索技术和生成技术(Retrieval-Augmented Generation, RAG),我们能够构建一个能够理解并回答复杂问题的系统。本文将详细介绍如何构建一个基于RAG的问答系统。
在构建问答系统之前,我们需要准备好文档数据。首先,我们需要从文件中加载文档内容,然后将其分块以便后续处理。
我们支持多种文件格式,包括PDF、DOCX、TXT等。根据文件扩展名选择合适的加载器:
为了确保文档能够高效检索,我们需要对文档进行分块操作。使用RecursiveCharacterTextSplitter工具,我们可以将文档分割成固定大小的块,同时设置块之间的重叠大小。这样可以在保持文本连贯性的同时,提高检索效率。
假设我们有一个PDF文件company_law.pdf,我们可以按照以下步骤进行加载和分块:
from langchain.document_loaders import PyPDFLoaderdef load_and_split_documents(file_path): if not os.path.isfile(file_path): raise FileNotFoundError(f"文件不存在: {file_path}") print(f"加载文件: {file_path}") loader = PyPDFLoader(file_path) documents = loader.load() print(f"加载了 {len(documents)} 个文档块") text_splitter = RecursiveCharacterTextSplitter( chunk_size=500, chunk_overlap=50 ) chunks = text_splitter.split_documents(documents) print(f"分块后得到 {len(chunks)} 个块") return chunks 为了提高检索效率,我们需要对文档进行向量化处理。使用FAISS(一种高效的向量索引工具),我们可以将文档转换为嵌入向量,便于后续的检索操作。
我们使用NomicEmbedText模型来生成嵌入向量。该模型基于Ollama API,能够根据输入文本生成高质量的嵌入向量。
from langchain_community.vectorstores import FAISSfrom langchain.embeddings.base import Embeddingsfrom langchain_community.vectorstores import FAISSclass NomicEmbedText(Embeddings): def __init__(self, base_url="http://127.0.0.1:11434"): self.base_url = base_url def embed_query(self, text): response = requests.post( f"{self.base_url}/api/embeddings", json={"model": "nomic-embed-text:v1.5", "prompt": text} ) if response.status_code != 200: raise ValueError(f"嵌入生成失败: {response.text}") return response.json()["embedding"] def embed_documents(self, texts): embeddings = [] for text in texts: embedding = self.embed_query(text) embeddings.append(embedding) return embeddings 将文档分块后的内容提取出来,并与嵌入向量对应,最后存储到FAISS中。
def create_vector_store(chunks): embeddings = NomicEmbedText() texts = [chunk.page_content for chunk in chunks] vector_store = FAISS.from_texts( texts=texts, embedding=embeddings, metadatas=[chunk.metadata for chunk in chunks] ) return vector_store
接下来,我们需要构建RAG(检索增强生成)管道。通过结合检索器和语言模型,我们可以实现基于向量存储的问答系统。
我们使用预训练的语言模型作为生成模型。以下是初始化Ollama模型的示例:
from langchain.llms import Ollamallm = Ollama( model="deepseek-r1:1.5b", base_url="http://127.0.0.1:11434")
使用RetrievalQA类,我们可以将检索器和语言模型结合起来,构建RAG管道。
from langchain.chains import RetrievalQAqa_pipeline = RetrievalQA.from_chain_type( llm=llm, chain_type="stuff", retriever=vector_store.as_retriever(search_kwargs={"k": 3})) 最终,我们需要通过查询RAG管道来获取问题答案。
def query_rag_pipeline(qa_pipeline, question): result = qa_pipeline({"query": question}) return result["result"] 将以上组件整合到一个主函数中,便于使用。
def main(): file_path = r"C:\Users\leon\Desktop\断点续传\python_learn\2025\20250322\rag\pdf\company_law.pdf" if not os.path.isfile(file_path): raise FileNotFoundError(f"文件不存在: {file_path}") chunks = load_and_split_documents(file_path) vector_store = create_vector_store(chunks) qa_pipeline = setup_rag_pipeline(vector_store) question = "关于公司法律条款的解释" answer = query_rag_pipeline(qa_pipeline, question) print("回答:", answer)if __name__ == "__main__": main() 通过以上步骤,我们成功构建了一个基于RAG的问答系统。该系统能够从PDF文件中加载文档,分块处理,并通过向量化技术进行快速检索。最终,用户可以通过输入问题,获取到相关的答案。
转载地址:http://voqfk.baihongyu.com/