בלוג

20 בספטמבר 2026

מודל החלטה בלולאה: ה-LLM כותב, Jev מכריע

מודל החלטה מחזיר הסתברות מכוילת במקום פרוזה. ארבעה אתרים ב-Routines v1.6.0, כל סף בשמו, וחמש קריאות חיות ב-$0.000102.

פוסט ב-X שבו James McDonald מבקש שיסבירו לו מה זה Jev כאילו הוא בן חמש, ו-Aaron Francis עונה שאם שואלים את אמא אם השמיים כחולים היא עונה כן מיד, וזה jev, ואם שואלים את אבא למה השמיים כחולים הוא מדבר עשר דקות, וזה LLM

‏זה מודל החלטה בשני משפטים, מ-Aaron Francis בתגובה ל-James McDonald ב-X. כל שאר המאמר הוא אותה הבחנה, עם הספים, שמות הקבצים והמספרים.

מודל החלטה עונה על שאלה סגורה בהסתברות מכוילת ולא יודע לכתוב משפט. Routines v1.6.0 מעבירה ארבע הכרעות ממודל צ׳אט למודל כזה, Jev, ואחת חמישית, בחירת התיקייה לפגישות, עברה כבר ב-v1.5.15. כל סף שפועל על ההסתברויות האלה מופיע כאן בשמו, וכל ההוכחה החיה שמאחורי המספרים עלתה $0.000102.

‏Routines מבקשת ממודל צ׳אט לעשות את הכתיבה. ארבע פעמים ביקשנו ממנו גם הכרעה: להמשיך או לעצור, עבר או נכשל, לשמור או למחוק, לתייק כאן או בשום מקום. הכרעה חמישית, האם פלט גמור שווה תג, מעולם לא הייתה קריאה למודל בכלל, רק בדיקת מילת מפתח. כל החמש עוברות עכשיו למודל החלטה שמחזיר הסתברות מכוילת ולא יודע לכתוב משפט: ארבע מהן בגרסה v1.6.0, שכבר יצאה, ובחירת התיקייה קודם לכן, בגרסה v1.5.15. המודל נקרא Jev, והוא של TypeSafe AI, לא שלנו.

חמשת המקומות שבהם היינו צריכים הכרעה

  • שער על קשת בזרימה: האם הזרימה ממשיכה בקשת הזאת.
  • בדיקה כפולה של פלט: האם הפלט הזה עומד ביעד שלו.
  • בעלות על משימה מפגישה: הפעולה הזאת שלכם או שלהם.
  • בחירת תיקייה לפגישה: לאיזו תיקייה בהערות שלכם הולכות הערות הפגישה האלה.
  • תג ״דורש תשומת לב״: האם הפלט הזה שווה תג.

ארבעת הראשונים הם קריאות למודל צ׳אט, בנויות כמו שבונים קריאה שמתכוונים לפרסר: בלי כלים, בלי היסטוריה, סכמת JSON על הבקשה, ופרסר חילוץ על התשובה. השער והבדיקה הכפולה רצים בשכבה המהירה ב-temperature: Some(0.0), הבעלות על המשימה ב-0.1, ובחירת התיקייה שכבה אחת מעל, ב-0.2. בחירת התיקייה הזאת הייתה הראשונה לעבור: כשיש מפתח שמור ולפחות שתי תיקיות מועמדות היא נענית מ-Jev עוד לפני שנבנית בקשת הצ׳אט, והיא שוחררה קודם, בגרסה v1.5.15. החמישי מעולם לא היה קריאה למודל. התג הוא בדיקת מילת מפתח שרצה מחדש בכל רינדור של React ומחפשת בטקסט את ״high-priority״, ״high priority״ או ״urgent״.

You are an impartial reviewer. You are given the GOAL of an automated task and
the OUTPUT it produced. Judge ONLY whether the output fulfills the goal and is
internally consistent (dates, numbers, and claims do not contradict each other).
Respond with ONLY a JSON object of the exact shape {"pass": boolean, "reason":
string, "fix": string} where "reason" is one short sentence and "fix" is a
concrete instruction for what to change (empty string when pass is true). No
prose, no markdown.

הפרומפט הישן של השער אמר למודל לענות continue כשהוא לא יכול לדעת, וכך כיבס כל ריצה לא ודאית לכדי מעבר ירוק ונקי. תיקנו את זה, והערת התיעוד אומרת עכשיו את הכלל שהיא שומרת: ״שער שנשבר אף פעם לא נרשם כהכרעה נקייה.״ אותה הערה נוקבת באתר שעדיין מכבס: ״verify_output בולע תוצאת בודק בלתי קריאה לתוך passed פשוט; זרימות לא רשאיות.״ זה חי, מכוון ומוצמד בבדיקה, כי הכרעה בלתי קריאה לא רשאית להכשיל את הריצה.

מה זה מודל החלטה מסוג System One

‏Jev הוא מודל ה-System One של TypeSafe AI, ופוסט ההשקה הוא שלהם להסביר. חוזה החוט הוא בקשת POST אל https://api.typesafe.ai/v1/systemone תחת מפתח Bearer, שנושאת state, model ומפה של questions שהמפתחות שלה שלכם. noul עונה כן או לא בהסתברות אחת בין 0 ל-1. choice בוחרת אחת ממפה של אפשרויות בשם, עם הסתברות לכל אחת ורמת ביטחון. score ממקם את המצב על סרגל מסודר של שתי רמות לפחות ומחזיר ציון, התפלגות, מקרא ורמת ביטחון.

החצי של needs_attention מתוך הבקשה של התג, עם שתי מחרוזות הקריטריונים מקוצרות והמצב מוחלף בממלא מקום. ציון how_soon רוכב על אותה קריאה.

{
  "state": {
    "routine_name": "<the routine's name>",
    "output_excerpt": "<the first 800 characters of the output>"
  },
  "model": "jev-latest",
  "questions": {
    "needs_attention": {
      "type": "noul",
      "instructions": "Does this output tell the user about something of their own that needs action soon?",
      "criteria": {
        "true": "[...]",
        "false": "[...] names a company or product whose name contains such a word"
      }
    }
  }
}

זה מה שחזר על פיתיון שכתבנו כדי לשבור את בדיקת מילת המפתח, עם usage ו-legend מקוצרים.

{
  "model": "jev-1.13.0",
  "answers": {
    "needs_attention": { "type": "noul", "noul": 0.03 },
    "how_soon": {
      "type": "score",
      "score": 0.08,
      "probabilities": { "0": 0.92, "1": 0.08, "2": 0.0 },
      "confidence": 0.88
    }
  }
}

לתשובת noul אין שדה ביטחון. השדות היחידים שלה הם הסוג וההסתברות, וההסתברות היא אי הוודאות. Jev לא יודע לכתוב טקסט בכלל, ולכן הוא מחליף את הפרסור ומשאיר את הפרוזה למודל הצ׳אט. ה-AI SDK של Laravel שילח את אותה צורה ב-2026-09-17 ב-PR laravel/ai#1010, בשמות Boolean, Choice ו-Score, מזהה ספק typesafe, מודל ברירת מחדל jev-latest. שיקפנו את השמות שלו.

הארכיטקטורה: ה-LLM כותב, Jev מכריע, הקוד שולט

ה-LLM עדיין כותב. Jev מחזיר מספר. הקוד מחזיק את הסף, קבוע בעל שם שאתם יכולים לקרוא. כשהמספר לא מספיק, התשובה מנותבת למקום שכבר היה שם: מסלול הצ׳אט, או בן אדם.

תרשים ארכיטקטורה של מודל החלטה בלולאה: ה-LLM כותב, Jev מכריע, הקוד מחיל ספים, ובן אדם תופס את התחום הלא ודאי, עם ארבעת אתרי הקריאה ששוחררו כהערות צד איור 1. ה-LLM כותב, Jev מכריע, הקוד שולט, והתחום הלא ודאי מנותב למסלול שתמיד היה שם.

One decision, end to endA routine run asks the chat model for the output, then asks Jev one typed question about it, and the code compares the probability to a named constant before anything acts.JevRoutinesChat modelRoutine runJevRoutinesChat modelRoutine runalt[p >= ATTENTION_FLAG_MIN][below the line]alt[a decision key is stored][no key stored]do the workthe output, as prosedoes this need attention?build the state,ask one noulPOST /v1/systemone0.97actthe path that was always therethe path that was always there

איור 2. הכרעה אחת, מקצה לקצה. בלי מפתח שמור, הריצה הולכת במסלול שתמיד הלכה בו.

איך בחרנו איפה לשים אותו

ארבעה מאתרים עיוורים סרקו את הקוד לפי דפוס, לפי תת מערכת, לפי נתונים ולפי עלות. מיזגנו את המועמדים שלהם ומדדנו נפח מול מסד ה-SQLite של האפליקציה עצמה. הנוסחה היא רווח צפוי כפול נפח מדוד, חלקי סיכון, שניהם בסולם 1 עד 5, כשסיכון הוא כמה רע וכמה בשקט נוחתת תשובה שגויה, כפול כמה משטח השינוי נוגע בו.

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

גם הספירה הגולמית לפני האיחוד לא נרשמה, ולכן לא שמנו עליה מספר. מה ששרד: 18 מועמדים מדורגים, 4 ליישום עכשיו, 8 לאחר כך, 6 לעולם לא.

שני המועמדים שהתדריך עצמו זרע, השער והבדיקה הכפולה, מדדו שניהם נפח אפס נוכחי: אפס מתוך 6 קשתות זרימה נושאות תנאי, אפס מתוך 687 פלטים נושאים סטטוס אימות. הם שוחררו כדירוג 1 ו-2 בכל זאת, כל אחד על הנחה קדימה משלו שנאמרה במפורש. של השער: ריצות הזרימה רצו 2 ביום מ-2026-08-08 עד 2026-09-03 ואז נעצרו, כך ש-2 ריצות ביום על 1 קשת מגודרת הן 2 הערכות ביום. מעוגן בהיסטוריה, אבל הנחה, והסקירה מתייגת אותה ככזו.

בנפח מדוד הסדר שונה: 6.9 לתג, 3.4 לבעלות על המשימה, 5.0 לשער על הנפח המונח שלו, ו-0.78 או 17.0 לבודק, גם שני אלה על נפח מונח. הנפח המדוד הגבוה ביותר מבין הארבעה, 10.27 פלטי רוטינה גמורים ביום, שייך לתג, שלא התדריך ולא חצי מהמאתרים הובילו איתו, כי הוא היה בדיקת מחרוזת ולא קריאה למודל.

ארבעת האתרים ששחררנו

לכל אחד יש קבוע בעל שם, מסלול לתשובה לא ודאית, ואותה הבטחה של ״בלי מפתח״: המסלול המוטפס לא קיים והענף הישן רץ.

שער על קשת בזרימה. GATE_JEV_CONTINUE_MIN = 0.85. בסף ומעליו הזרימה ממשיכה ולא מוציאה קריאת צ׳אט; מתחתיו ההערכה מוסלמת לשער הצ׳אט. ל-Jev אף פעם אין רשות לעצור זרימה.

בדיקה כפולה של פלט. VERIFY_JEV_PASS_MIN = 0.85 על ערך ה-normalized() של הציון, ובנוסף VERIFY_JEV_CONFIDENCE_MIN = 0.6 כשנמדדת רמת ביטחון. מ-VERIFY_JEV_CONCERN_MAX = 0.5 ועד 0.85 זה מוסלם לבודק הפרוזה. מתחת ל-0.5 זה מוסלם גם כן, ומסמן הסתייגות: זה התחום היחיד שבו הכרעת בודק בלתי קריאה כבר לא נבלעת לתוך מעבר.

בעלות על משימה מפגישה. TODO_OWNER_USER_MIN = 0.75 שומר את הפריט, TODO_OWNER_DROP_MAX = 0.25 מוחק אותו, ובין השניים הוא נופל אל ההכרעה המחרוזתית של היום. קו השמירה יושב מתחת ל-0.85 בכוונה: משימה שגויה מתה במחווה אחת, ומשימה שנמחקה היא התחייבות שאיש לא רואה שוב.

תג ״דורש תשומת לב״. ATTENTION_FLAG_MIN = 0.85 מרים את התג. כל השאר עונה כלום, העמודה נשארת NULL, ובדיקת מילת המפתח רצה כמו קודם.

The flow gate, before and afterBefore, a chat model wrote a verdict that had to be parsed and salvaged. After, Jev returns one probability and only a confident yes skips the chat call, so the branch a Mac without a key takes is the old one, unchanged.After, with a keyyesno

Jev returns
one probability

p >= 0.85?

continue, and
no chat call
at all

escalate to
the same
chat gate,
unchanged

Before, and still, with no keyyesno

Chat model writes
verdict plus reason

Parse the JSON

Salvage parser

Readable?

continue,
stop, or
unsure

unparseable,
the edge
policy
decides

איור 4. השער לפני ואחרי. רק ״כן״ בטוח מדלג על קריאת הצ׳אט.

תרשים תחומי סף שמראה את תחום הפעולה, ההסלמה והנפילה לאחור לכל אתר החלטה על ציר הסתברות מאפס עד אחד, עם כל קבוע בעל שם מסומן במקומו איור 5. כל תחום, כל קבוע. שום דבר לא פועל ב-0.5 או מתחתיו, כי בשאלה דו ערכית המקרה לבדו שם 0.5 על המנצח.

התחום החמישי הוא בחירת התיקייה לפגישה, MIN_FOLDER_PICK_CONFIDENCE = 0.6, ששוחרר בגרסה v1.5.15. ארבעת התחומים שמעליו הם מה שגרסה v1.6.0 הוסיפה.

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

#[tokio::test]
async fn with_no_key_an_unreadable_verdict_is_still_absorbed_into_passed() {
    // THE pin. Today an unreadable grader verdict delivers the run marked
    // "passed" with no note, and with no decision key that must not change
    // by a single byte.
    let (result, sends) = run_double_check(
        JevVerdict::Unjudged,
        &verify_long_output(),
        vec![Ok("totally not json".to_string())],
    )
    .await;
    let result = result.expect("a verdict was returned");
    assert_eq!(result.status, "passed");
    assert_eq!(result.content, verify_long_output());
    assert_eq!(result.note, None);
    assert_eq!(sends, 1);
}

המספרים החיים

ההוכחה החיה היא ארבע בדיקות probe מסומנות ignore, אחת לכל אתר. ה-probe של התג רץ בלולאה על שני מקרים, ולכן ארבע בדיקות מייצרות חמש קריאות: $0.000016, $0.000019, $0.000028, $0.000020 ו-$0.000019, בסך הכול $0.000102. הדוח שלנו עצמו אמר $0.000083, שהוא ארבע הראשונות מבין החמש: הוא ספר בדיקות, לא קריאות.

תרשים עמודות שמשווה את העלות לקריאה של הכרעת מודל צ׳אט מול החלטה של Jev בשער הזרימה ובבדיקה הכפולה של הפלט, זול פי 25 ופי 27 בערך איור 6. עלות לקריאה, נגזרת מחדש מספירות הטוקנים לפי $0.042 למיליון טוקני קלט. ההשהיה לא מצוירת: שום דבר בקוד הזה לא מודד זמן של קריאה למודל.

ב-$0.042 למיליון טוקני קלט כשהפלט חינם, 3,250 הטוקנים המוערכים של השער עולים $0.000137 מול $0.0034 להכרעת הצ׳אט, זול פי 25; 3,560 הטוקנים של הבודק עולים $0.000150 מול $0.0040, פי 27. ספירות הטוקנים האלה הן הערכות של המאתר, לא גופי בקשה שנמדדו, וצד הצ׳אט מתומחר על בסיס הנפילה לאחור של Haiku 4.5: ה-Mac הזה רץ בשכבה שאין לה שורת מחיר, ולכן האפליקציה שומרת NULL ואף פעם לא אפס מומצא. בנפח המדוד של ה-Mac הזה לשני האתרים, אפס, החיסכון ליום הוא בדיוק $0.00. ההשהיה המפורסמת של Jev היא 70 עד 500 מילישניות, המספר של הספק ולא שלנו.

שתי עמודות הסתברות זו לצד זו, 0.03 על פיתיון שנוקב בשם החברה UrgentIQ ו-0.97 על תוספת לחוזה שכירות, כשבדיקת מילת המפתח טועה בשתיהן איור 7. הזוג שעשה את הטיעון. בדיקת מילת המפתח ששוחררה טועה בשני הכיוונים; Jev צודק בשניהם.

הזוג שעשה את הטיעון של התג רץ מול jev-1.13.0. הפיתיון: ״UrgentIQ raised a 15M Series A this week. Analysts call the compliance gap it targets large, urgent and under-served.״ בדיקת מילת המפתח מתייגת אותו. Jev מחזיר needs_attention 0.03 ולא מרים כלום, כי הקריטריון false של השאלה עצמה מכסה אותו: פלט ש״נוקב בשם של חברה או מוצר שהשם שלו מכיל מילה כזאת״ הוא לא פלט שדורש אתכם. השני: ״The landlord replied and needs your signature on the lease addendum before Friday or the renewal lapses.״ בדיקת מילת המפתח אומרת FALSE; Jev מחזיר 0.97.

The needs attention badge, judged instead of matchedThe shipped keyword test raises a badge on a company called UrgentIQ and misses a lease addendum that needs a signature. Jev scores the first 0.03 and the second 0.97, and is right on both.

Industry news digest
names a company
UrgentIQ

keyword test:
finds urgent,
says YES

Jev: 0.03

a badge that
should not show

below 0.85,
no badge

Inbox triage: sign the
lease addendum
by Friday

keyword test:
no match,
says NO

Jev: 0.97

the badge is
missed entirely

clears 0.85,
badge raised

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

טעינו בדיוק אחד בסקירה ותפסנו אותו לפני שהפך לכרטיס. אותה קריאה שואלת גם ציון how_soon, ועל הפיתיון הוא חזר ב-0.08 עם 92 אחוז מהמסה שלו על ״אין צורך בפעולה״ ועם ביטחון 0.88. ה-0.88 שייך לציון, לעולם לא ל-0.03. ל-noul אין שדה ביטחון. הציון נרשם ביומן ואף פעם לא פועלים לפיו: טוקני פלט הם חינם, וכיול מחדש עתידי של ATTENTION_FLAG_MIN ירצה את ההתפלגות של ה-Mac הזה עצמו.

החוקים שהפקדנו

  1. שום דבר לא פועל ב-0.5 או מתחתיו בשאלה דו ערכית: המקרה לבדו שם 0.5 על המנצח.
  2. אפשרות ״לא בטוח״ הופכת את הכיול: היא עושה מאי הוודאות תשובה ולוקחת מסה מהתוצאות האמיתיות, ועם שלוש אפשרויות המקרה יושב על 0.33.
  3. האפשרויות מגיעות מהקוד, אף פעם לא מהמצב. השם של האפשרות המנצחת ב-choice נרשם ביומן, וזה מה שהופך את הכלל הזה לנושא משקל.
  4. אף פעם אל תגדרו סוכן עם כלים מאחורי מסווג.
  5. ל-noul אין שדה ביטחון. ההסתברות היא אי הוודאות.
  6. רשמו ביומן את ההחלטה, אף פעם לא את המצב.
  7. לכל תשובה לא ודאית צריך מסלול כתוב, ושגיאת תעבורה לוקחת את אותו מסלול.
  8. שמרו חשבון וכללים קשיחים בקוד. Jev שופט משמעות.

מה לא עשינו, ומה הלאה

שישה מועמדים סומנו ״לעולם לא״. נתב הכוונה של צ׳אט הפגישות נשאר נתב: חוק 4 מצוטט מזיכרון הפרויקט שלנו עצמו, וכישלון פתוח עושה אותו לשער שנכשל בכיוון הבטוח, לא לשער שהפסיק להיות שער. רשימת ההיתרים של הגישה ל-Slack נשארת כלל קשיח, כי בקרת גישה הסתברותית היא פגם מעצם הבנייה. מיזוג אוטומטי של התנגשות בסנכרון נשאר ידני: מיזוג שגוי הוא אובדן שקט ובלתי הפיך בתוך ה-vault של המשתמש עצמו, וספירת ההתנגשויות היא אפס, ולכן אין גם נתוני כיול. מסווגים ללוח הגזירים בחוץ, כי לוחות גזירים נושאים סיסמאות וטוקנים. משווי הכללים הקשיחים משווים מחרוזות מדויקות שנוצרות פנימית, וכמה מהם רצים בלולאות חמות שבהן קריאת רשת פוסלת. הפרוקסי של הארנק המנוהל מחוץ לתחום לפי הכלל של התדריך עצמו.

שלושה דברים הלאה. השלילה הבטוחה: השופט של התג אף פעם לא מחזיר ״לא״ בטוח היום, ולכן ״לא״ כזה נופל אל בדיקת מילת המפתח והתג השגוי מוצג. הפיתיון ייצר את נקודת הכיול שחסרה, והעמודה והרכיב כבר יודעים לטפל ב-false. השארנו את זה מחוץ למעבר הזה, כי שינוי סמנטיקה של החלטה אחרי אישור יריב בלי אימות חוזר הוא בדיוק האופן שבו משוחררת התנהגות לא מאומתת. ספים מכוילים על הנתונים שלנו: כל קבוע למעלה הוא שיקול דעת, ועמודת דירוג המשתמש היא NULL בכל שורת פלט, ולכן אין עדיין קורפוס מתויג. גרסת מודל מוצמדת: jev-latest עוקב אחרי היציב ורץ היום; אחרי הכיול ההצמדה עוברת ל-jev-1.13.0, כדי שעדכון של הספק לא יזיז סף מתחתינו.

הפועל routines decide והכלי decide שוחררו בגרסה v1.5.15, ומדריך ה-CLI מתעד את הפועל, כולל מפתח ה-TypeSafe או ה-OpenRouter שהוא דורש. ארבעת האתרים שלמעלה חיים בגרסה v1.6.0. כרטיס מפתח ה-TypeSafe יושב בהגדרות, תחת חיבורים. מפתח OpenRouter יושב בהגדרות של ספק הבינה, במקום שבו הוא כבר נמצא אם אתם משתמשים באחד לצ׳אט. כך או כך המפתח חי ב-Keychain של macOS ואף פעם לא מסתנכרן בין מחשבי Mac. בלעדיו שום דבר באפליקציה לא משתנה. איתו, הטקסט ש-Jev שופט נשלח אל אותו ספק, ויומן ההחלטות שומר את ההכרעה ולא את המילים: אף פעם לא את טקסט המצב, בלי ציטוט ממנו, בלי שום דבר שנגזר ממנו, עם בדיקה שנכשלת אם כן.

‏Routines היא הורדה חינמית ל-macOS, עם CLI ועם מדריך הפקודות שלו. אחת מההכרעות שלמעלה נראית מבחוץ: תג ״דורש תשומת לב״, בכל רוטינה שתבנו ממתכון מיון תיבת הדואר.

שאלות נפוצות

מה זה מודל החלטה?

מודל החלטה עונה על שאלה סגורה במספר מכויל במקום בפרוזה. Jev, מודל ה-System One של TypeSafe AI, מקבל מצב ומפה של שאלות ועונה בשלוש צורות: noul, שהיא הסתברות כן או לא בין 0 ל-1, choice, שבוחרת אפשרות אחת בשם מתוך שתיים לפחות ומחזירה הסתברות לכל אחת, ו-score, שממקמת את המצב על סרגל מסודר של שתי רמות לפחות. הוא לא מייצר טקסט חופשי ואף פעם לא מחזיר ערך מחוץ לסכמה, ולכן אין מה לפרסר ואין מה לחלץ כשהתשובה חוזרת. זה כל ההבדל מהדפוס שהוא מחליף. מודל צ׳אט שמבקשים ממנו הכרעה מחזיר משפט שבמקרה יש בתוכו הכרעה, ומתחת לכל קורא כזה יושב פרסר חילוץ. ה-AI SDK של Laravel הוסיף את אותן שלוש צורות ב-PR laravel/ai#1010, שמוזג ב-2026-09-17, בשמות Boolean, Choice ו-Score, ו-Routines משקפת את השמות האלה כדי שאוצר המילים יתאים למה שמפתחי Laravel כבר קוראים.

מה זה Jev, ומי מפתח אותו?

‏Jev הוא מודל החלטה מסוג System One של TypeSafe AI, לא שלנו. Routines היא לקוחה שלו, בדיוק כפי שהיא לקוחה של כל ספק צ׳אט. מזהה הדגם הנוכחי הוא jev-1.13.0, והכינויים jev-latest ו-jev-preview מפנים אליו היום. הגישה אליו היא POST אל https://api.typesafe.ai/v1/systemone עם מפתח Bearer, ולגוף הבקשה יש בדיוק שלושה שדות עליונים נדרשים: state, model ו-questions. המחיר הוא $0.042 למיליון טוקני קלט והפלט חינם, מגבלות הקצב הן 250,000 טוקנים בשנייה ו-1,200 בקשות בדקה, וההקשר הוא 64k לבקשה, ומתוכו 32k למצב ולשאלה הארוכה ביותר יחד. TypeSafe מפרסמת זמן תגובה של 70 עד 500 מילישניות לתשובה. המספר הזה שלהם, מעולם לא מדדנו אותו בקוד הזה, ולכן צריך לקרוא אותו כהצהרה שלהם ולא שלנו. יש מסלול שני אל אותו מודל: ‏OpenRouter חושפת אותו בשם typesafe/jev-1.13 בכתובת POST https://openrouter.ai/api/alpha/decisions, עם הקשר של 32000 טוקנים.

במה מודל החלטה שונה מבקשה למודל צ׳אט להחזיר JSON?

מודל החלטה לא יכול לייצר שום דבר מלבד התשובה, ולכן אין מתחתיו פרסר. כשמבקשים JSON ממודל צ׳אט מקבלים פרוזה שבדרך כלל היא JSON. כל ארבעת אתרי ההכרעה ב-Routines נכתבו ככה: בלי כלים, בלי היסטוריה, עם סכמת JSON על הבקשה, טמפרטורה מקובעת על 0.0 בשער הזרימה ובבודק הפלט, ועם פרסר חילוץ על התשובה בשביל הריצות שבהן הסכמה לא נשמרה. Jev מחזיר תשובה מוטפסת או שגיאה, ולשכבת החילוץ לא נשאר מה לעשות. ההבדל השני חשוב יותר. הכרעת צ׳אט היא מילה, ומילה מסתירה את אי הוודאות של עצמה. ככה קרה שהפרומפט הישן של השער הורה למודל לענות continue בכל פעם שהוא לא ידע להכריע, והלבין כל ריצה לא ודאית לכדי מעבר ירוק נקי. תשובת ‏noul מחזירה הסתברות, וההסתברות היא אי הוודאות, ולכן הסף חי בקוד שלנו ולא במזג של המודל. הקבוע ‏GATE_JEV_CONTINUE_MIN עומד על 0.85 והוא כתוב ב-flows/gate.rs, במקום שכל אחד יכול לקרוא.

האם תשובת noul נושאת ציון ביטחון?

לא. השדות היחידים של תשובת noul הם הסוג שלה וההסתברות שלה, וההסתברות היא אי הוודאות: 0.03 הוא ״לא״ בטוח, 0.97 הוא ״כן״ בטוח, ו-0.5 הוא הטלת מטבע. תשובות choice ו-score כן נושאות שדה ביטחון, ו-Routines קוראת אותו כאופציונלי, כי ספק עשוי לא למדוד עד כמה ההתפלגות ודאית. קל לאבד את ההבחנה הזאת בתוך קריאה אחת. ב-probe חי של שאלת התג, הפלט המתעתע החזיר needs_attention 0.03 לצד ציון how_soon שהביטחון שלו ‏0.88. ה-0.88 שייך לציון ולעולם לא ל-0.03, והערבוב בין השניים היה פגם שתפסנו בסקירה לפני שהגיע לכרטיס. הכלל המעשי שנובע מזה הוא ששום דבר ב-Routines לא פועל ב-0.5 או מתחת, כי noul היא שאלה עם שתי תוצאות והמקרה לבדו מניח 0.5 על המנצחת. החוק הזה כתוב ב-attention_flag.rs, וכל סף באפליקציה יושב מעליו.

מה קורה ב-Routines כשאין מפתח TypeSafe?

כלום לא משתנה. בלי מפתח TypeSafe בכלל, לא שמור ולא במשתנה הסביבה TYPESAFE_API_KEY, הפונקציה available_route ב-llm/decision.rs נופלת אחורה למפתח ‏OpenRouter שמור, ובלי אף אחד מהשניים המסלול לא נפתר לכלום, שום בקשה לא נבנית, והכלי decide לא נרשם בכלל. כל אחד מאתרי ההחלטה רץ אז בדיוק בענף שרץ קודם, בית אחר בית, כולל הענפים שאנחנו חושבים שהם שגויים. בדיקת Rust מקבעת את זה ב-commands/routines.rs:7047, ושמה אומר מה היא שומרת: ‏with_no_key_an_unreadable_verdict_is_still_absorbed_into_passed. ההערה שלה כותבת שבלי מפתח החלטות זה לא רשאי להשתנות אפילו בבית אחד. הסיבה שמסלול חוסר המפתח כל כך מילולי היא שקריאת החלטה איננה חינם בזמן, גם כשהיא כמעט חינם בכסף. קריאת decide בלי חסם יכולה לעלות כשלוש דקות וחצי של זמן שעון, כי אפשר לשלם את פסק הזמן של 30 שניות ארבע פעמים כשבין הניסיונות יושבת נסיגה של 10, 30 ו-60 שניות. בדיוק לכן בדיקה מוקדמת מוטפסת מקבלת PRECHECK_BUDGET משלה של 10 שניות, וכל אלה נמצאים ב-typesafe.rs. מחשב Mac בלי מפתח לא אמור לשלם על זה, והוא באמת לא משלם, כי הוא לא נכנס לנתיב הזה בכלל.

האם ההערות שלי עוזבות את ה-Mac כש-Routines משתמשת ב-Jev?

רק אם תוסיפו בעצמכם מפתח להחלטות מוטפסות, מפתח TypeSafe או מפתח OpenRouter, שאותו אדפטר מקבל כנפילה לאחור כשאין מפתח TypeSafe שמור. בלי אף אחד מהשניים המסלול לא נפתר לכלום, שום בקשה לא נבנית, הכלי ‏decide לא נרשם, וכל אתר החלטה רץ בענף שרץ קודם. כשאתם כן מוסיפים מפתח, הטקסט ש-Jev שופט נשלח אל הספק שהמפתח שייך לו, TypeSafe בכתובת api.typesafe.ai או OpenRouter בכתובת openrouter.ai, ולשום מקום אחר. כרטיס מפתח ה-TypeSafe יושב בהגדרות תחת חיבורים, והמפתח עצמו יושב ב-Keychain של macOS תחת השם typesafe, ומפתח OpenRouter יושב בהגדרות של ספק הבינה, שם הוא כבר חי בשביל הצ׳אט. מפתחות אף פעם לא מסתנכרנים בין מחשבי Mac. בצד שלנו, Routines רושמת ביומן את ההחלטה ואף פעם לא את המצב: הקובץ llm/decision_log.rs כותב שאסור לו לרשום את טקסט המצב, שום ציטוט ממנו ושום דבר שנגזר ממנו, ובדיקה קוראת את המקור בחזרה ונכשלת אם מופיע בו פרמטר מצב. שם האפשרות המנצחת ב-choice כן נרשם, ובדיוק לכן האפשרויות נבנות בקוד ולא מהתוכן שלכם, והתווית של score לא נרשמת. הכלי decide הוא לקריאה בלבד, ומצב טיוטה אף פעם לא מכניס אותו לתור.

כמה עולה קריאה ל-Jev לעומת קריאה למודל צ׳אט?

‏Jev מתומחר ב-$0.042 למיליון טוקני קלט והפלט חינם, ולכן החלטה אחת עולה שבריר של סנט. ב-3,250 טוקני הקלט המוערכים של שער הזרימה זה $0.000137 לקריאה מול $0.0034 להכרעת הצ׳אט שהוא מחליף, יחס של בערך 25. ב-3,560 הטוקנים המוערכים של בודק הפלט זה $0.000150 מול $0.0040, בערך פי 27. שתי הסתייגויות כנות נוסעות עם היחסים האלה. צד הצ׳אט מתומחר על בסיס הנפילה לאחור של Haiku 4.5 ב-llm/pricing.rs, כי ה-Mac שממנו המספרים מגיעים רץ בשכבה שאין לה שורת מחיר בכלל, ושם cost_usd לא מחזיר ערך והאפליקציה שומרת NULL במקום אפס מומצא. וההוזלה היא שיעור, לא חשבון. בנפח המדוד של המחשב הזה לשער ולבודק, שהוא אפס קריאות, החיסכון ליום הוא בדיוק $0.00. כל ההוכחה החיה מאחורי המאמר הזה הייתה ארבע בדיקות probe שייצרו חמש קריאות, והיא עלתה $0.000102 בסך הכול.

למה התג ״דורש תשומת לב״ עדיין מופיע על פלט מתעתע?

כי המודל רשאי להרים את התג ועדיין לא רשאי להוריד אותו. הפונקציה attention_flag::judge מרימה את הדגל כשההסתברות היא 0.85 או יותר, הערך של ATTENTION_FLAG_MIN ב-attention_flag.rs, ולכל מקרה אחר היא עונה כלום. כלום אומר שהעמודה השמורה נשארת NULL, ועמודה NULL משאירה את ההתנהגות המקורית במקומה: בדיקת מילות מפתח ב-src/components/homescreen/NeedsAttentionSection.tsx שמחושבת מחדש בכל רינדור של React ומחפשת בטקסט את high-priority, high priority ו-urgent. ולכן תקציר חדשות שרק מצטט את המילה urgent עדיין אוסף את התג. ה-probe החי מראה בדיוק את הפער הזה. על הפלט המתעתע המודל ענה needs_attention 0.03 והניח 92 אחוז ממסת how_soon על הרמה שמשמעותה שלא נדרשת פעולה, ובכל זאת הדגל חזר ככלום ובדיקת מילות המפתח עדיין אמרה כן. הדחקת התג על שלילה בטוחה היא הצעד הבא בשמו, והיא לא נשלחה בסבב הזה במכוון, כי שינוי סמנטיקה של החלטות אחרי אישור יריב ובלי אימות מחדש הוא בדיוק הדרך שבה מגיעה לייצור התנהגות לא מאומתת.

פוסטים קשורים

נסו את זה על ה-Mac שלכם.

Routines שומרת את ההערות, התמלולים והפלטים של השגרות שלכם כקבצי markdown וב-SQLite על המחשב שלכם, והם נשארים שם אלא אם תפעילו את Cloud Sync.

הורדה