Spaces:
Sleeping
Sleeping
| """ | |
| Same-input consistency test (spec #7). | |
| Runs each configured provider on the same JD 3 times and reports score variance. | |
| High-variance providers should get a lower production priority in | |
| config.LLM_GENERATION.provider_order. | |
| Usage: | |
| PYTHONPATH=. python scripts/consistency_test.py | |
| PYTHONPATH=. python scripts/consistency_test.py --jd airtel_pm --runs 3 | |
| """ | |
| import os | |
| import sys | |
| import io | |
| import json | |
| import argparse | |
| sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) | |
| if hasattr(sys.stdout, "buffer"): | |
| sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace") | |
| from src.provider_eval import load_base_resume, load_jd_fixtures, consistency_runs | |
| from src.providers import build_provider_chain | |
| from src.llm_client import LLMClient | |
| def main(): | |
| ap = argparse.ArgumentParser() | |
| ap.add_argument("--jd", type=str, default=None, help="JD fixture slug (default: first)") | |
| ap.add_argument("--runs", type=int, default=3) | |
| args = ap.parse_args() | |
| base = load_base_resume() | |
| if base is None: | |
| print("ERROR: no base resume.") | |
| sys.exit(1) | |
| jobs = load_jd_fixtures() | |
| if not jobs: | |
| print("ERROR: no JD fixtures.") | |
| sys.exit(1) | |
| job = next((j for j in jobs if j["_jd_slug"] == args.jd), jobs[0]) if args.jd else jobs[0] | |
| llm = LLMClient.__new__(LLMClient) | |
| providers = build_provider_chain(llm) | |
| real = [p for p in providers if getattr(p, "cfg", {}).get("api_key")] | |
| if not real: | |
| print("*** NO PROVIDER KEYS — StubProvider is deterministic, so variance") | |
| print("*** will be 0 by construction. Run with Kimi/NVIDIA keys for a real test. ***\n") | |
| print(f"JD under test: {job['_jd_slug']} | runs each: {args.runs}\n") | |
| out_root = os.path.join("data", "output", "eval", "consistency") | |
| results = [] | |
| print(f"{'Provider':<16} {'Run1':>5} {'Run2':>5} {'Run3':>5} {'Var':>6} {'Spread':>7} Stable?") | |
| for p in providers: | |
| res = consistency_runs(p, base, job, os.path.join(out_root, p.name), | |
| n=args.runs, llm=llm) | |
| results.append(res) | |
| sc = res["scores"] + [""] * (3 - len(res["scores"])) | |
| print(f"{p.name[:16]:<16} {str(sc[0]):>5} {str(sc[1]):>5} {str(sc[2]):>5} " | |
| f"{res['variance']:>6} {res['spread']:>7} {'YES' if res['stable'] else 'NO'}") | |
| os.makedirs(out_root, exist_ok=True) | |
| with open(os.path.join(out_root, "consistency.json"), "w", encoding="utf-8") as f: | |
| json.dump(results, f, ensure_ascii=False, indent=2) | |
| print(f"\nSaved -> {os.path.join(out_root, 'consistency.json')}") | |
| if __name__ == "__main__": | |
| main() | |