英文开放域问答(OpenQA)实验仓库:提供稀疏检索(BM25 / TF-IDF)、多检索器融合、RAG 批量推理、离线评测,以及一个简单的可视化演示页。
datasets/*.jsonl → build_bm25.py → artifacts/bm25.db
│
├→ build_hybrid.py --target tfidf → artifacts/tfidf.db
search.py / server.py / process_dev.py
│
└→ retrieval_runtime.py(解析 retriever/retrievers + 构建检索器/融合器)
│
└→ retriever/
- bm25.py (FTS5 BM25)
- tfidf.py (SQLite 倒排 TF-IDF)
- hybrid.py (RRF / Weighted 融合)
- rerank.py (可选 cross-encoder 重排)
.
├── README.md
├── datasets/
│ ├── dev.jsonl
│ ├── test.jsonl
│ └── wiki18_100w.jsonl
├── artifacts/
│ ├── bm25.db
│ ├── tfidf.db
├── src/
│ ├── api.py
│ ├── api_key.py
│ ├── build_bm25.py
│ ├── build_hybrid.py
│ ├── evaluate.py
│ ├── experiment_presets.py
│ ├── process_dev.py
│ ├── retrieval_runtime.py
│ ├── search.py
│ ├── server.py
│ └── retriever/
│ ├── bm25.py
│ ├── hybrid.py
│ ├── rerank.py
│ ├── tfidf.py
│ └── utils.py
├── web/
│ ├── index.html
│ ├── app.js
│ └── style.css
└── requirements.txt
- BM25(src/retriever/bm25.py):SQLite FTS5 提供全文索引,查询时由 FTS5 在底层完成 BM25 打分;支持
title_weight/body_weight字段权重。 - TF-IDF(src/retriever/tfidf.py):构建 SQLite 倒排索引
postings(token→doc_id, weight);查询时只读取 query 词对应 postings,累加余弦相似度(文档权重已做归一化)。 - 融合(src/retriever/hybrid.py):
rrf:按名次做 Reciprocal Rank Fusion,更稳健(不依赖分数尺度)。weighted:各检索器分数归一化后按权重线性加和。
- 重排(src/retriever/rerank.py):可选调用 rerank API,对候选文档做 cross-encoder 相关性重排(用于
--rerank)。 - RAG 流水线(src/process_dev.py):检索(可 query rewrite / snippet)→ 拼 prompt → 调模型 → 后处理 → 写 jsonl。
- 服务端(src/server.py):
POST /api/chat,复用process_dev.py的单条流水线,返回答案 + 检索结果(含 body/snippet)。
pip install -r requirements.txt创建 src/api_key.py:
API_KEY = "YOUR_API_KEY"BM25:
python src/build_bm25.py --resetTF-IDF(SQLite 倒排索引,默认写 artifacts/tfidf.db):
python src/build_hybrid.py --target tfidf --tfidf-index artifacts/tfidf.dbpython src/search.py "Who is Evan Morris?" --retriever bm25 --top-k 3
python src/search.py "Who is Evan Morris?" --retriever tfidf --top-k 3
python src/search.py "Who is Evan Morris?" --retrievers bm25 tfidf --fusion rrf --top-k 3- 参数含义:
query(位置参数):查询文本(例如"Who is Evan Morris?")。--retriever {bm25,tfidf,hybrid}:单一检索器模式;hybrid为内置融合检索器(更推荐直接用--retrievers明确指定组合)。--retrievers bm25 tfidf ...:多检索器模式(可同时启用多个,覆盖--retriever)。--db PATH:BM25 的 SQLite FTS5 索引路径(默认artifacts/bm25.db)。--tfidf-index PATH:TF-IDF 索引路径(默认artifacts/tfidf.db)。--fusion {rrf,weighted}:多检索器融合方式;rrf为按名次融合,weighted为归一化后按权重线性加和。--bm25-weight FLOAT:--fusion weighted时 BM25 的权重。--tfidf-weight FLOAT:--fusion weighted时 TF-IDF 的权重。--title-weight FLOAT:BM25 title 字段权重(只影响 BM25)。--body-weight FLOAT:BM25 body 字段权重(只影响 BM25)。--top-k N:返回 Top-N 检索结果。--rerank N:对检索到的 top-k 进行重排并保留 N 条(不传则关闭)。--preview-chars N:命令行打印每条结果的 body 预览最长字符数。
批量推理(示例):
python src/process_dev.py --retriever bm25 --workers 4 --limit 20 --output results/smoke/dev_bm25.txt
python src/process_dev.py --retrievers bm25 tfidf --fusion weighted --bm25-weight 0.6 --tfidf-weight 0.4 --limit 20 --output results/smoke/dev_hybrid.txt- 参数含义:
--preset NAME:应用一个实验预设(会覆盖部分默认参数;可用值见--help,默认custom)。--input PATH:输入数据集 jsonl 路径(默认datasets/dev.jsonl)。--output PATH:推理输出文件路径(jsonl,每行一条结果;默认results/no_rag/dev.txt)。--retriever {none,bm25,tfidf,hybrid}:单一检索器模式;none表示不检索(纯生成);hybrid为融合检索器。--retrievers bm25 tfidf ...:多检索器模式(可同时启用多个,覆盖--retriever)。--db PATH:BM25 的 SQLite FTS5 索引路径(默认artifacts/bm25.db)。--tfidf-index PATH:TF-IDF 索引路径(默认artifacts/tfidf.db)。--fusion {rrf,weighted}:多检索器融合方式;rrf为按名次融合,weighted为归一化后按权重线性加和。--bm25-weight FLOAT:--fusion weighted时 BM25 的权重。--tfidf-weight FLOAT:--fusion weighted时 TF-IDF 的权重。--title-weight FLOAT:BM25 title 字段权重(只影响 BM25)。--body-weight FLOAT:BM25 body 字段权重(只影响 BM25)。--top-k N:每条样本检索的候选文档数。--rerank N:对检索到的 top-k 进行重排并保留 N 条用于 RAG(不传则关闭)。--workers N:并行处理的 worker 数(用于批量推理提速)。--limit N:只处理前 N 条样例(做 smoke test 很方便)。--start-line N:从输入文件第 N 行(1-based,跳过空行后)开始处理。--query-rewrite:将原问题改写为更短的关键词查询后再检索(开关参数)。--snippet-mode:构造 RAG 上下文时用“高重叠片段”替代完整 passage(开关参数)。--cot BOOL:是否启用 chain-of-thought 分支(该参数是显式布尔值,例如--cot True;默认 False)。--method {default,entity_tree,query_decompose}:多跳检索策略选择。
评测:
python src/evaluate.py --answers datasets/dev.jsonl --responses results/smoke/dev_bm25.txt --output results/smoke/dev_bm25_metrics.txt评测指标当前包括:
- Exact Match
- Substring Match
- Average Recall
- Average Precision
- Average F1
后端:
python src/server.py前端:
python -m http.server 8000浏览器打开:
http://localhost:8000/web/index.html
- TF-IDF 构建很占磁盘:
tfidf.db可能较大,建议先用--max-docs做小规模实验;或将--tfidf-index指向空间更大的磁盘。 - 看到的“文档不完整”:语料本身按 chunk 拆分存储(wiki18_100w.jsonl),数据库返回的是该 chunk 的完整内容,不是 UI 截断。