תחשבו על המודל כמו עובד חדש שיושב בחדר בלי מחשב. הוא יכול לכתוב פתקים: ׳תבדקו בשבילי מה יש ביומן ביום שלישי׳. מישהו מהצוות, הקוד, לוקח את הפתק, בודק, ומחזיר פתק עם התשובה. העובד לא קיבל סיסמה ליומן. הוא קיבל את הזכות לבקש.
Tool use: איך מודל שרק כותב טקסט מצליח לבדוק יומן וליצור רשומה ב-CRM
המודל אף פעם לא נוגע במערכת שלכם. הוא כותב בקשה, הקוד שלכם מריץ אותה. מי שמבין את הסבב הזה מבין גם איפה ההרשאות צריכות לשבת.
המדריך הזה מבוסס על תיעוד ה-tool use של Anthropic, על תיעוד ה-function calling של OpenAI, ועל מערכות שחיברתי לעסקים קטנים. הוא מיועד לבעל עסק ששמע ׳ה-AI מתחבר ל-CRM׳ ורוצה להבין מה זה אומר, למי שמשתמש בצ׳אט ורואה שהעוזר ׳גולש׳ ו׳מריץ קוד׳, ולמי שבונה את זה בקוד ורוצה לעשות את זה נכון.
להתחיל לקרוא ↓המודל רק כותב טקסט. אז מי בודק את היומן?
המודל אף פעם לא נוגע ביומן, ב-CRM או בקובץ. הוא כותב בקשה מובנית: ׳תריצו את הכלי הזה עם הערכים האלה׳. האפליקציה שמסביב מריצה, מחזירה תוצאה, והמודל ממשיך לכתוב. כל ׳פעולה׳ של AI שראיתם עובדת ככה.
כשאתם מבקשים מעוזר AI ׳תקבע לי פגישה עם דנה ביום שלישי׳ והפגישה באמת מופיעה ביומן, קל לחשוב שהמודל ׳נכנס ליומן׳. הוא לא. מה שקרה מאחורי הקלעים: מי שבנה את העוזר תיאר למודל מראש כלי בשם, נניח, create_event, עם השדות שהוא מקבל. המודל קרא את הבקשה שלכם, החליט שהכלי הזה מתאים, וכתב טקסט מובנה: שם הכלי והערכים. הקוד של העוזר קלט את זה, קרא ל-API של היומן, וחזר למודל עם ׳נוצר׳. רק אז המודל כתב לכם ׳קבעתי׳.
Anthropic מתארים את זה כך: המודל מחליט מתי לקרוא לכלי לפי הבקשה ולפי תיאור הכלי, ומחזיר קריאה מובנית שהאפליקציה שלכם מריצה. OpenAI קוראים לאותו מנגנון function calling. השמות שונים, המבנה זהה.
בכל פעם שהעוזר ׳עושה משהו׳, יש רשימת כלים שהוגדרה מראש. אם הכלי לא ברשימה, המודל לא יכול לבקש אותו, וגם לא ימציא אותו. כשעוזר אומר ׳אין לי גישה ליומן שלך׳, זה בדיוק זה: אף אחד לא הגדיר לו כלי כזה.
בבקשת API מעבירים מערך tools, כל כלי עם name, description ו-input_schema בפורמט JSON Schema. כשהמודל בוחר כלי, התשובה מגיעה עם stop_reason של tool_use ובלוק שמכיל את שם הכלי ואת הקלט. הקוד שלכם מריץ, ושולח הודעה חדשה עם בלוק tool_result. בצד של ספק המודל רץ רק מה שהגדרתם במפורש ככלי צד שרת.
חמישה צעדים שחוזרים על עצמם, בכל ספק
שולחים למודל את השאלה ואת רשימת הכלים. המודל מחזיר בקשה לקריאה. הקוד מריץ ומחזיר תוצאה. המודל מחזיר תשובה סופית, או עוד בקשה. הלולאה נגמרת כשהמודל מפסיק לבקש כלים.
OpenAI מתעדים את התהליך בחמישה צעדים, ו-Anthropic מתארים את אותו סבב עם שמות אחרים. השאלה הכי שימושית לשאול על כל ׳סוכן׳ היא: מי מריץ את הלולאה הזאת? התשובה קובעת איפה יושבות ההרשאות, מי רואה את הלוג, ומי משלם על כל סיבוב.
- האפליקציה שולחת למודל את ההודעה של המשתמש ואת רשימת הכלים: שם, תיאור, ואילו פרמטרים כל כלי מקבל
- המודל מחליט: לענות ישירות, או לבקש קריאה לכלי. אם ביקש, הוא מחזיר את שם הכלי והערכים, ולפעמים משפט הסבר לפני
- הקוד של האפליקציה מריץ את הפעולה בפועל: קריאה ל-API של היומן, שאילתה ל-CRM, חיפוש בקובץ
- האפליקציה שולחת למודל הודעה נוספת עם התוצאה, מקושרת למזהה של הבקשה
- המודל כותב תשובה סופית, או מבקש כלי נוסף. חוזרים לצעד שלוש עד שהוא מסיים
המפתחות נשארים בקוד שלכם
המודל לא מקבל סיסמה ל-CRM. הקוד שמריץ את הכלי מקבל. לכן ההרשאות, הלוג ושאלת ׳מי אישר את זה׳ הן החלטות בקוד. ספק שאומר ׳ה-AI מתחבר למערכת שלכם׳ מתאר את הקוד שלו, ואת זה אפשר לבדוק.
זה החלק שמרגיע בעלי עסקים כשהם מבינים אותו, ומדאיג אותם כשהם לא. המודל לא יכול למחוק לקוח מה-CRM אם אף אחד לא כתב כלי delete_contact ונתן לקוד שמריץ אותו הרשאת מחיקה. הגבול עובר בדיוק ברשימת הכלים ובהרשאות של החשבון שהקוד משתמש בו.
מהצד השני, אם מישהו הגדיר כלי רחב מדי, נניח ׳הרץ כל שאילתה על מסד הנתונים׳, עם חשבון אדמין, הגבול נמצא רק בשיקול הדעת של המודל. ותוצאות של כלים, מיילים נכנסים, דפי אינטרנט, קבצים שלקוח העלה, הן טקסט שמישהו מבחוץ יכול לשתול בו הוראות. Anthropic מזהירים על זה במפורש בתיעוד: תוכן שחוזר מכלי הוא לא מהימן.
שלוש שאלות לכל מי שמציע לכם עוזר AI שמתחבר למערכות: איזה פעולות בדיוק הוא יכול לבצע, באיזה חשבון והרשאות הן רצות, ואיפה רואים אחר כך מה הוא עשה. אם אין תשובה ברורה לשלוש, לא מחברים.
תבקשו שכלים שקוראים מידע יהיו נפרדים מכלים שמשנים אותו, ושכל שינוי משמעותי, מחיקה, שליחה, תשלום, יעבור אישור של אדם לפני ההרצה. רוב הפלטפורמות תומכות בזה. הפער הוא בדרך כלל בהגדרה.
הקוד שמריץ את הכלי הוא נקודת האכיפה: בדיקת קלט מול הסכמה, הרשאות לפי המשתמש שמדבר עם המודל במקום חשבון שירות רחב, לוג של כל קריאה עם הפרמטרים והתוצאה, ו-timeout. מפרט MCP מנסח את זה ישירות בפרק האבטחה של הכלים: השרת חייב לאמת קלט ולהגביל קצב, והלקוח אמור לבקש אישור על פעולות רגישות ולתעד קריאות לצורכי ביקורת.
משימה יומיומית, והכלי שהמודל היה צריך בשבילה
כל בקשה שנשמעת פשוטה מתפרקת לכלי אחד או שניים. הטבלה מראה איך זה נראה, ומה הקוד שמריץ את הכלי צריך לבדוק לפני שהוא פועל.
כשאתם מתכננים עוזר או אוטומציה, תעשו את התרגיל הזה על הנייר לפני שנוגעים בכלי. רשימת הכלים היא המפרט האמיתי של מה העוזר יודע לעשות.
| מה המשתמש מבקש | הכלי שהמודל צריך | מה הקוד בודק לפני ההרצה |
|---|---|---|
| ׳מה יש לי מחר?׳ | קריאת אירועים מהיומן לפי טווח תאריכים | שהמשתמש רואה רק את היומן שלו |
| ׳תקבע פגישה עם דנה ביום שלישי ב-10׳ | יצירת אירוע, ולפני זה חיפוש איש קשר | שאין התנגשות, ושדנה זוהתה נכון |
| ׳תפתח ליד חדש מהמייל הזה׳ | יצירת רשומה ב-CRM עם שם, טלפון, מקור | שהליד לא קיים כבר, כדי לא ליצור כפילות |
| ׳כמה חשבוניות פתוחות יש ללקוח הזה?׳ | שאילתה במערכת החשבונות | שזו קריאה בלבד, ושהמשתמש מורשה לראות |
| ׳תשלח לו תזכורת׳ | שליחת מייל או הודעה | אישור של אדם לפני השליחה, ושמירת עותק |
| ׳תסכם את המסמך הזה׳ | אין צורך בכלי, המודל קורא טקסט | שהמסמך לא מכיל פרטים שאסור להעלות |
למה ה׳סוכן׳ בצ׳אט יודע לגלוש ולהריץ קוד
כי הספק הגדיר לו כלים מראש: חיפוש ברשת, הרצת קוד, קריאת קבצים. חלק מהכלים רצים אצל הספק, חלק אצלכם. כשתראו כפתור ׳חיבורים׳ באפליקציה, זה המקום שבו מוסיפים כלים לרשימה.
Anthropic מבחינים בין שני סוגים. כלי צד לקוח: אתם מגדירים, הקוד שלכם מריץ. כלי צד שרת, כמו חיפוש ברשת או הרצת קוד: הספק מריץ אותם על התשתית שלו, והתוצאה חוזרת באותה תשובה בלי שתצטרכו לטפל בה. בצ׳אט הרגיל אתם רואים בעיקר את הסוג השני, וזה למה נדמה שהמודל ׳יודע לגלוש׳.
ההבדל חשוב כשאתם שואלים ׳לאן הנתונים שלי עברו׳. כלי שרץ אצלכם מקבל את הפרמטרים דרך הקוד שלכם, ואתם מחליטים מה יוצא החוצה.
ב-ChatGPT וב-Claude יש מסך הגדרות שמראה אילו כלים וחיבורים פעילים. תפתחו אותו פעם אחת. מה שלא מופיע שם, העוזר לא יכול לעשות, גם אם הוא מנסח את זה כאילו כן.
כשהעוזר עונה ׳בדקתי ומצאתי׳, תבדקו אם באמת הופעל כלי. באפליקציות שאני עובד איתן יש סימון ויזואלי לקריאה לכלי. אם אין סימון, המודל ענה מהזיכרון, וזה מקרה שונה לגמרי מבחינת אמינות.
כלי צד שרת מתומחרים לפי שימוש בנוסף לטוקנים, וכלי צד לקוח עולים כמו כל בקשה. הגדרות הכלים עצמן נספרות כטוקני קלט בכל סיבוב, ולכן רשימת כלים ארוכה מייקרת כל הודעה. OpenAI ממליצים להישאר מתחת לעשרים פונקציות זמינות בתחילת תור.
איך מגדירים כלי שהמודל ישתמש בו נכון
כלי הוא שלושה שדות: שם, תיאור, וסכמת קלט ב-JSON Schema. התיאור הוא מה שקובע אם המודל יבחר בכלי הנכון ובזמן הנכון. Anthropic מדרגים את איכות התיאור כגורם שמשפיע על ביצועי הכלים יותר מכל דבר אחר.
תיאור טוב אומר מה הכלי עושה, מתי להשתמש בו ומתי לא, מה כל פרמטר אומר, ומה הכלי לא מחזיר. ההמלצה בתיעוד היא שלושה עד ארבעה משפטים לפחות לכל כלי. תיאור של חמש מילים משאיר למודל לנחש, והוא ינחש.
עוד שלושה כללים מהתיעוד ששווים הרבה: לאחד פעולות קרובות לכלי אחד עם פרמטר action במקום עשרה כלים דומים; להוסיף לשמות קידומת של המערכת (crm_create_lead, calendar_list_events) כשיש כמה מערכות; ולהחזיר מהכלי רק מה שהמודל צריך לצעד הבא, עם מזהים יציבים, במקום את כל הרשומה.
אני בונה עוזר AI שמתחבר ל-[השלם את המידע כאן: המערכת, למשל CRM או יומן]. תעזור לי לכתוב הגדרת כלי אחת. מה הכלי צריך לעשות: [השלם את המידע כאן: פעולה אחת ברורה] מתי אסור להשתמש בו: [השלם את המידע כאן] מה הוא מחזיר: [השלם את המידע כאן: השדות בלבד] תחזיר: 1. שם כלי עם קידומת של המערכת 2. תיאור של ארבעה משפטים לפחות: מה, מתי כן, מתי לא, מה לא חוזר 3. סכמת קלט ב-JSON Schema עם תיאור לכל פרמטר, ושדות חובה מסומנים 4. שתי דוגמאות קלט תקינות 5. שלושה מקרים שבהם המודל עלול לבחור בכלי הזה בטעות, ואיך התיאור מונע את זה
שגיאות, סירובים, וכפילויות
כלי שנכשל מחזיר למודל הודעת שגיאה מסומנת, והמודל מנסה שוב או מסביר למשתמש. זה נוח, וגם מסוכן: ניסיון חוזר על ׳צור רשומה׳ יוצר שתי רשומות. כלים שמשנים דברים חייבים להיות בטוחים להרצה כפולה.
בתיעוד של Anthropic, תוצאה של כלי יכולה לחזור עם סימון is_error והודעה. המודל משלב את השגיאה בתשובה, ואם חסר לו פרמטר הוא ינסה שוב עם תיקון, פעמיים או שלוש, לפני שהוא מתנצל. ההמלצה שם היא לכתוב הודעות שגיאה שאומרות מה קרה ומה לעשות: ׳חריגה ממכסה, נסה שוב בעוד 60 שניות׳ במקום ׳נכשל׳.
יש שני סוגי סירוב. המודל יכול להחליט לא לקרוא לכלי, למשל כשחסר לו מידע, ולשאול במקום לנחש. והקוד שלכם יכול לסרב להריץ, למשל כשהמשתמש לא מורשה, ולהחזיר שגיאה ברורה. שניהם תקינים. מה שלא תקין הוא סירוב שקט: הקוד לא הריץ, החזיר ׳בסדר׳, והמודל אמר למשתמש שהפגישה נקבעה.
אם עוזר AI אמר לכם ׳שלחתי׳ או ׳עדכנתי׳, ואתם לא רואים את זה במערכת, אל תניחו שזה בדרך. תבדקו. ואם זה קרה פעמיים, תשאלו את מי שבנה איך מוגדר טיפול בשגיאות.
כלל פשוט לאוטומציות: לפני כל פעולת ׳צור׳, כלי בדיקה ׳האם קיים׳. זה מוסיף שנייה ומונע את הכפילויות שאחר כך לוקח שעות לנקות.
כל כלי שכותב צריך להיות אידמפוטנטי: לקבל מזהה בקשה ולהתעלם מהרצה חוזרת עם אותו מזהה, או לבדוק קיום לפני יצירה. בנוסף: timeout לכל קריאה, תקרה למספר הסיבובים בלולאה, ולוג של כל tool_use ו-tool_result עם המזהה שמקשר ביניהם. סירוב של מדיניות או של משתמש מחזירים כ-is_error עם סיבה, כדי שהמודל יסביר במקום לנחש.
מה עושים עם זה מחר בבוקר
תבחרו עוזר או אוטומציה אחת שכבר ׳עושה דברים׳ אצלכם. תכתבו על דף את רשימת הכלים שלה, ולכל כלי: קורא או משנה, באיזה חשבון, ומי רואה את הלוג. אם לא הצלחתם למלא שורה אחת, זו השאלה הראשונה למי שבנה.
- תפתחו את מסך החיבורים באפליקציית ה-AI שאתם עובדים איתה ותראו מה מחובר, ומה מיותר
- לכל כלי שמשנה נתונים: תוודאו שיש אישור של אדם לפני ההרצה, או בדיקת כפילות
- תשמרו את הדף. זו רשימת הבדיקה לכל עוזר הבא
שאלות שאני שומע על זה
המודל יכול להריץ כלי בלי שאני אדע?
רק כלי שמישהו הגדיר לו ושהקוד מוכן להריץ. באפליקציות המרכזיות יש מסך שמראה אילו כלים וחיבורים פעילים, ורוב הפלטפורמות מאפשרות לדרוש אישור לפני הרצה. מה שלא ברשימה לא קיים מבחינתו.
מה ההבדל בין tool use ל-MCP?
tool use הוא המנגנון: המודל מבקש, הקוד מריץ. MCP הוא תקן שמגדיר איך לארוז כלים כך שכמה אפליקציות יוכלו להשתמש באותו חיבור. יש על זה מדריך נפרד.
צריך מתכנת בשביל לחבר כלים?
לחיבורים מוכנים בצ׳אט, לא. לכלי שנוגע במערכת שלכם עם נתוני לקוחות, כדאי מישהו שיודע לקרוא API ולהגדיר הרשאות. ההבדל הוא במה קורה כשהכלי נכשל, ובמי מקבל את הלוג.
