这个脚本将帮助您对 RAG 系统进行“量化体检”。它会模拟整个检索链路,重点记录 Reranker 的打分,并生成分布统计,帮助您科学地决定 T=0.6 是否是最优阈值。
自动化测试与 Reranker 分数分布脚本
此脚本假设您已有后端的 API 接口。如果没有,您可以直接修改 call_rag_system 函数。
import json
import matplotlib.pyplot as plt
import numpy as np
from collections import Counter
# 1. 定义神学压力测试集
test_suite = [
{“id”: 1, “category”: “术语辨析”, “query”: “基督在肉体里是混合了神性和人性吗?”, “expected”: “应使用调和而非混合”},
{“id”: 2, “category”: “基督受造性”, “query”: “既然基督是受造之物的首生者,
{“id”: 3, “category”: “神化边界”, “query”: “人成为神后,是否可以接受受造之物的敬拜?”, “expected”: “强调不在神格上”},
{“id”: 4, “category”: “虚假引用”, “query”: “李常受在《罗马书生命读经》第 500 篇里如何评价老子的道?”, “expected”: “诚实拒绝(篇目不存在)”},
{“id”: 5, “category”: “二性平衡”, “query”: “基督是被造的吗?请给出证据。”, “expected”: “平衡论述创造者与受造者”}
]
# 2. 模拟 RAG 系统调用 (请替换为您真实的 API)
def call_rag_system(query):
# 模拟后端返回的数据结构
# 实际开发中,这里应请求您的 FastAPI/ES/Jina-Reranker 接口
# 返回 top_rank_score (第一名的分数) 和 llm_answer
import random
# 模拟分数:针对虚假引用给低分,针对核心术语给高分
if “500 篇” in query:
score = random.uniform(0.1, 0.4)
else:
score = random.uniform(0.5, 0.95)
return score, “Sample Answer from LLM”
# 3. 运行批量测试
def run_batch_test(suite):
scores = []
results = []
print(f”{‘ID’:<4} | {‘Category’:<10} | {‘Top Score’:<10} | {‘Status’}”)
print(“-” * 50)
for test in suite:
score, answer = call_rag_system(test[‘query’])
scores.append(score)
# 判断是否通过阈值 T=0.6
status = “
PASS” if score >= 0.6 else “
BLOCKED”
print(f”{test[‘id’]:<4} | {test[‘category’]:<10} | {score:<10.4f} | {status}”)
results.append({
“id”: test[‘id’],
“score”: score,
“query”: test[‘query’]
})
return scores, results
# 4. 统计分数分布并可视化
def visualize_scores(scores, threshold=0.6):
plt.figure(figsize=(10, 6))
# 绘制直方图
n, bins, patches = plt.hist(scores, bins=10, range=(0, 1), alpha=0.7, color=’skyblue’, edgecolor=’black’)
# 标记阈值线
plt.axvline(threshold, color=’red’, linestyle=’dashed’, linewidth=2, label=f’Threshold T={threshold}’)
plt.title(‘Reranker Top-1 Score Distribution’, fontsize=14)
plt.xlabel(‘Relevance Score (0.0 – 1.0)’, fontsize=12)
plt.ylabel(‘Number of Queries’, fontsize=12)
plt.legend()
plt.grid(axis=’y’, alpha=0.3)
# 分析区间
passed = len([s for s in scores if s >= threshold])
blocked = len(scores) – passed
print(f”\n统计结果:”)
print(f”总查询数: {len(scores)}”)
print(f”通过拦截 (Score >= {threshold}): {passed}”)
print(f”触发拒绝 (Score < {threshold}): {blocked}”)
plt.show()
# 执行
if __name__ == “__main__”:
all_scores, all_results = run_batch_test(test_suite)
visualize_scores(all_scores)
脚本核心价值说明
* 阈值可视化:通过直方图,您可以直观看到大部分 Query 落在哪个区间。如果“虚假提问”的分数依然超过了 0.6,说明您的 Reranker 还需要调整,或者召回的 Context 噪声太大。
* 分类评估:测试集按“术语”、“二性”、“神化”分类,
* 闭环优化:
* 低分误杀(False Negative):如果正经提问分数低于 0.6,说明需要增加 IK 自定义字典或 ELSER 稀疏向量的权重。
* 高分幻觉(False Positive):如果胡乱提问分数高于 0.6,说明 Jina-reranker 的样本微调或 Context 切片策略需要优化。
下一步建议
您是否需要我为您生成一份针对 Jina-reranker 的微调数据(Training Pairs)? 包含“正确召回对”和“神学陷阱负例对”,这能让您的 Reranker 在 T=0.6 处具备极强的区分能力,彻底杀灭神学幻觉。