#!/usr/bin/env python3 """Komut satırından toplu değerlendirme ve başarım raporu üretimi. Örnekler: python scripts/run_benchmark.py --model qwen2.5-coder:7b python scripts/run_benchmark.py --model qwen2.5-coder:7b --model llama3.1:8b --max-iterations 4 python scripts/run_benchmark.py --languages python java --items py-bank java-calc python scripts/run_benchmark.py --model qwen2.5-coder:7b --max-iterations 1 # geri beslemesiz taban çizgisi python scripts/run_benchmark.py --reference # insan yazımı referans testlerle ölçüm (LLM gerekmez) python scripts/run_benchmark.py --model qwen2.5-coder:14b --split test --repeats 3 python scripts/run_benchmark.py --model qwen2.5-coder:14b --ablate judge # hakem kapalı ablasyon """ from __future__ import annotations import argparse import json import sys import time from pathlib import Path ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(ROOT / "backend")) from app.eval import benchmark # noqa: E402 from app.eval.report import render # noqa: E402 from app.llm.ollama import OllamaClient # noqa: E402 def main() -> None: ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) ap.add_argument("--model", action="append", help="Model (birden çok verilebilir): Ollama adı ya da openai: / anthropic:") ap.add_argument("--languages", nargs="*") ap.add_argument("--items", nargs="*", help="benchmarks/manifest.json içindeki id'ler") ap.add_argument("--max-iterations", type=int, default=4) ap.add_argument("--max-mutants", type=int, default=30) ap.add_argument("--coverage-target", type=float, default=85) ap.add_argument("--temperature", type=float, default=0.2) ap.add_argument("--no-mutation", action="store_true") ap.add_argument("--split", choices=["dev", "test", "bagimsiz", "all"], default="all", help="dev: geliştirmede kullanılan, test: geliştirmede görülmemiş, " "bagimsiz: üçüncü kişilerce yazılmış (QuixBugs) öğeler") ap.add_argument("--repeats", type=int, default=1, help="her öğe kaç kez koşulsun (rastgelelik için)") ap.add_argument("--ablate", nargs="*", default=[], choices=["judge", "prune", "restart", "repair", "planfree", "best", "mutfix"], help="kapatılacak mekanizmalar (ablasyon)") ap.add_argument("--label", default="", help="rapora yazılacak yapılandırma etiketi") ap.add_argument("--reference", action="store_true", help="LLM yerine benchmarks/reference altındaki insan yazımı testleri kullan (taban çizgisi)") ap.add_argument("--out", default=str(ROOT / "reports" / "LLM_SONUCLARI.md")) ap.add_argument("--report-lang", choices=["tr", "en"], default="tr", help="Markdown raporunun dili (ajan istemlerini değiştirmez)") args = ap.parse_args() if args.reference: run_reference(args) return from app.llm import providers models = args.model or [OllamaClient().model] health = OllamaClient().health() if not health["ok"] and any(providers.is_local(m) for m in models): sys.exit(f"Ollama'ya ulaşılamadı: {health.get('error')}\n`ollama serve` çalışıyor mu?") for p in providers.CLOUD: if providers.configured(p) and any(providers.provider_of(m) == p for m in models): providers.sync(p) missing = [m for m in models if not providers.available(m, health.get("models", []))] if missing: sys.exit(f"Model(ler) yüklü değil: {missing}. Önce: ollama pull {missing[0]}") cfg = {"max_iterations": args.max_iterations, "max_mutants": args.max_mutants, "coverage_target": args.coverage_target, "temperature": args.temperature, "run_mutation": not args.no_mutation, "ablate": args.ablate} evals = [] for model in models: print(f"\n=== {model} ===") t0 = time.time() ev = benchmark.run_eval(model, cfg, args.items, args.languages, background=False, split=args.split, repeats=args.repeats, label=args.label) for it in ev.items: print(f" {it.id:<16} {it.status:<7} kapsama={it.final_coverage} mutasyon={it.mutation_score} " f"yerleştirilmiş={it.seeded_caught}/{it.seeded_total} tur={it.iterations} {it.error}") print(f" süre: {time.time() - t0:.0f} sn") evals.append(ev) out = Path(args.out) out.parent.mkdir(parents=True, exist_ok=True) out.write_text(render(evals, lang=args.report_lang), encoding="utf-8") out.with_suffix(".json").write_text(json.dumps([e.model_dump() for e in evals], ensure_ascii=False, indent=2)) print(f"\nRapor: {out}") def run_reference(args) -> None: """İnsan yazımı referans test paketleriyle aynı ölçüm hattını koşar (altyapı doğrulaması + taban çizgisi).""" from app.llm.scripted import ScriptedLLM, text, tool items = {i["id"]: i for i in benchmark.load_manifest() if i.get("reference_tests")} ids = [i for i in (args.items or items) if i in items] from app.sandbox.registry import get_runner junit4 = get_runner("java").framework() == "junit4" def factory(item): key = "reference_tests_junit4" if junit4 and item.get("reference_tests_junit4") else "reference_tests" ref = (benchmark.BENCH_DIR / item[key]).read_text(encoding="utf-8") return ScriptedLLM([text('{"summary": "insan yazımı referans test paketi"}'), tool("write_tests", code=ref), tool("finish", summary="referans")], model="referans") cfg = {"max_iterations": 1, "max_mutants": args.max_mutants, "coverage_target": args.coverage_target, "run_mutation": not args.no_mutation} ev = benchmark.run_eval("referans (insan yazımı)", cfg, ids, None, background=False, llm_factory=factory, split=args.split, label="referans") for it in ev.items: green = "" if it.final_pass_rate == 100.0 else f" UYARI: referans paket yeşil değil (geçen %{it.final_pass_rate})" print(f" {it.id:<16} {it.split:<4} {it.status:<7} kapsama={it.final_coverage} mutasyon={it.mutation_score} " f"yerleştirilmiş={it.seeded_caught}/{it.seeded_total} {it.error}{green}") out = Path(args.out) if out.name == "LLM_SONUCLARI.md": out = out.with_name("REFERANS_TABAN_CIZGISI.md") out.parent.mkdir(parents=True, exist_ok=True) out.write_text(render([ev], title="Referans (insan yazımı) taban çizgisi"), encoding="utf-8") out.with_suffix(".json").write_text(json.dumps([ev.model_dump()], ensure_ascii=False, indent=2)) print(f"Rapor: {out}") if __name__ == "__main__": main()