完成RAG测试

This commit is contained in:
2026-01-27 01:41:45 +08:00
parent 155974572c
commit f78efc7125
16 changed files with 1434 additions and 66 deletions

157
docs/RAGtest.md Normal file
View File

@@ -0,0 +1,157 @@
这是一份标准的 **RAG 系统测试与验证设计文档**。你可以将其作为项目文档的一部分用于指导开发团队进行自动化测试框架的搭建、QA 团队进行测试用例的编写,以及算法工程师进行模型选型。
---
# RAG 知识库检索与生成系统测试设计规范
**RAG System Test Design Specification**
**版本**: 1.0
**状态**: 拟定中
---
## 1. 测试背景与目标 (Background & Objectives)
RAG检索增强生成系统涉及“检索器Retriever”与“生成器Generator”的复杂交互。传统的软件测试单元测试、集成测试无法有效评估其回答质量。本设计文档旨在建立一套**端到端End-to-End**与**分段式Component-wise**结合的测试框架,以达成以下目标:
1. **量化评估**:将模糊的“回答好坏”转化为可度量的指标(如召回率、忠实度得分)。
2. **归因分析**当系统表现不佳时能快速定位是“检索没找对”还是“LLM 没答好”。
3. **选型决策**通过横向对比Benchmark为检索算法BM25/Vector/Hybrid和模型选择提供数据支撑。
4. **短板识别**:自动识别系统在特定场景(如多语言、数值推理、负向测试)下的薄弱环节。
---
## 2. 测试架构原理 (Test Architecture)
测试框架基于 **RAG 三元组 (RAG Triad)** 理论进行设计,分别针对链路中的三个关键节点进行评估:
### 2.1 评估对象
* **Query (用户提问)**: 测试的输入。
* **Context (检索上下文)**: 检索器从知识库召回的 Top-K 文档片段。
* **Response (系统回答)**: LLM 基于 Query 和 Context 生成的最终文本。
### 2.2 测试流向
1. **检索层评估 (Retrieval Evaluation)**: `Query` $\leftrightarrow$ `Context`
* *核心问题*: 检索到的内容是否包含回答问题所需的全部信息?
2. **生成层评估 (Generation Evaluation)**:
* `Context` $\leftrightarrow$ `Response`: **忠实度 (Faithfulness)**。回答是否完全基于上下文?有无幻觉?
* `Query` $\leftrightarrow$ `Response`: **相关度 (Relevance)**。回答是否解决了用户的问题?
---
## 3. 测试数据集设计 (Dataset Design)
为了全面评估系统能力,构建“黄金数据集”是测试的基础。数据集需包含以下维度的字段:
### 3.1 数据字段定义
| 字段名 | 说明 | 用途 |
| :--- | :--- | :--- |
| **ID** | 唯一标识符 | 用于追踪 Case |
| **Type** | 问题分类 | 用于计算 "Weakest Category" (见 3.2) |
| **Query** | 用户模拟问题 | 输入 |
| **Ground Truth Answer** | 标准答案 | 用于生成层对比评分 |
| **Keywords/Key Information** | 关键信息点/术语 | 用于计算检索层的 Recall |
| **Ground Truth Context IDs** | (可选) 预期命中的文档ID | 用于计算 Hit Rate |
### 3.2 场景分类体系 (Category Taxonomy)
测试集必须覆盖以下场景,以防止模型“偏科”:
1. **Core Function (核心功能)**: 基础的概念解释和流程指引。
2. **Detail/Numeric (细节与数值)**: 涉及具体参数、价格、限制阈值等精确信息(考察向量检索的弱点)。
3. **Inference (推理集成)**: 需要综合多段文档才能回答的复杂问题(考察 Context Window 和推理能力)。
4. **Multilingual (跨语言)**: 中文问英文文档,或反之(考察 Embedding 对齐能力)。
5. **Negative Test (负向/拒答)**: 知识库中不存在的问题(考察系统抗幻觉能力,预期输出为“未找到信息”)。
6. **Safety/Injection (安全)**: Prompt 注入攻击防御测试。
---
## 4. 控制变量与横向对比设计 (Experimental Design)
为选出最佳技术方案需设计控制变量矩阵Control Matrix进行 A/B 测试或横向评测。
### 4.1 实验组配置 (Configuration Matrix)
| 实验组 | 检索机制 (Retrieval) | 权重策略 | 重排序 (Rerank) | 测试目的 |
| :--- | :--- | :--- | :--- | :--- |
| **Group A (Baseline)** | **Keyword (BM25)** | Vector=0, Keyword=1 | OFF | 模拟传统全文检索,设立基准线。 |
| **Group B (Semantic)** | **Dense Vector** | Vector=1, Keyword=0 | OFF | 验证语义理解能力,检测对专有名词的丢失情况。 |
| **Group C (Hybrid)** | **Hybrid Search** | Vector=0.7, Keyword=0.3 | OFF | 验证双路召回的互补性(当前主流方案)。 |
| **Group D (High Acc)** | **Hybrid Search** | Vector=0.7, Keyword=0.3 | **ON (Top N)** | 验证引入 Rerank 模型对长尾、复杂问题的提升效果及延迟代价。 |
### 4.2 性能监控
在运行上述配置时,同步记录以下工程指标:
* **Latency**: 端到端耗时P50, P95
* **Token Usage**: 消耗的 Token 数量(计算成本 ROI
---
## 5. 核心评估指标 (Key Metrics)
采用 **规则计算 + LLM裁判 (LLM-as-a-Judge)** 相结合的方式。
### 5.1 检索层指标 (Retrieval Metrics)
| 指标 | 定义 | 计算方法 | 优劣判断 |
| :--- | :--- | :--- | :--- |
| **Keyword Recall** | 关键词召回率 | $\frac{\text{检索内容中命中的关键词数}}{\text{标准答案中的关键词总数}}$ | 低于 50% 说明切片策略或检索算法严重失效。 |
| **Hit Rate** | 命中率 | 检索结果 Top-K 中是否包含至少一个相关文档片段。 | 二分类指标 (0/1)。 |
### 5.2 生成层指标 (Generation Metrics)
使用高智能模型(如 GPT-4o / Qwen-Max作为裁判进行 1-5 分打分。
| 指标 | 定义 | 评分标准 (Rubric) |
| :--- | :--- | :--- |
| **Correctness** | 正确性 | **5分**: 含义与 Ground Truth 完全一致。<br>**1分**: 完全错误或包含严重幻觉。 |
| **Completeness** | 完整性 | 答案是否涵盖了问题询问的所有方面?(主要针对列表类问题)。 |
| **Honesty** | 诚实度 | (针对负向测试) 当无相关信息时,是否诚实回答“不知道”而非编造。 |
### 5.3 诊断性指标 (Diagnostic Metrics)
* **Weakest Category (最弱类别)**:
* 计算逻辑:按 `Type` 分组,计算各组的平均分,取最低者。
* 作用:直接指出系统短板(例如:“多语言能力最差”或“数值细节最差”),指导后续优化方向。
---
## 6. 自动化测试流程 (Workflow)
1. **Setup Phase**:
* 加载 `dataset.json`
* 初始化所有待测的 RAG Pipeline 配置。
2. **Execution Phase (Loop)**:
* 遍历测试集中的每个 Query。
* **Step 1 Retrieve**: 调用检索接口,获取 Context。
* **Step 2 Generate**: 将 Context + Query 送入 LLM 生成 Answer。
* **Step 3 Measure**: 记录 Latency。
3. **Evaluation Phase**:
* **Rule Check**: 计算 Keyword Recall。
* **AI Judge**: 将 (Query, Answer, Ground Truth) 组装 Prompt 发送给裁判 LLM 打分。
4. **Reporting Phase**:
* 输出汇总报表,包含:各配置的平均分、平均召回率、延迟、最弱类别。
* 输出 Bad Case 列表(得分 < 3 的用例)。
---
## 7. 附录LLM 裁判 Prompt 模板
```markdown
你是一名 RAG 系统测试裁判。请评估【系统回答】相对于【标准答案】的质量。
【问题类型】: {type}
【用户问题】: {query}
【标准答案】: {ground_truth}
【系统回答】: {prediction}
请打分 (1-5)
- 5分: 完美。逻辑正确,无幻觉,细节精准。
- 3分: 及格。包含核心信息,但有遗漏或啰嗦。
- 1分: 错误。答非所问,或在负向测试中产生幻觉。
特别规则:对于 "Negative Test",如果标准答案是“不支持/未提及”,而系统回答了“未找到相关信息”,请给 5 分。
输出 JSON: {"score": int, "reason": "string"}
```

View File

@@ -6,7 +6,7 @@
| **字段** | **当前值 (示例)** | **说明** | **每次要改吗?** |
| -------------------- | ---------------------------------- | ------------------------------ | ---------------------- |
| **Version** | **v1.0.6** | **镜像的版本标签 (Tag)** | **是 (必须改)** |
| **Version** | **v1.0.7** | **镜像的版本标签 (Tag)** | **是 (必须改)** |
| **Image Name** | **wiki-crawl-backend** | **镜像/容器的名字** | **否 (固定)** |
| **Namespace** | **qg-demo** | **阿里云命名空间** | **否 (固定)** |
| **Registry** | **crpi-1rwd6fvain6t49g2...** | **阿里云仓库地址** | **否 (固定)** |
@@ -19,18 +19,18 @@
### 1. 构建镜像 (Build)
**修改命令最后的版本号** **v1.0.6**
**修改命令最后的版本号** **v1.0.7**
```powershell
docker build -t crpi-1rwd6fvain6t49g2.cn-hangzhou.personal.cr.aliyuncs.com/qg-demo/wiki-crawl-backend:v1.0.6 .
docker build -t crpi-1rwd6fvain6t49g2.cn-hangzhou.personal.cr.aliyuncs.com/qg-demo/wiki-crawl-backend:v1.0.7 .
```
### 2. 推送镜像 (Push)
**修改命令最后的版本号** **v1.0.6**
**修改命令最后的版本号** **v1.0.7**
```powershell
docker push crpi-1rwd6fvain6t49g2.cn-hangzhou.personal.cr.aliyuncs.com/qg-demo/wiki-crawl-backend:v1.0.6
docker push crpi-1rwd6fvain6t49g2.cn-hangzhou.personal.cr.aliyuncs.com/qg-demo/wiki-crawl-backend:v1.0.7
```
> **成功标准:** **看到进度条走完,且最后显示** **Pushed**。
@@ -43,10 +43,10 @@ docker push crpi-1rwd6fvain6t49g2.cn-hangzhou.personal.cr.aliyuncs.com/qg-demo/w
### 1. 拉取新镜像 (Pull)
**修改命令最后的版本号** **v1.0.6**
**修改命令最后的版本号** **v1.0.7**
```bash
docker pull crpi-1rwd6fvain6t49g2.cn-hangzhou.personal.cr.aliyuncs.com/qg-demo/wiki-crawl-backend:v1.0.6
docker pull crpi-1rwd6fvain6t49g2.cn-hangzhou.personal.cr.aliyuncs.com/qg-demo/wiki-crawl-backend:v1.0.7
```
### 2. 停止并删除旧容器
@@ -61,7 +61,7 @@ docker rm wiki-crawl-backend
### 3. 启动新容器 (Run) - 关键步骤
**修改命令最后的版本号** **v1.0.6**
**修改命令最后的版本号** **v1.0.7**
**code**Bash
@@ -69,7 +69,7 @@ docker rm wiki-crawl-backend
docker run -d --name wiki-crawl-backend \
-e PYTHONUNBUFFERED=1 \
-p 80:8000 \
crpi-1rwd6fvain6t49g2.cn-hangzhou.personal.cr.aliyuncs.com/qg-demo/wiki-crawl-backend:v1.0.6
crpi-1rwd6fvain6t49g2.cn-hangzhou.personal.cr.aliyuncs.com/qg-demo/wiki-crawl-backend:v1.0.7
```
### 4. 验证与日志查看
@@ -132,9 +132,9 @@ docker image prune -a -f
### 5. 那个超长的 URL
**crpi-1rwd6fvain6t49g2.cn-hangzhou.personal.cr.aliyuncs.com/qg-demo/wiki-crawl-backend:v1.0.6**
**crpi-1rwd6fvain6t49g2.cn-hangzhou.personal.cr.aliyuncs.com/qg-demo/wiki-crawl-backend:v1.0.7**
* **Registry (仓库地址)**: **crpi-1rwd...aliyuncs.com** **-> 你的专属阿里云仓库服务器。**
* **Namespace (命名空间)**: **qg-demo** **-> 你在仓库里划出的个人地盘。**
* **Image Name (镜像名)**: **wiki-crawl-backend** **-> 这个项目的名字。**
* **Tag (标签)**: **v1.0.6** **-> 相当于软件的版本号。如果不写 Tag默认就是** **latest**。**生产环境强烈建议写明确的版本号**,方便回滚(比如 1.0.3 挂了,你可以立马用 1.0.2 启动)。
* **Tag (标签)**: **v1.0.7** **-> 相当于软件的版本号。如果不写 Tag默认就是** **latest**。**生产环境强烈建议写明确的版本号**,方便回滚(比如 1.0.3 挂了,你可以立马用 1.0.2 启动)。

View File

@@ -1,60 +1,49 @@
# 下一步开发计划
## 2025.1.13
## 2025.1.20
1. 知识库RAG
1. 测试
测试相关资料参考链接: <https://1988251901502969000zhuanlan.zhihu.com/p/>
- [ ] 参照主流知识库架构增减修改当前知识库字段
- [ ] 根据主流RAG测试要求完善知识库检索测试
- [ ] 开发LLM输出测试
- [ ] 横向对比不同检索方法或模型下的测试效果
- [ ] 参照主流知识库架构增减修改当前知识库字段
- [ ] 根据主流RAG测试要求完善知识库检索测试
- [ ] 开发LLM输出测试
- [ ] 横向对比不同检索方法或模型下的测试效果
2. dify原生知识库
dify原生支持的知识库可以直接配置firecrawl的api_key实现知识库爬取因此
2. 后端封装backend
1. 新增v3接口替代v2和v1。
预期实现效果:
- [ ] 添加任务
- [ ] 查询任务
- [ ] 执行任务
- [ ] 知识库搜索
2. 包装成MCP
1. 重置接口v1版本restfulAPI
预期实现效果:
- [x] 添加任务
- [x] 查询任务
- [x] 执行任务
- [x] 获取所有知识库
- [x] 知识库搜索
2. 新增功能
- [ ] 业务操作原子化
- [ ] 知识库更新相关
- [ ] 日志功能
3. 包装成MCP工具供dify调用
- [x] 完成backend的MCP包装并测试
- [x] 发现dify可以直接用http接口封装工具所以就用原来的fastapi去做了
4. 阿里云部署
- [x] 将后端部署阿里云
3. dify节点
- [ ] 完成dify的LLM输出工具主要负责处理搜索逻辑和问题分类调用api发布工具。
- [x] 完成dify的LLM输出工具主要负责处理搜索逻辑和问题分类调用api发布工具。
也可能直接在backend里全部实现直接集成到bot里
4. firecrawl与替代方案调研
1. firecrawl付费方案
- 常规订阅链接: <https://www.firecrawl.dev/pricing>
注意: 此链接下均是按时间订阅的,每月限制额度, 可额外购买, 但是考虑到客户使用的时候可能会固定时间集中使用(**采集新wiki, 更新旧wiki**)
- 企业订阅方案: 需要联系firecrawl订制
2. firecrawl开源方案
- 开源github链接: <https://github.com/mendableai/firecrawl>
- 优劣对比
| 对比维度 | 开源版 (Self-hosted) | 云服务版 (Cloud / SaaS) | 核心差异说明 |
| :-------------------------- | :------------------------------------------------------------- | :-------------------------------------------------------------- | :------------------------------------------------------------------ |
| **部署方式** | 🐳 **Docker 自托管**<br>需自行配置服务器环境 | ☁️ **开箱即用**<br>注册 API Key 即可调用 | 云版省去了复杂的环境搭建过程。 |
| **成本** | 🆓 **软件免费**<br>需支付服务器/带宽费用 | 💰 **订阅制**<br>按 Credits (页数) 计费,有免费额度 | 量大且有闲置服务器时开源版更省钱;量小或追求稳定时云版更划算。 |
| **反爬虫绕过**<br>(Proxies) | ❌ **弱 / 需自行配置**<br>默认使用本机 IP易被 Cloudflare 拦截 | ✅ **强 / 内置智能代理**<br>自动轮换 IP擅长绕过 WAF 和人机验证 | **这是最大的区别。** 云版包含商业代理池成本,开源版需你自己买代理。 |
| **维护难度** | 🛠 **高**<br>需维护 Redis、队列、无头浏览器更新 | ☕ **零**<br>官方团队维护基础设施 | 开源版遇到浏览器崩溃或内存泄漏需自己修。 |
| **并发与性能** | ⚠️ **受限于硬件**<br>取决于你的服务器配置 | 🚀 **弹性扩容**<br>支持高并发,速度通常更快 | 云版对并行抓取做了优化。 |
| **JS 渲染** | ✅ **支持**<br>需配置 Playwright/Puppeteer | ✅ **支持**<br>默认优化,加载更稳定 | 两者核心引擎相同,但云版资源分配更合理。 |
| **数据隐私** | 🔒 **高 (本地化)**<br>数据不经过第三方服务器 | ☁️ **中**<br>数据需传输至 Firecrawl 服务器处理 | 对数据合规性要求极高的场景(如金融/医疗)首选开源版。 |
| **适用场景** | 极客折腾、内网抓取、低频低难度网站、数据极度敏感 | 商业项目、大规模抓取、高难度网站 (有反爬)、追求稳定性 | |
3. 自主研发爬虫
1. 反爬机制: 维基百科对IP有访问频率限制, 且有验证码, 需自行处理
2. 动态内容: 维基百科有很多动态内容, 如表格, 图片等, 需自行处理, 如使用Selenium等工具模拟浏览器行为
**Firecrawl方案和替代评估总结**
假设客户的产品需求是: 从不同的网站爬取文档制成知识库, 并且需要定期维护, 那么其实只有在爬取新的站点和维护旧的站点的时候会集中使用firecrawl的额度, 主要特点是**使用时间集中**且**使用时段内额度需求量很大**以及**优先要保证爬虫模块的稳定性**
因此最推荐的方案是: 定时采购额度, 但是考虑到常规的订阅只有按时间计费, 而客户的需求是**定期维护**, 而**按使用额度计费, 即企业协商订阅**的方案是最符合客户需求的.
| 类别 | 成本 | 困难 |
| --- | --- | --- |
| 闭源版 | 购买定制服务, 如果企业长期话成本可能几千? 按年也就一年左右的量够用了 | 用起来很顺手, 目前的接口返回值基本能满足开发需求 |
| 开源版 | 需要准备IP池之类的反爬机制, 需要为IP代理付费 | 配置和学习相关的运营维护 |
| 自主研发 | 除了研发的时间精力外, 也必需IP池的购买 | 高 |
4. firecrawl方案
1. 闭源方案购买
年费大概9000元/年不支持绕过robots.txt
2. 开源方案
这个可以考虑自己部署一套然后分发apikey问题在于firecrawl的开源证书的法律风险以及需要修改robots和计费相关的部分以下是调研任务
- [x] robots.txt问题
在apps/api这个是可以直接修改代码改的但是关键是要吃透相关代码在各层级间的传递
- [x] 部署的计费相关
在apps/nuq-postgres后续可能部署之后单独分发apikey给客户因此需要一个计费方案
- [x] .env问题
需要查阅资料了解里面的一些参数配置重新配置之后好上云包括API_KEY配置、流量统计和配置