diff --git a/.taskmaster/tasks/tasks.json b/.taskmaster/tasks/tasks.json index ac894ff..de77343 100644 --- a/.taskmaster/tasks/tasks.json +++ b/.taskmaster/tasks/tasks.json @@ -1171,14 +1171,15 @@ }, { "id": "15", - "title": "Backfill multimodal — החלטה על rollout מורחב לאחר A/B עם דפנה", - "description": "תזכורת לבדוק עם דפנה אם voyage-multimodal-3 על 8174-24 + 8137-24 עוזר בפועל, ולהחליט אם להריץ backfill על שאר הקורפוס (~236 docs, ~17,700 pages, ~2 שעות זמן API, ~350MB disk).", - "details": "תאריך יעד מומלץ: ~2026-05-10 (שבוע מהיום, 2026-05-03).\n\nקריטריונים להחלטה (אם מתקיים אחד — להריץ rollout):\n • דפנה זיהתה לפחות פעמיים ערך מוסף ב-8174-24 או 8137-24 (תקדים שלא הייתה מוצאת בלי image side, או חתימה/טבלה/תרשים שצף ב-top results)\n • היא ביקשה במפורש להפעיל על תיק נוסף ספציפי\n • היא מבקשת לעבור ל-search מצטלב (search_decisions, find_similar_cases) מעבר לתיק הנוכחי\n\nאם דפנה לא ראתה ערך — להחליט: לבטל / לכוונן MULTIMODAL_TEXT_WEIGHT (0.5 → 0.55-0.65) / לחכות עוד שבוע.\n\nאם החליטו להריץ — סדר עדיפויות:\n 1. שמאי-heavy: 8xxx (היטל השבחה) ו-9xxx (פיצויים) — שם הערך הגדול ביותר\n 2. תיקי 1xxx (רישוי ובניה) אחרון\n\nהרצה:\n CONTAINER=$(sudo docker ps --format '{{.Names}}' | grep gyjo | head -1)\n sudo docker cp scripts/multimodal_backfill.py $CONTAINER:/tmp/\n sudo docker cp scripts/backfill_chunk_pages.py $CONTAINER:/tmp/\n sudo docker exec $CONTAINER python /tmp/multimodal_backfill.py 8xxx-yy 9xxx-yy ...\n sudo docker exec $CONTAINER python /tmp/backfill_chunk_pages.py 8xxx-yy 9xxx-yy ...\n\nרפרנסים:\n • docs/voyage-upgrades-plan.md סעיף 'שלב C — voyage-multimodal-3 (✅ בוצע)'\n • commits 242f668..d12cdb1 על main\n • זיכרון: project_multimodal_stage_c.md, feedback_hybrid_retrieval_rrf.md", + "title": "Multimodal — כיוונון MULTIMODAL_TEXT_WEIGHT (A/B) + הכרעה על backfill", + "description": "נסגר 2026-06-03 לאחר A/B אובייקטיבי על gold-set (86 שאילתות, eval_retrieval.py). הנחת היסוד התיישנה: multimodal כבר ברירת-מחדל בייצור (110 מסמכים מוטמעים אוטומטית בהעלאה), לא רק 2 תיקי A/B. ממצא: ה-weight 0.5 (ברירת-מחדל) היה mis-tuned — צד-התמונה כבד מדי וחתך recall של precedent_library (0.971→0.885). sweep 0.5→0.75: במשקל 0.65 multimodal מנצח את text-only בכל מדד ובכל corpus (R@5 0.994 מול 0.989; nDCG@5 0.960 מול 0.944; MRR 0.954 מול 0.936; precedent_library R@5 0.983, internal_decisions nDCG 0.978). כיסוי: 28/79 מסמכי gold-set מוטמעים multimodal (35% — אות אמיתי). דפנה אישרה.", + "details": "בוצע: MULTIMODAL_TEXT_WEIGHT=0.65 הוגדר ב-Coolify env של legal-ai (runtime) + redeploy; baseline (data/eval/baseline.json) עודכן לקונפיג 0.65. ה-backfill היקר ל-140 התיקים ה-legacy *לא* בוצע — אין הצדקת-אחזור לשאלות טקסט, וערך ה-image-answer לא נבדק. מומר ל-#80 (מותנה). ראיות: data/eval/eval-report-20260603T08*.md, project_multimodal_stage_c.", "testStrategy": "", - "status": "pending", + "status": "done", "dependencies": [], - "priority": "low", - "subtasks": [] + "priority": "medium", + "subtasks": [], + "updatedAt": "2026-06-03T00:00:00.000Z" }, { "id": "16", @@ -2524,20 +2525,34 @@ "description": "ה-chunker ההיררכי הנוכחי (אחרי תיקון #55) עדיין פולט מדי פעם chunk זעיר שהוא כותרת-סעיף בודדת שלא מוזגה קדימה לתוכן שאחריה. התגלה בסגירת #57 (re-chunk legacy): מתוך 73 תקדימים שעברו reindex, נשארו 4 chunks זעירים — כולם כותרות מבודדות: 'דיון' (ע\"א 5138/04, len=4), 'טענות המשיבים' (בג\"ץ 6525/15, len=13), 'העובדות וההליכים' (בר\"מ 2340/02, len=16), ושבר-ציטוט 'כלל התושבים\". (ע' 13 להחלטה)' (403-17, len=32). לא שאריות legacy — אלה פלט דטרמיניסטי של ה-chunker הנוכחי.", "details": "השפעה: נמוכה — chunks אלה כבר מסוננים ב-query-time (פילטר length>=50 שנוסף ב-#55), אז החיפוש לא מושפע; זו בעיית-איכות-chunking ולא בעיית-אחזור. מיקום: chunker ההיררכי ב-mcp-server (chunk_document_hierarchical / מדיניות מיזוג הכותרות שב-#55). התיקון הצפוי: כשכותרת/heading קצרה (<50, או section_type שמתחיל סעיף) נותרת כ-chunk עצמאי ללא גוף — למזג אותה קדימה אל ה-chunk הבא (anchor-forward), או אחורה אם אין הבא. לשים לב ל-section boundaries: 'דיון'/'טענות המשיבים' הן תחילת סעיף — המיזוג צריך לצרף את הכותרת לראש הסעיף שאחריה, לא לזנב הקודם. אימות: להריץ scripts/rechunk_legacy_precedents.py אחרי התיקון — אמור להגיע ל-0 chunks<50 (או רק שברי-ציטוט לגיטימיים נדירים). תלוי ב-#55. ראה גם feedback_no_reocr_retrofit (re-chunk מ-full_text בלבד).", "testStrategy": "אחרי תיקון ה-chunker: reindex של 4 התיקים (ע\"א 5138/04, בג\"ץ 6525/15, בר\"מ 2340/02, 403-17) → 0 chunks<50 בהם; SELECT count(*) FROM precedent_chunks WHERE length(trim(content))<50 → 0 (או רק שברי-ציטוט). ללא רגרסיה: search_precedent_library עדיין מחזיר את התיקים.", - "status": "pending", + "status": "done", "dependencies": [ "55" ], "priority": "low", "subtasks": [], + "updatedAt": "2026-06-03T08:10:57.844Z" + }, + { + "id": "80", + "title": "[#15 follow-up] בדיקת ערך image-answer ל-multimodal → הכרעה על backfill 140 legacy", + "description": "ה-A/B של #15 הוכיח ש-multimodal עוזר לאחזור טקסט (במשקל 0.65), אבל **ערך הליבה** של multimodal — שאלות שהתשובה בהן בתוך טבלה/חתימה/עמוד-image ש-OCR מאבד (דוחות שמאי 8xxx/9xxx) — לא נבדק כי ה-gold-set טקסטואלי. כדי להכריע אם שווה לעשות backfill של 140 מסמכי התיקים ה-legacy (שהועלו לפני שה-multimodal עלה; חדשים מקבלים אוטומטית), צריך mini-gold-set ממוקד של 5-10 שאלות 'התשובה בטבלה/תמונה'.", + "details": "לבנות gold-set קטן: לזהות דוחות שמאי עם תוכן image-only/טבלאי (document_image_embeddings קיימים), לנסח שאלות שהתשובה בהן בטבלה/תרשים, ולהריץ eval_retrieval.py עם MULTIMODAL_ENABLED ON מול OFF על אותן שאלות. אם multimodal מאחזר תוכן ש-text-only מפספס → ה-backfill מוצדק (~שעתיים API, ~350MB, דורש אישור עלות chaim). אם לא → לוותר. scope ה-backfill: 140 מסמכי case ללא image embeddings (SELECT ... WHERE NOT EXISTS document_image_embeddings).", + "testStrategy": "eval על ה-image-answer gold-set: multimodal ON מאחזר ≥1 מסמך/קטע ש-OFF מפספס (R@k גבוה יותר על שאלות-טבלה).", + "status": "pending", + "dependencies": [ + "15" + ], + "priority": "low", + "subtasks": [], "updatedAt": "2026-06-03T00:00:00.000Z" } ], "metadata": { "version": "1.0.0", - "lastModified": "2026-06-03T07:56:21.688Z", - "taskCount": 78, - "completedCount": 71, + "lastModified": "2026-06-03T08:10:57.844Z", + "taskCount": 79, + "completedCount": 72, "tags": [ "legal-ai" ] diff --git a/data/eval/baseline.json b/data/eval/baseline.json index acbc40c..04d8dc7 100644 --- a/data/eval/baseline.json +++ b/data/eval/baseline.json @@ -2,50 +2,50 @@ "gold_size": 86, "retrieval_config": { "MULTIMODAL_ENABLED": true, - "VOYAGE_RERANK_ENABLED": true, + "VOYAGE_RERANK_ENABLED": false, "VOYAGE_MODEL": "voyage-3", - "MULTIMODAL_TEXT_WEIGHT": 0.5, + "MULTIMODAL_TEXT_WEIGHT": 0.65, "MULTIMODAL_RRF_K": 60, "BM25_HYBRID_ENABLED": true }, "overall": { - "P@5": 0.214, - "R@5": 0.899, - "nDCG@5": 0.8311, - "P@10": 0.1163, - "R@10": 0.9649, - "nDCG@10": 0.8554, - "MRR": 0.8482 + "P@5": 0.2465, + "R@5": 0.9938, + "nDCG@5": 0.9597, + "P@10": 0.1244, + "R@10": 0.9961, + "nDCG@10": 0.9611, + "MRR": 0.9535 }, "by_corpus": { "internal_decisions": { - "P@5": 0.1963, - "R@5": 0.963, - "nDCG@5": 0.887, + "P@5": 0.2037, + "R@5": 1.0, + "nDCG@5": 0.978, "P@10": 0.1019, "R@10": 1.0, - "nDCG@10": 0.8994, - "MRR": 0.8713 + "nDCG@10": 0.978, + "MRR": 0.9722 }, "precedent_library": { - "P@5": 0.2438, - "R@5": 0.7911, - "nDCG@5": 0.7367, - "P@10": 0.1406, - "R@10": 0.9057, - "nDCG@10": 0.7813, - "MRR": 0.8092 + "P@5": 0.3188, + "R@5": 0.9833, + "nDCG@5": 0.9288, + "P@10": 0.1625, + "R@10": 0.9896, + "nDCG@10": 0.9326, + "MRR": 0.9219 } }, "by_practice_area": { "betterment_levy": { - "P@5": 0.1897, - "R@5": 0.9231, - "nDCG@5": 0.8595, - "P@10": 0.1, - "R@10": 0.9744, - "nDCG@10": 0.8766, - "MRR": 0.8437 + "P@5": 0.2051, + "R@5": 1.0, + "nDCG@5": 0.9621, + "P@10": 0.1026, + "R@10": 1.0, + "nDCG@10": 0.9621, + "MRR": 0.9487 }, "compensation_197": { "P@5": 0.2, @@ -57,14 +57,14 @@ "MRR": 1.0 }, "rishuy_uvniya": { - "P@5": 0.2, - "R@5": 0.9706, - "nDCG@5": 0.861, + "P@5": 0.2059, + "R@5": 1.0, + "nDCG@5": 0.9976, "P@10": 0.1029, "R@10": 1.0, - "nDCG@10": 0.8708, - "MRR": 0.8346 + "nDCG@10": 0.9976, + "MRR": 1.0 } }, - "generated_at": "20260531T155717Z" + "generated_at": "20260603T084350Z" } \ No newline at end of file