בחירה בקוד דטרמיניסטי ובחלופות LLM מוגבלות
הדוגמאות לא הורצו ולא נבדקו בייצור.
תאריך הפרסום המקורי באנגלית: 2026-06-14T21:22:34.641+03:00 — המאמר המקורי באנגלית
ברוכים השבים ל־Coding with Alex באתר sysseder.com. כלי AI יכולים ליצור לחץ להעביר כל משימה דרך מודל, משאילתות מסד נתונים ועד CSS וכללים עסקיים. במקום לטעון להסכמה עכשווית ב־Hacker News, ב־TechCrunch או בערוצי Slack, נבחן את הבחירה הארכיטקטונית לגופה.
לא כל בעיה זקוקה ל־AI יוצר. זו הבחנה הנדסית, לא ראיה לכך שהתעשייה הגיעה לשלב מסוים במחזור באז. מדדו אם מודל משפר את המשימה בפועל במידה שמצדיקה את התלויות שהוא מוסיף.
נשווה שיקולי השהיה, עלות ונכונות בחילוץ מבוסס מודל למנתח דטרמיניסטי מצומצם במכוון. לא מובאים סקר צוותים מובילים או מדד ביצועים; הדוגמאות הן הצעות, לא פריסות שנמדדו.
המס הנסתר של ארכיטקטורת AI בכל מקום
אפשר לשקול מודל לניתוח טקסט מבולגן, לסיווג פניות תמיכה או לחילוץ מ־PDF ישן. אבל אלו משימות שונות: חילוץ מבנה עמוד, פרשנות סמנטית ואימות סכמה נכשלים בדרכים שונות, ו־API של מודל אינו תחליף אוניברסלי לכולן.
אב־טיפוס מהיר אינו מכריע את פשרות הייצור. בחנו השהיה, עלות כוללת, שונות בפלט והשלכות של תשובות שגויות.
1. צוואר הבקבוק של השהיה ותפוקה
מערכות רשת ממטבות זמני תגובה באמצעות מטמון, אינדקסים וחבילות קטנות יותר. קריאת מודל מוסיפה זמן הסקה, רשת ותור, אך אין טווח אוניברסלי של 500 אלפיות שנייה עד שתי שניות או מודל יחיד שהוא תמיד המהיר ביותר. מדדו זמן לפלט ראשון, זמן סיום כולל והשהיות p50/p95 בעומס הנבחר, לרבות ניסיונות חוזרים, ובחנו אם הזרמה או עיבוד אסינכרוני מתאימים לצורך. [2]
2. עלות הטוקנים בקנה מידה גדול
אמדו עלות לפי טוקני קלט ופלט בפועל, נפח בקשות, ניסיונות חוזרים והסכם הספק העדכני. השוו לעלויות חישוב, אחסון, תפעול ותחזוקה של שירות דטרמיניסטי. קוד מקומי אינו חינם, ואי אפשר להסיק ״סדרי גודל״ או ״מיליונים בפרוטות״ בלי הגדרת עומס ובסיס מחירים.
3. הסיוט של אי־דטרמיניזם
מנתח קבוע יכול להחזיר אותה תוצאה לאותו קלט באותו מימוש. אין להתייחס לקריאת מודל בטמפרטורה נמוכה כהבטחה לשחזור מוחלט. שינויי גרסה וקלט עמום מחייבים הערכה. חשוב במיוחד לדחות פלט לא תקין באימות היישום, ולא לאפשר לו להפיל ממשק; גם מבנה תקין אינו מוכיח נכונות עובדתית. [1]
משימת חילוץ עסקאות להמחשה
נבחן תרחיש קונקרטי. נניח שאתם בונים יישום למעקב הוצאות. המשתמשים מעלים מחרוזת טקסט גולמית, למשל התראת SMS או קבלה בדוא״ל, וצריך לחלץ ממנה את הסכום, המטבע ובית העסק.
במימוש עם מודל מתארח, השתמשו ב־SDK ובמודל נתמכים ובמצב פלט מוגבל סכמה כשאפשר. מצב JSON אינו קריאת כלים ואינו אוכף כשלעצמו טיפוסי שדות. המתאם ללא רשת שלהלן מגדיר טיפול מפורש בכישלון; הפונקציה המוזרקת propose היא ממשק תלוי פריסה, לא לקוח ספק שמומש או נבדק. עליה להשתמש בספק מאושר מבחינת פרטיות ובתקציבים מוגבלים של בקשות, טוקנים וניסיונות חוזרים. [1]
type Transaction = {
amountMinor: string; // Nonnegative integer minor units, not a binary float.
currency: "USD" | "EUR" | "GBP" | "JPY";
merchant: string;
};
type ModelReply =
| { kind: "complete"; value: unknown }
| { kind: "refusal" | "incomplete" | "error" };
type Propose = (text: string) => Promise<ModelReply>;
function validateCandidate(value: unknown): Transaction | null {
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
const v = value as Record<string, unknown>;
if (Object.keys(v).sort().join(",") !== "amountMinor,currency,merchant") return null;
if (typeof v.amountMinor !== "string") return null;
const amountMatch = /^(0|[1-9][0-9]{0,11})$/.exec(v.amountMinor);
if (!amountMatch || amountMatch[0] !== v.amountMinor) return null;
if (typeof v.currency !== "string" || !["USD", "EUR", "GBP", "JPY"].includes(v.currency)) return null;
if (typeof v.merchant !== "string" || !v.merchant.trim() || v.merchant.length > 80) return null;
if (/[\u0000-\u001f\u007f]/.test(v.merchant)) return null;
return { amountMinor: v.amountMinor,
currency: v.currency as Transaction["currency"], merchant: v.merchant.trim() };
}
export async function proposeTransaction(rawText: string, propose: Propose) {
if (rawText.length > 2000) return null;
try {
const reply = await propose(rawText);
return reply.kind === "complete" ? validateCandidate(reply.value) : null;
} catch {
return null;
}
}
// A valid candidate still needs semantic review; do not post it to an account.
// No SDK, API key, provider connection or call was made for this article.מודל מתארח מוסיף שיקולי ספק, קישוריות, פרטיות ועלות. לטענת ההצלחה של 95% במקור אין מערך נתונים תומך. חלופה דטרמיניסטית יכולה להיות מצוינת לפורמט מתועד, אך אין לטעון שכמה ביטויים רגולריים מפענחים קבלות שרירותיות. הדוגמה הבאה מקבלת רק את המבנה “Spent USD 120.50 at Merchant”, גם עם EUR או GBP, וסכום שלם ב־JPY; כל יתר הקלט מחזיר null לבדיקה או לחלופה שאושרה במפורש.
// Uses the Transaction type above; requires a TypeScript target supporting BigInt.
export function parseTransactionDeterministic(rawText: string): Transaction | null {
if (rawText.length > 2000) return null;
const m = /^Spent (USD|EUR|GBP|JPY) (0|[1-9][0-9]{0,8})(?:\.([0-9]{2}))? at ([^\r\n]{1,80})$/.exec(rawText);
// JS $ can match before a final newline: require an exact full-string match.
if (!m || m[0] !== rawText) return null;
const [, currency, whole, fraction, merchantText] = m;
if (currency === "JPY" ? fraction !== undefined : fraction === undefined) return null;
const merchant = merchantText.trim();
if (!merchant || /[\u0000-\u001f\u007f]/.test(merchant)) return null;
const amountMinor = currency === "JPY"
? BigInt(whole)
: BigInt(whole) * 100n + BigInt(fraction!);
return { amountMinor: amountMinor.toString(),
currency: currency as Transaction["currency"], merchant };
}
// Deliberately rejects ambiguous $/¥ symbols, grouping commas, negative amounts,
// decimal commas, multiple transactions and unknown formats. Not a general receipt parser.נשווה את שתי הגישות זו לצד זו:
- השהיה: השוו מימושים על אותם קלטים מייצגים ובאותם תנאי חומרה ורשת. דווחו התפלגויות, כשלים ועלות ניסיונות חוזרים. לא נערכה כאן מדידה של 0.05 אלפיות שנייה, 300–1,000 אלפיות שנייה או כל מדד אחר.
- עלות: מנתח מקומי חוסך חיוב מודל לכל קריאה, אך עדיין צורך משאבי הנדסה וחישוב. השוו עלות כוללת ברמת הדיוק והכיסוי הנדרשת.
- אבטחה: המנתח הטהור הזה אינו שולח קלט לספק ואין בו ערוץ הזרקת הנחיות למודל. אין פירוש הדבר אפס סיכון כולל: יומנים, תלויות, הצגה בהמשך וקריאות חלופה מאוחרות עלולים להדליף מידע או להשתמש בו לרעה. בצעו escaping לטקסט בית העסק המוצג ושמרו על בקרות גישה. [3]
- אמינות: דטרמיניזם עוזר לבדיקה ניתנת לשחזור; הוא אינו מוכיח שהערכים שחולצו נכונים. בדקו פורמטים נתמכים, דחיות, ערכי גבול, Unicode וקלט פגום, והעריכו קבלה שגויה בנפרד מהכיסוי. לא הורצו בדיקות לדוגמה זו.
ארכיטקטורת החלופה ההיברידית
מערכת היברידית היא אפשרות אחת, לא הוכחה למה שעושים ״המהנדסים הטובים ביותר״. קוד דטרמיניסטי יכול לטפל בדקדוק מצומצם ונתמך, ו־LLM עשוי להציע פרשנויות לקלט לא מובנה כשהפרטיות והאיכות מאפשרות זאת. בדיקה אנושית או טופס קלט ברור יותר עשויים להיות חלופה טובה יותר.
תהליך היברידי מוצע מפריד בין אימות, בדיקות פרטיות וחלופה, במקום להעביר כל בקשה למודל:
בקשה נכנסת ← מנתח דטרמיניסטי מוגבל ← תוצאה נתמכת לאחר אימות. קלט לא נתמך ← בדיקת פרטיות ומדיניות ← הצעת מודל מאושרת או בדיקה אנושית ← אימות סמנטי לפני שימוש.
בארכיטקטורה הזאת, כאשר נתונים נכנסים למערכת:
- תחילה החילו מגבלות קלט ואת המנתח הדטרמיניסטי המתועד.
- החזירו תוצאות שנתמכו ואומתו. התאמה לדקדוק אינה ציון ביטחון מכויל, ואין הבטחה להשהיה קטנה מאלפית שנייה.
- לקלט לא נתמך, בחרו בבדיקה, בטופס ברור יותר או בקריאת מודל מאושרת. אל תשלחו קבלות רגישות אוטומטית רק משום שביטוי רגולרי נכשל. אמתו הצעות מודל ובמקרים שההשלכות מצדיקות זאת בדקו אותן לפני שימוש.
החיסכון תלוי בשיעור שנמדד של בקשות שהתקבלו נכון מקומית, בשימוש הטוקנים בחלופה ובעלויות התפעול. ירידה של 90% במספר הקריאות אינה גוררת אוטומטית ירידה של 90% בעלות הכוללת. המקור אינו מספק ראיה לשום אחד מהאחוזים.
מתי כדאי ומתי לא כדאי לפנות ל־AI
כדי לעזור בהחלטות ארכיטקטורה בעבודה או בפרויקטים צדדיים, הנה רשימת כללי אצבע קצרה: מתי להישאר עם קוד רגיל ומתי להשתמש במודלים יוצרים.
העדיפו רכיבים דטרמיניסטיים עבור
- מתמטיקה: השתמשו בחישובים מאומתים לתוצאות סמכותיות. מודל יכול לעזור להסביר או להפעיל מחשבון, אך טקסט מספרי שנוצר לבדו אינו צריך להיות תוצאת חשבונאות או מערכת בקרה.
- ניהול מצב ולוגיקה עסקית: השאירו ניתוב, מכונות מצבים וכללים עסקיים בקוד דטרמיניסטי, למשל באילוצי מסד נתונים ובספריות מצב.
- מיפוי סכמות ידועות: השתמשו בהמרות מפורשות ובאימות סכמה. Zod יכול להגדיר ולאמת טיפוסים והמרות; הוא אינו מסיק מעצמו מיפוי עסקי נכון.
- חיפוש פשוט: לחיפוש בשדות מסד נתונים, השתמשו באינדקסים של Postgres, בחיפוש טקסט מלא או ב־Elasticsearch לפני קפיצה למסדי נתונים וקטוריים ולמודלי הטמעה סמנטיים.
שקלו AI לאחר הערכה עבור
- חיפוש סמנטי: הטמעות או שיטות דירוג נלמדות אחרות עשויות לעזור בשאילתות מושגיות, למשל ״תחושות חמימות של חורף״ בספריית תמונות. אין צורך בהכרח ב־LLM יוצר בכל בקשה; השוו רלוונטיות, השהיה ופרטיות לחיפוש פשוט יותר.
- יצירה וסיכום: סיכום מאמרים ארוכים, יצירת טיוטות דוא״ל מותאמות אישית או סיעור מוחות.
- תרגום וסיווג: מודלים עשויים לעזור בתרגום שפות טבעיות או בסיווג רגשות בפניות תמיכה. בדקו כיסוי שפות, דיוק בתחום וסיווגים שגויים מזיקים; ״שפות דינמיות״ אינו המונח המתאים לשפות האנושיות המתורגמות.
סיכום
כמפתחים, המטרה הסופית היא לבנות תוכנה אמינה, ניתנת לתחזוקה, חסכונית ומהירה שפותרת בעיות אמיתיות. לפעמים הכלי המלהיב ביותר בארגז הכלים אינו ה־LLM החדש והנוצץ אלא אינדקס SQL ממוטב היטב, ביטוי רגולרי עמיד או מכונת מצבים שתוכננה בקפידה.
אל תוסיפו מודל רק כדי ללכת בעקבות מגמה. בחרו בגישה הפשוטה ביותר שעומדת בדרישות שנמדדו, שמרו כללים בעלי השלכות מפורשים והשתמשו ב־AI כשהערכה מראה תועלת. זו המלצת תכנון, לא טענה לגבי הצוותים המצליחים ביותר.
ומה איתכם? האם נאלצתם להחזיר לאחור ״תכונת AI״ לטובת פתרון דטרמיניסטי? או שהצלחתם לבנות ארכיטקטורה היברידית ששומרת על השהיה נמוכה? ספרו לי בתגובות!
עד הפעם הבאה, תכנות מהנה!