Improve block-yod prompt: require minimum length, numbered claims, precedent citations
- Add minimum word count guidance (2000-4000 words) - Number each claim in claims_context for explicit tracking - Require 3-5 case law citations minimum - Fix max_tokens > budget_tokens for extended thinking - Use streaming for opus+thinking requests (>10min timeout) Tested on Hecht case: block-yod improved from 1039 to 1927 words. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -199,20 +199,21 @@ BLOCK_PROMPTS = {
|
|||||||
"block-yod": """כתוב את בלוק הדיון וההכרעה (בלוק י) של החלטת ועדת ערר.
|
"block-yod": """כתוב את בלוק הדיון וההכרעה (בלוק י) של החלטת ועדת ערר.
|
||||||
|
|
||||||
## זהו הבלוק הקריטי ביותר — ליבת ההחלטה (ratio decidendi).
|
## זהו הבלוק הקריטי ביותר — ליבת ההחלטה (ratio decidendi).
|
||||||
|
## אורך נדרש: **2,000-4,000 מילים לפחות**. זהו הבלוק הארוך ביותר בהחלטה (35-50%).
|
||||||
|
|
||||||
## מתודולוגיה — CREAC:
|
## מתודולוגיה — CREAC:
|
||||||
1. **C** (Conclusion) — פתח במסקנה: "לאחר שעיינו... מצאנו כי הערר [נדחה/מתקבל]"
|
1. **C** (Conclusion) — פתח במסקנה: "לאחר שעיינו... מצאנו כי הערר [נדחה/מתקבל]"
|
||||||
2. **R** (Rule) — הצג את הכלל המשפטי הרלוונטי
|
2. **R** (Rule) — הצג את הכלל המשפטי הרלוונטי עם ציטוט פסיקה
|
||||||
3. **E** (Explanation) — צטט פסיקה שמסבירה את הכלל
|
3. **E** (Explanation) — צטט פסיקה שמסבירה את הכלל (200-600 מילים לכל ציטוט)
|
||||||
4. **A** (Application) — יישם על העובדות הספציפיות
|
4. **A** (Application) — יישם על העובדות הספציפיות של התיק
|
||||||
5. **C** (Conclusion) — מסקנת ביניים
|
5. **C** (Conclusion) — מסקנת ביניים
|
||||||
|
|
||||||
## כללים קריטיים:
|
## כללים קריטיים:
|
||||||
- **מסקנה בפתיחה** — לא בסוף
|
- **מסקנה בפתיחה** — לא בסוף
|
||||||
- **מענה לכל טענה** שהוצגה בבלוק ז
|
- **מענה פרטני לכל טענה** שהוצגה בבלוק ז — עבור על כל טענה ברשימה והתייחס אליה בנפרד. אל תדלג על שום טענה.
|
||||||
|
- **ציטוטי פסיקה** — צטט לפחות 3-5 פסקי דין רלוונטיים. כל ציטוט עם שם התיק המלא.
|
||||||
- **ללא כפילות** — הפנה לבלוקים קודמים: "כאמור בסעיף X לעיל"
|
- **ללא כפילות** — הפנה לבלוקים קודמים: "כאמור בסעיף X לעיל"
|
||||||
- **ללא כותרות משנה** (חריג: נושאים נפרדים לחלוטין)
|
- **ללא כותרות משנה** (חריג: נושאים נפרדים לחלוטין)
|
||||||
- ציטוט פסיקה בבלוקים ארוכים (200-600 מילים)
|
|
||||||
- מספור רציף
|
- מספור רציף
|
||||||
|
|
||||||
## כיוון מאושר (חובה):
|
## כיוון מאושר (חובה):
|
||||||
@@ -221,13 +222,13 @@ BLOCK_PROMPTS = {
|
|||||||
## מבנה לפי תוצאה:
|
## מבנה לפי תוצאה:
|
||||||
{structure_guidance}
|
{structure_guidance}
|
||||||
|
|
||||||
## טענות שצריך לענות עליהן:
|
## טענות שצריך לענות עליהן (חובה — כל טענה חייבת מענה):
|
||||||
{claims_context}
|
{claims_context}
|
||||||
|
|
||||||
## חומרי מקור:
|
## חומרי מקור:
|
||||||
{source_context}
|
{source_context}
|
||||||
|
|
||||||
## פסיקה רלוונטית:
|
## פסיקה רלוונטית (צטט מכאן ומהידע הכללי שלך):
|
||||||
{precedents_context}
|
{precedents_context}
|
||||||
|
|
||||||
## סגנון דפנה:
|
## סגנון דפנה:
|
||||||
@@ -349,19 +350,33 @@ async def write_block(
|
|||||||
|
|
||||||
if model_key == "opus" and temperature >= 0.3:
|
if model_key == "opus" and temperature >= 0.3:
|
||||||
# Extended thinking for complex blocks
|
# Extended thinking for complex blocks
|
||||||
|
# max_tokens must be > budget_tokens
|
||||||
|
kwargs["max_tokens"] = max(max_tokens, 20000)
|
||||||
kwargs["temperature"] = 1 # Required for extended thinking
|
kwargs["temperature"] = 1 # Required for extended thinking
|
||||||
kwargs["thinking"] = {"type": "enabled", "budget_tokens": 16000}
|
kwargs["thinking"] = {"type": "enabled", "budget_tokens": 16000}
|
||||||
else:
|
else:
|
||||||
kwargs["temperature"] = temperature
|
kwargs["temperature"] = temperature
|
||||||
|
|
||||||
message = client.messages.create(**kwargs)
|
# Use streaming for long requests (opus + thinking)
|
||||||
|
use_stream = model_key == "opus" and kwargs.get("thinking")
|
||||||
|
|
||||||
# Extract text from response (skip thinking blocks)
|
if use_stream:
|
||||||
content = ""
|
content_parts = []
|
||||||
for block in message.content:
|
with client.messages.stream(**kwargs) as stream:
|
||||||
if block.type == "text":
|
for event in stream:
|
||||||
content = block.text
|
pass # consume stream
|
||||||
break
|
response = stream.get_final_message()
|
||||||
|
for block in response.content:
|
||||||
|
if block.type == "text":
|
||||||
|
content_parts.append(block.text)
|
||||||
|
content = "\n".join(content_parts)
|
||||||
|
else:
|
||||||
|
message = client.messages.create(**kwargs)
|
||||||
|
content = ""
|
||||||
|
for block in message.content:
|
||||||
|
if block.type == "text":
|
||||||
|
content = block.text
|
||||||
|
break
|
||||||
|
|
||||||
return _build_result(block_id, content, block_cfg)
|
return _build_result(block_id, content, block_cfg)
|
||||||
|
|
||||||
@@ -419,11 +434,14 @@ async def _build_claims_context(case_id: UUID) -> str:
|
|||||||
current_role = ""
|
current_role = ""
|
||||||
role_heb = {"appellant": "טענות העוררים", "respondent": "טענות המשיבים",
|
role_heb = {"appellant": "טענות העוררים", "respondent": "טענות המשיבים",
|
||||||
"committee": "עמדת הוועדה המקומית", "permit_applicant": "עמדת מבקשי ההיתר"}
|
"committee": "עמדת הוועדה המקומית", "permit_applicant": "עמדת מבקשי ההיתר"}
|
||||||
|
claim_num = 0
|
||||||
for c in claims:
|
for c in claims:
|
||||||
if c["party_role"] != current_role:
|
if c["party_role"] != current_role:
|
||||||
current_role = c["party_role"]
|
current_role = c["party_role"]
|
||||||
lines.append(f"\n### {role_heb.get(current_role, current_role)}")
|
lines.append(f"\n### {role_heb.get(current_role, current_role)}")
|
||||||
lines.append(f"- {c['claim_text'][:300]}")
|
claim_num += 1
|
||||||
|
lines.append(f"טענה #{claim_num}: {c['claim_text'][:400]}")
|
||||||
|
lines.append(f"\n**סה\"כ {claim_num} טענות — חובה לענות על כל אחת.**")
|
||||||
return "\n".join(lines)
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user