במהלך השנה האחרונה, עבדנו עם עשרות צוותים שבונים סוכני מודלי שפה גדולים (LLM) ברחבי מגוון תעשיות. גילינו באופן עקבי שהיישומים המוצלחים ביותר לא השתמשו בפריימוורקים מורכבים או ספריות ייעודיות, אלא נבנו באמצעות תבניות פשוטות וניתנות להרכבה.
בפוסט זה, אנו חולקים את מה שלמדנו מעבודה עם הלקוחות שלנו ומבניית סוכנים בעצמנו, ומספקים עצות מעשיות למפתחים לבניית סוכנים יעילים.
מהם סוכנים?
המונח "סוכן" יכול להיות מוגדר במספר דרכים. חלק מהלקוחות מגדירים סוכנים כמערכות אוטונומיות לחלוטין הפועלות באופן עצמאי לאורך תקופות ארוכות, תוך שימוש בכלים שונים לביצוע משימות מורכבות. אחרים משתמשים במונח לתיאור יישומים מדויקים יותר העוקבים אחר תהליכי עבודה מוגדרים מראש. באנתרופיק (Anthropic), אנו מסווגים את כל הווריאציות הללו כמערכות סוכניוֹת, אך מבדילים הבחנה ארכיטקטונית חשובה בין תהליכי עבודה לסוכנים:
- תהליכי עבודה הם מערכות שבהן LLMs וכלים מתואמים באמצעות נתיבי קוד מוגדרים מראש.
- סוכנים, לעומת זאת, הם מערכות שבהן LLMs מכוונים באופן דינמי את התהליכים ושימושם בכלים, ושומרים על שליטה באופן שבו הם מבצעים משימות.
להלן, נחקור את שני הסוגים של מערכות סוכניוֹת בפירוט. בנספח 1 ("סוכנים בפועל"), אנו מתארים שני תחומים שבהם לקוחות מצאו ערך מיוחד בשימוש במערכות מסוג זה.
מתי (ומתי לא) להשתמש בסוכנים
בעת בניית יישומים עם LLMs, אנו ממליצים למצוא את הפתרון הפשוט ביותר האפשרי, ולהגדיל את המורכבות רק בעת הצורך. ייתכן שמשמעות הדבר היא לא לבנות מערכות סוכניוֹת כלל. מערכות סוכניוֹת לרוב מחליפות זמן השהיה ועלות בביצועי משימות טובים יותר, ועליכם לשקול מתי פשרה זו הגיונית.
כאשר יש צורך במורכבות רבה יותר, תהליכי עבודה מציעים יכולת חיזוי ועקביות למשימות מוגדרות היטב, בעוד שסוכנים הם האפשרות הטובה יותר כאשר נדרשים גמישות וקבלת החלטות מונחית-מודל בקנה מידה רחב. עבור יישומים רבים, עם זאת, אופטימיזציה של קריאות LLM בודדות באמצעות שליפה (retrieval) ודוגמאות בתוך ההקשר (in-context examples) לרוב מספקת.
מתי וכיצד להשתמש בפריימוורקים
קיימים פריימוורקים רבים המקלים על יישום מערכות סוכניוֹת, כולל:
- ה-Claude Agent SDK;
- Strands Agents SDK by AWS;
- Rivet, בונה תהליכי עבודה של LLM עם ממשק גרפי (drag and drop GUI); וכן
- Vellum, כלי GUI נוסף לבנייה ובדיקה של תהליכי עבודה מורכבים.
פריימוורקים אלה מקלים על תחילת העבודה על ידי פישוט משימות בסיסיות סטנדרטיות כמו קריאה ל-LLMs, הגדרה וניתוח כלים, ושרשור קריאות יחד. עם זאת, הם לעיתים קרובות יוצרים שכבות הפשטה נוספות שיכולות לטשטש את הפרומפטים והתגובות הבסיסיות, מה שמקשה על ניפוי באגים. הם גם עלולים לפתות להוסיף מורכבות כאשר הגדרה פשוטה יותר הייתה מספקת.
אנו מציעים למפתחים להתחיל בשימוש ישיר ב-API של LLM: דפוסים רבים ניתנים ליישום בכמה שורות קוד בלבד. אם אתם כן משתמשים בפריימוורק, ודאו שאתם מבינים את הקוד הבסיסי. הנחות שגויות לגבי מה שמסתתר מתחת לפני השטח הן מקור נפוץ לשגיאות אצל לקוחות.
עיינו בספריית הדוגמאות (cookbook) שלנו ליישומים לדוגמה.
אבני בניין, תהליכי עבודה וסוכנים
בסעיף זה, נחקור את התבניות הנפוצות למערכות סוכניוֹת שראינו בייצור. נתחיל באבן הבניין הבסיסית שלנו – ה-LLM המועצם – ונגדיל בהדרגה את המורכבות, מתהליכי עבודה פשוטים ועד לסוכנים אוטונומיים.
אבן בניין: ה-LLM המועצם
אבן הבניין הבסיסית של מערכות סוכניוֹת היא LLM המשופר עם הרחבות כגון שליפה (retrieval), כלים וזיכרון. המודלים הנוכחיים שלנו יכולים להשתמש באופן פעיל ביכולות אלו – ליצור שאילתות חיפוש משלהם, לבחור כלים מתאימים ולקבוע איזו מידע לשמר.
אנו ממליצים להתמקד בשני היבטים מרכזיים של היישום: התאמת יכולות אלו למקרה השימוש הספציפי שלכם, והבטחת שהן מספקות ממשק קל ומתועד היטב עבור ה-LLM שלכם. בעוד שישנן דרכים רבות ליישם הרחבות אלו, גישה אחת היא באמצעות Model Context Protocol (MCP) ששחררנו לאחרונה, המאפשר למפתחים להשתלב עם אקוסיסטם הולך וגדל של כלי צד שלישי באמצעות יישום client פשוט.
לשאר הפוסט הזה, נניח שלכל קריאת LLM יש גישה ליכולות מועצמות אלו.
תהליך עבודה: שרשור פרומפטים
שרשור פרומפטים מפרק משימה לרצף של צעדים, כאשר כל קריאת LLM מעבדת את הפלט של הקריאה הקודמת. ניתן להוסיף בדיקות תכנותיות (ראו "שער" בתרשים למטה) בכל שלבי הביניים כדי לוודא שהתהליך עדיין במסלול הנכון.
מתי להשתמש בתהליך עבודה זה: תהליך עבודה זה אידיאלי למצבים שבהם המשימה ניתנת לפירוק בקלות ובניקיון למשימות משנה קבועות. המטרה העיקרית היא להחליף זמן השהיה (latency) לטובת דיוק גבוה יותר, על ידי הפיכת כל קריאת LLM למשימה קלה יותר.
דוגמאות שבהן שרשור פרומפטים שימושי:
- יצירת קמפיין שיווקי, ולאחר מכן תרגומו לשפה אחרת.
- כתיבת ראשי פרקים למסמך, בדיקה שראשי הפרקים עומדים בקריטריונים מסוימים, ולאחר מכן כתיבת המסמך על בסיס ראשי הפרקים.
תהליך עבודה: ניתוב
ניתוב מסווג קלט ומנתב אותו למשימת המשך ייעודית. תהליך עבודה זה מאפשר הפרדת אחריות ובניית פרומפטים ממוקדים יותר. ללא תהליך עבודה זה, אופטימיזציה עבור סוג אחד של קלט עלולה לפגוע בביצועים על קלטים אחרים.
מתי להשתמש בתהליך עבודה זה: ניתוב עובד היטב עבור משימות מורכבות שבהן קיימות קטגוריות נפרדות שטוב יותר לטפל בהן בנפרד, ושבהן סיווג יכול להתבצע במדויק, בין אם על ידי LLM או מודל/אלגוריתם סיווג מסורתי יותר.
דוגמאות שבהן ניתוב שימושי:
- ניתוב סוגים שונים של שאילתות שירות לקוחות (שאלות כלליות, בקשות להחזר כספי, תמיכה טכנית) לתהליכים, פרומפטים וכלים שונים במורד הזרם.
- ניתוב שאלות קלות/נפוצות למודלים קטנים וחסכוניים כמו Claude Haiku 4.5 ושאלות קשות/יוצאות דופן למודלים בעלי יכולות גבוהות יותר כמו Claude Sonnet 4.5 כדי למטב את הביצועים.
תהליך עבודה: מקביליות (Parallelization)
LLMs יכולים לעיתים לעבוד במקביל על משימה אחת ולסכם את הפלטים שלהם באופן תכנותי. תהליך עבודה זה, מקביליות, בא לידי ביטוי בשתי וריאציות מרכזיות:
- חיתוך (Sectioning): פירוק משימה למשימות משנה בלתי תלויות שמופעלות במקביל.
- הצבעה (Voting): הפעלת אותה משימה מספר פעמים כדי לקבל פלטים מגוונים.
מתי להשתמש בתהליך עבודה זה: מקביליות יעילה כאשר משימות המשנה ניתנות לפיצול להרצה מקבילה עבור מהירות, או כאשר נדרשות מספר פרספקטיבות או ניסיונות עבור תוצאות מהימנות יותר. עבור משימות מורכבות עם שיקולים רבים, LLMs לרוב מבצעים טוב יותר כאשר כל שיקול מטופל על ידי קריאת LLM נפרדת, מה שמאפשר התמקדות בכל היבט ספציפי.
דוגמאות שבהן מקביליות שימושית:
- חיתוך:
- יישום מנגנוני הגנה (guardrails) שבהם מופע מודל אחד מעבד שאילתות משתמשים בעוד אחר בודק אותן לתכנים או בקשות בלתי הולמים. זה נוטה לבצע טוב יותר מאשר שקריאת ה-LLM יחידה תטפל גם במנגנוני ההגנה וגם בתגובה הליבה.
- אוטומציה של הערכות (evals) לבדיקת ביצועי LLM, שבה כל קריאת LLM מעריכה היבט שונה של ביצועי המודל על פרומפט נתון.
- הצבעה:
- סקירת פיסת קוד עבור פגיעויות, שבה מספר פרומפטים שונים סוקרים ומסמנים את הקוד אם הם מוצאים בעיה.
- הערכה האם פיסת תוכן נתונה אינה הולמת, עם מספר פרומפטים המעריכים היבטים שונים או דורשים סף הצבעה שונה כדי לאזן בין חיוביות ושליליות כוזבות.
תהליך עבודה: מתזמן-עובדים (Orchestrator-workers)
בתהליך העבודה של מתזמן-עובדים, LLM מרכזי מפרק באופן דינמי משימות, מפצל אותן ל-LLMs עובדים (worker LLMs), ומסנתז את תוצאותיהם.
מתי להשתמש בתהליך עבודה זה: תהליך עבודה זה מתאים היטב למשימות מורכבות שבהן לא ניתן לחזות את מספר משימות המשנה הנדרשות (בקידוד, למשל, מספר הקבצים שיש לשנות ואופי השינוי בכל קובץ תלויים כנראה במשימה). בעוד שהוא דומה מבחינה טופוגרפית למקביליות, ההבדל המרכזי הוא גמישותו – משימות המשנה אינן מוגדרות מראש, אלא נקבעות על ידי המתזמן בהתבסס על הקלט הספציפי.
דוגמאות שבהן מתזמן-עובדים שימושי:
- מוצרי קידוד שמבצעים שינויים מורכבים במספר קבצים בכל פעם.
- משימות חיפוש הכוללות איסוף וניתוח מידע ממספר מקורות עבור מידע רלוונטי אפשרי.
סוכנים
סוכנים צומחים בייצור ככל ש-LLMs מתבגרים ביכולות מפתח – הבנת קלטים מורכבים, עיסוק בחשיבה ותכנון, שימוש אמין בכלים, והתאוששות משגיאות. סוכנים מתחילים את עבודתם בפקודה ממשתמש אנושי, או בדיון אינטראקטיבי איתו. לאחר שהמשימה ברורה, סוכנים מתכננים ופועלים באופן עצמאי, ואף עשויים לחזור למשתמש האנושי למידע נוסף או לשיפוט. במהלך הביצוע, חיוני לסוכנים להשיג "אמת קרקע" (ground truth) מהסביבה בכל צעד (כגון תוצאות קריאת כלי או ביצוע קוד) כדי להעריך את התקדמותם. סוכנים יכולים אז להשהות לצורך משוב אנושי בנקודות בקרה או בעת נתקעות. המשימה לרוב מסתיימת עם השלמתה, אך נפוץ גם לכלול תנאי עצירה (כגון מספר איטרציות מרבי) כדי לשמור על שליטה.
סוכנים יכולים להתמודד עם משימות מתוחכמות, אך היישום שלהם לרוב פשוט. הם בדרך כלל רק LLMs המשתמשים בכלים בהתבסס על משוב סביבתי בלולאה. לכן, חיוני לתכנן ערכות כלים והתיעוד שלהם באופן ברור ומתחשב. אנו מרחיבים על שיטות עבודה מומלצות לפיתוח כלים בנספח 2 ("הנדסת פרומפטים לכלים שלכם").
מתי להשתמש בסוכנים: סוכנים יכולים לשמש לבעיות פתוחות שבהן קשה או בלתי אפשרי לחזות את מספר הצעדים הנדרש, ושבהן לא ניתן לקודד נתיב קבוע. ה-LLM יפעל ככל הנראה במשך תורות רבות, ועליכם להיות בעלי רמה מסוימת של אמון בקבלת ההחלטות שלו. האוטונומיה של הסוכנים הופכת אותם לאידיאליים להרחבת (scaling) משימות בסביבות מהימנות.
האופי האוטונומי של סוכנים טומן בחובו עלויות גבוהות יותר, ופוטנציאל לשגיאות מצטברות. אנו ממליצים על בדיקות מקיפות בסביבות מבודדות (sandboxed environments), יחד עם מנגנוני הגנה (guardrails) מתאימים.
דוגמאות שבהן סוכנים שימושיים:
הדוגמאות הבאות הן מיישומים שלנו:
- סוכן קידוד לפתרון משימות SWE-bench, הכוללות עריכות בקבצים רבים על בסיס תיאור משימה;
- יישום הייחוס שלנו ל"שימוש במחשב" (computer use), שבו Claude משתמש במחשב לביצוע משימות.
שילוב והתאמה אישית של תבניות אלה
אבני הבניין הללו אינן קבועות מראש. הן תבניות נפוצות שמפתחים יכולים לעצב ולשלב כדי להתאים למקרי שימוש שונים. המפתח להצלחה, כמו בכל תכונות ה-LLM, הוא מדידת ביצועים ואיטרציה על יישומים. נחזור ונדגיש: עליכם לשקול הוספת מורכבות רק כאשר היא משפרת באופן מוכח את התוצאות.
סיכום
הצלחה בתחום ה-LLM אינה עוסקת בבניית המערכת המתוחכמת ביותר, אלא בבניית המערכת הנכונה לצרכים שלכם. התחילו עם פרומפטים פשוטים, מטבו אותם באמצעות הערכה מקיפה, והוסיפו מערכות סוכניוֹת מרובות שלבים רק כאשר פתרונות פשוטים יותר אינם מספקים.
בעת יישום סוכנים, אנו מנסים לעקוב אחר שלושה עקרונות ליבה:
- שמרו על פשטות בעיצוב הסוכן שלכם.
- תעדיפו שקיפות על ידי הצגת שלבי התכנון של הסוכן באופן מפורש.
- עצבו בקפידה את ממשק הסוכן-מחשב (ACI) שלכם באמצעות תיעוד ובדיקת כלים יסודיים.
פריימוורקים יכולים לעזור לכם להתחיל במהירות, אך אל תהססו להפחית שכבות הפשטה ולבנות עם רכיבים בסיסיים כשאתם עוברים לייצור. על ידי יישום עקרונות אלה, תוכלו ליצור סוכנים שהם לא רק רבי עוצמה, אלא גם אמינים, ניתנים לתחזוקה ומהימנים בעיני המשתמשים שלהם.
תודות
נכתב על ידי אריק ס'. ובארי ז'אנג (Erik S. and Barry Zhang). עבודה זו מתבססת על חוויותינו בבניית סוכנים באנתרופיק ועל התובנות החשובות ששותפו על ידי לקוחותינו, עליהן אנו אסירי תודה עמוקות.
נספח 1: סוכנים בפועל
עבודתנו עם לקוחות חשפה שני יישומים מבטיחים במיוחד עבור סוכני AI המדגימים את הערך המעשי של התבניות שנדונו לעיל. שני היישומים ממחישים כיצד סוכנים מוסיפים את הערך הרב ביותר למשימות הדורשות שיחה ופעולה כאחד, בעלות קריטריוני הצלחה ברורים, מאפשרות לולאות משוב, ומשלבות פיקוח אנושי משמעותי.
א. תמיכת לקוחות
תמיכת לקוחות משלבת ממשקי צ'אטבוט מוכרים עם יכולות משופרות באמצעות שילוב כלים. זהו התאמה טבעית לסוכנים פתוחים יותר מכיוון ש:
- אינטראקציות תמיכה עוקבות באופן טבעי אחר זרימת שיחה תוך דרישה לגישה למידע ופעולות חיצוניים;
- ניתן לשלב כלים כדי לשלוף נתוני לקוחות, היסטוריית הזמנות ומאמרי בסיס ידע;
- פעולות כגון הנפקת החזרים כספיים או עדכון כרטיסים יכולות להיעשות באופן תכנותי; וכן
- ניתן למדוד הצלחה באופן ברור באמצעות פתרונות המוגדרים על ידי המשתמש.
מספר חברות הדגימו את כדאיות הגישה הזו באמצעות מודלי תמחור מבוססי שימוש הגובים תשלום רק עבור פתרונות מוצלחים, מה שמראה אמון ביעילות הסוכנים שלהם.
ב. סוכני קידוד
תחום פיתוח התוכנה הראה פוטנציאל יוצא דופן לתכונות LLM, כאשר היכולות מתפתחות מהשלמת קוד לפתרון בעיות אוטונומי. סוכנים יעילים במיוחד מכיוון ש:
- פתרונות קוד ניתנים לאימות באמצעות בדיקות אוטומטיות;
- סוכנים יכולים לבצע איטרציות על פתרונות באמצעות תוצאות בדיקה כמשוב;
- מרחב הבעיה מוגדר ומובנה היטב; וכן
- ניתן למדוד את איכות הפלט באופן אובייקטיבי.
ביישום שלנו, סוכנים יכולים כעת לפתור בעיות GitHub אמיתיות במדד הביצועים SWE-bench Verified על בסיס תיאור ה-pull request בלבד. עם זאת, בעוד שבדיקות אוטומטיות עוזרות לוודא פונקציונליות, סקירה אנושית נשארת קריטית להבטחת שהפתרונות מתיישרים עם דרישות המערכת הרחבות יותר.
נספח 2: הנדסת פרומפטים לכלים שלכם
לא משנה איזו מערכת סוכניוֹת אתם בונים, כלים ככל הנראה יהיו חלק חשוב מהסוכן שלכם. כלים מאפשרים ל-Claude ליצור אינטראקציה עם שירותים חיצוניים ו-APIs על ידי ציון המבנה וההגדרה המדויקים שלהם ב-API שלנו. כאשר Claude מגיב, הוא יכלול tool use block בתגובת ה-API אם הוא מתכנן להפעיל כלי. הגדרות ומפרטי כלים צריכים לקבל תשומת לב בהנדסת פרומפטים במידה שווה לפרומפטים הכלליים שלכם. בנספח קצר זה, אנו מתארים כיצד לבצע הנדסת פרומפטים לכלים שלכם.
לרוב ישנן מספר דרכים לציין את אותה פעולה. לדוגמה, ניתן לציין עריכת קובץ על ידי כתיבת diff, או על ידי כתיבה מחדש של הקובץ כולו. עבור פלט מובנה, ניתן להחזיר קוד בתוך markdown או בתוך JSON. בהנדסת תוכנה, הבדלים כאלה הם קוסמטיים וניתנים להמרה ללא אובדן מפורמט אחד למשנהו. עם זאת, פורמטים מסוימים קשים בהרבה ל-LLM לכתיבה מאחרים. כתיבת diff דורשת לדעת כמה שורות משתנות בכותרת ה-chunk לפני כתיבת הקוד החדש. כתיבת קוד בתוך JSON (בהשוואה ל-markdown) דורשת ביטול בריחה (escaping) נוסף של מעברי שורה וגרשיים.
ההצעות שלנו להחלטה על פורמטים של כלים הן הבאות:
- תנו למודל מספיק טוקנים כדי "לחשוב" לפני שהוא נכנס למבוי סתום.
- שמרו על הפורמט קרוב למה שהמודל ראה באופן טבעי בטקסט באינטרנט.
- ודאו שאין "תקורה" של עיצוב, כגון הצורך לשמור על ספירה מדויקת של אלפי שורות קוד, או ביטול בריחה (string-escaping) של כל קוד שהוא כותב.
כלל אצבע אחד הוא לחשוב כמה מאמץ מושקע בממשקי אדם-מחשב (HCI), ולתכנן להשקיע בדיוק את אותה כמות מאמץ ביצירת ממשקי סוכן-מחשב (ACI) טובים. הנה כמה מחשבות כיצד לעשות זאת:
- שימו את עצמכם בנעלי המודל. האם ברור כיצד להשתמש בכלי זה, בהתבסס על התיאור והפרמטרים, או שתצטרכו לחשוב עליו בזהירות? אם כן, אז כנראה שזה נכון גם לגבי המודל. הגדרת כלי טובה כוללת לעיתים קרובות שימוש לדוגמה, מקרי קצה, דרישות פורמט קלט וגבולות ברורים מכלים אחרים.
- כיצד תוכלו לשנות שמות פרמטרים או תיאורים כדי להפוך דברים לברורים יותר? חשבו על כך כעל כתיבת docstring מעולה עבור מפתח זוטר בצוות שלכם. זה חשוב במיוחד כאשר משתמשים בכלים רבים ודומים.
- בדקו כיצד המודל משתמש בכלים שלכם: הריצו דוגמאות קלט רבות ב-Workbench שלנו כדי לראות אילו טעויות המודל עושה, ובצעו איטרציות.
- בצעו Poka-yoke לכלים שלכם. שנו את הארגומנטים כך שיהיה קשה יותר לעשות טעויות. (Poka-yoke היא שיטה יפנית למניעת טעויות אנוש באמצעות עיצוב תהליכים כך שיהיה בלתי אפשרי לבצע טעות, או שהיא תתגלה מיד).
בעת בניית הסוכן שלנו עבור SWE-bench, למעשה הקדשנו יותר זמן לאופטימיזציה של הכלים שלנו מאשר לפרומפט הכולל. לדוגמה, מצאנו שהמודל יעשה טעויות עם כלים המשתמשים בנתיבי קבצים יחסיים (relative filepaths) לאחר שהסוכן יצא מתיקיית השורש. כדי לתקן זאת, שינינו את הכלי כך שידרוש תמיד נתיבי קבצים מוחלטים (absolute filepaths) – ומצאנו שהמודל השתמש בשיטה זו ללא דופי.



