File size: 3,668 Bytes
7a74082
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
"""Stage 2: turn graded answers into Jedi's verifier dataset.

One example per (task, agent answer): Jedi reads `judge_view(...)` and must reply `accept` (the answer was graded
correct) or `escalate` (graded wrong). Splits are by task, never by answer, so no task leaks across splits:
  * test - the in-domain Shaktimaan-routing test tasks (text + code) plus 10% of the new-domain tasks;
  * ood  - every BIG-Bench Hard task (never trained on: measures generalisation to unseen task families);
  * val  - 6% of the remaining tasks, used only to calibrate confidence (Platt scaling);
  * train - the rest. Wrong answers are the minority, so they are oversampled in train to ~40% of examples.
Extra samples from the borderline pass (gen.py BORDERLINE=1) are used for train only, so held-out splits keep the
same, unselected sampling for every task.
"""
import json, random
from collections import Counter
from datasets import Dataset, DatasetDict, load_dataset
from common import JEDI_SYSTEM, judge_view

random.seed(0)
WRONG_SHARE = 0.40
BASE_SAMPLES = {"glm-5.3-flash": 2, "qwen3.8-27b": 1, "kimi-vl": 1}


def main():
    tasks = {t["id"]: t for t in map(json.loads, open("data/tasks.jsonl"))}
    answers = [a for a in map(json.loads, open("data/answers.jsonl")) if not a.get("error") and not a.get("skipped")]
    shak_test = set(load_dataset("podstack/Shaktimaan-routing", split="test")["id"])
    split = {}
    for tid, t in tasks.items():
        if t["source"] == "bbh":
            split[tid] = "ood"
        elif tid in shak_test or (t["source"] in ("aqua", "csqa") and random.random() < 0.10):
            split[tid] = "test"
        else:
            split[tid] = "val" if random.random() < 0.06 else "train"
    rows = {k: [] for k in ("train", "val", "test", "ood")}
    for a in answers:
        t = tasks[a["task_id"]]
        if split[t["id"]] != "train" and a["sample"] >= BASE_SAMPLES.get(a["agent"], 1):
            continue
        verdict = "accept" if a["correct"] else "escalate"
        view = judge_view(t["prompt"], a["text"], a["agent"], t["kind"], a["finish"])
        rows[split[t["id"]]].append(dict(
            task_id=t["id"], source=t["source"], kind=t["kind"], agent=a["agent"], sample=a["sample"],
            correct=bool(a["correct"]), finish=a["finish"] or "", completion_tokens=a["completion_tokens"],
            latency=a["latency"], pred=a["pred"], gold=t["gold"], judge_input=view, verdict=verdict,
            prompt=[{"role": "system", "content": JEDI_SYSTEM}, {"role": "user", "content": view}],
            completion=[{"role": "assistant", "content": verdict}]))
    train = rows["train"]
    wrong = [r for r in train if not r["correct"]]
    need = int(WRONG_SHARE * (len(train) - len(wrong)) / (1 - WRONG_SHARE)) - len(wrong)
    train += random.choices(wrong, k=max(0, need))
    random.shuffle(train)
    dd = DatasetDict({k: Dataset.from_list(v) for k, v in rows.items()})
    dd.save_to_disk("data/jedi_judge")
    print(dd)
    for k, v in rows.items():
        print(f"{k:5s} tasks={len({r['task_id'] for r in v}):5d} answers={len(v):6d} "
              f"wrong={sum(not r['correct'] for r in v) / len(v):.1%} "
              f"agents={dict(Counter(r['agent'] for r in v))}")
    print("solve rate by source x agent (all answers):")
    by = Counter((tasks[a["task_id"]]["source"], a["agent"]) for a in answers)
    ok = Counter((tasks[a["task_id"]]["source"], a["agent"]) for a in answers if a["correct"])
    for src in sorted({s for s, _ in by}):
        print(f"  {src:10s} " + " ".join(f"{ag}={ok[src, ag] / by[src, ag]:.2f}" for s, ag in sorted(by) if s == src))


if __name__ == "__main__":
    main()