一个强调检索质量、证据引用、回答校验、任务恢复和本地数据边界的开源 RAG Agent。
RAG Agent 是一个本地优先的文档知识库与智能问答系统。用户上传文档后,可以直接使用自然语言提问;系统会完成意图识别、查询消歧、混合检索、工具调用、证据组织、流式回答和引用校验。
它不仅是“上传文档后调用一次大模型”,而是一套覆盖文档入库、检索、生成、校验、持久化、恢复、认证和评测的完整工程链路。
当前阶段:v0.2.1-beta。
| 核心能力 | 项目中的实现 |
|---|---|
| 检索质量 | Qdrant 语义检索 + SQLite BM25 + 加权 RRF + 可选 Reranker |
| Agent 推理 | 自研 ReAct 循环、多工具并行、上下文预算、循环收敛与长期记忆 |
| 回答可信度 | 来源卡片、行内引用、数字一致性检查、拒答与有界回答修复 |
| 工程可靠性 | 持久入库任务、重启恢复、Alembic、备份恢复、JWT、SSE 与发布门禁 |
快速入口:产品演示 · 一键启动 · 系统架构 · 评测结果 · v0.2.1-beta 发布说明 · 完整项目参考
演示展示了跨 Word/PDF 检索、恢复步骤、SLA 条件判断、流式回答、行内引用和来源卡片。另有文档列表、精确检索、计算器及无答案拒答等完整场景,见产品演示指南。素材来自公开合成数据,不包含真实业务信息或密钥。
无需本地构建,直接拉取 GHCR 镜像:
git clone https://github.com/MoMoM101/RAG-ReActAgent.git
cd RAG-ReActAgent
cp backend/.env.example backend/.env
docker compose --env-file backend/.env -f docker-compose.ghcr.yml up -dWindows PowerShell 将第三行替换为:
Copy-Item backend/.env.example backend/.env默认首次登录用户名:
admin
默认首次登录密码:
RAGAgent2026!
建议登录后立即修改密码,并在设置页填写 LLM 与 Embedding 配置。
本地部署:源码构建、本地开发和 OCR 安装方式见快速开始。
| 回答评测(93 条受控问答) | 结果 |
|---|---|
| 回答忠实度 / 引用精确率 | 100.00% / 99.62% |
| 拒答准确率 | 100.00% |
| 首 Token / 总延迟 P95 | 746.89 / 4,759.69 ms |
指标来自包含开发子集的固定合成基准,不是严格隔离的 held-out test,也不能直接外推到任意业务数据。完整口径、失败案例与复现方法见评测方法。
- 5 分钟了解项目
- 产品演示
- 一键启动
- 评测摘要
- 项目亮点
- 适用场景
- 核心功能
- 系统架构
- 文档入库流程
- 问答与检索流程
- 支持的文件格式与限制
- 快速开始
- 账号、登录与密码
- 配置说明
- 使用指南
- 质量评测
- 自动化测试
- 安全与隐私
- 可靠性设计
- 常见问题
- 项目来源与开发说明
- 项目文档
- 参与贡献
- 许可证
当前正式在线评测包含 93 条问答:
| 指标 | 结果 |
|---|---|
| 回答忠实度 | 100.00% |
| 引用精确率 | 99.62% |
| 引用召回率 | 99.62% |
| 拒答准确率 | 100.00% |
| 回答完成度 | 100.00% |
| 预期事实召回 | 85.21% |
| 首 Token 延迟 P95 | 746.89 ms |
| 总延迟 P95 | 4,759.69 ms |
| 评测运行错误 | 0 |
质量门禁和性能门禁均通过,且没有门禁违规项。
系统并行执行两条检索路径:
| 检索路径 | 引擎 | 主要优势 |
|---|---|---|
| 语义检索 | Qdrant | 自然语言、同义表达、上下文相关问题 |
| 关键词检索 | SQLite BM25 | 错误码、SKU、型号、专有名词和精确字段 |
两路结果经过加权 RRF 融合、查询消歧、内容去重、质量过滤和可选 Cross-Encoder 精排,再作为证据发送给大模型。
严格 qrels 检索评测结果:
| 指标 | Top-3 | Top-5 | Top-10 |
|---|---|---|---|
| Recall | 88.65% | 92.96% | 99.57% |
| Hit Rate | 100.00% | 100.00% | 100.00% |
| NDCG | 92.80% | 93.17% | 95.13% |
MRR 为 97.70%。
回答生成后并不会直接结束。系统会进一步检查:
- 引用是否真实存在(含 phantom citation
[S99]自动修复为 FORMAT_ONLY); - 引用位置是否正确;
- 引用是否能够支持对应声明;
- 声明中的数字是否与证据一致(支持版本号前缀匹配和单位空格容错);
- 联网搜索结果纳入独立引证体系(WS 前缀),与知识库引用(S 前缀)共存;
- 是否遗漏必须引用的事实;
- 没有充分证据时是否应当拒答;
- 是否需要确定性修复或有界 LLM 修复;
- 验证超时时执行确定性修复而非静默接受。
这套机制可以减少”回答看起来合理,但证据并不支持”的情况。流验证默认关闭,内容直达用户,后验证作为安全网兜底。
文档处理不是一次性后台协程,而是带持久状态的任务:
- 保存任务类型、参数、执行次数和心跳;
- 异常后进入重试等待;
- 超过最大次数进入死信状态;
- 服务重启后恢复未完成任务;
- OCR 尚未就绪时进入明确等待状态;
- 删除、恢复和重建同时维护文件、SQLite、Qdrant 与 BM25 一致性;
- 索引失败时同时清理 Qdrant 和 BM25(防止孤儿向量污染搜索结果);
- 删除文档采用 SQLite 优先策略(先删记录,best-effort 清理外部存储);
- 清空全部文档原子执行(先批量删 SQLite,再逐文档清理外部存储)。
- 上传文件、SQLite、Qdrant、BM25 和模型缓存默认保存在本地;
- 业务 API 使用 JWT Bearer 鉴权;
- Refresh Token 只保存在
HttpOnly + SameSite=LaxCookie; - 前端 JavaScript 无法读取 Refresh Token;
- 修改密码后旧 Refresh Token 自动失效;
- 支持基础角色和系统管理员权限检查;
- 默认只监听
127.0.0.1。
- 企业制度、操作手册、产品资料和技术文档问答;
- 项目资料、研究报告和会议纪要检索;
- 错误码、接口字段、型号和配置项精确查询;
- 多文档对比、内容总结和关键事实抽取;
- 需要显示来源和引用位置的专业问答;
- 对文档本地保存、权限控制和结果可追溯有要求的知识库;
- 希望研究 RAG、Agent、混合检索和引用校验实现的开发者。
- 单文件与批量上传;
- 流式写入磁盘,避免大文件一次性进入内存;
- SHA-256 内容重复检测;
- 文档解析、切片、Embedding 和索引;
- 实时显示上传与处理进度;
- 文档删除、重新处理和集合重建;
- Qdrant 与 BM25 双索引;
- 文档状态持久化;
- 服务端文件数量和容量限制;
- 备份与恢复。
- Qdrant 语义检索;
- SQLite BM25 关键词检索;
- 中文分词及精确代码保留;
- 查询类型分类;
- 错误码、数字、货币、时间和实体消歧;
- 可选查询改写;
- 加权 Reciprocal Rank Fusion;
- 跨文档重复内容过滤;
- Chunk 质量预过滤;
- 可选 Cross-Encoder Reranker;
- 单路检索故障降级。
- 自研 ReAct 工具循环,模型自主推理决策;
- 模型根据问题类型自行选择工具、组合调用、评估结果;
- 意图分类精简为 person_memory / general_chat,不再硬编码工具推荐;
- 系统提示词从"规则手册"改为"角色+能力+原则",强调观察→判断→行动;
- 知识库检索不足时,Agent 可自主升级到联网搜索(
web_search); - 同工具连续调用 ≥3 次自动收敛,防止搜索死循环;
- 多工具并行调用;
- 参数校验与结构化错误;
- 工具级超时与重试策略;
- 客户端断连取消;
- 循环次数与总耗时限制;
- 上下文溢出渐进恢复;
- 工具结果压缩和不可信内容隔离;
- 答案后验证(引用校验、数字匹配、确定性和 LLM 修复)保持 RAG 正确性底线;
- Safety guard 从正则替换改为通知式(信任模型自我修正);
- 流验证默认关闭(内容直达用户,后验证兜底)。
内置工具包括:
| 工具 | 用途 | 说明 |
|---|---|---|
search_docs |
检索本地知识库 | Qdrant + BM25 混合检索 |
web_search |
联网检索 | KB 不足时 Agent 自主升级,结果纳入 WS 引证体系 |
calculator |
数学计算 | 安全沙箱,支持四则运算和常用函数 |
list_documents |
查看知识库文档 | 返回文件名、类型、状态和上传时间 |
get_document_info |
获取单个文档详情 | 分块数、状态、错误信息 |
recall_memory |
读取用户长期记忆 | 画像搜索和上下文召回 |
Agent 根据问题类型(常识/知识库/计算/记忆)自主决定调用哪些工具。知识库检索不足时,可自动升级到 web_search 补充信息,无需用户干预。
- SSE 流式输出;
- 工具调用过程卡片;
- 来源列表与引用展示;
- Markdown 与表格渲染;
- 引用精确率、引用完整度与事实覆盖检查;
- 对无证据问题选择性拒答;
- 对话创建、切换、重命名和删除;
- 文档管理页面;
- 设置页面;
- 记忆管理页面;
- 登录、可选修改密码和退出登录。
- Tokenizer 感知的上下文预算;
- 系统提示、工具定义、历史消息和输出预留统一计费;
- 工具调用和工具结果原子裁剪;
- 被裁剪历史的有界摘要;
- 摘要指纹、水位和并发保护;
- 用户偏好、决定、身份和项目事实提取;
- 精确匹配、向量相似度和字符串相似度三级去重;
- 访问频率与最近时间加权保留。
- 核心健康检查;
- LLM、Embedding、Qdrant、OCR 和 Reranker 依赖状态;
- Prometheus 格式指标;
- 结构化日志;
- 审计日志;
- 后台任务状态;
- 数据库迁移和迁移前快照;
- 发布质量门禁;
- Docker E2E 验收脚本。
flowchart LR
U["用户浏览器"] --> F["React 19 前端"]
F -->|"JWT / SSE"| A["FastAPI API"]
A --> G["ReAct Agent(自主推理)"]
A --> I["文档入库任务"]
A --> D["SQLite / Alembic"]
I --> P["解析 / OCR / 切片"]
P --> V["Qdrant 向量索引"]
P --> B["SQLite BM25"]
G --> S["工具执行:search_docs / web_search / list_docs / calculator / recall_memory"]
S --> V
S --> B
V --> R["RRF / 去重 / 精排"]
B --> R
R --> L["LLM 生成"]
L --> C["后验证:引用校验 + 确定性/LLM 修复"]
C -->|"流式回答"| F
G --> M["上下文摘要与长期记忆"]
G --> LD["循环检测:≥3 次同工具自动收敛"]
主要目录:
RAG-ReActAgent/
├── main.py 统一启动后端和前端
├── backend/
│ ├── main.py FastAPI 应用与生命周期
│ ├── api/ 文档、聊天、会话、用户、备份等接口
│ ├── agent/ Agent 循环、上下文、工具和回答校验
│ ├── rag/ 加载、切片、查询分类、检索与消歧
│ ├── embedding/ Embedding 抽象
│ ├── llm/ LLM 抽象
│ ├── textdb/ SQLite BM25
│ ├── vectordb/ Qdrant
│ ├── reranker/ 可选 Cross-Encoder 精排
│ ├── ocr/ 可选 OCR
│ ├── memory/ 长期记忆与用户画像
│ ├── worker/ 持久后台任务
│ ├── alembic/ 数据库迁移
│ ├── tests/ 单元、集成、质量和发布门禁测试
│ └── tools/ 可选模型下载等工具
├── frontend/
│ ├── src/api/ API 与 SSE 客户端
│ ├── src/components/ 页面和组件
│ ├── src/stores/ Zustand 状态
│ └── e2e/ Playwright 场景
├── scripts/ Docker 验收与性能基准
└── docs/ 对外项目文档
上传文件
→ 检查扩展名、数量和容量
→ 流式写入临时对象
→ 计算 SHA-256 并检查重复
→ 创建文档记录和持久任务
→ 解析正文
→ 必要时执行 OCR
→ 按段落、标题和表格边界切片
→ 批量生成 Embedding
→ 写入 Qdrant
→ 写入 SQLite BM25
→ 更新文档状态
→ 前端收到完成进度
切片默认使用 200 Token 大小和 40 Token 重叠。系统优先在段落、Markdown 标题和句号附近切分,并尽量避免破坏表格。
用户问题
→ LLM 意图分类(仅识别 personal_memory / general_chat)
→ Agent 自主决定调用哪些工具
→ 并行语义检索与关键词检索(Qdrant + BM25)
→ RRF 融合
→ 消歧、去重和质量过滤
→ 可选 Reranker
→ 形成 Top-K 证据
→ Agent 评估结果:充分则回答,不足则升级到 web_search 或其他工具
→ 同工具 ≥3 次自动收敛,强制生成文本回答
→ 答案后验证(引用校验、数字匹配、确定性和 LLM 修复)
→ SSE 流式返回
→ 保存消息、来源和校验结果
Agent 在 ReAct 循环中自主决策:观察→判断→调用→评估→决定下一步。系统保留三个硬约束层(循环上限、上下文裁剪、后验证)确保安全,其余工具选择和执行策略交给模型。
当前上传 API 支持:
| 格式 | 扩展名 |
|---|---|
.pdf |
|
| Word | .docx |
| 文本 | .txt |
| Markdown | .md |
| CSV | .csv |
| Excel | .xlsx |
默认限制:
| 项目 | 默认值 | 可配置范围 |
|---|---|---|
| 单文件大小 | 200 MB | 1–512 MB |
| 单批文件数量 | 50 | 2–200 |
| 单批总容量 | 1024 MB | 1–10240 MB |
| 入库并发数 | 3 | 正整数 |
扫描 PDF 需要 OCR。文件大小上限只是上传边界,不代表推荐把 512 MB 文件直接作为常规输入;大文件还会消耗 OCR、切片、Embedding 和索引时间。
基础本地开发环境:
- Python 3.12;
- Node.js 22.22 或更高版本;
- npm;
- Windows、Linux 或 macOS;
- 至少一个可用的 OpenAI 兼容 LLM 与 Embedding 服务,才能执行完整知识问答。
Docker 部署额外需要:
- Docker;
- Docker Compose。
克隆项目并创建配置:
git clone https://github.com/MoMoM101/RAG-ReActAgent.git
cd RAG-ReActAgent
cp backend/.env.example backend/.envWindows PowerShell 可以使用:
Copy-Item backend/.env.example backend/.env.env.example 已提供合理默认值:
JWT_SECRET— 首次启动时自动生成并写入.envBOOTSTRAP_ADMIN_PASSWORD— 默认RAGAgent2026!(首次登录后建议修改)
LLM 和 Embedding 的 Key 可启动后在设置页面配置,无需提前写入 .env。
在项目根目录创建虚拟环境:
python -m venv .venv激活虚拟环境:
# Windows PowerShell
.venv\Scripts\Activate.ps1
# Windows cmd
.venv\Scripts\activate.bat
# Linux / macOS
source .venv/bin/activate安装基础后端依赖:
pip install -r backend/requirements.txt可选安装:
# 开发、测试、Ruff 和 MyPy
pip install -r backend/requirements-dev.txt
# Reranker
pip install -r backend/requirements-rerank.txt
# OCR
pip install -r backend/requirements-ocr.txt安装前端依赖:
cd frontend
npm install
cd ..启动:
python main.py统一启动器会:
- 检查环境和端口;
- 启动后端;
- 等待核心 FastAPI 服务就绪;
- 启动前端;
- 输出 Web、设置页和 API 文档地址;
- 在退出时关闭子进程。
OCR 和 Reranker 默认关闭(OCR_ENABLED=false / RERANK_ENABLED=false),不下载模型也不阻塞启动。
如需启用,先安装对应依赖,再将配置改为 true,然后重启:
# OCR(扫描 PDF / 图片中的文字)
pip install -r backend/requirements-ocr.txt
# 在 backend/.env 设置 OCR_ENABLED=true
# Reranker(提升搜索精度)
pip install -r backend/requirements-rerank.txt
# 在 backend/.env 设置 RERANK_ENABLED=true启用后首次启动时模型会在后台下载,不影响核心服务就绪。
默认地址:
- 前端:http://localhost:5173
- 后端:http://localhost:8000
- OpenAPI:http://localhost:8000/docs
- 健康检查:http://localhost:8000/api/health
- 依赖状态:http://localhost:8000/api/health/dependencies
确保已克隆项目并创建 backend/.env 配置(见方式一的前两步),然后:
docker compose --env-file backend/.env up -d查看状态:
docker compose ps
docker compose logs -f backend停止:
docker compose downDocker 基础镜像默认不安装 OCR 扩展依赖,DOCKER_OCR_ENABLED 默认关闭。需要 OCR 时应构建包含 requirements-ocr.txt 及相应系统依赖的镜像。
后端:
cd backend
..\.venv\Scripts\python.exe -m uvicorn main:app --host 127.0.0.1 --port 8000 --reloadLinux 或 macOS:
cd backend
../.venv/bin/python -m uvicorn main:app --host 127.0.0.1 --port 8000 --reload前端:
cd frontend
npm run dev当用户表为空时,后端根据以下变量创建首个管理员:
BOOTSTRAP_ADMIN_USERNAME=admin
BOOTSTRAP_ADMIN_PASSWORD=RAGAgent2026!后续启动不会使用环境变量覆盖数据库中已有用户的密码。
RAGAgent2026! 是公开的临时初始密码,仅用于首次启动;首次登录后请立即通过登录页旁的”修改密码”入口更换。
- Access Token 保存在当前页面的
sessionStorage; - Refresh Token 保存在 HttpOnly Cookie;
- Cookie 默认有效 7 天;
- 刷新页面不需要重新登录;
- 关闭页面或浏览器后,Cookie 未过期时可以自动恢复登录;
- 退出登录会调用后端接口清除 Cookie;
- 修改密码会使旧 Refresh Token 失效。
登录页面提供可选的“修改密码”入口,用户可以自行选择是否修改。设置页面也提供账户安全入口。
修改时需要:
- 输入用户名;
- 验证当前密码;
- 两次输入相同的新密码;
- 新密码不能为空且不能与当前密码完全相同。
密码修改接口不限制字符类型,并支持超过 bcrypt 原生 72 字节限制的长密码。
本地 HTTP:
AUTH_COOKIE_SECURE=false正式 HTTPS:
AUTH_COOKIE_SECURE=true公网环境必须使用 HTTPS,否则不应提供持久登录。
完整模板见 backend/.env.example,全部字段定义见 backend/config.py。
| 变量 | 默认值 | 说明 |
|---|---|---|
LLM_PROVIDER |
openai |
Provider 标识 |
LLM_MODEL |
gpt-4o |
模型名称 |
LLM_BASE_URL |
OpenAI 地址 | OpenAI 兼容接口 |
LLM_API_KEY |
空 | 调用密钥 |
LLM_MAX_CONTEXT |
0 |
0 表示自动识别 |
LLM_OUTPUT_TOKEN_RESERVE |
4096 |
回答预留 |
LLM_REASONING_TOKEN_RESERVE |
0 |
推理预留 |
LLM_CONNECT_TIMEOUT |
10 |
建连超时,秒 |
LLM_READ_TIMEOUT |
60 |
读取超时,秒 |
LLM_FIRST_TOKEN_TIMEOUT |
30 |
首 Token 超时,秒 |
| 变量 | 默认值 | 说明 |
|---|---|---|
EMBEDDING_PROVIDER |
openai |
Provider 标识 |
EMBEDDING_MODEL |
text-embedding-3-small |
模型名称 |
EMBEDDING_BASE_URL |
OpenAI 地址 | OpenAI 兼容接口 |
EMBEDDING_API_KEY |
空 | 调用密钥 |
EMBEDDING_DIM |
1536 |
预期向量维度 |
EMBEDDING_TIMEOUT |
30 |
调用超时,秒 |
服务启动时会尝试检测实际向量维度。外部服务暂时不可用时会保留配置维度,首次成功调用后再完成检查。
| 变量 | 默认值 | 说明 |
|---|---|---|
CHUNK_SIZE |
200 |
分块 Token 数 |
CHUNK_OVERLAP |
40 |
相邻块重叠 |
RETRIEVAL_TOP_K |
8 |
最终检索数量 |
RRF_K |
60 |
RRF 平滑常量 |
RRF_SEMANTIC_WEIGHT |
2.0 |
语义检索权重 |
RRF_KEYWORD_WEIGHT |
1.0 |
关键词检索权重 |
DEDUP_ENABLED |
true |
内容去重 |
DEDUP_SIMILARITY_THRESHOLD |
0.85 |
重复相似度阈值 |
QUERY_REWRITE_ENABLED |
true |
启用查询改写 |
CHUNK_QUALITY_FILTER_ENABLED |
true |
启用 Chunk 质量过滤 |
| 变量 | 默认值 | 说明 |
|---|---|---|
RERANK_ENABLED |
false |
启用精排 |
RERANK_MODEL |
BAAI/bge-reranker-v2-m3 |
精排模型 |
RERANK_TOP_N |
16 |
精排候选数 |
OCR_ENABLED |
true |
本地运行时启用 OCR |
OCR_MIN_TEXT_LENGTH |
50 |
PDF 文本不足时触发 OCR |
OPTIONAL_MODEL_NOTICE_SECONDS |
180 |
后台加载提示阈值 |
OPTIONAL_MODEL_NOTICE_SECONDS 不是下载超时。超过该时间后,模型仍可继续下载或加载。
手动预下载:
cd backend
..\.venv\Scripts\python.exe -m tools.download_models --ocr --reranker| 变量 | 默认值 | 说明 |
|---|---|---|
DOCUMENT_MAX_UPLOAD_MB |
200 |
单文件容量 |
DOCUMENT_BATCH_MAX_FILES |
50 |
单批文件数量 |
DOCUMENT_BATCH_MAX_TOTAL_MB |
1024 |
单批总容量 |
INGESTION_MAX_CONCURRENCY |
3 |
入库并发 |
INGESTION_MAX_RETRIES |
3 |
最大入库尝试次数 |
INGESTION_RETRY_BASE_SEC |
5 |
初始退避 |
INGESTION_RETRY_MAX_SEC |
300 |
最大退避 |
| 变量 | 默认值 | 说明 |
|---|---|---|
JWT_SECRET |
空 | 必须固定,至少 32 字符 |
JWT_ACCESS_TOKEN_EXPIRE_MINUTES |
60 |
Access Token 有效期 |
JWT_REFRESH_TOKEN_EXPIRE_DAYS |
7 |
Refresh Cookie 有效期 |
AUTH_COOKIE_SECURE |
false |
HTTPS 部署设为 true |
BOOTSTRAP_ADMIN_USERNAME |
admin |
首次管理员用户名 |
BOOTSTRAP_ADMIN_PASSWORD |
RAGAgent2026! |
默认密码,首次登录后建议修改 |
SERVER_HOST |
127.0.0.1 |
监听地址 |
ALLOW_REMOTE_ACCESS |
false |
是否允许远程访问 |
LOG_LEVEL |
INFO |
日志等级 |
不要把真实 .env、API Key、JWT Secret 或管理员密码提交到 Git。
打开 http://localhost:5173,输入管理员用户名和密码。
可以直接修改 backend/.env,也可以在设置页配置 LLM 与 Embedding。
建议先确认:
- LLM 地址和模型名称正确;
- Embedding 地址和模型名称正确;
- Embedding 维度与现有集合一致;
/api/health/dependencies中对应组件可用。
进入“知识库”页面:
- 选择单个或多个文件;
- 前端读取服务端容量限制;
- 上传后观察处理状态;
- 等待状态变为
ready; - 若状态为
waiting_for_ocr,等待 OCR 就绪或手动预下载模型; - 若状态为
failed,查看错误并重新处理。
进入“对话”页面,可以提问:
- “总结这份文档的主要内容”;
- “ERR_40005 是什么错误?”;
- “对比文档 A 和文档 B 的核心差异”;
- “列出所有涉及金额和时间的条款”;
- “这个结论来自哪一段?”。
回答下方会显示来源。对于精确代码、数字和型号,建议在问题中保留原始写法。
系统可以从对话中识别长期有用的身份、偏好、决定和项目事实。进入“记忆”页面可以查看和删除已保存内容。
备份与恢复不仅处理 SQLite,还会检查文件、Schema Revision、内容哈希和索引一致性。恢复前建议停止写入,并保留独立备份副本。
详细流程见 项目参考。
适用范围: 当前指标来自项目自建的固定合成数据集。93 条正式结果使用了包含开发子集在内的全量基准,尚不是严格隔离的 held-out test;它不能直接外推到任意真实业务文档。数据构成、复现命令、消融、失败案例和待补项见 评测方法与复现说明。
正式报告:
backend/tests/grounded_answer_eval_final_full_rescored.json
评测参数:
| 项目 | 数值 |
|---|---|
| 完成问题 | 93 |
| 可回答问题 | 66(70.97%) |
| 不可回答问题 | 27(29.03%) |
| 模型调用 | 191 / 200 |
| 平均总延迟 | 1,990.28 ms |
| 总延迟 P95 | 4,759.69 ms |
| 首 Token 延迟 P95 | 746.89 ms |
最后一次完整在线运行保留了真实 draft 与 TTFT;multi-hop-001 和 multi-hop-004 的 LLM 修复均超时且未产生替换文本,正式报告仅对这两个本地后处理阶段按当前确定性策略进行了可审计 replay。原始阶段耗时、replay 标记、原因和 query id 均保存在报告中。
数据集 rag-agent-eval-v2 包含 4 个合成文档、93 条人工标注查询,覆盖精确字段、跨文档、数值、中英混合、长查询、不可回答、歧义、提示词注入、拼写错误等类型。数据、预期事实、必须引用项和可回答性标签均在 qrels_data_v2.json 中公开。
与不强制引用的控制组相比:
| 指标 | 控制组 | 当前版本 | 提升 |
|---|---|---|---|
| 忠实度 | 72.35% | 100.00% | +27.65 个百分点 |
| 拒答准确率 | 44.44% | 100.00% | +55.56 个百分点 |
| 预期事实召回 | 85.31% | 85.21% | -0.10 个百分点 |
| 回答完成度 | 80.65% | 100.00% | +19.35 个百分点 |
| 平均总延迟 | 3,465.77 ms | 1,990.28 ms | -42.57% |
正式报告:
backend/tests/evaluation_results_complex_v2.json
该报告使用 9 个支付、传感器和合规类合成文档、29 条复杂和跨文档查询,qrels_fallback_count=0,所有查询均使用显式 qrels 标注。
评测参数:
| 参数 | 数值 |
|---|---|
| Embedding | Qwen text-embedding-v2 |
| 向量维度 | 1536 |
| Chunk Size / Overlap | 200 / 40 |
| Retrieval Top-K | 10 |
| Rerank Top-N | 24 |
| RRF K | 30 |
| 语义 / 关键词权重 | 2.0 / 1.0 |
评测结果:
| 指标 | Top-3 | Top-5 | Top-10 |
|---|---|---|---|
| Recall | 88.65% | 92.96% | 99.57% |
| Hit Rate | 100.00% | 100.00% | 100.00% |
| NDCG | 92.80% | 93.17% | 95.13% |
报告同时包含 semantic-only、keyword-only、hybrid-no-rerank 和 hybrid-rerank 四组消融。在当前小型合成集上,混合检索的 NDCG@5 为 93.17%,高于语义单路的 90.72% 和关键词单路的 75.99%;Reranker 没有带来可见质量提升。完整表格和限制见 评测方法与复现说明。
从 backend 目录执行:
# 无外部模型调用:检查数据、qrels、BM25 索引和基础命中
python -m tests.run_grounded_answer_eval --dry-run
# 完整回答质量评测:需要配置 LLM,最多 200 次模型调用
python -m tests.run_grounded_answer_eval `
--output tests/grounded_answer_eval_reproduced.json `
--max-model-calls 200 `
--concurrency 2 `
--enforce-gate
# 复杂检索与四组消融:需要配置 Embedding、Qdrant 和可选 Reranker
python tests/complex_eval_runner.py
# 校验已有正式报告;该命令不会重新调用模型
python release_gate.pycomparison-003询问 DRF 与 FastAPI 的优劣,但资料没有直接给出完整比较结论;确定性摘录保持 100% 忠实度,但该样本预期事实召回仅 20%;- optimized 组有 24 条记录未达到 100% 的预期事实召回,总体 expected fact recall 为 85.21%,因此引用指标不能替代事实覆盖率;
- 当前 dev 子集和 93 条正式结果来自同一数据集,没有严格隔离的冻结 test;
- 当前支付、传感器、合规和药品语料均为人工编写的业务风格合成文本,不是真实客户文档;
- 独立 held-out test、多人标注一致性和真实授权脱敏业务集仍待补充。
评测百分比必须与数据集、模型、参数和报告中的 provenance 一起理解。修改检索器、提示词、数据集或模型后,应重新生成报告。
2026-08-21 本地代码质量验证记录(Docker E2E 保留最近发布快照):
| 项目 | 结果 |
|---|---|
| 后端收集测试 | 1,046 项 |
| 离线测试选择 | 1,037 项 |
| 后端通过 | 1,026 项 |
| 后端跳过 | 11 项 |
| 真实模型与 Docker 标记排除 | 9 项 |
| 已执行测试通过率 | 100.00%(1,026 / 1,026) |
| 后端代码覆盖率 | 73.13%(含分支覆盖) |
| 前端 Vitest | 70 / 70,100% |
| 前端 Oxlint | 通过 |
| TypeScript 与生产构建 | 通过 |
| Python 基础依赖审计 | 0 个已知漏洞 |
| npm 生产依赖审计 | 0 个已知漏洞 |
| Docker E2E | 12 / 12 阶段通过 |
| Docker 严格冒烟测试 | 5 / 5 通过 |
离线统计主动排除了需要真实 LLM、Embedding 或运行中 Docker 环境的测试。真实模型链路已在 Docker E2E 中通过两条带引用的 SSE 问答验证;它不替代针对不同 Provider 的独立兼容性测试。
离线和本地测试:
cd backend
pytest -m "not docker and not needs_llm and not needs_embedding"包含代码覆盖率:
pytest -m "not docker and not needs_llm and not needs_embedding" \
--cov=. --cov-config=.coveragerc --cov-report=term-missing连接真实模型后执行全部非 Docker 测试:
pytest -m "not docker"代码检查:
ruff check .
mypy . --config-file ../pyproject.tomlcd frontend
npm test
npm run lint
npm run build需要运行后端的浏览器场景:
npm run test:e2eDocker 仅在运行 Compose 或 Docker E2E 时必需:
.\scripts\docker_e2e_acceptance.ps1 -Clean2026-07-23 的验收测试中,配置、构建、健康检查、密钥检查、JWT 鉴权、文档上传、索引一致性、SSE 问答、重启持久化、备份恢复、Qdrant 降级恢复和严格冒烟测试全部通过,测试容器和卷已在结束后清理。
默认本地数据包括:
- SQLite:用户、会话、消息、文档状态、任务和配置元数据;
- Qdrant:文档向量;
- SQLite BM25:关键词索引;
- Upload 目录:上传原文件;
- 模型缓存:OCR 和 Reranker;
- 日志和备份。
删除单个文件不一定等于删除所有相关数据。完整删除需要同时处理文件、SQLite、Qdrant、BM25、缓存和备份。
启用外部服务时,以下内容可能发送给相应供应商:
- 用户问题;
- 文档切片;
- 检索上下文;
- Embedding 文本;
- 查询改写内容;
- 可选 Web Search 查询。
使用前应确认数据是否允许离开本机。
- 生产环境使用 HTTPS;
- 设置固定且随机的
JWT_SECRET; - 设置独立的
SECRET_KEY; - 设置
AUTH_COOKIE_SECURE=true; - 不暴露 Qdrant 端口;
- 使用防火墙和反向代理;
- 限制备份文件访问;
- 定期轮换 API Key;
- 不在日志或 Git 中保存密钥;
- 对公网部署增加监控、告警和访问审计。
OCR 和 Reranker 有独立生命周期:
disabled → downloading → loading → ready
└→ failed / missing_dependency
可选模型失败时:
- 核心健康检查仍可用;
- Reranker 回退到 RRF 顺序;
- 需要 OCR 的扫描 PDF 进入等待状态;
- 模型就绪后恢复等待任务;
- 设置页显示失败原因和手动处理命令。
任务保存:
- 类型;
- JSON 参数;
- 尝试次数;
- 心跳;
- 下次重试时间;
- 状态;
- 错误信息。
异常任务执行指数退避,达到上限后进入死信状态。
- 使用 Alembic 管理 Revision;
- 自动迁移前创建 SQLite 快照;
- 未知或不安全状态拒绝盲目 stamp;
- 迁移失败时恢复快照;
- 迁移备份按数量清理。
恢复包会检查:
- 归档路径安全;
- 文件数量;
- 解压后总容量;
- Schema Revision;
- SHA-256;
- Qdrant 集合指针;
- 文档文件一致性。
先检查:
curl http://localhost:8000/api/health然后查看后端日志。Embedding 自动维度检测失败、OCR 或 Reranker 下载慢,不应阻止核心服务启动。
检查:
LLM_API_KEY是否配置;LLM_BASE_URL和LLM_MODEL是否正确;EMBEDDING_API_KEY是否配置;- Embedding 维度是否与集合一致;
/api/health/dependencies的依赖状态;- 当前文档是否已经进入
ready。
说明文档正文不足,需要 OCR,但 OCR 模型尚未就绪。可以等待后台加载,或运行:
cd backend
..\.venv\Scripts\python.exe -m tools.download_models --ocrReranker 是可选组件。失败时系统继续使用 Qdrant、BM25 和 RRF。可以配置 HF_ENDPOINT 后重新下载:
cd backend
..\.venv\Scripts\python.exe -m tools.download_models --reranker通常不需要。Refresh Cookie 默认保留 7 天。以下情况需要重新登录:
- 主动退出;
- Cookie 过期;
- 浏览器清除 Cookie;
- 修改密码导致旧 Refresh Token 失效;
- JWT Secret 被轮换。
不是。只有 Docker Compose 部署和 Docker E2E 需要 Docker。本地开发可以直接使用项目根目录的 main.py。
不同模型可能产生不同维度的向量。切换 Embedding 模型后,应先检查维度,再通过设置页或管理接口重建集合。
这是一个始于 2026-06-24 的个人独立开发项目。需求定义、架构取舍、代码集成、环境调试、测试评测和开源发布均由仓库所有者个人负责;开发过程中使用 Claude Code、Codex 等 AI 编码助手进行方案讨论、局部代码草拟、测试补充、排错和文档整理,所有进入仓库的内容均由开发者选择、审查、集成并承担最终责任。
公开分支于 2026-07-23 建立。根提交 5a939d2 是从此前开发工作区整理出的首个开源快照,因此一次加入了 389 个文件、84,037 行;这表示首次公开的代码量,不表示项目在一次提交中从零生成。根提交和部分发布整理提交中的 RAG Agent Contributors、RAG Agent Dev 是同一位个人开发者在开源整理阶段使用的通用本地 Git 身份,不代表未披露的开发团队。后续提交已改用仓库所有者身份,旧提交为保持公开哈希稳定未重写。
开发者主导设计和集成的核心范围包括:文档入库与失败恢复、Qdrant + BM25 + RRF 混合检索、ReAct 工具循环与上下文预算、引用与回答校验、跨存储一致性、JWT 认证、数据库迁移与备份恢复,以及 qrels 和发布质量门禁。
完整的 AI 使用边界、核心模块、公开前开发阶段和版本时间线见 项目来源与开发说明。
| 文档 | 内容 |
|---|---|
| 项目介绍 | 项目优势、量化指标和对外介绍 |
| 项目参考 | 架构、配置、数据、安全、运维和故障排查 |
| 项目来源与开发说明 | 个人开发、首次开源快照、AI 使用边界和版本时间线 |
| 评测方法与复现说明 | 数据集、标注、隔离边界、命令、消融和失败案例 |
| 贡献指南 | 开发流程、测试命令和提交规范 |
| 安全策略 | 漏洞私下报告方式和部署安全边界 |
| 更新日志 | 版本能力、验证结果和已知限制 |
| 社区行为准则 | 社区协作和维护规则 |
| 测试数据来源 | 合成夹具、qrels 和评测数据的来源与许可 |
| 环境变量模板 | 完整配置字段 |
| 许可证 | MIT License |
欢迎提交 Issue 和 Pull Request。
建议流程:
- Fork 仓库;
- 从目标分支创建功能分支;
- 完成代码和测试;
- 运行后端与前端检查;
- 使用清晰的 Conventional Commit;
- 提交 Pull Request 并说明行为变化、验证结果和兼容性影响。
提交前至少确认:
- 没有提交
.env、API Key、密码或本地数据; - 新功能包含测试;
- 后端 Ruff、MyPy 和相关 Pytest 通过;
- 前端测试、Lint 和生产构建通过;
- 文档与配置模板同步;
- 数据库变更包含 Alembic Revision;
- 评测逻辑没有使用运行结果反向生成 ground truth。
本项目使用 MIT License。
