Spaces:
Sleeping
Sleeping
| """Run the AgroSense RAG evaluation harness and print a report. | |
| Usage: | |
| python scripts/evaluate.py # uses data/eval_set.json | |
| python scripts/evaluate.py path/to/set.json --json out.json | |
| Runs fully offline (set AGROSENSE_EMBEDDING_BACKEND=hashing for determinism). | |
| Exit code is non-zero if any report target is missed (handy for CI). | |
| """ | |
| from __future__ import annotations | |
| import json | |
| import sys | |
| from pathlib import Path | |
| sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) | |
| from agrosense import RAGEngine | |
| from agrosense.config import DATA_DIR | |
| from agrosense.evaluation import evaluate, load_cases | |
| def main(argv: list[str]) -> int: | |
| args = [a for a in argv[1:] if not a.startswith("--")] | |
| out_json = None | |
| if "--json" in argv: | |
| idx = argv.index("--json") | |
| if idx + 1 < len(argv): | |
| out_json = argv[idx + 1] | |
| set_path = Path(args[0]) if args else (DATA_DIR / "eval_set.json") | |
| print(f"Loading eval set: {set_path}") | |
| cases = load_cases(set_path) | |
| print(f"{len(cases)} cases. Building engine...") | |
| engine = RAGEngine() | |
| report = evaluate(engine, cases) | |
| m, t = report["metrics"], report["targets_met"] | |
| print("\n=== AgroSense RAG Evaluation ===") | |
| print(f" In-domain cases : {m['n_in_domain']}") | |
| print(f" Out-of-domain cases : {m['n_out_of_domain']}") | |
| print(" --- quality ---") | |
| print(f" Context relevance : {m['context_relevance']:.1%} " | |
| f"(target >=95%) {'PASS' if t['context_relevance'] else 'FAIL'}") | |
| print(f" Citation MRR : {m['citation_mrr']:.3f}") | |
| print(f" Faithfulness : {m['faithfulness']:.1%} " | |
| f"(target >=95%) {'PASS' if t['faithfulness'] else 'FAIL'}") | |
| print(f" Hallucination rate : {m['hallucination_rate']:.1%} " | |
| f"(target <5%) {'PASS' if t['hallucination_rate'] else 'FAIL'}") | |
| print(f" Answer relevance : {m['answer_relevance']:.1%}") | |
| print(f" Out-of-domain acc. : " | |
| + ("n/a" if m['ood_accuracy'] is None else f"{m['ood_accuracy']:.1%}")) | |
| print(" --- latency ---") | |
| print(f" p50 / p95 / max ms : {m['latency_ms_p50']} / {m['latency_ms_p95']} / " | |
| f"{m['latency_ms_max']} (p95 target <=3000) " | |
| f"{'PASS' if t['latency_ms_p95'] else 'FAIL'}") | |
| print(f"\n ALL TARGETS MET: {report['all_targets_met']}") | |
| if out_json: | |
| Path(out_json).write_text(json.dumps(report, indent=2), encoding="utf-8") | |
| print(f" (full report written to {out_json})") | |
| return 0 if report["all_targets_met"] else 1 | |
| if __name__ == "__main__": | |
| raise SystemExit(main(sys.argv)) | |