Skip to content

Repository files navigation

RAG Agent:本地知识库智能助手

一个强调检索质量、证据引用、回答校验、任务恢复和本地数据边界的开源 RAG Agent。

Python React 许可证 Faithfulness Citation CI Version Docker

RAG Agent 是一个本地优先的文档知识库与智能问答系统。用户上传文档后,可以直接使用自然语言提问;系统会完成意图识别、查询消歧、混合检索、工具调用、证据组织、流式回答和引用校验。

它不仅是“上传文档后调用一次大模型”,而是一套覆盖文档入库、检索、生成、校验、持久化、恢复、认证和评测的完整工程链路。

当前阶段:v0.2.1-beta

5 分钟了解项目

核心能力 项目中的实现
检索质量 Qdrant 语义检索 + SQLite BM25 + 加权 RRF + 可选 Reranker
Agent 推理 自研 ReAct 循环、多工具并行、上下文预算、循环收敛与长期记忆
回答可信度 来源卡片、行内引用、数字一致性检查、拒答与有界回答修复
工程可靠性 持久入库任务、重启恢复、Alembic、备份恢复、JWT、SSE 与发布门禁

快速入口:产品演示 · 一键启动 · 系统架构 · 评测结果 · v0.2.1-beta 发布说明 · 完整项目参考

产品演示

RAG Agent 跨 Word 与 PDF 检索、恢复步骤和 SLA 条件判断

演示展示了跨 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 -d

Windows PowerShell 将第三行替换为:

Copy-Item backend/.env.example backend/.env

打开 http://localhost:5173

默认首次登录用户名:

admin

默认首次登录密码:

RAGAgent2026!

建议登录后立即修改密码,并在设置页填写 LLM 与 Embedding 配置。

本地部署:源码构建、本地开发和 OCR 安装方式见快速开始

评测摘要

回答评测(93 条受控问答) 结果
回答忠实度 / 引用精确率 100.00% / 99.62%
拒答准确率 100.00%
首 Token / 总延迟 P95 746.89 / 4,759.69 ms

指标来自包含开发子集的固定合成基准,不是严格隔离的 held-out test,也不能直接外推到任意业务数据。完整口径、失败案例与复现方法见评测方法

目录

项目亮点

可量化的回答质量

当前正式在线评测包含 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=Lax Cookie;
  • 前端 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;
  • 单路检索故障降级。

Agent

  • 自研 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 次同工具自动收敛"]
Loading

主要目录:

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 .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/.env

Windows PowerShell 可以使用:

Copy-Item backend/.env.example backend/.env

.env.example 已提供合理默认值:

  • JWT_SECRET — 首次启动时自动生成并写入 .env
  • BOOTSTRAP_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

统一启动器会:

  1. 检查环境和端口;
  2. 启动后端;
  3. 等待核心 FastAPI 服务就绪;
  4. 启动前端;
  5. 输出 Web、设置页和 API 文档地址;
  6. 在退出时关闭子进程。

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

启用后首次启动时模型会在后台下载,不影响核心服务就绪。

默认地址:

方式二:Docker Compose

确保已克隆项目并创建 backend/.env 配置(见方式一的前两步),然后:

docker compose --env-file backend/.env up -d

查看状态:

docker compose ps
docker compose logs -f backend

停止:

docker compose down

Docker 基础镜像默认不安装 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 --reload

Linux 或 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 字节限制的长密码。

HTTPS 部署

本地 HTTP:

AUTH_COOKIE_SECURE=false

正式 HTTPS:

AUTH_COOKIE_SECURE=true

公网环境必须使用 HTTPS,否则不应提供持久登录。

配置说明

完整模板见 backend/.env.example,全部字段定义见 backend/config.py

LLM

变量 默认值 说明
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

变量 默认值 说明
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 质量过滤

Reranker 与 OCR

变量 默认值 说明
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。

使用指南

1. 登录

打开 http://localhost:5173,输入管理员用户名和密码。

2. 配置模型

可以直接修改 backend/.env,也可以在设置页配置 LLM 与 Embedding。

建议先确认:

  • LLM 地址和模型名称正确;
  • Embedding 地址和模型名称正确;
  • Embedding 维度与现有集合一致;
  • /api/health/dependencies 中对应组件可用。

3. 上传文档

进入“知识库”页面:

  1. 选择单个或多个文件;
  2. 前端读取服务端容量限制;
  3. 上传后观察处理状态;
  4. 等待状态变为 ready
  5. 若状态为 waiting_for_ocr,等待 OCR 就绪或手动预下载模型;
  6. 若状态为 failed,查看错误并重新处理。

4. 开始问答

进入“对话”页面,可以提问:

  • “总结这份文档的主要内容”;
  • “ERR_40005 是什么错误?”;
  • “对比文档 A 和文档 B 的核心差异”;
  • “列出所有涉及金额和时间的条款”;
  • “这个结论来自哪一段?”。

回答下方会显示来源。对于精确代码、数字和型号,建议在问题中保留原始写法。

5. 管理记忆

系统可以从对话中识别长期有用的身份、偏好、决定和项目事实。进入“记忆”页面可以查看和删除已保存内容。

6. 备份与恢复

备份与恢复不仅处理 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-001multi-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.py

失败案例与已知限制

  • comparison-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.toml

前端测试

cd frontend
npm test
npm run lint
npm run build

需要运行后端的浏览器场景:

npm run test:e2e

Docker 验收

Docker 仅在运行 Compose 或 Docker E2E 时必需:

.\scripts\docker_e2e_acceptance.ps1 -Clean

2026-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 下载慢,不应阻止核心服务启动。

页面可以打开,但无法问答

检查:

  1. LLM_API_KEY 是否配置;
  2. LLM_BASE_URLLLM_MODEL 是否正确;
  3. EMBEDDING_API_KEY 是否配置;
  4. Embedding 维度是否与集合一致;
  5. /api/health/dependencies 的依赖状态;
  6. 当前文档是否已经进入 ready

上传扫描 PDF 后停在等待 OCR

说明文档正文不足,需要 OCR,但 OCR 模型尚未就绪。可以等待后台加载,或运行:

cd backend
..\.venv\Scripts\python.exe -m tools.download_models --ocr

Reranker 下载失败

Reranker 是可选组件。失败时系统继续使用 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 是否是必需的

不是。只有 Docker Compose 部署和 Docker E2E 需要 Docker。本地开发可以直接使用项目根目录的 main.py

修改 Embedding 模型后检索异常

不同模型可能产生不同维度的向量。切换 Embedding 模型后,应先检查维度,再通过设置页或管理接口重建集合。

项目来源与开发说明

这是一个始于 2026-06-24 的个人独立开发项目。需求定义、架构取舍、代码集成、环境调试、测试评测和开源发布均由仓库所有者个人负责;开发过程中使用 Claude Code、Codex 等 AI 编码助手进行方案讨论、局部代码草拟、测试补充、排错和文档整理,所有进入仓库的内容均由开发者选择、审查、集成并承担最终责任。

公开分支于 2026-07-23 建立。根提交 5a939d2 是从此前开发工作区整理出的首个开源快照,因此一次加入了 389 个文件、84,037 行;这表示首次公开的代码量,不表示项目在一次提交中从零生成。根提交和部分发布整理提交中的 RAG Agent ContributorsRAG Agent Dev 是同一位个人开发者在开源整理阶段使用的通用本地 Git 身份,不代表未披露的开发团队。后续提交已改用仓库所有者身份,旧提交为保持公开哈希稳定未重写。

开发者主导设计和集成的核心范围包括:文档入库与失败恢复、Qdrant + BM25 + RRF 混合检索、ReAct 工具循环与上下文预算、引用与回答校验、跨存储一致性、JWT 认证、数据库迁移与备份恢复,以及 qrels 和发布质量门禁。

完整的 AI 使用边界、核心模块、公开前开发阶段和版本时间线见 项目来源与开发说明

项目文档

文档 内容
项目介绍 项目优势、量化指标和对外介绍
项目参考 架构、配置、数据、安全、运维和故障排查
项目来源与开发说明 个人开发、首次开源快照、AI 使用边界和版本时间线
评测方法与复现说明 数据集、标注、隔离边界、命令、消融和失败案例
贡献指南 开发流程、测试命令和提交规范
安全策略 漏洞私下报告方式和部署安全边界
更新日志 版本能力、验证结果和已知限制
社区行为准则 社区协作和维护规则
测试数据来源 合成夹具、qrels 和评测数据的来源与许可
环境变量模板 完整配置字段
许可证 MIT License

参与贡献

欢迎提交 Issue 和 Pull Request。

建议流程:

  1. Fork 仓库;
  2. 从目标分支创建功能分支;
  3. 完成代码和测试;
  4. 运行后端与前端检查;
  5. 使用清晰的 Conventional Commit;
  6. 提交 Pull Request 并说明行为变化、验证结果和兼容性影响。

提交前至少确认:

  • 没有提交 .env、API Key、密码或本地数据;
  • 新功能包含测试;
  • 后端 Ruff、MyPy 和相关 Pytest 通过;
  • 前端测试、Lint 和生产构建通过;
  • 文档与配置模板同步;
  • 数据库变更包含 Alembic Revision;
  • 评测逻辑没有使用运行结果反向生成 ground truth。

许可证

本项目使用 MIT License


更完整的项目优势与评测参数见 项目介绍,架构、配置、运维和安全边界见 项目参考

About

RAG ReAct Agent - A Retrieval-Augmented Generation system with ReAct (Reasoning+Acting) agent loop for intelligent question answering with multi-hop reasoning

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

31 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages