zuoyebot / evaluate.py
ln17200's picture
Upload 64 files
2b90d85 verified
Raw
History Blame Contribute Delete
3.38 kB
from __future__ import annotations
import json
from pathlib import Path
from rag_pipeline import HandbookRAG, REFUSAL_TEXT
ROOT = Path(__file__).resolve().parent
GOLDEN_DATASET_PATH = ROOT / "golden_dataset.json"
RESULTS_PATH = ROOT / "test_results.json"
def load_golden_dataset() -> list[dict]:
return json.loads(GOLDEN_DATASET_PATH.read_text(encoding="utf-8"))
def matches_keywords(answer: str, keywords: list[str]) -> bool:
answer_lower = answer.lower()
if not keywords:
return True
hits = 0
for keyword in keywords:
keyword_lower = keyword.lower()
if keyword_lower in answer_lower:
hits += 1
continue
words = [word for word in keyword_lower.split() if word]
if words and all(word in answer_lower for word in words):
hits += 1
required = 1 if len(keywords) == 1 else min(2, len(keywords))
return hits >= required
def is_refusal(answer: str) -> bool:
answer_lower = answer.lower()
refusal_markers = [
"could not find enough support",
"cannot answer from the handbook",
"not enough support",
"try rephrasing",
"cannot be answered",
"does not state a specific",
"cannot answer this question",
"does not provide",
]
return any(marker in answer_lower for marker in refusal_markers) or answer.strip() == REFUSAL_TEXT
def main() -> None:
payload = {
"status": "completed",
"results": [],
"summary": {},
}
try:
bot = HandbookRAG()
except Exception as exc:
payload["status"] = "not_run"
payload["summary"] = {"reason": str(exc)}
RESULTS_PATH.write_text(json.dumps(payload, indent=2), encoding="utf-8")
print(json.dumps(payload, indent=2))
return
golden_dataset = load_golden_dataset()
passed = 0
for item in golden_dataset:
try:
answer, contexts = bot.answer(item["question"], [])
retrieved_sources = [context.source for context in contexts]
if item["answerable"]:
source_ok = any(source in retrieved_sources for source in item["expected_sources"])
keyword_ok = matches_keywords(answer, item["expected_keywords"])
item_passed = source_ok and keyword_ok and not is_refusal(answer)
else:
item_passed = is_refusal(answer)
except Exception as exc:
answer = f"Error: {exc}"
retrieved_sources = []
item_passed = False
if item_passed:
passed += 1
payload["results"].append(
{
"id": item["id"],
"question": item["question"],
"answerable": item["answerable"],
"expected_sources": item["expected_sources"],
"retrieved_sources": retrieved_sources,
"answer": answer,
"passed": item_passed,
}
)
payload["summary"] = {
"num_questions": len(golden_dataset),
"num_passed": passed,
"pass_rate": round(passed / len(golden_dataset), 4) if golden_dataset else 0.0,
}
RESULTS_PATH.write_text(json.dumps(payload, indent=2), encoding="utf-8")
print(json.dumps(payload["summary"], indent=2))
if __name__ == "__main__":
main()