固定题库 + 固定 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.2cd 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:8001id, 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_*.csv 的 pass 列与通过率。
默认 关闭(RERANK_ENABLED=false),CI / 日常 golden 不打外网 rerank。
后端单测 tests/test_rerank_rank_eval.py 用 fake 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 -qRERANK_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 序,不会整句炸掉。