EmpathRAG / eval /run_router_eval.py
MukulRay's picture
Implement EmpathRAG Core hybrid router
b2f5c42
Raw
History Blame Contribute Delete
2.91 kB
"""Evaluate rule routing vs lightweight ML routing."""
from __future__ import annotations
import argparse
import csv
import json
from pathlib import Path
import sys
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "src"))
from pipeline.ml_router import DEFAULT_MODEL_DIR, MLRouter # noqa: E402
from pipeline.v2_schema import SafetyTier, classify_route # noqa: E402
DEFAULT_DATASET = ROOT / "eval" / "empathrag_core_supervised.csv"
def read_rows(path: Path) -> list[dict]:
with path.open("r", encoding="utf-8-sig", newline="") as handle:
return list(csv.DictReader(handle))
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument("--dataset", type=Path, default=DEFAULT_DATASET)
parser.add_argument("--model-dir", type=Path, default=ROOT / DEFAULT_MODEL_DIR)
parser.add_argument("--split", default="test")
parser.add_argument("--output", type=Path, default=ROOT / "eval" / "router_eval_results.json")
args = parser.parse_args()
rows = [row for row in read_rows(args.dataset) if row.get("split") == args.split]
router = MLRouter(args.model_dir)
cases = []
rule_route_correct = 0
ml_route_correct = 0
ml_tier_correct = 0
for row in rows:
expected_route = row["route_label"]
expected_tier = row["safety_tier"]
rule_route = classify_route(row["query_text"], SafetyTier(expected_tier), row.get("audience_mode") or "student").route.value
pred = router.predict(row["query_text"], rule_route, expected_tier)
rule_route_correct += int(rule_route == expected_route)
ml_route_correct += int(pred.route_label == expected_route)
ml_tier_correct += int(pred.safety_tier == expected_tier)
cases.append(
{
"query_id": row["query_id"],
"query_text": row["query_text"],
"expected_route": expected_route,
"rule_route": rule_route,
"ml_route": pred.route_label,
"expected_tier": expected_tier,
"ml_tier": pred.safety_tier,
"route_confidence": pred.route_confidence,
"tier_confidence": pred.tier_confidence,
"used_ml": pred.used_ml,
"reason": pred.reason,
}
)
total = len(rows)
result = {
"summary": {
"rows": total,
"model_available": router.available,
"rule_route_accuracy": rule_route_correct / total if total else None,
"ml_route_accuracy": ml_route_correct / total if total else None,
"ml_tier_accuracy": ml_tier_correct / total if total else None,
},
"cases": cases,
}
args.output.write_text(json.dumps(result, indent=2), encoding="utf-8")
print(json.dumps(result["summary"], indent=2))
if __name__ == "__main__":
main()