הפסיקו לבקש מה‑LLM לבצע חישובים
הם לא מצליחים בזה. הנה איך לתקן זאת.
אתה יודע מה מוזר במודלים של שפה? הם יכולים להסביר מכניקת קוונטום, לכתוב שירה ולדבג את ה‑TypeScript שלך… אבל אם תבקש מהם להכפיל 18472 ב‑9347 יש סיכוי גבוה שהם יענו בביטחון משהו שגוי באלפי יחידות.
זה היה מבלבל אותי עד שהבנתי מה אנחנו בעצם מבקשים מהם. אנחנו מבקשים ממנוע התאמה לתבניות להיות מחשבון. זה כמו לבקש ממאמן גימסטיקה לאזן את ספר החשבון שלך רק בגלל שהוא מבין את מושג ה„איזון“.
העניין הוא, שה‑LLM‑ים אינם מחשבים דבר. כשאתה שואל את GPT או Claude מה תוצאת 2 + 2, הם לא מבצעים חיבור. הם מנבאים שהטוקן „4“ הוא הסביר ביותר שיופיע אחרי „2 + 2 =“. רוב הזמן זה עובד מצוין כי תבניות כאלה קיימות בנתוני האימון שלהם. אבל אם תדחוף מעבר לחישוב פשוט למספר שלבים או לכל דבר עם מספרים שלא היו נפוצים באימון, אתה בעצם מגלגל קובייה.
נתקלתי בזה ישירות לאחרונה כשבדקתי קוד שהשתמש במודל ברמה עליונה כדי לחשב תשלומי משכנתא. המודל ענה בביטחון מלא, ובו בזמן היה שגוי ב‑400 $ לחודש. זה הסוג של טעות שיש לה משמעות.
גם כשמודלים משתפרים ביכולת ההיסק (GPT‑5, שלפי השמועות, מציג שיפורים), הם עדיין מבצעים התאמה מתוחכמת לתבניות, לא חישוב סימבולי. עבור משימות יצירתיות ושפה טבעית, האופי ההסתברותי הזה הוא בדיוק מה שמקנה להם קסם. עבור מתמטיקה? לא כל כך.
מה באמת פותר את הבעיה?
התשובה אינה לחכות למודלים חכמים יותר. היא במתן הכלי המתאים למודל.
תחשוב איך היית פותר את הבעיה אם היית בונה מערכת ללא AI. לא היית כותב לוגיקה מתמטית מותאמת אישית, אלא היית פונה לספרייה. אותו עיקרון חל כאן, רק שהפעם אנחנו מלמדים את ה‑LLM מתי ואיך להשתמש בספרייה הזו.
קריאת כלים ב‑SDK‑ים מודרניים של AI מאפשרת לנו להעביר למודל פונקציות מובנות שהוא יכול לקרוא. במקום לכפות על ה‑LLM להעמיד פנים שהוא יודע מתמטיקה, אנחנו נותנים לו משהו שעושה זאת באמת: מנוע מתמטיקה סימבולי.
השתמשתי ב‑AI SDK v5 ו‑v6 לשם כך, יחד עם CortexJS Compute Engine. ה‑SDK מטפל בתזמור ובניתוב הכלים, בעוד ש‑CortexJS מטפל מכל חישוב בסיסי ועד לקלוקולוס. ההפרדה בין תחומי האחריות היא מפתיעה ונקייה.
bun add ai @ai-sdk/anthropic @cortex-js/compute-engine zodבניית כלי המתמטיקה
היישום פשוט יותר ממה שאתה עשוי לחשוב. מה שאנחנו בונים הוא גשר בין הבנת השפה הטבעית של ה‑LLM לבין חישוב מתמטי אמיתי.
import { generateText, stepCountIs, tool } from 'ai';import { ComputeEngine } from '@cortex-js/compute-engine';import { z } from 'zod';
// אתחול המנוע פעם אחתconst ce = new ComputeEngine();
const mathTool = tool({ description: 'הערכת ביטויים מתמטיים ופתרון משוואות עם דיוק מובטח. יש להשתמש בכלי לכל הפעולות המתמטיות כדי לאמת נכונות – אין לנסות חישוב מנטלי. תומך בחשבון, אלגברה, חשבון דיפרנציאלי ואינטגרלי, ובפעולות מורכבות. יכול לעבד מספר ביטויים במקביל.', parameters: z.object({ expressions: z.array(z.string()).describe( 'מערך של ביטויים מתמטיים ב‑LaTeX או בנוטציה רגילה, לדוגמה ["2 + 2", "\\frac{x^2 + 1}{x - 1}", "\\int x^2 dx"]' ), }), execute: async ({ expressions }) => { // עיבוד כל הביטויים במקביל (או באצווה מפורטת) return expressions.map(expression => { try { const result = ce.parse(expression).evaluate(); return { expression, result: result.toString(), latex: result.latex, }; } catch (error) { return { expression, error: (error as Error).message }; } }); },});כמה נקודות שכדאי לשים לב אליהן:
התיאור עושה את רוב העבודה. הניסוח “יש להשתמש בכלי” עשוי להיראות תוקפני, אך מניסיוני, היות והמודל מודע במפורש מתי להשתמש בכלי הוא ההבדל בין תפקוד מקרי לתפקוד אמין. אפשר לראות זאת כהנדסת פרומפט ברמת הכלי.
עיבוד באצווה דרך מערך expressions חשוב יותר ממה שנדמה. לכל קריאת מודל יש השהייה. אם אתה פותר מערכת משוואות או מבצע חישובים מרובי שלבים, עיבוד נפרד של כל משימה יוצר חוויית משתמש גרועה. אצווה משמעותה סיבוב אחד בלבד כדי לפתור עשר בעיות.
שימוש במנוע סימבולי במקום eval() (בבקשה אל תשתמשו ב‑eval()) נותן לנו הבנה מתמטית אמיתית. המנוע מפענח כוונה, מטפל בפורמט LaTeX, ויכול לעבוד עם נגזרות ואינטגרלים. אנחנו לא רק מבצעים חישובים, אנחנו עושים מתמטיקה.
טיפול בשגיאות מוגבל לכל ביטוי. אם חישוב אחד נכשל, אנחנו מחזירים את השגיאה אך ממשיכים עם השאר. זה מאפשר למודל לראות מה הצליח ומה לא, ובכך לתקן את עצמו בשלב הבא.
הפעלת הכלי
בואו נזרוק עליו משהו שבדרך כלל היה גורם למודל גולמי להמציא:
import { anthropic } from '@ai-sdk/anthropic';
const { text } = await generateText({ model: anthropic('claude-sonnet-4-5'), prompt: 'Calculate 18472 × 9347, divide by 127, then take the square root of the result.', tools: { mathTool }, stopWhen: stepCountIs(5), // מאפשר עד חמש שלבים של מודל/כלי});
console.log(text);המודל רואה את המתמטיקה, מזהה שהדיוק נדרש, קורא לכלי, מקבל תוצאה מדויקת, ואז מסביר זאת בשפה טבעית. כל רכיב עושה את מה שהוא עושה הכי טוב.
מעבר לחישובים בסיסיים
מאחר שאנחנו משתמשים במנוע סימבולי, גישה זו מתמודדת עם דברים שכלי מחשבון פשוט לא יכול לטפל בהם.
רוצים לפתור משוואות אלגבריות? "Solve these equations: 3x + 7 = 22 and 2y - 5 = 13" עובד מצוין.
צריך חשבון דיפרנציאלי? "Find the derivative of x^3 + 2x^2 and evaluate it at x = 2" הוא רק קריאה נוספת לכלי.
תמיכת LaTeX שימושית במיוחד אם אתם בונים אפליקציות חינוכיות. המנוע מבין קלט LaTeX באופן מובנה ויכול להחזיר תוצאות בפורמט שמיועד להצגה. אין צורך בניתוח נוסף.
התמונה הגדולה יותר
אני חושב שהדפוס הזה משמעותי מעבר למתמטיקה בלבד. מה שאנחנו באמת עושים הוא להכיר במגבלות של מודלים גדולים של שפה תוך ניצול החוזקות שלהם. הם מצוינים בהבנת כוונה, בניתוח שפה טבעית ובתזמור זרימות עבודה. הם אינם מחשבונים, מסדי נתונים או מערכות קבצים.
בכל פעם שאנחנו מנסים לגרום למודל לבצע משהו דטרמיניסטי, אנחנו מתנגדים לטבעם. אבל כשמחברים את ההבנה של השפה הטבעית עם כלים מתמחים שמטפלים בחלקים הדטרמיניסטיים? כאן הדברים הופכים למעניינים.
כלי המתמטיקה הוא רק דוגמה אחת. אותו עיקרון חל על מניפולציית תאריכים, חישובים פיננסיים, עיבוד תמונות, שאילתות למסדי נתונים… בכל מקום שבו דיוק חשוב יותר מהיצירתיות. תנו למודל להבין מה המשתמש רוצה, ואז העבירו את העבודה המעשית למשהו שנבנה במיוחד למטרה זו.
זה שינוי באופן שבו אנחנו חושבים על בנייה עם AI. לא “האם המודל יכול לעשות את זה?” אלא “האם המודל יכול לתזמור זאת?” שינוי קטן בניסוח, שינוי משמעותי באמינות.