import os import pytest os.environ.setdefault("OPENAI_API_KEY", "test-key") from yuxi.knowledge.eval.metrics import EvaluationMetricsCalculator, RetrievalMetrics def test_retrieval_metrics_use_metadata_chunk_id(): retrieved_chunks = [ {"metadata": {"chunk_id": "chunk_a"}}, {"metadata": {"chunk_id": "chunk_b"}}, ] metrics = EvaluationMetricsCalculator.calculate_retrieval_metrics( retrieved_chunks, ["chunk_b", "chunk_c"], k_values=[1, 3] ) assert metrics["recall@1"] == 0.0 assert metrics["recall@3"] == 0.5 assert metrics["f1@3"] == RetrievalMetrics.f1_score_at_k(["chunk_a", "chunk_b"], ["chunk_b", "chunk_c"], 3) def test_overall_score_uses_answer_accuracy_when_available(): # 有答案准确率时,综合得分取各题 score 的平均,且与检索指标无关 retrieval = [{"recall@10": 1.0, "f1@10": 0.2}, {"recall@10": 0.0, "f1@10": 0.0}] answers = [{"score": 1.0}, {"score": 0.0}, {"score": 1.0}, {"score": 1.0}] score = EvaluationMetricsCalculator.calculate_overall_score(retrieval, answers) assert score == 0.75 def test_overall_score_uses_recall_at_10_without_answers(): # 无答案准确率时,综合得分取各题 recall@10 的平均,不受 f1/其它 k 影响 retrieval = [ {"recall@1": 0.0, "recall@5": 0.5, "recall@10": 0.8, "f1@10": 0.1}, {"recall@1": 1.0, "recall@5": 1.0, "recall@10": 0.4, "f1@10": 0.9}, ] score = EvaluationMetricsCalculator.calculate_overall_score(retrieval, []) assert score == pytest.approx(0.6) def test_overall_score_returns_none_without_any_metrics(): score = EvaluationMetricsCalculator.calculate_overall_score([], []) assert score is None