Skip to content

Latest commit

 

History

History

README.md

RAG 可复现评估(Golden 20)

固定题库 + 固定 fixture 文档库,一键跑出 CSV,用于对比改检索/Prompt 前后的命中率。

目录

路径 说明
golden_20.jsonl 20 道题(库内 / 库外拒答 / 元数据)
fixtures/*.txt 评估用原文(生成 PDF 索引)
run_rag_eval.py 主脚本
dump_topk_rank.py FAISS 排序探针(无 LLM / 不走 rerank)
probe_rerank_pool.py 候选池 vs rerank 后 final_k(换模型用)
lib/scoring.py 打分逻辑
results/eval_*.csv 运行输出(默认 gitignore)
.eval_state.json 本地 kb_id(gitignore)

前置

backend/ 配置好 .env(Embedding + LLM API)。评估会真实调用模型。

可选:启用检索距离阈值(FAISS L2,越小越相似):

# 0=仅空结果拒答;建议用 golden 标定后设为 0.8~1.5
RETRIEVAL_MAX_DISTANCE=1.2

命令

cd backend

# 首次:建库 + 上传 fixture PDF + 同步索引
python ../eval/run_rag_eval.py --setup-only

# 跑 20 题(默认 direct=检索+LLM,读 .eval_state.json 中的 kb_id)
python ../eval/run_rag_eval.py

# 测完整 Agent 链路(含工具调用,流式聚合可能不完整)
python ../eval/run_rag_eval.py --mode agent

# 建库并立刻跑评估
python ../eval/run_rag_eval.py --setup

# 对已启动的 uvicorn(如 8001)发 HTTP
python ../eval/run_rag_eval.py --http --base-url http://127.0.0.1:8001

CSV 字段

id, category, question, answer, citation_count, top1_l2, latency_ms, pass, reason, model, kb_id, run_at

top1_l2:direct 模式下、距离阈值过滤前最近一条 chunk 的 FAISS L2(越小越相似),用于标定 RETRIEVAL_MAX_DISTANCE

题型

  • in_kb:答案须包含 must_contain 关键词
  • out_of_kb:期望拒答(命中拒答话术或无引用;未做距离阈值前可能仍命中弱相关 chunk)

评估模式

--mode 说明
direct(默认) query_knowledge_base 相同:检索 → Prompt → LLM
agent 完整 Agent + /api/v1/chat

迭代对比

改代码后重新 python ../eval/run_rag_eval.py,对比两次 results/eval_*.csvpass 列与通过率。

检索重排(Rerank)

默认 关闭RERANK_ENABLED=false),CI / 日常 golden 不打外网 rerank

CI 可跑的排序断言(fake)

后端单测 tests/test_rerank_rank_eval.pyfake provider:对 A-class(q07/q13/q15/q16/q20)把含 must_contain 的 gold 片段顶进 search_k;关闭重排时保持 FAISS 序、gold 不进 final_k。无需 API Key。

cd backend
python -m pytest tests/test_rerank_*.py -q

可选:真 SiliconFlow 抽查(非门禁)

RERANK_ENABLED=true
RERANK_PROVIDER=siliconflow
RERANK_API_KEY=sk-...
# 必须是文本 rerank 模型,勿填 embedding / VL-Reranker
RERANK_MODEL=Qwen/Qwen3-Reranker-8B
RERANK_RETRIEVE_K=20

然后跑评估,对比 A-class 题的 must_contain 是否变好或持平:

cd backend
python ../eval/run_rag_eval.py
# FAISS 基线(不走 rerank):gold 排第几、进不进 top-5
python ../eval/dump_topk_rank.py
# 开着重排:候选池有无 gold → rerank 后是否进 final_k(换模型时先跑这个)
python ../eval/probe_rerank_pool.py

失败时漏斗会降级为 FAISS 序,不会整句炸掉。