目录

基于 Vue3 + Flask + ChromaDB 的知识库问答系统 v1.1.0:从 Prompt 注入到 RAG 检索增强的升级实践

v1.0.0 博客地址:
https://blog.csdn.net/qq_31953115/article/details/160073791?spm=1011.2415.3001.5331


一、项目背景

在 v1.0.0 版本中,我实现了一个基于 Vue3 + Flask + SQLite + 智谱 AI 的知识库问答系统。
当时系统的核心思路比较直接:

  • 用户上传知识库文档
  • 后端读取文档内容
  • 将文档内容拼接进 Prompt
  • 调用大模型生成答案

这种方式适合快速验证原型,但随着知识库规模增大,很快就会遇到几个问题:

  1. 上下文长度受限:整篇文档直接注入 Prompt,文档稍长就容易超过模型上下文窗口。
  2. Token 消耗较高:每次提问都重复发送大段原文,成本和延迟都不理想。
  3. 回答聚焦能力不足:模型面对大段原文时,未必能稳定抓住真正相关的知识点。
  4. 缺少真正的会话结构:历史记录更像“问答日志”,不适合连续追问和会话恢复。

因此,v1.1.0 的核心升级方向非常明确:

从“整篇文档直接喂给模型”升级为“RAG 检索增强生成”,并补上会话式聊天能力。


二、v1.1.0 版本升级目标

这次版本迭代并不是简单增加几个页面,而是一次架构级升级,重点包括:

  • Prompt 全文注入 升级为 RAG 检索增强
  • 单轮问答记录 升级为 会话式多轮问答
  • 单一文本支持 升级为 多格式文档解析
  • 功能可用 升级为 具备一定工程化能力

三、项目演示截图

1)登录页面

系统采用预置账号登录,后端通过 JWT 进行接口鉴权,前端在请求时自动携带 Token。

登录页面


2)知识库管理页面

在 v1.1.0 中,知识库管理模块已经支持多格式文件上传,并在上传成功后自动完成文档解析和向量索引建立。

知识库管理页面


3)AI 智能问答页面

AI 问答页面支持按知识库发起对话,并基于会话上下文进行连续追问。
与 v1.0.0 最大的区别是:本版本不再直接把整篇知识库原文注入模型,而是先进行向量检索,再把相关片段交给模型生成回答。

AI 智能问答页面


4)问答历史页面

历史记录页面已经从“单条问答列表”升级成“按会话组织”的结构,支持筛选、继续聊天和删除会话。

问答历史页面


四、v1.1.0 核心升级点概览

相比 v1.0.0,v1.1.0 主要完成了以下几个升级:

1. 引入 RAG 检索增强架构

  • 使用 ChromaDB 作为向量数据库
  • 使用 智谱 Embedding 模型 生成文本向量
  • 提问时先检索相关知识片段,再调用大模型生成答案

2. 支持多格式知识库文件

目前支持上传:

  • .txt
  • .md
  • .markdown
  • .pdf
  • .docx

3. 新增会话式聊天

  • 支持自动创建会话
  • 支持手动新建会话
  • 支持基于知识库维度管理多个会话
  • 支持刷新页面后恢复历史会话继续聊天

4. 历史记录结构升级

  • 问答记录按会话归档
  • 支持按知识库、按会话筛选历史
  • 支持删除整段会话

5. 工程化能力增强

  • 自动兼容旧版 SQLite 表结构
  • 支持知识库重建向量索引
  • 删除知识库时联动删除向量索引、会话和历史记录
  • 保存检索参考片段,便于后续做答案溯源

五、技术栈

前端

技术 版本 用途
Vue 3 3.4 前端框架,Composition API
Vite 5.3 构建工具,开发服务器
Vue Router 4.3 前端路由与登录守卫
Pinia 2.1 状态管理
Axios 1.7 HTTP 请求与拦截器封装

后端

技术 版本 用途
Python 3.11 后端语言
Flask 3.0 Web 框架
Flask-SQLAlchemy 3.1 ORM 数据库操作
Flask-JWT-Extended 4.6 JWT 鉴权
Flask-CORS 4.0 跨域处理

AI 与 RAG

技术 说明
智谱 AI glm-4-flash 对话生成模型
智谱 embedding-3 向量化模型
ChromaDB 本地持久化向量数据库

数据存储

技术 说明
SQLite 开发阶段使用的轻量级关系型数据库

六、为什么要从 Prompt 注入升级到 RAG?

v1.0.0 使用的是一种最直观的实现方式:

读取知识库全文 → 拼进 Prompt → 调用模型回答

这种方案的优点是实现简单,但缺点也很明显。

1. 文档一长就不稳定

如果知识库内容很多,直接全文注入不仅会超出上下文长度限制,还会让模型难以聚焦真正相关的段落。

2. Token 开销过高

用户每问一次,都要重复发送大量原始文本,效率较低。

3. 可扩展性差

当知识库规模从几千字增长到几十万字时,这种方案基本不可持续。

因此,v1.1.0 改为采用更标准的 RAG(Retrieval-Augmented Generation,检索增强生成) 架构:

先检索,再生成。

即:

  • 先把知识库切分成多个文本片段
  • 对每个片段做向量化并写入 ChromaDB
  • 用户提问时先做向量检索
  • 把检索出的 Top-K 相关片段交给模型
  • 模型基于这些片段生成回答

这样做可以显著提高回答的聚焦度,并降低上下文浪费。


七、系统整体架构设计

v1.1.0 的整体处理流程如下:

用户上传文档
    ↓
文档解析(txt / md / pdf / docx)
    ↓
文本清洗与切分
    ↓
调用 Embedding 模型生成向量
    ↓
写入 ChromaDB 向量库
    ↓
用户提问
    ↓
问题向量化
    ↓
ChromaDB 相似度检索 Top-K 片段
    ↓
拼接检索上下文 + 会话历史
    ↓
调用 GLM-4-Flash 生成答案
    ↓
保存问答记录、引用片段、Token 消耗

这个架构相比 v1.0.0,已经从“原型式 AI 接入”升级为“轻量级 RAG 问答系统”。


八、后端核心模块拆解

为了提升可维护性,v1.1.0 对后端逻辑做了明确拆分:

kb-qa-backend/
├── app.py                # Flask 主应用、接口定义、业务流程编排
├── ai_service.py         # AI 问答服务,负责 Prompt 构建和模型调用
├── document_loader.py    # 多格式文档解析
├── rag_service.py        # 文本切分、向量化、索引、检索
├── models.py             # 数据模型定义
├── requirements.txt      # Python 依赖
└── uploads/              # 上传文件目录

这种拆分的好处是:

  • app.py 不需要承担所有逻辑
  • RAG 与普通接口逻辑解耦
  • 文档解析模块独立,方便后续扩展格式
  • AI 服务层职责清晰,便于替换模型

九、多格式文档解析实现

v1.1.0 中新增了统一文档解析模块,支持:

  • txt
  • md
  • markdown
  • pdf
  • docx

不同格式的处理方式如下:

1. 文本类文件

文本类文件优先按 UTF-8 解码,失败后回退到 GBK,从而兼容部分中文 Windows 环境下的文本文件。

2. PDF 文件

使用 pypdf 按页提取文本内容。

3. DOCX 文件

使用 python-docx 解析段落和表格内容。

这样做的意义在于:

  1. 文件上传接口不需要关心具体格式解析细节
  2. RAG 层只面向“纯文本”工作
  3. 后续扩展更多格式时改动成本更低

十、RAG 关键实现:文本切分、向量化与检索

1. 文本切分

文档不能直接整篇做向量化,因此需要先切分。
v1.1.0 采用的是:

  • 固定窗口大小
  • chunk overlap 重叠
  • 优先在换行、标点等语义边界切分

这样做的目的有两个:

  • 避免切片过大导致检索粒度过粗
  • 避免切片过小导致语义不完整

2. 向量化入库

每个切片通过 Embedding 模型转换为向量后写入 ChromaDB,同时保存元信息:

  • kb_id
  • user_id
  • kb_name
  • chunk_index
  • source

这样可以保证:

  • 不同用户之间的数据隔离
  • 不同知识库之间的数据隔离
  • 后续能够追踪回答参考来源

3. 提问时检索

用户提问时,系统流程如下:

  1. 将问题向量化
  2. 在 ChromaDB 中按 user_id + kb_id 过滤
  3. 检索 Top-K 最相关文本片段
  4. 将片段拼接成检索上下文
  5. 交给大模型生成答案

这一步就是 v1.1.0 相比 v1.0.0 最本质的技术升级。


十一、AI 问答模块升级

在 v1.0.0 中,大模型看到的是“整篇知识库原文”;
而在 v1.1.0 中,大模型看到的是“检索到的相关知识片段”。

因此,Prompt 的职责也发生了变化:

  • 明确模型角色:知识库问答助手
  • 明确回答依据:必须根据检索片段作答
  • 限制幻觉:如果片段不足,必须明确说明无法回答
  • 支持多轮上下文:结合历史消息理解代词和上下文关系

这样设计后,模型的回答会更聚焦,也更容易控制。


十二、会话式聊天的实现思路

这次版本中,另一个很关键的升级是:
历史记录从“问答列表”升级成“会话模型”。

新增数据模型

  • ChatSession:表示一个独立会话
  • ChatHistory:表示会话中的每一轮问答消息

带来的好处

1)支持继续聊天

用户刷新页面后,可以恢复之前的会话继续提问。

2)支持同一知识库下多个对话主题

例如同一个“新生入学指南”知识库下,可以分别讨论:

  • 宿舍安排
  • 选课流程
  • 奖学金政策

每个主题都可以作为独立会话保存。

3)历史页更符合真实产品形态

相比“散装历史记录”,按会话管理的交互方式更接近真实 AI 聊天产品。


十三、数据库结构升级与兼容处理

v1.1.0 中新增了以下核心数据模型:

1. User

保存预置账号信息。

2. KnowledgeBase

保存知识库文件元信息,包括:

  • 名称
  • 原始文件名
  • 存储文件名
  • 文件路径
  • 大小
  • 字符数

3. ChatSession

保存会话信息,包括:

  • 归属用户
  • 归属知识库
  • 会话标题
  • 创建时间
  • 最近更新时间

4. ChatHistory

保存每轮问答信息,包括:

  • question
  • answer
  • tokens_used
  • references_json
  • session_id

兼容旧版数据库

考虑到 v1.0.0 可能已经存在旧版 SQLite 文件,v1.1.0 在启动时加入了自动补齐表结构的逻辑,例如:

  • 如果不存在 chat_sessions 表,则自动创建
  • 如果 chat_histories 缺少 session_id 字段,则自动补齐
  • 如果缺少 references_json 字段,则自动补齐

这意味着项目升级不需要简单粗暴地删库重建,具备了一定版本演进能力。


十四、知识库管理模块的工程化改进

在 v1.1.0 中,知识库管理不只是上传和删除文件,而是形成了完整生命周期。

上传时的处理流程

  • 校验文件格式
  • 处理文件名安全问题
  • 生成 UUID 文件名防止冲突
  • 保存物理文件
  • 解析文档内容
  • 统计字符数
  • 构建向量索引

删除时的处理流程

  • 删除向量索引
  • 删除物理文件
  • 删除关联会话
  • 删除关联问答历史
  • 删除数据库记录

重建索引能力

新增了重建索引接口,适用于以下情况:

  • 向量索引损坏
  • 需要重新切分文档
  • 需要重新生成 embedding

这个设计说明:
向量索引在系统中已经被视为一类需要独立管理的资源。


十五、为什么要保存 references?

v1.1.0 中,问答历史增加了 references_json 字段,用于保存本轮问答中检索到的参考片段。

这一步的意义很大:

1. 为答案溯源做准备

后续前端可以直接展示:

  • 回答参考了哪些片段
  • 片段来自哪一份知识库
  • 哪个片段最相关

2. 方便排查检索效果

如果回答效果不理想,可以快速判断问题出在:

  • 检索没召回对
  • 还是模型生成偏了

3. 提升系统可解释性

相比纯黑盒回答,带引用片段的问答结果更容易建立用户信任。


十六、前端适配升级

虽然这次版本的重点主要在后端,但前端也做了相应的结构升级。

1. 问答页面支持 session_id

前端在发送消息时,会维护当前会话 ID,实现真正的连续对话。

2. 历史页从“单条问答”改为“会话列表”

历史页支持展示:

  • 会话标题
  • 所属知识库
  • 消息数量
  • 最近更新时间
  • 继续聊天
  • 删除会话

3. 支持会话恢复

用户点击历史会话后,可以重新加载整段消息并继续聊天,而不是只能查看过去的单轮问答。


十七、接口设计概览

系统接口统一以 /api 为前缀。

认证接口

方法 路径 说明
POST /api/auth/login 用户登录
GET /api/auth/me 获取当前用户信息

知识库接口

方法 路径 说明
GET /api/kb 获取知识库列表
POST /api/kb/upload 上传知识库文件
DELETE /api/kb/<id> 删除知识库
POST /api/kb/<id>/reindex 重建知识库索引

会话接口

方法 路径 说明
GET /api/chat/sessions 获取会话列表
POST /api/chat/sessions 创建会话
GET /api/chat/sessions/<session_id> 获取会话详情
DELETE /api/chat/sessions/<session_id> 删除会话

问答接口

方法 路径 说明
POST /api/chat 发起问答
GET /api/chat/history 获取历史记录
DELETE /api/chat/history/<history_id> 删除单条历史记录

十八、v1.0.0 与 v1.1.0 对比总结

对比项 v1.0.0 v1.1.0
知识注入方式 全文直接注入 Prompt RAG 检索后注入相关片段
文档格式支持 以文本为主 txt / md / markdown / pdf / docx
向量检索 ChromaDB + Embedding
多轮对话 基础历史记录 会话式连续聊天
历史结构 单条问答记录 会话 + 消息记录
大文档支持 较弱 明显增强
工程化程度 原型验证 支持版本演进

十九、当前版本仍可继续优化的方向

虽然 v1.1.0 已经具备了一个轻量级 RAG 系统的核心能力,但还可以继续扩展:

1. 检索效果优化

  • 增加 rerank
  • 混合检索(关键词 + 向量)
  • 更智能的语义分块

2. 可解释性增强

  • 前端展示引用片段
  • 标注知识来源
  • 高亮命中片段

3. 会话体验优化

  • AI 自动生成会话标题
  • 会话重命名
  • 单条消息重试
  • 上下文摘要压缩

4. 存储层升级

  • SQLite 升级到 MySQL / PostgreSQL
  • 引入异步任务队列处理大文档 embedding

5. 权限体系升级

  • 用户注册
  • 管理员角色
  • 多用户共享知识库

二十、总结

v1.1.0 这次升级,最大的变化不是“功能更多了”,而是系统的思路变了:

  • Prompt 直接注入 升级为 RAG 检索增强
  • 单轮问答 升级为 会话式聊天
  • 原型系统 升级为 具备工程化扩展能力的 AI 应用

如果说 v1.0.0 更像一个“能跑起来的知识库问答 Demo”,那么 v1.1.0 已经更接近一个真正可持续演进的 AI 应用雏形。

这次迭代也让我更清楚地认识到:

做 AI 应用,不只是“把模型调通”,更重要的是如何围绕模型设计检索、上下文、会话、数据结构和工程能力。


二十一、项目说明

默认运行环境

  • Python 3.11+
  • Node.js 18+
  • npm 9+
  • 智谱 AI API Key

默认账号

用户名 密码
admin admin123
demo demo123

二十二、版本升级重点

  • 引入 RAG 架构
  • 接入 ChromaDB 向量数据库
  • 支持多格式文档解析
  • 实现会话式聊天
  • 支持历史会话恢复
  • 增加知识库重建索引能力
  • 增加引用片段保存能力
  • 增加旧版数据库兼容升级逻辑

如果这篇文章对你有帮助,欢迎交流讨论。
后续我也会继续完善这个项目,例如检索优化、引用高亮、会话标题生成等功能。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐