首页 > 其他分享 >【RAG】基于 RAG 的知识库问答系统设计与实现

【RAG】基于 RAG 的知识库问答系统设计与实现

时间:2024-11-27 09:31:58浏览次数:6  
标签:RAG 知识库 collection file path 问答

基于 RAG 的知识库问答系统设计与实现

项目代码地址https://github.com/AI-Meet/Knowledge_QA_RAG

1. 系统介绍

基于 Retrieval-Augmented Generation (RAG) 的知识库问答系统通过结合信息检索与生成式模型,为知识库问答提供了一种高效且智能的解决方案。传统问答系统在面对动态知识更新和复杂问题时,往往存在响应不准确、更新不及时等问题,而 RAG 系统通过将知识检索与自然语言生成相结合,显著提升了回答的精准性和上下文相关性。为此,本文设计了一种基于 RAG 的知识库问答系统 Demo,采用前后端分离的架构设计,具体如下:

  • 前端:基于 HTML/CSS/JavaScript 构建用户交互界面,支持问题输入、知识库创建和清空功能。
  • 后端:基于 FastAPI 构建,结合 LangChain 框架,提供问答服务和知识管理接口。

2. 技术与方法

  • 文档加载与分块:利用 LangChainDocumentLoader 模块高效加载文件内容,并通过 text_splitter 模块对文本进行分块处理,生成更小的知识单元,便于向量化存储和检索。
  • 嵌入生成:通过 LangChainEmbedding 模块,将分块后的文本向量化存储,本系统采用的是 jina-embeddings-v3 嵌入模型。
  • 检索与问答链LangChain 提供了 RetrievalQA 模块,整合检索和问答流程,支持快速集成向量数据库检索与语言模型生成的功能。
  • 向量化检索与存储:采用 Milvus 向量数据库管理嵌入模型生成的语义向量,通过配置索引参数和搜索参数,实现高效的 k-NN 检索,确保检索准确性和性能。

3. 核心功能代码片段

3.1 知识库创建

@app.post("/rag/create/")
async def create_knowledge(file: UploadFile = File(...)):
    """
    上传文件到指定目录后,处理文件内容并添加到向量库。
    """
    folder = './upload_files'  # 文件存储目录
    os.makedirs(folder, exist_ok=True)  # 确保目录存在
    file_path = os.path.join(folder, file.filename)

    try:
        # 保存文件
        with open(file_path, "wb") as f:
            content = await file.read()
            f.write(content)

        folder: str = './upload_files'
        file_path = os.path.join(folder, file.filename)

        # 初始化文件处理器
        file_processor = RagFileProcessor(chunk_size=64)
        # 处理文件内容并插入到向量库
        text_datas = file_processor.get_data(file_path=file_path)

        # 连接到 Milvus
        vector_store.add_texts(**text_datas)
        return {
            "status": "success",
            "message": f"文件 '{file.filename}' 上传成功并添加至向量数据库.",
        }
    except Exception as e:
        return {
            "status": "error",
            "message": f"文件 '{file.filename}'处理失败. 原因: {str(e)}",
        }

3.2 知识对话问答

@app.post("/rag/chat/")
async def chat(request: ChatRequest):
    """
    根据用户问题,从向量库检索并返回回答。
    """
    print(f"Q: {request.question}")
    try:
        # 初始化 OpenAI Chat 模型
        llm = ChatOpenAI(model=config.llm_model_name, api_key=config.api_key, base_url=config.base_url)
        # 定义 Prompt 模板
        qa_prompt = PromptTemplate(template=prompt_template, input_variables=["context", "question"])

        # 定义搜索参数
        search_kwargs = {"score_threshold": 0.3, "k": 5}
        retriever = vector_store.as_retriever(search_type="similarity_score_threshold", search_kwargs=search_kwargs)
        qa_chain = RetrievalQA.from_chain_type(
            llm=llm,
            chain_type="stuff",
            retriever=retriever,
            chain_type_kwargs={"prompt": qa_prompt},
            return_source_documents=True
        )
        result = qa_chain.invoke({"query": request.question})
        answer_result = result.get("result", "")
        print(f"A: {answer_result}")

        source = {"source_documents": [{"content": doc.page_content, "metadata": doc.metadata} for doc in
                                       result.get("source_documents", [])]}
        print(f"source: {source}")

        return {"answer": answer_result}
    except Exception as e:
        return {"status": "error", "message": str(e)}

3.3 知识库清空

@app.post("/rag/clear/")
async def clear_knowledge(collection_name: str = config.milvus_collection_name,
                          host: str = config.milvus_host,
                          port: int = config.milvus_port):
    """
    清空 Milvus 知识库集合,并删除指定目录中的文件
    """
    folder = "./upload_files"
    try:
        connections.connect("default", host=host, port=port)
        if utility.has_collection(collection_name):
            collection = Collection(name=collection_name)
            collection.drop()
            print(f"Collection '{collection_name}' 成功删除.")
        else:
            print(f"Collection '{collection_name}' 不存在.")
        connections.disconnect("default")

        for filename in os.listdir(folder):
            file_path = os.path.join(folder, filename)
            if os.path.isfile(file_path) or os.path.islink(file_path):
                os.unlink(file_path)
            elif os.path.isdir(file_path):
                shutil.rmtree(file_path)

        return {"message": f"知识库清空: Collection '{collection_name}' 删除, 文件夹 '{folder}' 清空."}
    except Exception as e:
        return {"error": f"知识库清空失败. 原因: {str(e)}"}

4. 系统运行效果截图

4.1 文件上传与知识库创建

  • 点击 创建知识库 选择上传的文件,上传成功后提示:文件 xxx 上传成功并添加至向量数据库.

在这里插入图片描述

  • 向量数据库中成功创建 knowledge_collection,并将向量数据加载到内存中。

在这里插入图片描述

4.2 知识库问答

  • 在输入框中输入问题,点击 发送 即可得到回答。

在这里插入图片描述

4.3 文件删除与知识库清空

  • 点击 清空知识库 ,清除成功后提示:知识库清空:Collection ‘knowledge_collection’ 删除,文件夹 './upload_files’清空.

在这里插入图片描述

  • 此时,向量数据库中成功删除 knowledge_collection,已经没有Collection。

在这里插入图片描述

总结

本系统以理解 RAG 技术为目标,提供了一种面向知识库问答的简单实现示例。通过结合文档加载、文本分块、向量检索与生成式问答,系统展示了 RAG 技术在小规模知识库中的应用潜力。然而,由于示例场景相对简单,系统尚未涉及多轮对话、检索召回重排序、提示词优化、分布式向量存储等更为复杂的问题。所以,可以进一步优化系统性能,例如引入多轮对话的上下文管理、使用先进的重排序模型提升检索精度,或探索更高效的提示词设计等,以支持更复杂的知识问答场景,为实践 RAG 技术提供更全面的支持。

项目代码地址https://github.com/AI-Meet/Knowledge_QA_RAG

标签:RAG,知识库,collection,file,path,问答
From: https://blog.csdn.net/weixin_47936614/article/details/143932997

相关文章

  • 【RAG 项目实战 08】为 RAG 添加历史对话能力
    【RAG项目实战08】为RAG添加历史对话能力NLPGithub项目:NLP项目实践:fasterai/nlp-project-practice介绍:该仓库围绕着NLP任务模型的设计、训练、优化、部署和应用,分享大模型算法工程师的日常工作和实战经验AI藏经阁:https://gitee.com/fasterai/ai-e-book介绍:该......
  • 【RAG 项目实战 07】替换 ConversationalRetrievalChain(单轮问答)
    【RAG项目实战07】替换ConversationalRetrievalChain(单轮问答)NLPGithub项目:NLP项目实践:fasterai/nlp-project-practice介绍:该仓库围绕着NLP任务模型的设计、训练、优化、部署和应用,分享大模型算法工程师的日常工作和实战经验AI藏经阁:https://gitee.com/fasterai......
  • 从开发到部署,搭建离线私有大模型知识库
    背景介绍最近一段时间搭建了一套完整的私有大模型知识库,目前完整的服务已经完成测试部署上线。基本之前的实践过程,从工程角度整理技术方案以及中间碰到的一些问题,方便后续对这个方向有需求的研发同学们。前排提示,文末有大模型AGI-CSDN独家资料包哦!为什么做离线私有化部署......
  • 超详细!!传统NLP算法结合大模型私有化部署简易知识问答体系工程实践
    作者:京东物流郭卓勋一、业务背景在物流私域体系构建中,形成了多个微信群生态,需要投放自动回复机器人来自动化回复用户问题,希望能够用最小的成本满足基本问答。由于需要从头开始自建全流程算法问答体系,需要面临一下几个问题:1.数据不外流:用户数属于隐私数据,不可以直接调用外部API......
  • HyDE 如何改进了传统的 RAG 方法?
    HyDE的方法就是让AI先自己猜一个答案,然后用这个猜测去寻找相关的真实信息,最后结合起来,给出一个更准确、更有参考依据的回答。一、什么是RAG?RAG(Retrieval-AugmentedGeneration)是指"检索增强生成"。这是一种让AI模型在回答问题时,不仅依赖自身的知识,还从一个数据库(比如文档库、知......
  • AttributeError: module ‘backend_interagg‘ has no attribute ‘FigureCanvas‘.
    plt.figure(figsize=(12,6))File"D:\anaconda\Lib\site-packages\matplotlib\pyplot.py",line1027,infiguremanager=new_figure_manager(^^^^^^^^^^^^^^^^^^^File"D:\anaconda\Lib\site-packages\matplotlib\pyplot.py",line549......
  • 灵感捕捉与知识整理:如何用免费工具管理知识库
    在知识管理领域,Heptabase凭借其可视化白板和非线性思维支持,成为许多知识工作者、创意工作者追捧的工具。它帮助用户以直观、灵活的方式捕捉灵感、整理信息和构建知识体系。然而,Heptabase是一款收费软件,目前仅支持年付模式,对部分用户而言,这无疑提高了试用门槛。其实,Heptabase......
  • 部署local-path-storage
    环境:os:Centos7k8s:1个master2个nodes以下操作都是在master节点上完成1.下载配置文件cd/softwgethttps://raw.githubusercontent.com/rancher/local-path-provisioner/v0.0.30/deploy/local-path-storage.yaml 2.修改镜像文件local-path-storage.yaml因为无法访问国外的......
  • BERT的中文问答系统42
    我们将对现有的代码进行扩展,以支持360百科的功能。这包括修改XihuaChatbotGUI类中的相关方法,以及添加一个新的搜索360百科的函数。此外,我们还需要更新历史记录的保存格式,以包含360百科的结果。项目结构codeproject_root/│├──data/│└──train_data.jsonl│......
  • 请描述一下cookies、sessionStorage和localStorage的区别?
    在前端开发中,cookies、sessionStorage和localStorage都是用于在浏览器中存储数据的机制,但它们之间存在显著的区别:1.数据的生命周期:Cookies:Cookie的生命周期可以通过expires或max-age属性设置。如果没有设置过期时间,Cookie会在浏览器会话结束时(关闭浏览器)被删除,这......