前端AI项目利器- RAG知识库助手(搜索推荐机制版)

技术栈

前端: Next.js + Ts

后端:Python(Flask)

模型相关:

  • LLM 模型(Ollama,Lama3):实现核心问答和扩展功能。
  • LangChain 工具链:处理 Prompt、上下文检索和输出解析。
  • NLP 工具(Jieba、TF-IDF):用于中文语料分析和推荐。
  • 文档加载与处理(PyPDFLoader):支持用户内容输入。

效果图

首页搜索图

热搜展开图

三大模块细节

文档的问答 + 相关问题生成

核心处理流程

  1. 流式响应处理

    使用了 StreamingCallbackHandler 实现流式输出响应,可以在生成答案的过程中逐步将结果返回给客户端,提升用户体验。

    • on_llm_new_token: 在每次生成新 token 时,将其写入响应流。
  2. Prompt 模板设计

    定义了多个 Prompt 模板,用于生成答案和相关问题:

    • 查询 Prompt (QUERY_PROMPT): 生成与用户问题相关的三个问题,以中文返回结果。
    • 文档搜索 Prompt (prompt): 基于上下文和问题生成答案,要求答案清晰流畅,且全部用中文。
    • 相关问题 Prompt (relatePrompt): 为查询问题生成从不同视角出发的相关问题,输出 JSON 格式。
  3. 检索与上下文合并

    • 向量数据库检索 :
      • 使用 get_vector_db 获取向量数据库实例。
      • 调用检索器方法 retriever.get_relevant_documents 获取与问题相关的文档。
    • 上下文合并: 将用户输入的上下文与检索到的文档内容结合,为后续模型生成提供更准确的上下文信息。
  4. 回答与相关问题生成

    根据 isRelate 参数分支:

    • 回答内容生成(文档模式):使用 Prompt 结合检索到的上下文和用户问题,通过 LLM(如 Ollama 模型)生成答案。
    • 相关问题生成:仅基于用户问题,生成多个从不同角度出发的相关问题。
  5. 容错与日志记录

    • 捕获异常并记录日志,确保错误可追踪。
    • 在异常情况下返回友好的错误信息。

主要功能模块与设计要点

  1. 流式输出 (StreamingCallbackHandler)

    • 提供了实时输出能力。
    • 改善用户体验,特别是处理复杂问题时无需等待完整答案生成。
  2. Prompt 模板与分支逻辑

    • 灵活的 Prompt 模板设计支持多种任务(文档问答、相关问题生成)。
    • 基于 isRelate 的条件判断,选择不同任务逻辑,提高代码复用性。
  3. 向量数据库检索

    • 使用向量数据库(例如通过 get_vector_db 方法获取)提升了答案生成的准确性。
    • 支持文档内容的语义检索,能够高效定位相关文档。
  4. 模型调用与流式处理

    • 使用 ChatOllama 实现语言模型的调用。
    • 流式 token 输出,减少用户等待时间。
  5. 上下文管理与合并

    • 通过 combine_contexts 方法确保用户输入与检索内容的有机结合,为 LLM 提供更高质量的上下文。

核心技术点总结

  • LangChain 集成 : 使用了 langchain 提供的多个工具,包括 Prompt 模板、可运行模块(RunnableMap)、向量数据库接口等。
  • LLM 模型支持 : 支持 ChatOllama 等大语言模型的调用,能适配不同场景。
  • 流式响应 : 基于 Flask 的 stream_with_context 和自定义回调实现实时响应。
  • 日志记录: 详细的日志记录用于监控和调试整个系统的运行。

简要代码展示

python 复制代码
def query(input_context, input, response_stream, isRelate):
    # 初始化模型和 Prompt
    handler = StreamingCallbackHandler(response_stream)
    llm = ChatOllama(model='llama3', callbacks=[handler])
    QUERY_PROMPT, prompt, relatePrompt = get_prompt()

    db = get_vector_db()  # 获取向量数据库
    retriever = db.as_retriever()  # 转换为检索器

    try:
        if isRelate == "false":  # 文档问答模式
            relevant_docs = retriever.get_relevant_documents(input)
            response = prompt.invoke({"context": relevant_docs, "question": input})
            for token in response:
                yield token
        else:  # 相关问题模式
            response = relatePrompt.invoke({"question": input})
            for token in response:
                yield token
    except Exception as e:
        logging.error(f"Error: {e}")
        yield "Error in processing your query."

日常模式 + 文档检索模式

核心依据功能: 从 Google 搜索中获取与查询相关的有机搜索结果(即非广告和非赞助内容)。具体步骤如下:

  1. 输入查询 :函数接收一个查询参数(query),这是用户想要搜索的内容。
  2. 发送API请求 :它通过 POST 请求将查询发送到 https://google.serper.dev/search,同时附带一些搜索参数(如 gl 指定地区为中国,hl 设置语言为简体中文)和 API 密钥用于身份验证。
  3. 处理响应:API 返回的响应数据包括 Google 搜索的有机结果,函数提取并返回这些结果。

通过 Serper API 获取 Google 搜索的自然搜索结果,返回相关内容以供进一步处理。

  • 日常模式: 只依据此搜索结果 + 模型自身能力 进行回答
  • 文档模式: 按照矢量数据库进行检索, 依靠相关内容信息进行回答

文档上传 + 文本嵌入 + 基于RAG

文件上传与文本嵌入处理模块说明

本文档概述了代码中实现的文件上传、内容分块、文本嵌入的核心逻辑和重要设计点。


功能模块概述

代码实现了一个文件上传与处理系统,主要包括以下功能:

  1. 文件类型检查与安全性保证
  2. PDF 文件解析和文本分块
  3. 向量数据库存储
  4. 临时文件的管理与清理

核心处理逻辑

1. 文件类型检查
  • 函数:allowed_file(filename)
  • 作用:判断用户上传的文件是否是支持的格式(PDF)。
  • 设计细节
    • 使用文件扩展名验证,确保仅处理 PDF 格式。
    • 提高文件系统安全性,防止潜在的恶意文件。
2. 文件存储与安全
  • 函数:save_file(file)
  • 作用:保存用户上传的文件到临时目录,并返回文件路径。
  • 设计细节
    • 使用 secure_filename 确保文件名安全性,防止路径注入等攻击。
    • 通过时间戳生成唯一文件名,避免文件名冲突。
    • 存储在一个指定的临时目录中,确保后续处理文件可追踪。
3. PDF 文件加载与分块
  • 函数:load_and_split_data(file_path)
  • 作用:将上传的 PDF 文件解析为文本,并拆分为小块。
  • 设计细节
    1. 使用 PyPDFLoader 加载 PDF 内容。
    2. 借助 RecursiveCharacterTextSplitter 按指定的分隔符(如段落、标点符号)将文本分块。
    3. 块大小:每块约 500 个字符,重叠部分 200 字符,确保上下文连续性。
    4. 提供块起始索引(add_start_index=True),便于内容定位和后续查询。
4. 文本嵌入与存储
  • 函数:embed(file)
  • 作用:实现完整的文件处理流程,包括文件合法性验证、内容分块、向量嵌入、存储和清理。
  • 处理流程
    1. 文件验证:确保文件存在且为合法类型。
    2. 内容加载 :通过上述 save_fileload_and_split_data 获取文档块。
    3. 向量嵌入 :调用 get_vector_db() 获取向量数据库,将分块内容嵌入并持久化。
    4. 日志记录:在每一步(嵌入成功、错误处理、清理临时文件)记录详细日志。
    5. 临时文件清理:确保处理后删除临时文件,避免资源占用。

文件处理部分流程图

plaintext 复制代码
用户上传文件
   └── 检查文件合法性 (`allowed_file`)
       └── 保存文件到临时目录 (`save_file`)
           └── 加载文件内容 (`load_and_split_data`)
               └── 分块并添加到向量数据库 (`db.add_documents`)
                   └── 记录日志和清理临时文件

基于所描述代码功能的简易代码片段,快速理解系统流程和关键点:

python 复制代码
import os
from werkzeug.utils import secure_filename
from datetime import datetime

# 临时文件目录
TEMP_FOLDER = './_temp'

# 检查文件类型是否为 PDF
def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() == 'pdf'

# 保存上传的文件到临时目录
def save_file(file):
    timestamp = datetime.now().timestamp()
    secure_name = secure_filename(file.filename)
    file_path = os.path.join(TEMP_FOLDER, f"{timestamp}_{secure_name}")
    file.save(file_path)
    return file_path

# 处理上传的 PDF 文件
def process_file(file):
    if allowed_file(file.filename):
        try:
            # 保存文件
            file_path = save_file(file)
            print(f"File saved at: {file_path}")
            # 模拟加载与分块(伪代码展示)
            chunks = ["Chunk 1", "Chunk 2", "Chunk 3"]  # 示例
            print(f"Processed {len(chunks)} chunks from the file.")
        finally:
            # 清理临时文件
            if os.path.exists(file_path):
                os.remove(file_path)
                print(f"Temporary file {file_path} deleted.")
    else:
        print("Invalid file type. Only PDF files are allowed.")

# 示例:模拟文件上传
class MockFile:
    filename = "example.pdf"
    def save(self, path):
        print(f"Mock save file to: {path}")

file = MockFile()
process_file(file)

搜索推荐机制

这段代码的run(query)函数的处理思路和重点在于根据用户的查询,提供相关的内容推荐。核心流程可以概括为以下几个步骤:

1. 加载训练数据

  • get_train_data()函数加载一组已分类的文本数据(包括不同的主题如摄影、编程、健康等)。
  • 数据被组织成pandasDataFrame格式,方便后续的处理和分析。

2. 构建One-Hot编码矩阵

  • get_group_one_hot()函数根据每个文本中的关键词,生成One-Hot编码矩阵。每个关键词是否出现在某篇文章中,用0和1表示。
  • 关键词通过jieba分词工具提取,extract_keywords()函数从文本中提取重要的关键词,并形成一个包含关键词的集合。

3. 筛选最相关的组

  • 使用get_top_similars()函数,根据用户输入的查询,提取查询文本的关键词并生成One-Hot编码。
  • 然后计算查询与每个组(分类)的相似度,使用余弦相似度(cosine_similarity())衡量查询与各组之间的相似性。
  • 获取与查询最相关的前2个组。

4. 在最相关的组中筛选具体内容

  • 通过get_recommendations()函数,计算用户查询与每个组内内容的相似度,挑选出最相关的Top N(默认5个)文本内容。
  • 推荐的内容是根据相似度排序的,并且附带相似度得分。

5. 输出推荐结果

  • 输出包含推荐文本、类别和相似度分数的结果列表。
  • 同时,推荐结果会通过日志记录输出,并格式化为保留两位小数的相似度得分。

核心:

  • 关键词提取 :通过jieba分词和TF-IDF方法提取关键词,为后续的相似度计算提供基础。
  • 相似度计算:通过余弦相似度计算查询与各组、组内内容的相关性。
  • 推荐排序:通过相似度得分,返回最相关的推荐内容,并确保推荐结果的准确性。
  • One-Hot编码:通过One-Hot编码矩阵计算查询与组的相似度,进一步提高推荐的准确性。

总结

作为前端AI项目还是很不错的,后续会继续完善,尽量训练自己模型进行使用。

相关推荐
GISer_Jing6 分钟前
2025前端面试热门题目——计算机网络篇
前端·计算机网络·面试
m0_748245528 分钟前
吉利前端、AI面试
前端·面试·职场和发展
理想不理想v20 分钟前
webpack最基础的配置
前端·webpack·node.js
pubuzhixing23 分钟前
开源白板新方案:Plait 同时支持 Angular 和 React 啦!
前端·开源·github
2401_8576009533 分钟前
SSM 与 Vue 共筑电脑测评系统:精准洞察电脑世界
前端·javascript·vue.js
2401_8576009533 分钟前
数字时代的医疗挂号变革:SSM+Vue 系统设计与实现之道
前端·javascript·vue.js
GDAL34 分钟前
vue入门教程:组件透传 Attributes
前端·javascript·vue.js
bastgia34 分钟前
Tokenformer: 下一代Transformer架构
人工智能·机器学习·llm
菜狗woc43 分钟前
opencv-python的简单练习
人工智能·python·opencv
2402_857583491 小时前
基于 SSM 框架的 Vue 电脑测评系统:照亮电脑品质之路
前端·javascript·vue.js