8 Integration · Capstone

צוות שעובד לבד — חיווט הכל ל-Production, והחלטת In-Process מול Hosted

בשבעת הפרקים האחרונים בנינו רכיב-רכיב: לולאה, context, tools, governance, observability, orchestration וזיכרון. עכשיו אנחנו מחווטים את כולם ל-harness אחד חי שמריץ צוות סוכנים שעובד לבד על משימת end-to-end אמיתית — ומקבלים את ההחלטה הגדולה של ה-production: להישאר in-process מול לעבור ל-hosted.

🧵 חוט הפרויקט — איפה אנחנו על הציר

פרק 7 (זיכרון ו-Dreaming): חיברנו ל-harness memory store מובנה ושיפור עצמי אסינכרוני — הצוות מפסיק לחזור על אותן טעויות.

הפרק הזה (8 — האחרון): מחווטים את כל שבע השכבות יחד לצוות שעובד לבד על משימת end-to-end, ומחליטים in-process מול hosted ל-production.

הבא: זהו. אין פרק 9. עם סיום הפרק הזה ה-harness שלך חי, רץ, ואתה יודע להחליט איפה לפרוס אותו. סוגרים את הקורס.

🎯 מטרות למידה

בסוף הפרק הזה תדע/י:

📋 דרישות קדם — מסתמכים על כל הקורס

זה הפרק האינטגרטיבי. הוא מחווט יחד את כל מה שבנינו, אז הוא מסתמך על כל שבעת הפרקים הקודמים:

נדרש גם: חשבון Anthropic עם API key פעיל (לא subscription בלבד — נסביר למה זה קריטי דווקא כאן), ונוחות ב-Terminal.

📦 מה תפיק/י בפרק הזה (Deliverables)

  1. harness שלם וחי — צוות שעובד לבד על משימת end-to-end (lead-enrichment pipeline): supervisor + 3 subagents + context + tools + gates + observability + recovery + memory, רץ מקצה לקצה.
  2. מטריצת in-process מול hosted — טבלת החלטה Claude Agent SDK מול Claude Managed Agents (control / cost / sandboxing / scaling / freshness), עם ההמלצה לפרויקט שלך.
  3. גרסת CMA — אותה משימה משוגרת ל-Claude Managed Agents עם ה-header managed-agents-2026-04-01, ומסמך "מה נשאר בידיי".
  4. cost-per-run calculator — אומדן tokens לריצה (supervisor + N subagents + memory + Dreaming) מתורגם לעלות חודשית ב-USD עם הערת VAT/ILS.
  5. Production readiness checklist + freshness/beta risk audit — 10–15 בדיקות לפני שמשחררים, וטבלת GA מול preview/beta.
  6. Abstraction layer wrappers — קוד עוטף לכל feature ב-preview/beta (V2 Session API, Dreaming, CMA) עם fallback מתועד.
  7. Cost Cascade diagram — מפה ויזואלית של זרימת ה-tokens בצוות, עם נקודות חיתוך אפשריות.

הארכיטקטורה של הצוות שעובד לבד — חיווט שבע השכבות

אינטגרציהארכיטקטורהcapstone#framework

עד עכשיו כל פרק הוסיף שכבה אחת ל-harness ובדק אותה בבידוד. בפרק הזה אנחנו עושים את הדבר שמבדיל בין "אוסף רכיבים שעובדים כל אחד לחוד" לבין "מערכת production": אנחנו מחווטים את כולם יחד ומגלים שהאינטגרציה היא לא העתק-הדבק של שבעה קטעי קוד — היא ההחלטות על איך השכבות מדברות ביניהן.

בואו נמפה את הצוות שעובד לבד כפי שהוא נראה כשהכל מחובר. המשימה שתלווה אותנו לאורך הפרק היא lead-enrichment pipeline — דוגמה אמיתית שמופיעה ב-course.research.json תחת creative_uses: ניטור כוכבי GitHub על ריפו open-source (למשל aden-hive/hive), העשרת ה-lead דרך Apollo, ניסוח טיוטת outreach מותאמת, ועצירה ל-human-approval דרך policy gate לפני שליחת מייל.

שכבהנבנתה ב-תפקיד בצוות שעובד לבד
Supervisor loopפרק 6מפרק את ה-pipeline לתת-משימות, מפצל subagents, מאחד תוצאות.
Subagents (×3)פרק 6monitor (GitHub) · enricher (Apollo) · writer (טיוטת outreach) — כל אחד session נפרד.
Context managementפרק 3handoff ממוקד מ-supervisor ל-subagent; threshold-backup לפני compaction.
Structured tools + MCPפרק 4כל tool מחזיר JSON עם schema קשיח; חיבור Apollo/GitHub דרך MCP.
Governance gatesפרק 4send_email → require-human-approval; bash rm -rf → block.
Observability + recoveryפרק 5trace לכל subagent כ-span; circuit-breaker; failure capture.
Memory + Dreamingפרק 7store של decisions/failures/patterns; Dreaming מרוסן לשיפור עצמי.

שימו לב לדבר אחד: ה-supervisor הוא harness שמעל harnesses. כל subagent הוא בעצמו לולאת agent מלאה עם ה-context, ה-tools וה-gates שלו. זה בדיוק מקור הכוח (בידוד, parallelism) וגם מקור הסכנה (כל subagent הוא session נפרד ששורף tokens — נחזור לזה ב-cost section).

למה דווקא lead-enrichment ולא משימה אחרת? כי הוא נוגע בכל נקודת כאב שהקורס פתר. הוא ארוך — מספיק turns כדי שה-context יתקרב ל-cliff (פרק 3). הוא מקבילי — שלושה תפקידים שונים שאפשר לפצל ל-subagents (פרק 6). הוא מסוכן — שולח מיילים לאנשים אמיתיים, מה שמחייב human-approval gate (פרק 4). והוא חוזר על עצמו — אותם סוגי leads, אותן שגיאות, מה שהופך אותו למקרה מבחן מושלם ל-memory ו-Dreaming (פרק 7). אם ה-harness שלך מריץ את ה-pipeline הזה נקי, הוא יריץ כמעט כל משימת אוטומציה עסקית.

חשוב להבין מה לא משתנה כשעוברים מ-demo ל-production. ב-demo כל שכבה רצה לבד ואתה צופה בה. ב-production אף אחד לא צופה — הצוות רץ בלילה, מול leads אמיתיים, מול חשבון tokens אמיתי. לכן כל החלטת חיווט נמדדת בשאלה אחת: "מה קורה כשזה נכשל ב-3 בבוקר ואני ישן?". אם התשובה היא "ה-pipeline נעצר בשקט, רושם failure, ומחכה לי" — זה production. אם התשובה היא "הוא שולח 50 מיילים שגויים" — זה demo מסוכן שמתחזה ל-production.

חמשת התפקידים של ה-subagent — לא רק "monitor, enricher, writer"

בפרק 6 דיברנו על supervisor שמפצל subagents, אבל בצוות שעובד לבד יש חמישה תפקידים ארכיטקטוניים שכל subagent יכול למלא, ולכל תפקיד יש השלכות שונות על context, budget ו-recovery:

1. Worker (עובד) — ברירת המחדל

מבצע משימה אטומית ומחזיר תוצאה. monitor ו-enricher ב-pipeline שלנו הם workers. הגדרות ברירת מחדל: budget 30K-60K, max-turns 10-15, circuit-breaker סף 3.

2. Specialist (מומחה) — worker עם context עשיר

worker שצריך היסטוריה ארוכה — למשל writer שצריך לראות את כל ה-leads הקודמים כדי לשמור על טון עקבי. הגדרות שונות: budget גדול יותר (80K-120K), handoff שכולל רק את ה-leads הרלוונטיים, לא את כל ה-history.

3. Gatekeeper (שומר סף) — worker שמאשר/דוחה

subagent שתפקידו לבדוק תוצר של worker אחר לפי קריטריונים דטרמיניסטיים. למשל: "האם הטיוטה הזו מכילה את כל 3 שדות הנדרשים?". שימושי כשרוצים שכבת validation אנושית-מבוססת-AI לפני שממשיכים.

4. Synthesizer (מסכם) — worker שמאחד

הסוכן האחרון בצוות, שלוקח תוצרים של כל ה-workers ומייצר פלט סופי אחד. ב-lead-enrichment זה ה-subagent שמייצר קובץ CSV עם כל ה-leads והטיוטות. הגדרות שונות: handoff עשיר (קיבל את כל הפלטים), budget גדול.

5. Auditor (מבקר) — worker שבודק את עצמו

subagent שמקבל תוצר של worker אחר ומנסה "לשבור" אותו — חיפוש הזיות, אי-עקביות, או הפרות policy. הוא לא תמיד רץ — רק כשצריך ביטחון גבוה (לפני פעולה הרסנית). הגדרות שונות: רץ במצב "scoring" ומחזיר score, לא תוצאה.

ב-pipeline הבסיסי שלנו נשתמש ב-workers, ובסוף נראה איך להוסיף auditor לפני שליחת המייל — שימו לב איך זה מוסיף עוד רמה של בטיחות מעל ה-human-approval gate.

✅ Do Now — שרטוט המפה לפני קוד

פתח/י דף ריק. צייר/י את שבע השכבות מהטבלה כקופסאות, וחבר/י ביניהן חיצים שמראים מה זורם: ה-goal נכנס ל-supervisor, ה-supervisor שולח context ממוקד לכל subagent, כל subagent מחזיר structured output, וה-failures זורמים ל-memory store. אם אתה לא יכול לצייר את זרימת הנתונים — עוד אין לך ארכיטקטורה, יש לך אוסף קבצים.

העיקרון המארגן: data flow, לא code flow

הטעות הקלאסית באינטגרציה היא לחשוב על "באיזה סדר לקרוא לפונקציות". זה code flow, והוא מטעה. החשיבה הנכונה היא data flow: איזה אובייקט state עובר בין השכבות, ומי בעלים שלו בכל רגע. ב-harness שלנו יש אובייקט מרכזי אחד — נקרא לו RunState — שמחזיק את ה-goal, את ה-messages, את ה-token accounting, את ה-trace_id ואת ה-reference ל-memory store. כל שכבה מקבלת אותו, נוגעת רק בחלק שלה, ומעבירה הלאה.

למה זה כל כך משנה? כי בלי RunState מרכזי, כל שכבה מתחילה לשמור עותק משלה של מה שהיא צריכה — וזה הרגע שבו ה-context מתנפח והאינטגרציה מתפרקת. שכבת ה-recovery (פרק 5) צריכה לדעת כמה turns כבר היו; שכבת ה-context (פרק 3) צריכה לדעת כמה tokens נצרכו; שכבת ה-cost צריכה את שניהם. אם כל אחת מודדת בנפרד, יש לך שלוש מדידות שלא מסכימות זו עם זו, ובאג שאי אפשר לדבג. עם RunState אחד, יש מקור אמת יחיד, וכל שכבה קוראת ממנו וכותבת אליו את החלק שלה בלבד.

# RunState — האובייקט שעובר בין כל השכבות (דוגמה מייצגת)
from dataclasses import dataclass, field

@dataclass
class RunState:
    goal: str
    messages: list = field(default_factory=list)   # פרק 2: message state
    tokens_used: int = 0                            # פרק 3: token accounting
    context_pct: float = 0.0                        # פרק 3: 83.5% threshold
    trace_id: str = ""                              # פרק 5: Langfuse span
    tool_call_log: list = field(default_factory=list)  # פרק 5: loop detection
    memory_ref: object = None                       # פרק 7: memory store
    budget_tokens: int = 200_000                    # פרק 6: subagent cap

ברגע שיש לך RunState אחד שעובר בכל מקום, האינטגרציה הופכת ממנגנון מבלבל למשהו שאפשר לקרוא: כל שכבה היא פונקציה layer(state) -> state. זה גם מה שיהפוך את ההחלטה in-process מול hosted לפשוטה בהמשך — כי ה-state הזה הוא בדיוק מה ש-Anthropic מנהלת בשבילך ב-hosted.

Anti-Patterns — ארבע דרכים נפוצות להרוס צוות שעובד לבד

לפני שממשיכים, חשוב להכיר את הדפוסים השליליים הנפוצים. אלה הצורות הקלאסיות שבהן harness "כמעט עובד" — אבל מתפרק תחת עומס, תחת production, או סתם בלילה השלישי.

1. "God Supervisor" — ה-supervisor שעושה הכל

supervisor שמתזמר את כל המשימה בעצמו, ללא subagents. נראה "פשוט" — אין תקורה של פיצול, אין סיבוך של קואורדינציה. בפועל: ה-context של ה-supervisor מתנפח תוך 3-4 ריצות, הוא מתחיל לשכוח constraints, וכל sub-task "כבד" גורר את כל הצוות לאטיות. הסימן המובהק: ה-supervisor מבצע קריאות ל-Apollo ו-GitHub בעצמו, במקום להאציל. הנגד: כל תפקיד עם state משלו = subagent.

2. "Context Soup" — העברת כל ההיסטוריה לכל subagent

handoff שמעביר לכל subagent "ליתר ביטחון" את כל היסטוריית השיחה. התוצאה: כל subagent מתחיל עם 50K-100K tokens של context מיותר, מאיץ את ה-compaction (פרק 3), ומכפיל את העלות פי 3. הסימן המובהק: הצוות מתחיל "לאבד זיכרון" באמצע ריצה. הנגד: distillation קפדני בכל handoff — רק מה שרלוונטי למשימה.

3. "Approval Theater" — human-approval שלא באמת עוצר

policy gate שמבקש אישור אדם, אבל הסוכן ממשיך אוטומטית אחרי timeout של 30 שניות. הסימן המובהק: "אישרתי" הופך לפעולה ריקה, ולאנשים אין זמן לקרוא מה הם מאשרים. הנגד: gate אמיתי = חוסם עד תגובה אנושית, עם UI שמציג את הפעולה במלואה.

4. "Dreams Everywhere" — Dreaming ללא רסן

Dreaming מתוזמן אחרי כל ריצה, או scope של 100+ transcripts בכל מחזור. הסימן המובהק: החשבון בסוף החודש גדול פי 5 מהצפוי, ורוב ה-tokens הלכו ל-curation, לא ל-production. הנגד: תדירות מרוסנת (פעם ביום/שבוע), scope מצומצם, ו-budget cap על כל מחזור Dreaming.

⚠️ טעות נפוצה: "אינטגרציה = למזג את שבעת קבצי הפרקים"

הרבה אנשים מנסים לחווט production על ידי copy-paste של הקוד משבעת הפרקים לקובץ אחד ענק. התוצאה: שכבות שדורסות זו את ה-state של זו, context שמתנפח כי כל שכבה שומרת עותק משלה, ובאג שאי אפשר לדבג כי אין בעלות ברורה. הנגד: אובייקט state אחד (RunState), כל שכבה היא טרנספורמציה עליו, ובעלות ברורה על כל שדה.

⚠️ טעות נפוצה: "ה-subagent יודע מה הוא עושה, לא צריך circuit-breaker"

circuit-breaker נתפס לפעמים כ"פיצ'ר נחמד" או "משהו למקרה חירום". בפועל, subagent שמבצע קריאה חוזרת לאותו tool (למשל קורא שוב ושוב את Apollo בגלל timeout שקט) הוא הסכנה הכי שכיחה ב-production. בלי circuit-breaker, הוא ירוץ עד max-turns וישרוף את כל ה-budget של הצוות. circuit-breaker הוא חובה, לא אופציה — בדיוק כמו seatbelt.

חיווט הקוד — מ-supervisor ועד memory, מקצה לקצה

קודorchestrationאינטגרציה#actionable

עכשיו נחווט בפועל. אני אראה את ה-supervisor loop — הלב של הצוות — כשהוא מפעיל את כל השכבות. שימו לב איך כל קריאה מצביעה חזרה לפרק שבנה אותה; זה לא קוד חדש, זו תזמורת של מה שכבר יש לך.

# supervisor.py — הצוות שעובד לבד, מחווט. (דוגמה מייצגת)
from claude_agent_sdk import query           # פרק 2: ה-SDK
from harness.context import backup_if_near_threshold  # פרק 3
from harness.gates import policy_gate         # פרק 4
from harness.trace import span                # פרק 5
from harness.recovery import circuit_breaker  # פרק 5
from harness.memory import recall, remember   # פרק 7

SUBAGENTS = ["monitor", "enricher", "writer"]

async def run_team(goal: str, state: RunState):
    with span("supervisor", state.trace_id):
        # פרק 7: קוראים patterns רלוונטיים מהזיכרון — לא את כל ה-store!
        learned = recall(state.memory_ref, task=goal, top_k=3)
        plan = await plan_subtasks(goal, learned, state)

        results = []
        for name in SUBAGENTS:
            subtask = plan[name]
            # פרק 6: כל subagent עם budget cap משלו
            sub_state = handoff(state, focus=subtask, budget=60_000)
            try:
                out = await run_subagent(name, sub_state)   # session נפרד
            except CircuitBreakerTripped as e:              # פרק 5
                remember(state.memory_ref, failure=e.record)  # פרק 7
                out = await fallback(name, sub_state)
            results.append(out)

        return await synthesize(results, state)

ועכשיו ה-subagent עצמו — לולאת agent מלאה מהפרקים 2–5, מקופלת לפונקציה אחת:

async def run_subagent(name: str, state: RunState):
    breaker = circuit_breaker(max_repeats=3)   # פרק 5
    for turn in range(20):                      # פרק 2: max-turns
        backup_if_near_threshold(state, at=0.75)  # פרק 3: לפני 83.5%
        resp = await call_model(state)
        for call in resp.tool_calls:
            breaker.check(call)                 # פרק 5: loop detection
            decision = policy_gate(call)        # פרק 4: gate דטרמיניסטי
            if decision == "require_human":
                await pause_for_approval(call)  # human-in-the-loop
            elif decision == "deny":
                continue
            result = await run_tool(call)       # פרק 4: structured output
            state.messages.append(tool_result(call, result))
        if resp.is_final:
            return resp.output
    raise MaxTurnsReached(name)

שימו לב לשלושה דברים שהפכו את זה ל-production ולא ל-demo:

  1. כל subagent מגודר פעמיים: max-turns מבחוץ (פרק 2) ו-budget cap מבפנים (פרק 6). אם monitor בורח, הוא לא לוקח את כל ה-budget של הצוות.
  2. כשל לא מפיל את הצוות: circuit_breaker תופס לולאה, רושם failure ל-memory, ועובר ל-fallback — ה-pipeline ממשיך.
  3. ה-gate הוא דטרמיניסטי: send_email תמיד עוצר באדם, גם אם המודל "החליט" שהוא בטוח. ה-prompt לא יכול לעקוף את זה.

שימו לב גם למה ש-לא נמצא בקוד: אין try/except אחד ענק שעוטף את כל הריצה ו"מקווה לטוב". כל כשל נתפס במקום הספציפי שלו, עם השכבה שאחראית עליו. circuit-breaker תופס לולאות; policy gate תופס פעולות מסוכנות; max-turns תופס ריצות שלא נגמרות. זה ההבדל בין harness ש"יודע למה הוא נכשל" לבין סקריפט ש"קרס ולא יודע למה". כל בלם הוא ספציפי, וכל בלם מצביע על שכבה.

ה-handoff — הנקודה שהכי קל לפשל בה

הפונקציה handoff(state, focus=subtask, budget=60_000) נראית תמימה, אבל היא הנקודה הכי רגישה בכל החיווט. מה היא עושה? היא מעבירה ל-subagent רק את ה-context הממוקד למשימה שלו — לא את כל ההיסטוריה של ה-supervisor. הטעות הנפוצה (ונחזור אליה ב-warning) היא להעביר לכל subagent "ליתר ביטחון" את כל ההיסטוריה. התוצאה: כל subagent מתחיל עם context מנופח, מאיץ compaction (פרק 3), ושורף tokens מיותרים — והכל מוכפל ב-3 subagents. handoff נכון הוא distillation: מהי המשימה, מה ה-leads הרלוונטיים, ומה ה-constraints — ותו לא.

יש שלושה דפוסי handoff שכדאי להכיר:

דפוס 1: Distilled Handoff (ברירת המחדל)

supervisor שולח רק את ה-subtask, את ה-constraints, ואת הזיכרון הרלוונטי. זה הדפוס הבריא. ה-subagent מתחיל עם 5K-10K tokens של context, מה שנותן לו מרחב נשימה ארוך.

דפוס 2: Reference Handoff (לתוצרים גדולים)

במקום להעביר קובץ CSV של 10K שורות לתוך ה-context, ה-supervisor שומר אותו ב-store חיצוני (למשל S3) ושולח רק {"ref": "s3://leads/2026-06-05.csv"}. ה-subagent קורא את הקובץ דרך כלי ייעודי, בלי להעתיק אותו לתוך ההיסטוריה. זה ההבדל בין "הקובץ זמין" לבין "הקובץ בתוך ההקשר שלי".

דפוס 3: Carryover Handoff (לכמה subagents רצופים)

כש-subagent A מייצר תוצר ש-subagent B צריך לעבד, ו-B לא צריך את כל ה-history של A. במקום זה, B מקבל רק את הפלט הסופי של A (structured, per פרק 4) — ולא את המסלול ש-A עבר כדי להגיע לשם. זה חוסך טוקנים וגם מונע "זיהום" של B בניסיונות כושלים של A.

✅ Do Now — בדיקת ה-handoff שלך

פתח/י את הקוד של ה-handoff שלך (או את הסקיצה שלו). ספור/י כמה tokens עוברים בכל קריאה. אם המספר גדול מ-15K-20K לכל handoff, כנראה אתה ב-Context Soup. שאל/י את עצמך: "האם ה-subagent באמת צריך את כל זה, או שזה 'ליתר ביטחון' שלי?".

מחזור החיים של ריצה (Run Lifecycle) — חמש הפאזות

כל ריצה של צוות שעובד לבד עוברת חמש פאזות, ולכל פאזה יש מאפיינים שמשפיעים על החיווט. הבנה של הפאזות עוזרת לדבג בעיות ("האם זה ב-pre-flight או ב-descent?") ולהחליט איפה לשים observability נוסף.

פאזה 1: Pre-Flight (לפני ההמראה)

טעינת ה-goal, אימות auth (API key, לא subscription!), בדיקת budget זמין, recall מה-memory store. טעות נפוצה: לדלג על הבדיקות האלה ולהגיע לפאזה 3 בלי budget.

פאזה 2: Climb (עלייה — planning)

supervisor מפרק את ה-goal לתת-משימות, בונה plan, ומחליט איזה subagents להפעיל. טעות נפוצה: plan שמבוסס על memory ישן ולא רלוונטי (top_k גדול מדי ב-recall).

פאזה 3: Plateau (ריצה אמיתית)

ה-subagents רצים, הכלים נקראים, ה-tokens נצרכים, ה-policy gates פועלים. זו הפאזה הארוכה ביותר. טעות נפוצה: בלי circuit-breaker, subagent אחד תוקע את כולם.

פאזה 4: Descent (סינתזה ואישור)

ה-supervisor מאחד תוצאות, מפעיל human-approval על פעולות הרסניות, מכין את הפלט הסופי. טעות נפוצה: לבקש אישור אחרי שכבר בוצעה הפעולה.

פאזה 5: Post-Flight (לאחר נחיתה)

כתיבת ה-failures ל-memory store, עדכון ה-tracing ב-Langfuse, חישוב עלות, סגירת spans. טעות נפוצה: לדלג על זה — ואז ב-debugging הבא אין לך מידע.

🧭 Framework: "אם X אז Y" — איזו שכבה אחראית כשהצוות נתקע

כשהצוות שעובד לבד נתקע, אל תנחש. השתמש/י בעץ ההחלטה הזה כדי לדעת איזו שכבה אשמה:

העיקרון: לכל סוג כשל יש שכבה אחראית. אם אתה לא יכול למפות כשל לשכבה — חסרה לך observability (פרק 5), וזו הבעיה הראשונה לתקן.

✅ Do Now — הרץ/י את עץ ההחלטה על כשל ישן

חזור/י לפרק כלשהו קודם בקורס שבו הסוכן שלך נתקע (למשל לולאת tool בפרק 5, או context שנמחק בפרק 3). קח/י את הכשל ההוא, והעבר/י אותו דרך ה-Framework של "אם X אז Y" שלמעלה. האם הצלחת למפות אותו לשכבה אחת ברורה? אם כן — אתה כבר חושב כמהנדס harness. אם לא — סמן/י את הכשל הזה כ"חסר observability" וזכור/י אותו לתרגיל ה-audit בסוף הפרק.

▶️ הפעל/י את סביבת הקורס לפני תרגיל 1

הריצה הראשונה של הצוות תיכשל אם ה-venv לא פעיל או אם ANTHROPIC_API_KEY חסר. בצע/י בדיוק את הרצף הזה מתוך תיקיית הקורס:

source .venv/bin/activate
export ANTHROPIC_API_KEY=sk-ant-...
export LANGFUSE_PUBLIC_KEY=pk-lf-...
export LANGFUSE_SECRET_KEY=sk-lf-...
make harness-up   # או: python -m harness.cli up

איך תדע/י שזה מוכן? הרץ/י make harness-doctor — הוא מחזיר OK: api_key, langfuse, venv, 3 tools ב-4 שורות. אם חסר אחד מהם, תרגיל 1 נופל על MissingApiKeyError או Langfuse 401 לפני שה-supervisor בכלל מתחיל.

🏋️ תרגיל קפסטון 1 — חיווט הצוות המלא end-to-end

משלב פרקים: 2 (loop) + 3 (context) + 4 (gates) + 5 (recovery) + 6 (orchestration) + 7 (memory).

בנה/י את ה-lead-enrichment pipeline המלא כצוות של 3 subagents תחת supervisor אחד. התחל/י מ-mock data קבוע (אנחנו בודקים חיווט, לא חיבור GitHub/Apollo אמיתי):

// fixtures/stargazers.json — קלט דטרמיניסטי ל-monitor
{
  "repo": "aden-hive/hive",
  "since": "2026-06-19T00:00:00Z",
  "stargazers": [
    {"login": "jane-doe",     "starred_at": "2026-06-20T14:02:11Z"},
    {"login": "acme-eng",     "starred_at": "2026-06-20T15:31:48Z"},
    {"login": "noa-lev",      "starred_at": "2026-06-20T18:09:05Z"}
  ]
}

// fixtures/apollo_mock.json — קלט דטרמיניסטי ל-enricher
{
  "jane-doe": {"name":"Jane Doe","company":"Acme","title":"Staff Eng"},
  "acme-eng": {"name":"Acme Eng","company":"Acme","title":"DevRel"},
  "noa-lev":  {"name":"Noa Lev", "company":"LevLabs","title":"Founder"}
}
  1. monitor (פלט צפוי: list[Lead] עם 3 רשומות): tool fetch_stargazers שקורא את fixtures/stargazers.json ומחזיר structured JSON עם schema קשיח: {login: str, starred_at: iso8601}. אסור free-text — רק JSON (פרק 4).
  2. enricher (פלט צפוי: list[EnrichedLead] עם 3 רשומות מועשרות): מקבל את ה-leads, קורא fixtures/apollo_mock.json, ומחזיר {login, name, company, title} לכל אחד. budget cap = 60_000 tokens, max_turns = 8 (פרק 6).
  3. writer (פלט צפוי: 3 קבצי .md ב-./drafts/): מנסח טיוטת outreach לכל lead. הוא לא שולח — הוא רק כותב קובץ. הפעולה send_email מוגדרת כ-tool נפרד שעובר policy_gate ומחזיר require_human (פרק 4).
  4. circuit_breaker + memory (פלט צפוי: span ב-Langfuse + שורה ב-memory.db): חבר/י circuit_breaker(max_repeats=3) לכל subagent (פרק 5) ו-remember() שרושם כל CircuitBreakerTripped ל-memory store (פרק 7).
  5. הרצה (פלט צפוי: AWAITING_HUMAN_APPROVAL ב-stdout): הרץ/י python -m harness.cli run --goal "enrich new stargazers of aden-hive/hive". ה-pipeline חייב לעצור על send_email עם הודעה ברורה, לא להמשיך ולשלוח.

קריטריוני הצלחה (חובה לעבור את כולם):

פלט נראה לעין: ריצה שמסתיימת עם 3 טיוטות מייל בתיקייה ./drafts/, log שמראה שה-supervisor פיצל 3 subagents, וה-pipeline נעצר ופנה אליך לאישור לפני שליחה. אם הוא שלח בלי לשאול — ה-gate לא מחובר נכון.

ההחלטה הגדולה: In-Process מול Hosted

החלטהproductionCMA#framework

זו ההחלטה שחזרה לאורך כל הקורס, ועכשיו, כשיש לך harness שלם, אפשר סוף-סוף להכריע בה במספרים. השאלה: האם להריץ את הצוות in-process — אתה מחזיק את הלולאה, ה-sandbox וה-scaling (Claude Agent SDK) — או hosted, כש-Anthropic מנהלת את כל זה (Claude Managed Agents)?

הסיבה שדחינו את ההחלטה הזו עד הפרק האחרון היא לא במקרה. אי אפשר להחליט נכון לפני שבנית את ה-harness, כי לפני שבנית אתה לא יודע כמה שליטה אתה באמת צריך. מי שמתחיל פרויקט בשאלה "in-process או hosted?" מחליט בעיוורון. מי ששואל אותה אחרי שבנה loop מותאם, context strategy, policy gates ו-observability — יודע בדיוק מה הוא ישים על הכף. זו הסיבה שזו השאלה האחרונה בקורס, לא הראשונה.

מה זה Claude Managed Agents (CMA)

לפי course.research.json: CMA הוא REST API serverless מנוהל לחלוטין, שבו Anthropic מנהלת את agent loop, את ה-execution harness, את ה-sandboxing המאובטח ואת ה-session persistence. הוא יצא ל-public beta ב-8 באפריל 2026 ודורש header managed-agents-2026-04-01. המחיר הוא API-only, ופרטי ה-pricing וה-sandboxing עשויים להשתנות (זה beta — נחזור לזה ב-risk audit).

⚠️ טעות נפוצה: לעבור ל-CMA בגלל "הנוחות" בלי למפות מה מאבדים

זו הטעות הכי יקרה בפרק הזה. CMA נראה מפתה — "Anthropic תנהל הכל בשבילי!" — אבל כל מה שבנינו בקורס (ה-loop המותאם, אסטרטגיית ה-context, ה-policy gates הביתיים שלך, ה-tracing הספציפי שלך ב-Langfuse) עובר לניהול Anthropic, ואתה מאבד עליו שליטה fine-grained. ההחלטה הזו חייבת להתקבל ממטריצה מסודרת, לא מתחושה. בוא נבנה אותה.

קריטריוןIn-Process (Claude Agent SDK)Hosted (Claude Managed Agents)
בעלות על הלולאהשלך. שולט בכל iteration, stop condition, max-turns.של Anthropic. הלולאה היא קופסה מנוהלת.
Governance מותאםpolicy gates ביתיים (Faramesh/FPL) — שליטה מלאה.מוגבל למה ש-CMA חושף; gates מותאמים פחות גמישים.
ObservabilityLangfuse המותאם שלך, כל span כפי שהגדרת.מה ש-CMA מספק; tracing מותאם פחות.
Sandboxingבאחריותך — צריך לבנות ולתחזק לבד.מנוהל ע"י Anthropic — יתרון גדול.
Scalingאתה מתחזק את התשתית, ה-queues, ה-concurrency.serverless — Anthropic מסקיילת.
Session persistenceאתה בונה את ה-store.מנוהל ב-CMA.
בשלות (freshness)SDK יציב; core loop GA.public beta — pricing/sandboxing עשויים להשתנות.
Latency לריצה ראשונהתלוי ב-runtime שלך.cold start אפשרי ב-serverless.
Lock-inנמוך — אתה מחזיק את הקוד.גבוה יותר — config ספציפי ל-Anthropic.

🧭 Framework: "אם X אז Y" — In-Process מול Hosted

אל תבחר לפי אופנה. בחר לפי החיתוך הזה:

הכלל הזהב: ככל שבנית יותר harness מותאם (וסיימת קורס שלם של זה), כך ה-tradeoff נוטה ל-in-process — כי ה-hosted מבטל בדיוק את העבודה שעשית.

יש כאן ניואנס שחובה לא לפספס: ההחלטה אינה בינארית ולא נצחית. אפשר להתחיל in-process כדי לפתח ולדבג עם שליטה מלאה (ה-tracing המותאם שלך עוזר דווקא בשלב הזה), ואז — כשהמשימה התייצבה וה-governance שלה פשוט — לשקול מעבר ל-CMA כדי להוריד עומס תחזוקת sandbox ו-scaling. גם ההפך לגיטימי: להתחיל ב-CMA כדי לעלות לאוויר מהר, ואם מגלים שצריך governance מותאם שה-beta לא חושף — להחזיר את הלולאה הביתה. המטריצה היא כלי שמריצים מחדש בכל נקודת החלטה, לא חותמת שמטביעים פעם אחת.

תרחיש א — סטארטאפ בן 3 אנשים, lead-enrichment בלבד

מצב: אין DevOps, אין תקציב sandbox, רוצים לעלות לאוויר מהר. המלצה: CMA. ה-governance פשוט (אישור אדם אחד), ה-sandboxing קריטי, ואין כוח אדם לתחזק. החיסרון (אובדן observability מותאם) לא משמעותי כשהמשימה פשוטה.

תרחיש ב — חברת ביטוח עם ציות רגולטורי

מצב: traces חייבים להישאר on-prem, audit logs מלאים, policy gates מורכבים. המלצה: in-process, ללא ספק. ה-hosted שולח מידע רגולטורי לענן, וזה לא חוקי במקרים מסוימים.

תרחיש ג — חברת SaaS בינונית עם 10,000 ריצות/יום

מצב: צריכים scaling אמיתי, אבל גם observability מותאם ו-budgeting מדויק. המלצה: hybrid — in-process loop, אבל עם containerized sandbox מנוהל (לא CMA מלא). זה שומר על השליטה ומוריד חלק מהתחזוקה.

✅ Do Now — מבחן ה-3 שאלות לפני שאתה אפילו פותח את המטריצה

לפני שתבנה מטריצה מלאה, ענה/י על שלוש שאלות מהירות בראש: (1) האם ה-human-approval gate שלי מותאם ומורכב, או פשוט? (2) האם אני סובל ש-pricing יכול להשתנות עליי בלי הודעה ארוכה (beta)? (3) האם תחזוקת sandbox ו-scaling היא כאב אמיתי אצלי, או שזה לא הצוואר-בקבוק? אם ענית "מורכב / לא סובל / לא כאב" — אתה כנראה in-process. אם ענית "פשוט / סובל / כן כאב" — שווה לבדוק CMA ברצינות.

🏋️ תרגיל קפסטון 2 — בניית מטריצת ההחלטה לפרויקט שלך

משלב: פרק 1 (in-process vs hosted) + פרק 4 (governance) + פרק 5 (observability) + הפרק הזה (CMA).

קח/י את ה-lead-enrichment pipeline שבנית ב-תרגיל 1, ומלא/י מטריצת החלטה אמיתית:

  1. צור/י קובץ in-process-vs-hosted.md עם הטבלה מהפרק כשלד.
  2. לכל שורה, כתוב/י את הערך הספציפי לפרויקט שלך: כמה sandboxing אתה באמת צריך? כמה ה-human-approval gate שלך מותאם? האם אתה סובל beta?
  3. תן/י לכל קריטריון משקל (1–5) לפי כמה הוא חשוב לך, וחשב/י ציון משוקלל לכל עמודה.
  4. כתוב/י שורת המלצה אחת: "אני נשאר in-process כי ___" או "אני עובר ל-CMA כי ___" — עם הנימוק המספרי.
  5. בחר/י אחד משלושת התרחישים (א/ב/ג) שמתאר הכי טוב את המצב שלך, וציין/י אם המלצתך תואמת.
פלט נראה לעין: מסמך in-process-vs-hosted.md עם טבלה ממולאת, ציון משוקלל לכל עמודה, והחלטה מנומקת אחת. זה לא תרגיל אקדמי — זה המסמך שתראה למנהל/ללקוח כשישאלו "למה לא עברנו ל-hosted?".

להעביר harness ל-CMA — מה מרוויחים, מה מאבדים

CMAmigrationbeta#actionable

נניח שמילאת את המטריצה והיא הצביעה על hosted (תרחיש לגיטימי: צוות קטן, scaling יקר לתחזק, governance פשוט). בוא נראה איך זה נראה בפועל. ההעברה ל-CMA היא לא rewrite — היא שינוי של מי מחזיק את הלולאה.

# הרצה via CMA — Anthropic מחזיקה את הלולאה. (דוגמה מייצגת)
import anthropic
client = anthropic.Anthropic()

run = client.beta.managed_agents.create(
    extra_headers={"anthropic-beta": "managed-agents-2026-04-01"},  # נדרש
    agent={
        "system": SUPERVISOR_PROMPT,      # ה-harness config שלך (פרק 2)
        "tools": TOOLS_SCHEMA,            # ה-schemas מפרק 4 — נשמרים!
        "max_turns": 20,                  # פרק 2 — נשמר
    },
    input={"goal": "enrich new stargazers of aden-hive/hive"},
)
# Anthropic מנהלת: loop, sandbox, session persistence, scaling

הקוד נראה קצר וזה לא במקרה — זה כל הרעיון של hosted. במקום לכתוב את ה-supervisor loop, את ה-subagent loop, את ה-context management ואת ה-recovery, אתה מתאר את הסוכן (system, tools, max-turns) ו-Anthropic מריצה את הכל. כל מה שהשקעת בו 200 שורות ב-in-process מצטמק לאובייקט config. זה היתרון — וזו בדיוק הסכנה: הצמצום הזה מסתיר את כל ההחלטות שקיבלת, ואתה כבר לא שולט בהן.

שימו לב מה עבר בקלות ומה נשאר מאחור:

רכיבעובר ל-CMA?הערה
tool schemas (פרק 4)✅ נשמרה-structured outputs שלך תקפים גם ב-CMA.
system prompt / config (פרק 2)✅ נשמרה-harness config עובר כ-system.
max-turns (פרק 2)✅ נשמרנתמך כפרמטר.
policy gates ביתיים (פרק 4)⚠️ חלקיgates דטרמיניסטיים מותאמים — מוגבל למה ש-CMA חושף.
Langfuse tracing מותאם (פרק 5)❌ נאבדה-observability עובר לניהול CMA; ה-spans המותאמים שלך לא.
context strategy ביתי (פרק 3)❌ נאבדcompaction מנוהל ע"י Anthropic — אתה מאבד את ה-threshold-backup שלך.
circuit-breaker מותאם (פרק 5)❌ נאבדrecovery עובר לניהול CMA.
memory store ביתי (פרק 7)❌ נאבדsession persistence מנוהל ע"י CMA; אתה מאבד שליטה על recall.

✅ Do Now — מבחן ה"מה נאבד"

עבור/י על ארבע השורות עם ❌ בטבלה. לכל אחת שאל/י את עצמך: "האם ה-context strategy / circuit-breaker / tracing / memory המותאם שלי הוא סיבה שבניתי harness ביתי, או שזה nice-to-have?". אם זו סיבה — זה דגל אדום למעבר ל-CMA. אם זה nice-to-have — אולי ה-hosted בסדר. כתוב/י את התשובה במשפט אחד לכל שורה.

שכבת ה-Abstraction — איך לעטוף features ב-preview

ההמלצה החוזרת בקורס היא "לעטוף כל feature ב-preview ב-abstraction דקה". הנה דוגמה מעשית למה זה אומר — עבור ה-V2 Session API שהוא unstable_v2_*:

# session_wrapper.py — abstraction מעל V2 Session API
# הקוד שלך משתמש רק ב-SessionManager, לא ב-unstable_v2 ישירות.
from claude_agent_sdk import unstable_v2  # import שעלול להשתנות

class SessionManager:
    """abstraction יציב. הקוד שלך לא מכיר את unstable_v2_*."""

    def __init__(self):
        self.client = unstable_v2.Client()

    def create(self, goal: str) -> str:
        # חתימה נוכחית; אם ה-API ישתנה — משנים רק פה
        return self.client.createSession(goal=goal).id

    def resume(self, session_id: str) -> Session:
        return self.client.resumeSession(id=session_id)

    def fork(self, session_id: str) -> Session:
        return self.client.forkSession(id=session_id)

    def list_active(self) -> list[Session]:
        return self.client.listSessions()

למה זה קריטי? כי כש-Anthropic תשנה את ה-API (והיא תשנה — זה unstable), אתה משנה רק את SessionManager. שאר הקוד ב-harness שלך ממשיך לעבוד. בלי ה-wrapper, היית צריך לעבור 30 קבצים ולתקן כל קריאה.

💡 דפוס Fallback — כשה-feature ה-hosted לא זמין

כל feature ב-preview/beta צריך fallback שעובד בלעדיו. דוגמאות:

הרעיון: ה-feature הוא אופטימיזציה, לא תלות קריטית. אם הוא נופל, המערכת ממשיכה לעבוד.

Playbook להעברה — חמשת הצעדים

הנה רצף מומלץ להעברה בפועל, בלי קפיצות:

שלב 1: זהוי הגרעין

הוצא/י את ה-system prompt, את ה-tools schema, ואת ה-max-turns מהקוד שלך. אלה הולכים ל-CMA כמו שהם. כל השאר — ה-loop, ה-recovery, ה-memory — נשארים בינתיים.

שלב 2: בנה/י adapter

כתוב/י פונקציה run_via_cma(goal) שעוטפת את ה-CMA call. הקוד שמשתמש בה לא יודע שהוא עובר דרך ענן Anthropic. זה ה-fallback layer שלך.

שלב 3: הרצה מקבילה (shadow mode)

הרץ/י את אותה משימה גם ב-in-process וגם ב-CMA, והשווה/י תוצאות. זה עוזר לגלות איפה ה-hosted מתנהג אחרת. אל תעבור ל-CMA production עד שעברת שבוע של shadow mode בלי הפתעות.

שלב 4: מעבר הדרגתי

החלף/י 10% מה-traffic ל-CMA. אם הכל יציב, 50%, אחר כך 100%. כל קפיצה עם rollback plan מוכן.

שלב 5: הסרת הקוד הישן (אופציונלי)

אחרי חודש יציב, אפשר להסיר את ה-in-process code. אבל — וזה חשוב — אל תמחקי אותו. הוא ה-fallback שלך אם CMA יקרוס. שמור/י אותו ב-branch נפרד.

⚠️ טעות נפוצה: "CMA זה drop-in replacement, אין מה לבדוק"

CMA הוא לא drop-in. הוא מנהל דברים שאתה ניהלת, ויש לו התנהגויות שלא תמיד תואמות לציפיות. למשל: latency שונה, error handling שונה, ומקרים שבהם session נמחק בלי שביקשת. תמיד תריצי shadow mode לפני cutover.

מעבר ה-Billing של 15 ביוני 2026 — והעלות האמיתית

billingcosttime-sensitive#concept

זה החלק הכי time-sensitive בכל הקורס, והוא רלוונטי בדיוק עכשיו. לפי course.research.json, ב-15 ביוני 2026 תוכניות ה-subscription של Claude עברו ל-Agent SDK credit חודשי ייעודי שמפריד בין שימוש אינטראקטיבי לאוטומטי. המשמעות הקריטית לצוות שעובד לבד: ריצות אוטומטיות על subscription auth יחטפו rate limits פתאומיים — אלא אם תעבור ל-API key auth.

למה ההפרדה הזו קיימת בכלל? כי עד עכשיו אדם יחיד שמשתמש ב-Claude אינטראקטיבית, וצוות סוכנים שרץ אוטומטית 24/7, נמשכו מאותו דלי. סוכן אוטומטי יכול לשרוף בלילה אחד את מה שאדם שורף בחודש — וזה עיוות שה-billing החדש מתקן בכך שהוא נותן לאוטומציה דלי נפרד (Agent SDK credit) או דורש ממנה auth נפרד (API key). מבחינתך, מהנדס ה-harness, המסקנה פשוטה וחד-משמעית: אם הצוות רץ בלי שאתה יושב מולו, הוא חייב auth שמיועד לאוטומציה.

✅ Do Now — בדיקת ה-auth של הצוות שלך עכשיו

פתח/י את משתני הסביבה של הפרויקט. האם הצוות מאומת דרך ANTHROPIC_API_KEY (טוב — auth לאוטומציה) או דרך session/subscription של חשבון אישי (מסוכן ל-production אוטומטי אחרי 15.6.2026)? אם זה subscription — זה הדבר הראשון לתקן לפני שמשחררים. רשום/י לעצמך: "auth status = ___" וודא/י שזה api_key לפני ה-checklist בסוף הפרק.

⚠️ טעות נפוצה: להשיק צוות אוטומטי על subscription auth

הצוות שעובד לבד הוא בהגדרה אוטומטי — הוא רץ בלי שאתה יושב מולו. אם הוא מאומת דרך ה-subscription האישי שלך, אחרי 15 ביוני 2026 הוא יפגע ב-rate limits באמצע הלילה, ה-pipeline ייעצר, ואתה תגלה רק בבוקר ש-50 leads לא טופלו. production אוטומטי חייב API key auth (או Agent SDK credit מתוכנן מראש). זו לא המלצה — זו תקלה שמחכה לקרות אם תתעלם.

Cost Cascade — מודל זרימת ה-tokens בצוות

הצוות שעובד לבד שורף tokens ביותר מקומות ממה שנראה. הנה המודל המלא של Cost Cascade — איך tokens זורמים דרך הצוות, ואיפה כדאי לחתוך:

🧭 Framework: Cost Cascade — 4 שלבים של זרימת tokens

שלב 1: Supervisor Ingest — ה-supervisor טוען את ה-goal, את ה-memory recall, ואת ה-plan. עלות: ~5K-10K. לא כדאי לחתוך — קריטי לאיכות התוצר.

שלב 2: Handoff Multiplication — כל subagent מקבל העתק של ה-context. עלות: ~10K-20K × N subagents. כאן החיתוך הכי משמעותי — distilled handoff במקום העברה מלאה.

שלב 3: Subagent Execution — כל subagent רץ את הלולאה שלו, עם ה-tool calls והתוצרים. עלות: ~30K-60K × N. כאן budget caps ו-circuit-breakers משחקים.

שלב 4: Synthesis & Approval — איחוד תוצרים, הכנה לאישור אדם, סינתזה סופית. עלות: ~5K-15K. אפשר להוזיל עם parallel synthesis — אבל רק אם היא לא תלויה.

טיפ: צייר/י את ה-Cascade של ה-pipeline שלך עם המספרים האמיתיים מ-Langfuse. 90% מה-tokens יהיו בשלב 2-3. אם הם לא — יש לך בעיה אחרת (אולי supervisor שעושה יותר מדי לבד).

עכשיו נמפה את כל מקורות העלות לריצה אחת ונבנה אומדן. (כל המספרים כאן הם דוגמה מייצגת להמחשת השיטה — חשב/י עם המספרים האמיתיים שלך מ-Langfuse, פרק 5.)

מקור עלותפרקtokens (דוגמה מייצגת)
supervisor loop6~30K (planning + synthesis)
subagent ×3 (כל אחד session נפרד!)6~3 × 50K = 150K
memory reads (patterns, top_k)7~5K
tool results בחזרה ל-context3,4~15K
סה"כ לריצה אחת~200K tokens
Dreaming (curation, לא בכל ריצה!)7עד מיליוני tokens — מתוזמן בנפרד

שלוש תובנות שחייבים להפנים:

  1. ה-subagents הם 75% מהעלות. כל subagent הוא session שלם נפרד (פרק 6) — זה ה-"Parallel Subagent Cost Explosion" מ-course.research.json. בלי budget caps, המספר הזה מתפוצץ אקספוננציאלית.
  2. Dreaming הוא לא חלק מ-cost-per-run — והוא מסוכן יותר. curation על עד 100 transcripts שורף מיליוני tokens (פרק 7). אם תתזמן אותו אחרי כל ריצה, החשבון יתפוצץ בשקט ברקע. תזמן אותו בתדירות מרוסנת.
  3. Tool results זולגים בחזרה ל-context. כל קריאת tool שמחזירה 10K tokens של JSON — התוצר נכנס להיסטוריה של ה-subagent, ומשם ל-supervisor, ומשם לסינתזה. reference handoff (דפוס 2 למעלה) חותך את זה בחדות.

למה האומדן הזה כל כך קל לפספס? כי האינטואיציה אומרת "ריצה אחת = פנייה אחת למודל". אבל ב-multi-agent זה לא נכון: ריצה אחת היא ארבע sessions לפחות (supervisor + 3 subagents), כל אחת עם ה-history המצטבר שלה. וה-history מצטבר בכל turn — אז subagent שעושה 15 turns שולח את כל ה-context שלו 15 פעמים, לא פעם אחת. זו הסיבה שהמספר נראה קטן בראש ("רק 3 subagents") אבל גדול בחשבון. הכלל: אל תאמוד tokens בראש. מדוד אותם ב-Langfuse (פרק 5), כי ה-token attribution לכל span הוא בדיוק מה שהופך את האומדן מניחוש למספר.

ויש כאן גם זווית מעשית של ROI: ה-budget caps וה-circuit-breakers שבנית לא רק מגינים מ-cost explosion — הם חוסכים כסף שנמדד. circuit-breaker שעוצר לולאה אחרי 3 קריאות חוזרות, במקום לתת לה לרוץ עד max-turns של 20, חוסך 17 קריאות מיותרות בכל פעם. כפול מספר הריצות בחודש, זה הופך מ"feature נחמד" ל"שורה בתקציב".

💱 הערת ישראל — VAT ושער ILS

לפי course.research.json, כל שירותי Anthropic ו-LangChain מחויבים ב-USD. למפתח/ת ישראלי/ת: 200K tokens × N ריצות ביום מצטברים מהר, וצריך להוסיף תנודות שער ILS/USD ו-VAT לתקציב. דוגמה מייצגת: 100 ריצות ביום × 200K = 20M tokens/יום. תרגם/י לפי מחיר ה-tokens הנוכחי שלך, הוסף/י VAT, וכפול/י בשער. תקצב/י לפי החודש, לא לפי הריצה.

Agent SDK Credit מול API Key Auth — ההחלטה הבאה

אחרי 15.6.2026 יש שתי אפשרויות לאוטומציה:

אפשרות 1: Agent SDK Credit (מתוך מנוי)

קרדיט חודשי ייעודי לשימוש אוטומטי, נפרד מה-sessions האינטראקטיביים. יתרון: חיזוי עלות חודשית, אינטגרציה עם חשבון Claude קיים. חיסרון: מכסה מוגבלת, אם חורגים — הצוות נעצר.

אפשרות 2: API Key Auth (חיוב לפי שימוש)

auth דרך ANTHROPIC_API_KEY, חיוב לפי tokens בפועל. יתרון: אין מכסה, scaling חופשי, מתאים לעומסים משתנים. חיסרון: דורש ניהול תקציב פנימי כי החיוב תלוי בפעילות.

ההחלטה: עבור צוות שעובד לבד עם עומס יציב, Agent SDK credit יכול להיות זול יותר. עבור עומסים משתנים או spikes, API key auth גמיש יותר. הרבה משתמשים מתחילים ב-API key auth כדי לאמוד עלויות אמיתיות, ואז עוברים ל-credit כשה-baseline יציב.

🏋️ תרגיל קפסטון 3 — cost-per-run calculator לצוות שלך

משלב: פרק 5 (token attribution) + פרק 6 (subagent cost) + פרק 7 (Dreaming burn) + billing.

  1. הרץ/י את ה-pipeline מ-תרגיל 1 פעם אחת עם Langfuse פעיל (פרק 5).
  2. קרא/י את ה-token count האמיתי לכל span: supervisor, כל subagent, memory reads, tool results.
  3. בנה/י סקריפט cost_per_run.py שמקבל את המספרים, מכפיל במחיר ה-tokens, מוסיף VAT, וכופל בשער ILS — ומדפיס עלות חודשית ל-N ריצות ביום.
  4. הוסף/י שורה נפרדת ל-Dreaming: בהינתן תדירות (פעם ביום/שבוע) ו-scope (כמה transcripts), כמה זה מוסיף.
  5. ודא/י שאתה רץ עם API key auth, לא subscription (בדוק/י את משתנה הסביבה).
  6. צייר/י את ה-Cascade של הריצה שלך עם המספרים האמיתיים — וזהה/י איפה החיתוך הכי משמעותי.
פלט נראה לעין: סקריפט שמדפיס טבלה: עלות לריצה / עלות יומית / עלות חודשית — ב-USD וב-ILS עם VAT, עם שורת Dreaming מופרדת. זה המסמך התקציבי שמונע את ההפתעה בחשבון בסוף החודש.

Production Readiness — Checklist ו-Freshness/Beta Risk Audit

productionriskfreshness#checklist

לפני שמשחררים צוות שעובד לבד, צריך לעבור שני שערים: production readiness checklist (האם כל הבלמים מחוברים?) ו-freshness/beta risk audit (מה מבוסס על preview/beta שעלול להישבר?). זה החלק שמבדיל בין "עובד אצלי" לבין "מוכן ל-production".

מה GA מול מה Preview/Beta — מפת הסיכונים

לפי course.research.json ו-course.syllabus.json, חלק מהרכיבים שבנינו עליהם בקורס יציבים, וחלק עדיין מתפתחים. אסור לבנות production קשיח על מה שלא GA:

רכיבסטטוססיכון + נגד
Core agent loop✅ יציבבטוח לבנות עליו.
Model Context Protocol (MCP)✅ סטנדרט פתוחבטוח.
Claude Agent Teams✅ GA (פברואר 2026)בטוח; יצא עם Sonnet 4.6.
Faramesh governance✅ Public Beta, governance-as-codeמתאים לproduction, אבל חתימת policy language עשויה להשתנות.
V2 Session API (unstable_v2_*)⚠️ previewחתימות createSession/resumeSession/forkSession עלולות להשתנות. נגד: עטוף ב-abstraction דקה.
Claude Dreaming⚠️ research preview (מאי 2026)pricing/מגבלות GA מתפתחים. נגד: fallback ל-self-improvement פשוט (סיכום failures ל-prompt).
Claude Managed Agents (CMA)⚠️ public beta (אפריל 2026)דורש header managed-agents-2026-04-01; pricing/sandboxing עשויים להשתנות.
Billing (Agent SDK credit)🔴 השתנה 15.6.2026subscription auto-runs → rate limits. נגד: API key auth.

⚠️ טעות נפוצה: לבנות production קשיח על feature ב-preview

אם תקבע קוד ישירות לחתימות של ה-V2 Session API או תניח ש-Dreaming הוא GA, השדרוג הבא ישבור לך את ה-production. הנגד שחוזר בכל הקורס: כל מה שב-preview/beta נעטף ב-abstraction דקה משלך — כך שכשהחתימה תשתנה, אתה משנה שורה אחת ב-wrapper, לא בכל ה-codebase. ול-Dreaming תמיד יש fallback: סיכום failures פשוט ל-prompt עובד גם בלי ה-feature ה-hosted.

מדד סיכון מצרפי: 4 רכיבים ב-preview/beta, 1 רכיב עם מעבר billing חד. רמת סיכון: בינונית-גבוהה. מתאים ל-Production עם abstraction + fallback לכל רכיב, ועם monitoring אגרסיבי על תקלות API.

✅ Production Readiness Checklist (18 בדיקות)

🏋️ תרגיל קפסטון 4 — Risk Audit ו-Go/No-Go

משלב: כל הקורס — זה ה-audit הסופי לפני שחרור.

התחל/י מה-template המוכן הבא (העתק/י ל-production-audit.md) ומלא/י אותו על ה-harness מתרגיל 1:

# Production Audit — <team-name>
תאריך: ____   חתימה: ____

## A. Production Readiness (18 בדיקות, ✅/❌ + הערה)
- [ ] API key auth (לא subscription)
- [ ] max-turns לכל subagent
- [ ] budget cap לכל subagent
- [ ] circuit_breaker (סף 3+)
- [ ] structured JSON לכל tool
- [ ] retry דטרמיניסטי על schema violation
- [ ] policy gates דטרמיניסטיים
- [ ] human-approval לפני פעולה בלתי-הפיכה
- [ ] threshold-backup ב-75%
- [ ] tool results גדולים = reference, לא context
- [ ] Langfuse tracing פעיל
- [ ] failure capture → memory
- [ ] Dreaming מרוסן (תדירות + scope)
- [ ] parallel calls + caching
- [ ] abstraction + fallback ל-preview/beta
- [ ] distilled handoff
- [ ] RunState יחיד
- [ ] cost-per-run ידוע

## B. Freshness / Beta Risk
| Feature | סטטוס | Abstraction | Fallback |
|---|---|---|---|
| V2 Session API | preview | SessionManager | single-query |
| Dreaming | research preview | DreamingClient | סיכום failures ל-prompt |
| CMA | public beta | HostedRunner | SDK מקומי |

## C. החלטה: GO / NO-GO
נימוק: ____
חוסם (אם NO-GO): ____

דוגמה מלאה — production-audit.md ממולא על ה-lead-enrichment pipeline מתרגיל 1:

בדיקהסטטוסהערה / ראיה
API key authANTHROPIC_API_KEY=sk-ant-o...7q ב-.env; make harness-doctor מאשר.
max-turns + budget capmonitor 10 turns / 30K; enricher 8 / 60K; writer 6 / 40K.
circuit_breakerסף 3; נוסה ב-test_breaker.py — תופס בקריאה ה-3.
policy gatessend_emailrequire_human; bash rm -rfdeny.
Langfuse tracingSpan tree ב-Langfuse: supervisor → 3 subagents → 8 tool calls; total 41K tokens.
cost-per-runcost_per_run.py על 41K tokens → $0.082/ריצה → $246/חודש (100 ריצות/יום) + VAT.
Dreaming abstractionרץ בתדירות 1/יום, scope ≤20 transcripts; fallback = סיכום ל-prompt.
(rest of 18)ראה production-audit.md במלואו.

דוגמת freshness/beta risk ממולאת:

FeatureסטטוסAbstractionFallbackהערה
V2 Session API (unstable_v2_*)⚠️ previewSessionManager ב-harness/session.pyחזרה ל-single-query מפרק 2חתימות עלולות להשתנות; שינוי עתידי = שורה אחת ב-wrapper.
Claude Dreaming⚠️ research previewDreamingClient ב-harness/memory.pyסיכום failures ל-promptpricing/mגבלות GA מתפתחים; תדירות 1/יום בלבד.
Claude Managed Agents⚠️ public betaHostedRunner ב-harness/hosted.pyחזרה ל-SDK מקומי (hybrid)דורש managed-agents-2026-04-01.
  1. הרץ/י את 18 הבדיקות ה-checklist על ה-harness מ-תרגיל 1. סמן/י כל אחת ✅ / ❌.
  2. לכל ❌ — תקן/י אותה או כתוב/י נימוק מפורש למה אפשר לשחרר בלעדיה.
  3. מלא/י את טבלת ה-freshness/beta risk: לכל feature ב-preview/beta שאתה משתמש בו, ציין/י את ה-abstraction וה-fallback.
  4. כתוב/י החלטת Go/No-Go אחת בתחתית: האם הצוות מוכן לרוץ לבד? אם No-Go — מה החוסם.
  5. חתום/י בתאריך ושם. החתימה הזו היא הקריאה שלך ל-production.
פלט נראה לעין: מסמך production-audit.md עם 18 בדיקות מסומנות, טבלת freshness ממולאת, והחלטת Go/No-Go מנומקת. זה השער האחרון — אם זה No-Go, הצוות לא משוחרר.

Work Routine — שגרת העבודה המצטברת של הקורס כולו

שגרהcumulativecapstone#actionable

זו שגרת העבודה המצטברת — היא מסכמת את ההרגלים מכל הקורס לכדי routine אחד שמלווה כל harness שתבנה מעכשיו. אל תתייחס אליה כ"רשימה לסיום הקורס"; זו הדיסציפלינה שמבדילה בין vibe coder שמריץ demos לבין מהנדס harness שמשחרר production.

🔄 Work Routine מצטבר — מ-loop ועד צוות שעובד לבד

לפני כל harness חדש שתבנה, עבור/י על השלבים לפי הסדר. כל שלב מצביע לפרק שלימד אותו:

  1. (פרק 1) הגדר/י את ה-5 רכיבים: לפני קוד — מי ה-loop, ה-state, ה-tools, ה-context וה-governance? אם אתה לא יכול לשרטט אותם, אל תתחיל.
  2. (פרק 2) בנה/י loop מפורש עם max-turns: לעולם לא לולאה בלי תקרת iterations. API key auth מההתחלה.
  3. (פרק 3) מדוד/י context לפני שתסבך: כמה באמת נצרך בריצה טיפוסית? חבר/י threshold-backup ב-75%.
  4. (פרק 4) אכוף/י structured output + gates: כל tool עם schema; כל פעולה מסוכנת מאחורי policy gate דטרמיניסטי.
  5. (פרק 5) חבר/י observability לפני שאתה מדבג: Langfuse פעיל, circuit-breaker מחובר. בלי tracing אתה עיוור.
  6. (פרק 6) פצל/י subagents עם budget caps: לכל subagent תקרה משלו. חשב/י cost לפני ההרצה.
  7. (פרק 7) חבר/י memory ו-Dreaming מרוסן: store מובנה; Dreaming בתדירות מרוסנת עם fallback.
  8. (פרק 8) הכרע/י in-process מול hosted במספרים: מטריצה, לא תחושה. cost-per-run לפני שחרור.
  9. (פרק 8) עבור/י את ה-checklist וה-risk audit: Go/No-Go מנומק. אף feature ב-preview בלי abstraction + fallback.
  10. (פרק 8) חתום/י Go/No-Go עם תאריך: חתימה = אחריות. אל תדלג על הרגע הזה.

הכלל המצטבר: כל בלם שהוספת בקורס (max-turns, budget cap, circuit-breaker, gate, threshold-backup) חוסך לך כסף או נזק. ביחד הם ההבדל בין "סוכן אוטונומי" לבין "תקלה שמחכה לקרות".

💡 Just One Thing

אם תזכור/י דבר אחד מכל הקורס, שזה יהיה: "אוטונומי" לא אומר "בלי בלמים" — זה אומר "כל בלם דטרמיניסטי במקומו".

צוות שעובד לבד הוא לא צוות בלי שערים. הוא צוות שכל פעולה בלתי-הפיכה שלו עוברת ב-gate, כל subagent שלו מגודר ב-budget, וכל כשל שלו נתפס ונרשם. ה-70% מהביצועים שחיים מחוץ למודל (פרק 1) הם בדיוק הבלמים האלה. בנה/י אותם, ותקבל/י צוות שאפשר לסמוך עליו שירוץ כשאתה ישן.

🤔 בדוק/י את עצמך — 7 שאלות

  1. data flow מול code flow: למה אובייקט RunState אחד שעובר בין השכבות עדיף על מיזוג שבעת קבצי הפרקים? מה הבעיה שהוא פותר?
  2. cost: בריצה של supervisor + 3 subagents, איזה רכיב צורך ~75% מה-tokens, ולמה? איזה בלם משני פרקים מונע את ה-explosion?
  3. ההחלטה: תן/י שני תרחישים — אחד שבו תישאר in-process ואחד שבו תעבור ל-CMA — ונמק/י כל אחד מתוך המטריצה (control / sandboxing / beta).
  4. billing: מה בדיוק קורה לצוות אוטומטי שמאומת ב-subscription אחרי 15 ביוני 2026, ומה הנגד?
  5. freshness: שלושה רכיבים בקורס הם preview/beta. מנה/י אותם, ולכל אחד ציין/י את ה-abstraction/fallback שמגן עליך מ-breaking change.
  6. anti-patterns: תאר/י שניים מתוך ארבעת ה-anti-patterns שלמדת, והסבר/י איך מזהים אותם לפני שהם הופכים לתקלה.
  7. Cost Cascade: מהם ארבעת השלבים של ה-Cascade, ואיזה שלב הוא ה-place הראשון לחתוך כשצריך להוזיל?

📕 סיכום הפרק — וסיכום הקורס

זה הפרק האחרון, אז הסיכום הזה סוגר גם את הפרק וגם את הקורס כולו. עברנו מסע: מהשאלה "למה harness?" ועד לצוות שעובד לבד ב-production.

🎯 מטרות למידה שהושגו — מה את/ה יודע/ת לעשות עכשיו

כל פריט מתאים ישירות לתרגיל קפסטון או לבדיקה ב-checklist:

  1. חיווט שבע השכבות: אינטגרציה היא data flow, לא code flow. אובייקט RunState אחד עובר בין השכבות, כל אחת היא layer(state) -> state, ויש בעלות ברורה על כל שדה.
  2. הצוות שעובד לבד: supervisor שמתזמר 3 subagents (monitor/enricher/writer), כל אחד עם max-turns + budget cap, circuit-breaker, ו-gates דטרמיניסטיים — עם human-approval לפני כל פעולה בלתי-הפיכה.
  3. In-process מול hosted: ההחלטה מתקבלת ממטריצה (control / cost / sandboxing / scaling / freshness), לא מתחושה. ככל שבנית יותר harness מותאם, כך ה-tradeoff נוטה ל-in-process — כי CMA מבטל בדיוק את העבודה שעשית.
  4. billing 15.6.2026: production אוטומטי חייב API key auth. subscription auto-runs יחטפו rate limits.
  5. cost-per-run: ה-subagents הם ~75% מהעלות; Dreaming הוא סכנת burn נפרדת. תקצב/י לפי החודש ב-USD עם VAT/ILS. ה-Cascade מראה איפה לחתוך.
  6. production audit: 18 בדיקות + freshness/beta risk map. כל feature ב-preview נעטף ב-abstraction עם fallback. Go/No-Go מנומק וחתום.
  7. anti-patterns: God Supervisor, Context Soup, Approval Theater, Dreams Everywhere — כל אחד עם דרך זיהוי מוקדם.

איפה היית כשהתחלנו, ואיפה אתה עכשיו: פתחת את הקורס כשהלולאה הייתה קופסה שחורה — לא ידעת למה הסוכן נתקע, איפה ה-context נמחק, או למה subagent שרף את כל ה-budget. עכשיו בנית harness דק משלך מעל ה-Claude Agent SDK, עם כל שבע השכבות, שמריץ צוות שעובד לבד ויודע להחליט מתי להישאר in-process ומתי לעבור ל-hosted. זה בדיוק ה-end state שהקורס הבטיח.

מה הלאה (מעבר לקורס) — 3 צעדים קונקרטיים לשבוע הקרוב:

  1. יום 1–2: העתק/י את harness/team/ לריפו האישי שלך ושנה את SUBAGENTS מ-["monitor","enricher","writer"] ל-3 תפקידים מהמשימה האמיתית שלך. הרץ/י make harness-doctor — חייב להחזיר OK ב-4 שורות לפני שממשיכים.
  2. יום 3–4: הרץ/י 5 ריצות יבשות על המשימה האמיתית, קרא/י את ה-Cost Cascade מ-Langfuse, וזהה/י איפה ה-subagent היקר ביותר. אם הוא >75% מה-tokens — צמצם/י max_turns שלו מ-8 ל-5 והרץ/י שוב.
  3. יום 5: מלא/י production-audit.md מהתבנית של תרגיל 4, חתום/י Go/No-Go, והחלט/י אם להריץ את הצוות בלילה הראשון. אם No-Go — רשום/י בפירוש מה החוסם ומתי אתה חוזר לתקן.

וכשמשהו ישבר בריצת הלילה הראשונה (וזה ישבר), חזור/י ל-Framework של "אם X אז Y" מתחילת הסיכום וזהה/י את השכבה האחראית בתוך 5 דקות. זו הדיסציפלינה של Harness Engineering. סיימת את הקורס — עכשיו אתה בונה harnesses.

📖 מילון מונחים

Self-Running Agent Team (צוות שעובד לבד)
harness שמתזמר כמה סוכנים על משימת end-to-end בלי פיקוח רציף — אבל עם gates דטרמיניסטיים שעוצרים באדם בנקודות קריטיות.
End-to-End Harness Composition
חיווט כל שכבות ה-harness (loop, context, tools, governance, observability, recovery, memory) ליחידה אחת שעובדת כמערכת, לא כאוסף רכיבים.
In-Process vs Hosted Decision
ההחלטה אם להריץ את הסוכן בתוך ה-runtime שלך (Claude Agent SDK — אתה מחזיק את הלולאה) או בענן מנוהל (Claude Managed Agents — Anthropic מחזיקה).
Claude Managed Agents (CMA)
REST API serverless מנוהל לחלוטין שבו Anthropic מנהלת את agent loop, sandboxing ו-session persistence. public beta מ-8.4.2026, דורש header managed-agents-2026-04-01.
managed-agents-2026-04-01 (beta header)
ה-HTTP header שמפעיל את ה-CMA beta. עצם הצורך בו מסמן שהשירות לא GA — pricing ו-sandboxing עשויים להשתנות.
June 15 2026 Billing Transition
המעבר של תוכניות subscription ל-Agent SDK credit חודשי ייעודי. ריצות אוטומטיות על subscription auth חוטפות rate limits — production חייב API key auth.
Agent SDK Credit
קרדיט חודשי ייעודי לשימוש אוטומטי דרך ה-SDK, נפרד מהשימוש האינטראקטיבי, שנכנס לתוקף ב-15.6.2026.
API Key Auth
אימות דרך ANTHROPIC_API_KEY (לעומת session/subscription), הדרך הנכונה לאוטומציה. מאפשר חיוב לפי שימוש בפועל בלי מכסה חודשית.
Cost-per-Run
אומדן ה-tokens לריצה אחת של הצוות (supervisor + N subagents + memory + tool results), מתורגם לעלות כספית — הבסיס לתקצוב חודשי.
Cost Cascade
מודל זרימת tokens בן 4 שלבים (Supervisor Ingest, Handoff Multiplication, Subagent Execution, Synthesis & Approval) שמראה איפה העלויות מצטברות ואיפה אפשר לחתוך.
Production Readiness Checklist
רשימת הבדיקות שכל בלם (max-turns, budget cap, gate, circuit-breaker, threshold-backup, tracing) מחובר, לפני שחרור צוות שעובד לבד.
Freshness / Beta Risk Audit
מיפוי מה GA (core loop, MCP, Agent Teams) מול מה preview/beta (V2 Session API, Dreaming, CMA), ועטיפת המסוכן ב-abstraction עם fallback.
RunState
אובייקט ה-state המרכזי שעובר בין כל שכבות ה-harness — מחזיק goal, messages, token accounting, trace_id ו-memory_ref. כל שכבה היא טרנספורמציה עליו.
Data Flow (בניגוד ל-Code Flow)
תפיסת ארכיטקטורה שבה המוקד הוא על איזה state עובר בין השכבות, לא על סדר הקריאות לפונקציות. מונע "אינטגרציה מבלבלת" ומקל על debugging.
Distilled Handoff
העברת context ממוקדת מ-supervisor ל-subagent — רק מה שרלוונטי למשימה, לא כל ההיסטוריה. הנגד ל-Context Soup.
Reference Handoff
העברת reference לתוצר גדול (S3, DB) במקום העתקתו לתוך ה-context. חוסך tokens ומונע זיהום.
Approval Theater
anti-pattern שבו human-approval gate נראה עובד, אבל הסוכן ממשיך אוטומטית אחרי timeout — ולאנשים אין זמן לבדוק באמת.
God Supervisor
anti-pattern שבו ה-supervisor מבצע את כל העבודה בעצמו במקום להאציל ל-subagents. גורם ל-context מנופח ולאיטיות.
Context Soup
anti-pattern שבו כל subagent מקבל את כל ההיסטוריה. מנפח את ה-context, מאיץ compaction, ומכפיל עלויות.
Abstraction Layer (שכבת הפשטה)
wrapper דק מעל feature ב-preview/beta שמבודד את הקוד שלך מהחתימות הלא-יציבות. שינוי עתידי = שורה אחת ב-wrapper, לא בכל ה-codebase.
Fallback Pattern
דפוס שבו לכל feature ב-preview/beta יש חלופה פשוטה שעובדת בלעדיו. דוגמה: Dreaming fallback = סיכום failures ל-prompt.
Shadow Mode
הרצה מקבילה של אותה משימה גם ב-in-process וגם ב-hosted, להשוואת התנהגות לפני cutover production.
Pre-Flight / Climb / Plateau / Descent / Post-Flight
חמש פאזות מחזור חיים של ריצת צוות: לפני המראה (validation), עלייה (planning), ריצה אמיתית, סינתזה ואישור, סגירה ו-tracing.
Specialist / Gatekeeper / Synthesizer / Auditor (תפקידי subagent)
ארבעת התפקידים הארכיטקטוניים של subagent מעבר ל-Worker הבסיסי: מומחה עם context עשיר, שומר סף שמאשר/דוחה, מסכם שמאחד, ומבקר שבודק תוצרים.
Cold Start (ב-hosted)
ה-latency הראשוני של סביבת serverless כשה-runtime לא "חם" — יכול להוסיף שניות לריצה הראשונה.
Subagent Budget Cap
תקרת tokens שמוגדרת לכל subagent בנפרד (פרק 6). מונעת מ-subagent "בורח" לבלוע את כל ה-budget של הצוות.
Parallel Subagent Cost Explosion
תופעה שבה כל subagent הוא session נפרד שצורך tokens בנפרד, ובלי caps מובילה לעלויות אקספוננציאליות (מ-course.research.json).
Compaction Buffer Trap
ה-33K tokens שה-SDK שומר לפלט ובטיחות, שמצמצם את החלון הזמין לפרק 3. בלי threshold-backup, state קריטי נמחק.
Langfuse Span
יחידת tracing ב-Langfuse שמייצגת קריאה אחת (model, tool, או sub-step). מאפשר token attribution מדויק (פרק 5).
Faramesh (FPL)
כלי governance-as-code שמאפשר policy gates דטרמיניסטיים בלי LLM שני. חלק מה-stack של פרק 4.
Failure Capture
רישום failures מובנים (מה נכשל, מתי, למה) ל-memory store (פרק 5 → 7). מאפשר ל-Dreaming ללמוד מהן.
Hybrid Runtime
שילוב in-process loop עם containerized sandbox מנוהל — תופס בין in-process מלא ל-CMA מלא. פשרה למי שלא רוצה all-or-nothing.
Token Attribution
שיוך tokens ל-span ספציפי ב-Langfuse — הבסיס ל-cost-per-run מדויק במקום הערכה.