feat(eval): ממד model×prompt ל-harness הכיול (#208) — A/B מודל-ייצור מול הסופיים #420

Merged
chaim merged 3 commits from worktree-opus5-model-calibration into main 2026-07-28 11:52:57 +00:00
Owner

מה ולמה

scripts/calibrate_effort.py (#208) כייל effort בלבד, על מודל נעוץ (GENERATION_MODEL). כדי לענות על "האם להחליף את מודל-הייצור" (opus-4-8 → opus-5) נדרש ממד שני — ובלי לפתוח מסלול-מדידה מקביל לצד style_distance/learning_loop הקיימים.

ה-PR מוסיף שני צירים ל-harness הקיים:

  1. --models — A/B של מודל-הייצור מול הסופיים החתומים של דפנה ב-draft_final_pairs.
  2. --instructions — A/B של וריאנט-פרומפט (למשל הוראת-עיצוב), שמוחל על כל המודלים בריצה כדי שהשוואת-מודלים לא תהפוך בשקט להשוואת-פרומפטים.

בצד ה-generation, block_writer.write_block מקבל model_override — אותו חוזה בדיוק כמו effort_override שכבר קיים ונוצר עבור #208.

החלטת-תכנון שכדאי לשים לב אליה: model_override מקבל את מזהה-הבסיס בלבד; אסקלציית ההקשר-1M (#216) מוחלת מעליו (<model>[1m] כשהפרומפט > 350K תווים). כלומר override לא מאבד בשקט את חלון ה-1M — מלכודת אמיתית עבור בלוק-י.

Invariants — הצהרה (חובה)

  • נוגע / מקיים:
    • INV-G8 (eval-harness — מדידה במקום הרגשה): מרחיב את הכיול מ-effort ל-model×effort. ההחלטה "להחליף מודל" נמדדת מול הסופיים במקום להיקבע בתחושה.
    • G2 (מקור-אמת יחיד / אין מסלול מקביל): אין מטריקה חדשה — משתמש ב-style_distance.block_distance_to_final ובשדה-התוצאה הקיים model_used. by_block נשאר בסכימה הקיימת (--rerank ממשיך לעבוד); by_model נוסף רק בריצה רב-מודלית.
    • כלל-הנדסה §6 (אין בליעה שקטה): כשל-תא מדווח ומדולג (התנהגות קיימת), ובנוסף — כל תא מתעד את model_used שה-CLI דיווח בפועל, ואי-התאמה מסומנת בדוח כאזהרת fallback-שקט במקום להיזקף בטעות למודל המבוקש. וריאנט-פרומפט נרשם בדוח כדי שלא יושווה בטעות לריצת-בסיס.
    • G12: לא נגעתי — אין מגע-Paperclip.

צ'קליסט — פרוטוקול כתיבת-קוד

  • קראתי את docs/spec/00-constitution.md + ספ-התחום הרלוונטי לפני הכתיבה
  • השינוי לא יוצר מסלול מקביל ליכולת קיימת (G2) ולא מתקן תסמין בקריאה (G1)
  • לא הוספתי מגע-Paperclip מחוץ ל-Platform Port (G12)
  • אין בליעה שקטה של שגיאות
  • בדקתי מול docs/spec/gap-audit.md — לא נוגע ב-GAP/FU ממופה
  • בדיקות עוברות
  • לא data-migration

אימות

  • scripts/calibrate_effort.py --self-test24/24 ALL PASS (לוגיקת-המדידה, offline).
  • pytest mcp-server/tests/470 passed.
  • --dry-run עם שני מודלים: תכנון-גריד נכון (מכפיל את total_generations במספר המודלים).
  • ריצה חיה על 8125-09-24 (16 ייצורים, 2 בלוקים × 2 efforts × 2 מודלים × 2 חזרות): 0 תאים שנכשלו, 0 retries, ו-models_used תאם את המודל המבוקש בכל תא (ללא fallback שקט). הדוח: data/eval/effort-calibration-20260728T093903-IL.md.

⚠️ ריצת ברירת-המחדל (ללא --models/--instructions) זהה התנהגותית לקודם: models=[None] ⇒ המודל הנעוץ, ואין מפתח by_model בפלט.

מה ה-PR הזה לא כולל

מסקנת-המודל עצמה. הריצה על 8125-09-24 היא n=1 ואינה מספיקה להכרעה; ריצה רחבה על 9 התיקים בעלי סופי חתום + וריאנט מכויל רצה בנפרד, ותדווח בנפרד.

## מה ולמה `scripts/calibrate_effort.py` (#208) כייל **effort בלבד**, על מודל נעוץ (`GENERATION_MODEL`). כדי לענות על "האם להחליף את מודל-הייצור" (opus-4-8 → opus-5) נדרש ממד שני — ובלי לפתוח מסלול-מדידה מקביל לצד `style_distance`/`learning_loop` הקיימים. ה-PR מוסיף שני צירים ל-harness הקיים: 1. **`--models`** — A/B של מודל-הייצור מול הסופיים החתומים של דפנה ב-`draft_final_pairs`. 2. **`--instructions`** — A/B של וריאנט-פרומפט (למשל הוראת-עיצוב), שמוחל על **כל** המודלים בריצה כדי שהשוואת-מודלים לא תהפוך בשקט להשוואת-פרומפטים. בצד ה-generation, `block_writer.write_block` מקבל `model_override` — אותו חוזה בדיוק כמו `effort_override` שכבר קיים ונוצר עבור #208. **החלטת-תכנון שכדאי לשים לב אליה:** `model_override` מקבל את **מזהה-הבסיס בלבד**; אסקלציית ההקשר-1M (#216) מוחלת מעליו (`<model>[1m]` כשהפרומפט > 350K תווים). כלומר override לא מאבד בשקט את חלון ה-1M — מלכודת אמיתית עבור בלוק-י. ## Invariants — הצהרה (חובה) - **נוגע / מקיים:** - **INV-G8 (eval-harness — מדידה במקום הרגשה):** מרחיב את הכיול מ-effort ל-model×effort. ההחלטה "להחליף מודל" נמדדת מול הסופיים במקום להיקבע בתחושה. - **G2 (מקור-אמת יחיד / אין מסלול מקביל):** אין מטריקה חדשה — משתמש ב-`style_distance.block_distance_to_final` ובשדה-התוצאה הקיים `model_used`. `by_block` נשאר בסכימה הקיימת (`--rerank` ממשיך לעבוד); `by_model` נוסף רק בריצה רב-מודלית. - **כלל-הנדסה §6 (אין בליעה שקטה):** כשל-תא מדווח ומדולג (התנהגות קיימת), ובנוסף — כל תא מתעד את `model_used` שה-CLI דיווח בפועל, ואי-התאמה מסומנת בדוח כאזהרת **fallback-שקט** במקום להיזקף בטעות למודל המבוקש. וריאנט-פרומפט נרשם בדוח כדי שלא יושווה בטעות לריצת-בסיס. - **G12:** לא נגעתי — אין מגע-Paperclip. ## צ'קליסט — פרוטוקול כתיבת-קוד - [x] קראתי את `docs/spec/00-constitution.md` + ספ-התחום הרלוונטי לפני הכתיבה - [x] השינוי **לא** יוצר מסלול מקביל ליכולת קיימת (G2) ולא מתקן תסמין בקריאה (G1) - [x] **לא** הוספתי מגע-Paperclip מחוץ ל-Platform Port (G12) - [x] אין בליעה שקטה של שגיאות - [x] בדקתי מול `docs/spec/gap-audit.md` — לא נוגע ב-GAP/FU ממופה - [x] בדיקות עוברות - [x] לא data-migration ## אימות - `scripts/calibrate_effort.py --self-test` — **24/24 ALL PASS** (לוגיקת-המדידה, offline). - `pytest mcp-server/tests/` — **470 passed**. - `--dry-run` עם שני מודלים: תכנון-גריד נכון (מכפיל את `total_generations` במספר המודלים). - **ריצה חיה על 8125-09-24** (16 ייצורים, 2 בלוקים × 2 efforts × 2 מודלים × 2 חזרות): 0 תאים שנכשלו, 0 retries, ו-`models_used` תאם את המודל המבוקש בכל תא (ללא fallback שקט). הדוח: `data/eval/effort-calibration-20260728T093903-IL.md`. > ⚠️ ריצת ברירת-המחדל (ללא `--models`/`--instructions`) **זהה התנהגותית** לקודם: `models=[None]` ⇒ המודל הנעוץ, ואין מפתח `by_model` בפלט. ## מה ה-PR הזה *לא* כולל מסקנת-המודל עצמה. הריצה על 8125-09-24 היא n=1 ו**אינה** מספיקה להכרעה; ריצה רחבה על 9 התיקים בעלי סופי חתום + וריאנט מכויל רצה בנפרד, ותדווח בנפרד.
chaim added 2 commits 2026-07-28 08:30:07 +00:00
`calibrate_effort.py` כייל `effort` בלבד, על מודל נעוץ (GENERATION_MODEL).
כדי להשוות מודל-ייצור (opus-4-8 מול opus-5) מול הסופיים החתומים של דפנה
נדרש ממד שני — ללא מסלול-מדידה מקביל.

- `block_writer.write_block(model_override=…)` — אותו חוזה כמו
  `effort_override` הקיים (נוצר בדיוק ל-#208). מקבל את המזהה הבסיסי בלבד;
  אסקלציית ההקשר-1M (#216) מוחלת מעליו, כך ש-override לא מאבד בשקט את
  חלון ה-1M.
- `--models` ל-harness (ריק = המודל הנעוץ ⇒ ריצת ברירת-המחדל זהה לקודם).
- הדוח מקבל טבלת השוואת-מודלים (block × effort × model) ומסמן  לפי
  אותו דירוג style-clean (#213): anti_total → ratioΔ → distance.
- כל תא מתעד את `model_used` שה-CLI דיווח בפועל; אי-התאמה מסומנת כאזהרת
  fallback-שקט במקום להיזקף בטעות למודל המבוקש.

invariants: INV-G8 (eval-harness — מדידה, לא הרגשה) · G2 (אין מסלול מקביל:
משתמש ב-style_distance/learning_loop הקיימים ובשדה result הקיים
`model_used`) · §6 (אין בליעה שקטה — כשל-תא מדווח ומדולג).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
feat(eval): --instructions ל-harness — A/B של וריאנט-פרומפט
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 34s
Lint — undefined names / undefined-names (pull_request) Successful in 12s
10e05700cc
מוחל על כל המודלים בריצה (אחרת השוואת-מודלים הופכת בשקט להשוואת-פרומפטים),
ונרשם ב-grid_summary + בכותרת הדוח כדי שריצת-וריאנט לא תושווה בטעות לבסיס.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
chaim added 1 commit 2026-07-28 11:17:37 +00:00
feat(eval): פילוח אנטי-דפוסים per-ריצה — "איזה כלל הופר", לא רק כמה
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 3s
Lint — undefined names / undefined-names (pull_request) Successful in 10s
86e66cc5bd
`block_distance_to_final` החזיר `anti_pattern_total` בלבד. ריצת-כיול שמדווחת
"anti=4" אינה יכולה לומר מה לתקן — באבחון ה-A/B של 2026-07-28 נאלצנו להסיק
את הדפוס האשם מהקשר במקום למדוד אותו.

- `anti_by_pattern` (שם-דפוס → מספר-פגיעות) נוסף לתא-המדידה, מ-
  `count_anti_patterns` הקיים — אין ספירה מקבילה.
- `_mean_by_pattern` ממצע על **כל** הריצות: דפוס שלא נורה בריצה נספר כ-0
  ולא מושמט, אחרת הממוצע היה מוטה כלפי מעלה.
- הדוח מקבל טבלת "פילוח אנטי-דפוסים (איזה כלל הופר)" per block×effort×model.

invariants: INV-G8 (eval-harness) · G2 (מרונדר מ-count_anti_patterns/
ANTI_PATTERNS הקנוניים — מקור אחד).

אימות: self-test ALL PASS · 470 passed · בדיקת-שפיות ישירה —
טקסט עם 1 כותרת + 2 תבליטים + 1 פיצול-מיני מפולח נכון ל-
{markdown_headers:1, bullet_lists:2, inline_numbered_fragments:1}.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
chaim merged commit 79d9ea55d8 into main 2026-07-28 11:52:57 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: ezer-mishpati/legal-ai#420