fix(boundary): 修复多库边界问题、版本管理及删除清理

多库检索与存储修复:
- RRF 融合去重改用 (collection, chunk_id) 复合键,修复同名文件结果被吞
- DocStore 存储路径加 collection 前缀,修复跨库同名切片数据覆盖
- search_multiple 去重改用复合键
- chunk_id 解析改用 rsplit 兼容下划线文件名

上传与版本管理修复:
- 同名文件上传改为覆盖模式,自动清理旧切片
- 修复首次上传不创建版本记录
- 修复覆盖上传版本号回退到 v1
- sync ADDED 分支改用动态版本号生成
- _generate_version_id 改为基于全部版本递增
- 废止/恢复操作同步 SQLite 版本记录
- mark_document_as_superseded 改为仅更新 SQLite

删除清理修复:
- 删除文档时同步清理 SQLite 版本记录和变更日志
- 删除向量库时同步清理该库所有版本记录
- cleanup 改为清理 SQLite 记录而非 ChromaDB

测试:
- test_version_management.py: 27 条版本管理单元测试
- test_edge_cases.py: 28 条边界用例测试
- test_upload_dedup.py: 5 条上传去重测试
- e2e_risk_test.py: 27 条端到端风险测试

文档:
- 新增风险边界问题修复注意事项.md(面向后端的对接文档)
- 新增向量库边界风险分析.md
- 更新多篇现有文档
This commit is contained in:
lacerate551
2026-06-04 23:58:44 +08:00
parent a1a0814633
commit cb75b9b274
50 changed files with 6385 additions and 6248 deletions

View File

@@ -2,7 +2,7 @@
本文档描述 RAG 知识库系统中所有数据库的结构和用途。
> **架构更新**v6.0 重构后,数据库从 6 个独立文件合并为 3 个,通过 `data/db.py` 统一管理
> **架构更新**v7.0 重构后,数据库按 prod/dev 环境分离为 4 个独立文件,通过 `data/db.py` 统一管理。生产模式数据库存放于 `data/prod/`,开发模式数据库存放于 `data/dev/`
---
@@ -18,28 +18,125 @@ from data.db import get_connection, init_databases
# 初始化数据库(首次运行时调用)
init_databases()
# 使用连接
with get_connection("core") as conn:
# 使用连接可选名称feedback / knowledge / session / exam
with get_connection("feedback") as conn:
cursor = conn.cursor()
cursor.execute("SELECT * FROM sessions WHERE user_id = ?", (user_id,))
cursor.execute("SELECT * FROM feedbacks WHERE user_id = ?", (user_id,))
rows = cursor.fetchall()
```
### 数据库文件列表
| 数据库 | 文件名 | 主要功能 | 所属模块 |
|--------|--------|----------|----------|
| core | `rag_core.db` | 会话管理、审计日志、用户反馈、FAQ | services/ |
| knowledge | `knowledge.db` | 知识库同步、文档哈希、纲要缓存、版本管理 | knowledge/ |
| exam | `exam.db` | 题目存储、试卷管理、批阅记录、分析报告 | exam_pkg/ |
| 数据库 | 文件名 | 存储路径 | 主要功能 | 环境 |
|--------|--------|----------|----------|------|
| feedback | `feedback.db` | `data/prod/` | 用户反馈、FAQ、质量报告、FAQ 建议 | 生产 + 开发 |
| knowledge | `knowledge.db` | `data/prod/` | 知识库同步、文档哈希、纲要缓存、版本管理 | 生产 + 开发 |
| session | `session.db` | `data/dev/` | 会话管理、消息历史、审计日志 | 仅开发 |
| exam | `exam.db` | `data/dev/` | 题目存储、试卷管理、批阅记录、分析报告 | 仅开发 |
---
## 1. rag_core.db - 核心交互数据库
## 1. feedback.db - 反馈系统数据库
**所属模块**`services/session.py``services/audit.py``services/feedback.py`
**存储路径**`data/prod/feedback.db`
**环境**:生产 + 开发(始终启用)
**所属模块**`services/feedback.py`
### 1.1 sessions 表 - 会话
### 1.1 feedbacks 表 - 反馈
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | INTEGER | 自增主键 |
| `session_id` | TEXT | 会话ID |
| `query` | TEXT | 用户问题 |
| `answer` | TEXT | 系统回答 |
| `sources` | TEXT | 来源文档JSON |
| `rating` | INTEGER | 评分1=赞,-1=踩 |
| `reason` | TEXT | 点踩原因 |
| `user_id` | TEXT | 用户ID |
| `created_at` | TIMESTAMP | 创建时间 |
**索引**
- `idx_feedback_session(session_id)`
- `idx_feedback_rating(rating)`
- `idx_feedback_created(created_at)`
### 1.2 faqs 表 - FAQ表
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | INTEGER | 自增主键 |
| `question` | TEXT | 问题 |
| `answer` | TEXT | 答案 |
| `source_documents` | TEXT | 来源文档JSON数组 |
| `frequency` | INTEGER | 出现频次 |
| `avg_rating` | REAL | 平均评分 |
| `status` | TEXT | 状态draft / approved / disabled |
| `created_at` | TIMESTAMP | 创建时间 |
| `updated_at` | TIMESTAMP | 更新时间 |
**索引**
- `idx_faq_status(status)`
### 1.3 faq_variants 表 - FAQ 问题变体表
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | INTEGER | 自增主键 |
| `faq_id` | INTEGER | 关联 FAQ ID |
| `variant_question` | TEXT | 变体问题 |
| `created_at` | TIMESTAMP | 创建时间 |
**索引**
- `idx_faq_variant_faq(faq_id)`
**外键**
- `faq_id` → faqs(id) ON DELETE CASCADE
**作用**Multi-Query Indexing为同一 FAQ 存储多种问法变体,提升语义召回率。
### 1.4 quality_reports 表 - 质量报告表
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | INTEGER | 自增主键 |
| `report_type` | TEXT | 报告类型weekly / monthly |
| `start_date` | DATE | 统计开始日期 |
| `end_date` | DATE | 统计结束日期 |
| `total_queries` | INTEGER | 总查询数 |
| `total_feedback` | INTEGER | 总反馈数 |
| `positive_count` | INTEGER | 正面反馈数 |
| `negative_count` | INTEGER | 负面反馈数 |
| `avg_rating` | REAL | 平均评分 |
| `satisfaction_rate` | REAL | 满意度 |
| `high_freq_queries` | TEXT | 高频问题JSON |
| `low_rating_queries` | TEXT | 低分问题JSON |
| `improvement_suggestions` | TEXT | 改进建议JSON |
| `created_at` | TIMESTAMP | 创建时间 |
### 1.5 faq_suggestions 表 - FAQ建议表
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | INTEGER | 自增主键 |
| `query` | TEXT | 用户问题 |
| `answer` | TEXT | 系统回答 |
| `frequency` | INTEGER | 出现频次 |
| `avg_rating` | REAL | 平均评分 |
| `status` | TEXT | 状态pending / approved / rejected |
| `created_at` | TIMESTAMP | 创建时间 |
**作用**高频优质问题自动建议沉淀为FAQ管理员审核后生效。
---
## 2. session.db - 会话管理数据库
**存储路径**`data/dev/session.db`
**环境**:仅开发模式
**所属模块**`services/session.py`
### 2.1 sessions 表 - 会话表
| 字段 | 类型 | 说明 |
|------|------|------|
@@ -54,7 +151,7 @@ with get_connection("core") as conn:
**作用**:实现多用户会话隔离,支持多轮对话记忆。
### 1.2 messages 表 - 消息历史表
### 2.2 messages 表 - 消息历史表
| 字段 | 类型 | 说明 |
|------|------|------|
@@ -62,6 +159,7 @@ with get_connection("core") as conn:
| `session_id` | TEXT | 关联会话ID |
| `role` | TEXT | 角色user / assistant |
| `content` | TEXT | 消息内容 |
| `metadata` | TEXT | 元数据JSON格式 |
| `created_at` | TIMESTAMP | 创建时间 |
**索引**
@@ -70,7 +168,7 @@ with get_connection("core") as conn:
**外键**
- `session_id` → sessions(session_id) ON DELETE CASCADE
### 1.3 audit_logs 表 - 审计日志表
### 2.3 audit_logs 表 - 审计日志表
| 字段 | 类型 | 说明 |
|------|------|------|
@@ -94,82 +192,15 @@ with get_connection("core") as conn:
**作用**:记录所有用户操作,用于安全审计和行为分析。
### 1.4 feedbacks 表 - 反馈表
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | INTEGER | 自增主键 |
| `session_id` | TEXT | 会话ID |
| `query` | TEXT | 用户问题 |
| `answer` | TEXT | 系统回答 |
| `sources` | TEXT | 来源文档JSON |
| `rating` | INTEGER | 评分1=赞,-1=踩 |
| `reason` | TEXT | 点踩原因 |
| `user_id` | TEXT | 用户ID |
| `created_at` | TIMESTAMP | 创建时间 |
**索引**
- `idx_feedback_session(session_id)`
- `idx_feedback_rating(rating)`
- `idx_feedback_created(created_at)`
### 1.5 faqs 表 - FAQ表
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | INTEGER | 自增主键 |
| `question` | TEXT | 问题 |
| `answer` | TEXT | 答案 |
| `source_documents` | TEXT | 来源文档JSON数组 |
| `frequency` | INTEGER | 出现频次 |
| `avg_rating` | REAL | 平均评分 |
| `status` | TEXT | 状态draft / approved / disabled |
| `created_at` | TIMESTAMP | 创建时间 |
| `updated_at` | TIMESTAMP | 更新时间 |
**索引**
- `idx_faq_status(status)`
### 1.6 faq_suggestions 表 - FAQ建议表
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | INTEGER | 自增主键 |
| `query` | TEXT | 用户问题 |
| `answer` | TEXT | 系统回答 |
| `frequency` | INTEGER | 出现频次 |
| `avg_rating` | REAL | 平均评分 |
| `status` | TEXT | 状态pending / approved / rejected |
| `created_at` | TIMESTAMP | 创建时间 |
**作用**高频优质问题自动建议沉淀为FAQ管理员审核后生效。
### 1.7 quality_reports 表 - 质量报告表
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | INTEGER | 自增主键 |
| `report_type` | TEXT | 报告类型weekly / monthly |
| `start_date` | DATE | 统计开始日期 |
| `end_date` | DATE | 统计结束日期 |
| `total_queries` | INTEGER | 总查询数 |
| `total_feedback` | INTEGER | 总反馈数 |
| `positive_count` | INTEGER | 正面反馈数 |
| `negative_count` | INTEGER | 负面反馈数 |
| `avg_rating` | REAL | 平均评分 |
| `satisfaction_rate` | REAL | 满意度 |
| `high_freq_queries` | TEXT | 高频问题JSON |
| `low_rating_queries` | TEXT | 低分问题JSON |
| `improvement_suggestions` | TEXT | 改进建议JSON |
| `created_at` | TIMESTAMP | 创建时间 |
---
## 2. knowledge.db - 知识管理数据库
## 3. knowledge.db - 知识管理数据库
**存储路径**`data/prod/knowledge.db`
**环境**:生产 + 开发(始终启用)
**所属模块**`knowledge/sync.py``services/outline.py`
### 2.1 document_hashes 表 - 文档哈希表
### 3.1 document_hashes 表 - 文档哈希表
| 字段 | 类型 | 说明 |
|------|------|------|
@@ -183,7 +214,7 @@ with get_connection("core") as conn:
**作用**:记录每个文档的当前状态,用于检测变更。
### 2.2 change_logs 表 - 变更日志表
### 3.2 change_logs 表 - 变更日志表
| 字段 | 类型 | 说明 |
|------|------|------|
@@ -202,39 +233,7 @@ with get_connection("core") as conn:
- `idx_change_logs_time(change_time)`
- `idx_change_logs_processed(processed)`
### 2.3 subscriptions 表 - 用户订阅
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | INTEGER | 自增主键 |
| `user_id` | TEXT | 用户ID |
| `document_id` | TEXT | 订阅的文档IDNULL表示订阅全部 |
| `document_name` | TEXT | 文档名称 |
| `created_at` | TIMESTAMP | 订阅时间 |
**唯一约束**`(user_id, document_id)`
**索引**
- `idx_subscriptions_user(user_id)`
### 2.4 notifications 表 - 通知记录表
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | INTEGER | 自增主键 |
| `user_id` | TEXT | 用户ID |
| `document_id` | TEXT | 文档ID |
| `document_name` | TEXT | 文档名称 |
| `change_type` | TEXT | 变更类型 |
| `message` | TEXT | 通知消息 |
| `read` | INTEGER | 是否已读0/1 |
| `created_at` | TIMESTAMP | 创建时间 |
**索引**
- `idx_notifications_user(user_id)`
- `idx_notifications_read(read)`
### 2.5 sync_status 表 - 同步状态表
### 3.3 sync_status 表 - 同步状态
| 字段 | 类型 | 说明 |
|------|------|------|
@@ -250,7 +249,7 @@ with get_connection("core") as conn:
| `error_message` | TEXT | 错误信息 |
| `created_at` | TIMESTAMP | 创建时间 |
### 2.6 outline_cache 表 - 纲要缓存表
### 3.4 outline_cache 表 - 纲要缓存表
| 字段 | 类型 | 说明 |
|------|------|------|
@@ -265,7 +264,7 @@ with get_connection("core") as conn:
**索引**
- `idx_outline_doc(document_id)`
### 2.7 document_vectors 表 - 文档向量缓存表
### 3.5 document_vectors 表 - 文档向量缓存表
| 字段 | 类型 | 说明 |
|------|------|------|
@@ -280,7 +279,7 @@ with get_connection("core") as conn:
**索引**
- `idx_vector_doc(document_id)`
### 2.8 recommendation_cache 表 - 推荐缓存表
### 3.6 recommendation_cache 表 - 推荐缓存表
| 字段 | 类型 | 说明 |
|------|------|------|
@@ -289,7 +288,7 @@ with get_connection("core") as conn:
| `recommendations_json` | TEXT | 推荐结果JSON |
| `generated_at` | TIMESTAMP | 生成时间 |
### 2.9 document_versions 表 - 文档版本表
### 3.7 document_versions 表 - 文档版本表
| 字段 | 类型 | 说明 |
|------|------|------|
@@ -313,7 +312,7 @@ with get_connection("core") as conn:
**唯一约束**`(document_id, collection, version)`
### 2.10 version_change_logs 表 - 版本变更日志表
### 3.8 version_change_logs 表 - 版本变更日志表
| 字段 | 类型 | 说明 |
|------|------|------|
@@ -331,11 +330,13 @@ with get_connection("core") as conn:
---
## 3. exam.db - 出题系统数据库
## 4. exam.db - 出题系统数据库
**存储路径**`data/dev/exam.db`
**环境**:仅开发模式
**所属模块**`exam_pkg/manager.py``exam_pkg/local_db.py``exam_pkg/analysis.py`
### 3.1 questions 表 - 题目表
### 4.1 questions 表 - 题目表
| 字段 | 类型 | 说明 |
|------|------|------|
@@ -360,7 +361,7 @@ with get_connection("core") as conn:
**索引**
- `idx_questions_source(source_file)`
### 3.2 exams 表 - 试卷表
### 4.2 exams 表 - 试卷表
| 字段 | 类型 | 说明 |
|------|------|------|
@@ -374,7 +375,7 @@ with get_connection("core") as conn:
| `created_at` | TIMESTAMP | 创建时间 |
| `created_by` | TEXT | 创建人 |
### 3.3 exam_questions 表 - 试卷题目关联表
### 4.3 exam_questions 表 - 试卷题目关联表
| 字段 | 类型 | 说明 |
|------|------|------|
@@ -388,7 +389,7 @@ with get_connection("core") as conn:
- `exam_id` → exams(id) ON DELETE CASCADE
- `question_id` → questions(id) ON DELETE CASCADE
### 3.4 student_answers 表 - 学生答卷表
### 4.4 student_answers 表 - 学生答卷表
| 字段 | 类型 | 说明 |
|------|------|------|
@@ -408,7 +409,7 @@ with get_connection("core") as conn:
**索引**
- `idx_student_answers_exam(exam_id, student_id)`
### 3.5 grade_reports 表 - 批阅报告表
### 4.5 grade_reports 表 - 批阅报告表
| 字段 | 类型 | 说明 |
|------|------|------|
@@ -421,7 +422,7 @@ with get_connection("core") as conn:
| `analysis` | TEXT | 分析JSON |
| `graded_at` | TIMESTAMP | 批阅时间 |
### 3.6 question_document_links 表 - 题目-制度关联表
### 4.6 question_document_links 表 - 题目-制度关联表
| 字段 | 类型 | 说明 |
|------|------|------|
@@ -440,7 +441,7 @@ with get_connection("core") as conn:
- `idx_qdl_question(question_id)`
- `idx_qdl_document(document_id)`
### 3.7 knowledge_points 表 - 知识点表
### 4.7 knowledge_points 表 - 知识点表
| 字段 | 类型 | 说明 |
|------|------|------|
@@ -454,7 +455,7 @@ with get_connection("core") as conn:
**外键**
- `parent_id` → knowledge_points(id)
### 3.8 question_knowledge_links 表 - 题目-知识点关联表
### 4.8 question_knowledge_links 表 - 题目-知识点关联表
| 字段 | 类型 | 说明 |
|------|------|------|
@@ -471,7 +472,7 @@ with get_connection("core") as conn:
- `idx_qkl_question(question_id)`
- `idx_qkl_knowledge(knowledge_point_id)`
### 3.9 question_status 表 - 题目状态表
### 4.9 question_status 表 - 题目状态表
| 字段 | 类型 | 说明 |
|------|------|------|
@@ -487,7 +488,7 @@ with get_connection("core") as conn:
**索引**
- `idx_qs_status(status)`
### 3.10 exam_analysis_reports 表 - 整卷分析报告表
### 4.10 exam_analysis_reports 表 - 整卷分析报告表
| 字段 | 类型 | 说明 |
|------|------|------|
@@ -507,7 +508,7 @@ with get_connection("core") as conn:
| `study_suggestions` | TEXT | 学习建议JSON |
| `created_at` | TIMESTAMP | 创建时间 |
### 3.11 question_suggestions 表 - 新题建议表
### 4.11 question_suggestions 表 - 新题建议表
| 字段 | 类型 | 说明 |
|------|------|------|
@@ -519,11 +520,11 @@ with get_connection("core") as conn:
---
## 4. ChromaDB 向量数据库
## 5. ChromaDB 向量数据库
**所属模块**`knowledge/manager.py`
### 4.1 向量库结构
### 5.1 向量库结构
```
knowledge/vector_store/chroma/
@@ -536,7 +537,7 @@ knowledge/vector_store/chroma/
└── ... # 其他部门向量库
```
### 4.2 权限矩阵
### 5.2 权限矩阵
| 角色 | 可访问向量库 | 可上传 | 可删除 | 可同步 |
|------|------------|--------|--------|--------|
@@ -544,7 +545,7 @@ knowledge/vector_store/chroma/
| manager | public_kb + 本部门 | 本部门 | 本部门 | 本部门 |
| user | public_kb + 本部门 | - | - | - |
### 4.3 文档元数据结构
### 5.3 文档元数据结构
每个文档 chunk 的元数据:
@@ -580,32 +581,33 @@ knowledge/vector_store/chroma/
user_id / document_id 关联 │
┌──────────────────┐
rag_core.db
(核心数据库)
• sessions
│ • messages
│ • audit_logs
│ • feedbacks
│ • faqs
• quality_reports
└────────┬─────────┘
│ user_id / document_id 关联
┌────────────────┐ ┌───────────────┐
knowledge.db exam.db
│ │
• document_ │ │ • questions
hashes │ │ • exams
│ • change_logs │ │ • student_
│ • subscriptions │ │ answers
│ • outline_cache │ │ • grade_ │
• document_ │ │ reports
versions │ │ • knowledge_
└─────────────────┘ │ points
└───────────────┘
┌──────────────────┐ ┌──────────────────┐
data/prod/ │ │ data/prod/
feedback.db │ │ knowledge.db
(生产+开发) (生产+开发)
│ │
│ • feedbacks │ │ • document_
│ • faqs │ │ hashes
│ • faq_variants │ │ • change_logs
│ • quality_ │ │ • sync_status
reports │ │ • outline_cache
│ • faq_ │ │ • document_ │
suggestions │ │ versions
└──────────────────┘ └──────────────────┘
┌──────────────────┐ ┌──────────────────
data/dev/│ data/dev/
session.db │ │ exam.db
(仅开发) │ │ (仅开发)
│ │
sessions │ │ questions
messages │ │ • exams
audit_logs │ │ student_ │
│ │ answers
│ │ grade_reports
│ │ │ • knowledge_
│ │ points │
└──────────────────┘ └──────────────────┘
```
---
@@ -615,25 +617,24 @@ knowledge/vector_store/chroma/
### 数据清理
```bash
# 清理过期会话24小时未活跃
sqlite3 data/rag_core.db "DELETE FROM sessions WHERE last_active < datetime('now', '-24 hours');"
sqlite3 data/rag_core.db "DELETE FROM messages WHERE session_id NOT IN (SELECT session_id FROM sessions);"
# 清理过期会话24小时未活跃- 仅开发环境
sqlite3 data/dev/session.db "DELETE FROM sessions WHERE last_active < datetime('now', '-24 hours');"
sqlite3 data/dev/session.db "DELETE FROM messages WHERE session_id NOT IN (SELECT session_id FROM sessions);"
# 清理旧审计日志保留30天
sqlite3 data/rag_core.db "DELETE FROM audit_logs WHERE created_at < datetime('now', '-30 days');"
# 清理已处理的通知保留7天
sqlite3 data/knowledge.db "DELETE FROM notifications WHERE read = 1 AND created_at < datetime('now', '-7 days');"
# 清理旧审计日志保留30天- 仅开发环境
sqlite3 data/dev/session.db "DELETE FROM audit_logs WHERE created_at < datetime('now', '-30 days');"
```
### 数据备份
```bash
# 备份 SQLite 数据库
cp data/*.db backup/
# 备份所有 SQLite 数据库
cp data/prod/*.db backup/
cp data/dev/*.db backup/
# 使用 SQLite 在线备份
sqlite3 data/rag_core.db ".backup backup/rag_core_backup.db"
sqlite3 data/prod/feedback.db ".backup backup/feedback_backup.db"
sqlite3 data/prod/knowledge.db ".backup backup/knowledge_backup.db"
```
### 重置数据库
@@ -641,14 +642,17 @@ sqlite3 data/rag_core.db ".backup backup/rag_core_backup.db"
删除对应的文件,服务启动时会自动重建表结构:
```bash
# 重置核心数据(会丢失会话和对话历史
rm data/rag_core.db
# 重置反馈数据(会丢失反馈和 FAQ
rm data/prod/feedback.db
# 重置知识管理数据(会丢失文档追踪和订阅
rm data/knowledge.db
# 重置知识管理数据(会丢失文档追踪和版本
rm data/prod/knowledge.db
# 重置出题系统数据(会丢失题目和试卷)
rm data/exam.db
# 重置会话数据(会丢失会话和对话历史)- 仅开发环境
rm data/dev/session.db
# 重置出题系统数据(会丢失题目和试卷)- 仅开发环境
rm data/dev/exam.db
```
---
@@ -657,6 +661,7 @@ rm data/exam.db
| 日期 | 版本 | 更新内容 |
|------|------|----------|
| 2026-06-04 | 4.0 | 修正为 4 库分离架构rag_core.db 拆分为 feedback.db + session.db按 prod/dev 子目录分离;新增 faq_variants 表;移除已废弃的 subscriptions/notifications 表 |
| 2026-04-13 | 3.0 | 数据库架构重构6 个独立数据库合并为 3 个 |
| 2026-04-09 | 2.0 | 新增多向量库架构文档 |
| 2026-04-07 | 1.0 | 初始版本 |