בשנה האחרונה עבדנו עם עשרות צוותים שבונים סוכנים מבוססי מודלי שפה גדולים (LLM) במגוון תעשיות. גילינו באופן עקבי שהיישומים המוצלחים ביותר לא השתמשו במסגרות מורכבות או בספריות ייעודיות, אלא נבנו באמצעות תבניות פשוטות וניתנות לשילוב.
במאמר זה, אנו חולקים את מה שלמדנו מעבודה עם לקוחותינו ובניית סוכנים בעצמנו, ומספקים עצות מעשיות למפתחים לבניית סוכנים אפקטיביים.
מהם סוכנים?
המונח 'סוכן' יכול להיות מוגדר במספר דרכים. חלק מהלקוחות מגדירים סוכנים כמערכות אוטונומיות לחלוטין הפועלות באופן עצמאי לאורך זמן, תוך שימוש בכלים שונים לביצוע משימות מורכבות. אחרים משתמשים במונח לתיאור יישומים מובנים יותר העוקבים אחר זרימות עבודה מוגדרות מראש. באנתרופיק (Anthropic), אנו מסווגים את כל הווריאציות הללו כמערכות סוכנייות, אך מבחינים בהבחנה ארכיטקטונית חשובה בין זרימות עבודה (Workflows) לבין סוכנים:
- זרימות עבודה (Workflows) הן מערכות בהן מודלי LLM וכלים מתואמים באמצעות נתיבי קוד מוגדרים מראש.
- סוכנים (Agents), לעומת זאת, הן מערכות בהן מודלי LLM מכוונים באופן דינמי את התהליכים ושימושם בכלים, ושומרים על שליטה באופן שבו הם מבצעים משימות.
בהמשך, נחקור את שני סוגי המערכות הסוכניות הללו בפירוט. בנספח 1 ('סוכנים בפועל'), אנו מתארים שני תחומים שבהם לקוחות מצאו ערך מיוחד בשימוש במערכות מסוג זה.
מתי (ומתי לא) להשתמש בסוכנים
בעת בניית יישומים עם מודלי LLM, אנו ממליצים למצוא את הפתרון הפשוט ביותר האפשרי, ולהגביר את המורכבות רק בעת הצורך. ייתכן שמשמעות הדבר היא שלא לבנות מערכות סוכנייות כלל. מערכות סוכנייות לרוב מציעות ביצועי משימה טובים יותר במחיר של השהיה (latency) ועלות, ועליכם לשקול מתי פשרה זו הגיונית.
כאשר נדרשת מורכבות רבה יותר, זרימות עבודה מציעות חיזוי ועקביות עבור משימות מוגדרות היטב, בעוד שסוכנים הם האפשרות הטובה יותר כאשר נדרשים גמישות וקבלת החלטות מונחית-מודל בקנה מידה רחב. עם זאת, עבור יישומים רבים, אופטימיזציה של קריאות LLM בודדות עם שליפה (retrieval) ודוגמאות מתוך חלון ההקשר (in-context examples) בדרך כלל מספיקה.
מתי ואיך להשתמש במסגרות פיתוח
ישנן מסגרות פיתוח רבות המקלות על הטמעת מערכות סוכנייות, כולל:
- ה-Claude Agent SDK;
- Strands Agents SDK by AWS;
- Rivet, בונה זרימות עבודה גרפיות (GUI) של LLM בשיטת גרירה ושחרור; ו-
- Vellum, כלי GUI נוסף לבנייה ובדיקה של זרימות עבודה מורכבות.
מסגרות פיתוח אלו מקלות על תחילת העבודה בכך שהן מפשטות משימות נפוצות ברמה נמוכה, כמו קריאה למודלי LLM, הגדרה וניתוח (parsing) של כלים, ושרשור קריאות יחד. עם זאת, הן יוצרות לעיתים קרובות שכבות מופשטות נוספות שיכולות לטשטש את הפרומפטים והתגובות הבסיסיות, ובכך להקשות על ניפוי באגים. הן גם עלולות לפתות להוסיף מורכבות כאשר הגדרה פשוטה יותר הייתה מספיקה.
אנו מציעים למפתחים להתחיל באמצעות שימוש ישיר ב-API של מודלי LLM: תבניות רבות ניתנות ליישום בכמה שורות קוד בלבד. אם אתם כן משתמשים במסגרת פיתוח, ודאו שאתם מבינים את הקוד הבסיסי. הנחות שגויות לגבי מה שמתחת למכסה המנוע הן מקור נפוץ לשגיאות מצד הלקוחות.
ליישומים לדוגמה, עיינו בספר המתכונים שלנו.
אבני בניין, זרימות עבודה וסוכנים
בחלק זה, נחקור את התבניות הנפוצות למערכות סוכנייות שראינו בשימוש מבצעי. נתחיל עם אבן הבניין הבסיסית שלנו – ה-LLM המוגבר – ונמשיך להגביר את המורכבות בהדרגה, מזרימות עבודה הרכבתיות פשוטות ועד לסוכנים אוטונומיים.
אבן בניין: ה-LLM המוגבר
אבן הבניין הבסיסית של מערכות סוכנייות היא מודל LLM משופר עם הרחבות (augmentations) כמו שליפה (retrieval), כלים וזיכרון. המודלים הנוכחיים שלנו יכולים להשתמש באופן פעיל ביכולות אלו – ליצור שאילתות חיפוש משלהם, לבחור כלים מתאימים ולקבוע איזה מידע לשמר.

אנו ממליצים להתמקד בשני היבטים מרכזיים של היישום: התאמת יכולות אלו למקרה השימוש הספציפי שלכם, וכן לוודא שהן מספקות ממשק קל ומתועד היטב עבור ה-LLM שלכם. בעוד שישנן דרכים רבות ליישם הרחבות אלו, גישה אחת היא באמצעות ה-Model Context Protocol (MCP) שהשקנו לאחרונה, המאפשר למפתחים להשתלב עם אקוסיסטם הולך וגדל של כלי צד שלישי באמצעות יישום לקוח פשוט.
להמשך מאמר זה, נניח שלכל קריאת LLM יש גישה ליכולות המוגברות הללו.
זרימת עבודה: שרשור פרומפטים
שרשור פרומפטים מפרק משימה לרצף של צעדים, כאשר כל קריאת LLM מעבדת את הפלט של הקריאה הקודמת. ניתן להוסיף בדיקות תכנותיות (ראו "gate" בתרשים מטה) על כל שלבי הביניים כדי לוודא שהתהליך נשאר במסלול הנכון.

מתי להשתמש בזרימת עבודה זו: זרימת עבודה זו אידיאלית למצבים שבהם ניתן לפרק את המשימה בקלות ובבהירות לתתי-משימות קבועות. המטרה העיקרית היא להחליף השהיה (latency) בדיוק גבוה יותר, על ידי הפיכת כל קריאת LLM למשימה קלה יותר.
דוגמאות לשימוש בשרשור פרומפטים:
- יצירת קופירייטינג שיווקי, ולאחר מכן תרגומו לשפה אחרת.
- כתיבת מתווה למסמך, בדיקה שהמתווה עומד בקריטריונים מסוימים, ולאחר מכן כתיבת המסמך בהתבסס על המתווה.
זרימת עבודה: ניתוב (Routing)
ניתוב מסווג קלט ומפנה אותו למשימת המשך מיוחדת. זרימת עבודה זו מאפשרת הפרדת דאגות ובניית פרומפטים ממוקדים יותר. ללא זרימת עבודה זו, אופטימיזציה לסוג קלט אחד עלולה לפגוע בביצועים על קלטים אחרים.

מתי להשתמש בזרימת עבודה זו: ניתוב עובד היטב עבור משימות מורכבות שיש בהן קטגוריות נפרדות אשר מטופלות טוב יותר בנפרד, ושבהן הסיווג יכול להתבצע במדויק, בין אם על ידי LLM או מודל/אלגוריתם סיווג מסורתי יותר.
דוגמאות לשימוש בניתוב:
- הפניית סוגים שונים של שאילתות שירות לקוחות (שאלות כלליות, בקשות להחזר כספי, תמיכה טכנית) לתהליכי המשך, פרומפטים וכלים שונים.
- ניתוב שאלות קלות/נפוצות למודלים קטנים וחסכוניים כמו Claude Haiku 4.5, ושאלות קשות/חריגות למודלים בעלי יכולת גבוהה יותר כמו Claude Sonnet 4.5, כדי לייעל את הביצועים.
זרימת עבודה: מקביליות (Parallelization)
מודלי LLM יכולים לעיתים לעבוד בו זמנית על משימה ולאחד את הפלטים שלהם באופן תכנותי. זרימת עבודה זו, מקביליות, מתבטאת בשתי וריאציות מרכזיות:
- חיתוך (Sectioning): פירוק משימה לתתי-משימות עצמאיות המורצות במקביל.
- הצבעה (Voting): הרצת אותה משימה מספר פעמים כדי לקבל פלטים מגוונים.

מתי להשתמש בזרימת עבודה זו: מקביליות יעילה כאשר ניתן להריץ את תתי-המשימות המחולקות במקביל כדי להשיג מהירות, או כאשר נדרשות מספר פרספקטיבות או ניסיונות לתוצאות אמינות יותר. עבור משימות מורכבות עם שיקולים רבים, מודלי LLM בדרך כלל מציגים ביצועים טובים יותר כאשר כל שיקול מטופל על ידי קריאת LLM נפרדת, מה שמאפשר התמקדות בכל היבט ספציפי.
דוגמאות לשימוש במקביליות:
- חיתוך (Sectioning):
- יישום מנגנוני הגנה (guardrails) שבהם מופע מודל אחד מעבד שאילתות משתמשים בעוד אחר בודק אותן לתכנים או בקשות לא הולמים. גישה זו נוטה להציג ביצועים טובים יותר מאשר כאשר אותה קריאת LLM מטפלת גם במנגנוני ההגנה וגם בתגובה המרכזית.
- אוטומציה של הערכות (evals) להערכת ביצועי LLM, כאשר כל קריאת LLM מעריכה היבט שונה של ביצועי המודל על פרומפט נתון.
- הצבעה (Voting):
- בדיקת קטע קוד לפרצות אבטחה, כאשר מספר פרומפטים שונים בודקים ומסמנים את הקוד אם הם מוצאים בעיה.
- הערכה האם פיסת תוכן נתונה אינה הולמת, כאשר פרומפטים מרובים מעריכים היבטים שונים או דורשים סף הצבעה שונה כדי לאזן בין חיובי שווא ושלילי שווא.
זרימת עבודה: מתזמר-עובדים (Orchestrator-workers)
בזרימת העבודה של מתזמר-עובדים, LLM מרכזי מפרק באופן דינמי משימות, מפזר אותן למודלי LLM עובדים, ומסנתז את התוצאות שלהם.

מתי להשתמש בזרימת עבודה זו: זרימת עבודה זו מתאימה היטב למשימות מורכבות שבהן אינכם יכולים לחזות מראש את מספר הצעדים הנדרשים (בקידוד, למשל, מספר הקבצים שיש לשנות ואופי השינוי בכל קובץ תלויים ככל הנראה במשימה). בעוד שהיא דומה מבחינה טופולוגית, ההבדל המרכזי ממקביליות הוא הגמישות שלה – תתי-המשימות אינן מוגדרות מראש, אלא נקבעות על ידי המתזמר בהתבסס על הקלט הספציפי.
דוגמאות לשימוש במתזמר-עובדים:
- מוצרי קידוד שמבצעים שינויים מורכבים במספר קבצים בכל פעם.
- משימות חיפוש הכוללות איסוף וניתוח מידע ממקורות מרובים למידע רלוונטי אפשרי.
זרימת עבודה: מעריך-ממטב (Evaluator-optimizer)
בזרימת העבודה של מעריך-ממטב, קריאת LLM אחת מייצרת תגובה בעוד אחרת מספקת הערכה ומשוב בלולאה.

מתי להשתמש בזרימת עבודה זו: זרימת עבודה זו יעילה במיוחד כאשר יש לנו קריטריונים ברורים להערכה, וכאשר שיפור איטרטיבי מספק ערך מדיד. שני הסימנים להתאמה טובה הם, ראשית, שתגובות LLM ניתנות לשיפור באופן מוכח כאשר אדם מביע את המשוב שלו; ושנית, שה-LLM יכול לספק משוב כזה. הדבר דומה לתהליך הכתיבה האיטרטיבי שעובר סופר אנושי בעת יצירת מסמך מלוטש.
דוגמאות לשימוש במעריך-ממטב:
- תרגום ספרותי שבו ישנם ניואנסים ש-LLM המתרגם עשוי שלא לתפוס בתחילה, אך שבו LLM מעריך יכול לספק ביקורות מועילות.
- משימות חיפוש מורכבות הדורשות מספר סבבים של חיפוש וניתוח לאיסוף מידע מקיף, כאשר המעריך מחליט אם יש צורך בחיפושים נוספים.
סוכנים (Agents)
סוכנים מתחילים לצוץ בשימוש מבצעי ככל שמודלי LLM מתבגרים ביכולות מפתח – הבנת קלטים מורכבים, עיסוק בחשיבה ותכנון, שימוש אמין בכלים והתאוששות משגיאות. סוכנים מתחילים את עבודתם בפקודה או בדיון אינטראקטיבי עם המשתמש האנושי. לאחר שהמשימה ברורה, סוכנים מתכננים ופועלים באופן עצמאי, ואף עשויים לחזור למשתמש לבקשת מידע נוסף או שיקול דעת. במהלך הביצוע, חיוני שהסוכנים יקבלו 'אמת קרקע' (ground truth) מהסביבה בכל שלב (כגון תוצאות קריאת כלים או ביצוע קוד) כדי להעריך את התקדמותם. סוכנים יכולים אז לעצור לקבלת משוב אנושי בנקודות בקרה או כאשר הם נתקלים בחסימות. המשימה לרוב מסתיימת עם השלמתה, אך נפוץ גם לכלול תנאי עצירה (כגון מספר איטרציות מרבי) כדי לשמור על שליטה.
סוכנים יכולים להתמודד עם משימות מתוחכמות, אך יישומם לרוב פשוט. הם בדרך כלל מודלי LLM המשתמשים בכלים בהתבסס על משוב סביבתי בלולאה. לכן, חיוני לתכנן את ערכות הכלים ואת התיעוד שלהם בצורה ברורה ומחושבת. אנו מרחיבים על שיטות עבודה מומלצות לפיתוח כלים בנספח 2 ("הנדסת פרומפטים של הכלים שלכם").

מתי להשתמש בסוכנים: סוכנים יכולים לשמש לבעיות פתוחות שבהן קשה או בלתי אפשרי לחזות את מספר הצעדים הנדרשים, ושבהן לא ניתן לקודד נתיב קבוע. ה-LLM יפעל פוטנציאלית במשך מהלכים רבים, ועליכם להקנות רמה מסוימת של אמון ביכולת קבלת ההחלטות שלו. האוטונומיה של סוכנים הופכת אותם לאידיאליים להרחבת משימות בסביבות אמינות.
האופי האוטונומי של סוכנים פירושו עלויות גבוהות יותר ופוטנציאל לשגיאות מצטברות. אנו ממליצים על בדיקות מקיפות בסביבות מבודדות (sandboxed environments), יחד עם מנגנוני הגנה מתאימים.
דוגמאות לשימוש בסוכנים:
הדוגמאות הבאות הן מיישומים שלנו:
- סוכן קידוד לפתרון משימות SWE-bench, הכוללות עריכות בקבצים רבים בהתבסס על תיאור משימה;
- יישום הייחוס שלנו ל"שימוש במחשב", שבו Claude משתמש במחשב לביצוע משימות.

שילוב והתאמה אישית של תבניות אלו
אבני בניין אלו אינן כופות דרך פעולה מסוימת. הן תבניות נפוצות שמפתחים יכולים לעצב ולשלב כדי להתאים למקרי שימוש שונים. המפתח להצלחה, כמו בכל תכונות LLM, הוא מדידת ביצועים ואיטרציה על יישומים. נחזור ונדגיש: עליכם לשקול להוסיף מורכבות רק כאשר היא משפרת באופן מוכח את התוצאות.
סיכום
הצלחה בתחום ה-LLM אינה עוסקת בבניית המערכת המתוחכמת ביותר, אלא בבניית המערכת הנכונה לצרכים שלכם. התחילו עם פרומפטים פשוטים, בצעו אופטימיזציה עם הערכה מקיפה, והוסיפו מערכות סוכנייות רב-שלביות רק כאשר פתרונות פשוטים יותר אינם מספקים.
בעת יישום סוכנים, אנו מנסים לפעול על פי שלושה עקרונות ליבה:
- שמרו על פשטות בעיצוב הסוכן שלכם.
- תעדוף שקיפות על ידי הצגת שלבי התכנון של הסוכן באופן מפורש.
- עצבו בקפידה את ממשק הסוכן-מחשב (ACI) באמצעות תיעוד ובדיקה יסודיים של הכלים.
מסגרות פיתוח יכולות לעזור לכם להתחיל במהירות, אך אל תהססו להפחית את שכבות ההפשטה ולבנות עם רכיבים בסיסיים כשאתם עוברים לייצור. על ידי יישום עקרונות אלו, תוכלו ליצור סוכנים שהם לא רק חזקים אלא גם אמינים, ניתנים לתחזוקה, וזוכים לאמון המשתמשים שלהם.
תודות
נכתב על ידי אריק ס. ובארי ג'אנג (Barry Zhang). עבודה זו מתבססת על הניסיון שלנו בבניית סוכנים באנתרופיק ועל התובנות החשובות ששותפו על ידי לקוחותינו, עליהן אנו אסירי תודה עמוקות.
נספח 1: סוכנים בפועל
העבודה שלנו עם לקוחות חשפה שני יישומים מבטיחים במיוחד עבור סוכני AI, המדגימים את הערך המעשי של התבניות שנדונו לעיל. שני היישומים ממחישים כיצד סוכנים מוסיפים את הערך הרב ביותר למשימות הדורשות הן שיחה והן פעולה, בעלי קריטריוני הצלחה ברורים, מאפשרים לולאות משוב, ומשלבים פיקוח אנושי משמעותי.
א. תמיכת לקוחות
תמיכת לקוחות משלבת ממשקי צ'אט בוט מוכרים עם יכולות משופרות באמצעות שילוב כלים. זה מתאים באופן טבעי לסוכנים פתוחים יותר מכיוון ש:
- אינטראקציות תמיכה עוקבות באופן טבעי אחר זרימת שיחה תוך דרישה לגישה למידע ופעולות חיצוניים;
- ניתן לשלב כלים למשיכת נתוני לקוחות, היסטוריית הזמנות ומאמרי בסיס ידע;
- פעולות כגון הנפקת החזרים כספיים או עדכון קריאות שירות ניתנות לטיפול תכנותי; ו-
- הצלחה ניתנת למדידה ברורה באמצעות פתרונות המוגדרים על ידי המשתמש.
כמה חברות הדגימו את היתכנות גישה זו באמצעות מודלי תמחור מבוססי שימוש, הגובים תשלום רק עבור פתרונות מוצלחים, מה שמראה אמון ביעילות הסוכנים שלהן.
ב. סוכני קידוד
תחום פיתוח התוכנה הראה פוטנציאל יוצא דופן עבור תכונות LLM, עם יכולות המתפתחות מהשלמת קוד ועד לפתרון בעיות אוטונומי. סוכנים יעילים במיוחד מכיוון ש:
- פתרונות קוד ניתנים לאימות באמצעות בדיקות אוטומטיות;
- סוכנים יכולים לבצע איטרציות על פתרונות באמצעות תוצאות בדיקה כמשוב;
- מרחב הבעיה מוגדר היטב ומובנה; ו-
- איכות הפלט ניתנת למדידה אובייקטיבית.
ביישום שלנו, סוכנים יכולים כעת לפתור בעיות GitHub אמיתיות במדד הביצועים SWE-bench Verified בהתבסס על תיאור ה-pull request בלבד. עם זאת, בעוד שבדיקות אוטומטיות מסייעות לאמת פונקציונליות, סקירה אנושית נותרה קריטית להבטחת התאמת הפתרונות לדרישות המערכת הרחבות יותר.
נספח 2: הנדסת פרומפטים של הכלים שלכם
לא משנה איזו מערכת סוכנית אתם בונים, כלים יהיו ככל הנראה חלק חשוב מהסוכן שלכם. כלים מאפשרים ל-Claude לתקשר עם שירותים ו-API חיצוניים על ידי ציון המבנה וההגדרה המדויקים שלהם ב-API שלנו. כאשר Claude מגיב, הוא יכלול בלוק של שימוש בכלים בתגובת ה-API אם הוא מתכנן להפעיל כלי. הגדרות ומפרטי כלים צריכים לקבל תשומת לב בהנדסת פרומפטים במידה שווה לפרומפטים הכלליים שלכם. בנספח קצר זה, אנו מתארים כיצד להנדס פרומפטים עבור הכלים שלכם.
לעתים קרובות ישנן מספר דרכים לציין את אותה פעולה. לדוגמה, ניתן לציין עריכת קובץ על ידי כתיבת diff, או על ידי כתיבת הקובץ כולו מחדש. עבור פלט מובנה, ניתן להחזיר קוד בתוך markdown או בתוך JSON. בהנדסת תוכנה, הבדלים כאלה הם קוסמטיים וניתנים להמרה ללא אובדן מפורמט אחד לאחר. עם זאת, פורמטים מסוימים קשים בהרבה למודל LLM לכתיבה מאחרים. כתיבת diff דורשת ידע על מספר השורות המשתנות בכותרת ה-chunk לפני כתיבת הקוד החדש. כתיבת קוד בתוך JSON (בהשוואה ל-markdown) דורשת בריחה (escaping) נוספת של שורות חדשות וגרשיים.
ההצעות שלנו לבחירת פורמטים של כלים הן כדלקמן:
- תנו למודל מספיק טוקנים כדי "לחשוב" לפני שהוא מכניס את עצמו לפינה.
- שמרו על הפורמט קרוב למה שהמודל ראה באופן טבעי בטקסט באינטרנט.
- ודאו שאין "עומס יתר" של פורמט, כמו הצורך לשמור על ספירה מדויקת של אלפי שורות קוד, או ביצוע בריחת מחרוזות (string-escaping) לכל קוד שהוא כותב.
כלל אצבע אחד הוא לחשוב כמה מאמץ מושקע בממשקי אדם-מחשב (HCI), ולתכנן להשקיע מאמץ דומה ביצירת ממשקי סוכן-מחשב (ACI) טובים. הנה כמה מחשבות על איך לעשות זאת:
- שימו את עצמכם בנעלי המודל. האם ברור כיצד להשתמש בכלי זה, בהתבסס על התיאור והפרמטרים, או שתצטרכו לחשוב עליו בזהירות? אם כן, זה כנראה נכון גם עבור המודל. הגדרת כלי טובה כוללת לעיתים קרובות דוגמאות שימוש, מקרי קצה, דרישות פורמט קלט, וגבולות ברורים מכלים אחרים.
- כיצד ניתן לשנות שמות או תיאורים של פרמטרים כדי להפוך את הדברים לברורים יותר? חשבו על כך כעל כתיבת docstring מעולה למפתח ג'וניור בצוות שלכם. זה חשוב במיוחד בעת שימוש בכלים רבים דומים.
- בדקו כיצד המודל משתמש בכלים שלכם: הריצו קלטים לדוגמה רבים ב-Workbench שלנו כדי לראות אילו טעויות המודל עושה, ובצעו איטרציות.
- בצעו Poka-yoke לכלים שלכם. שנו את הארגומנטים כך שיהיה קשה יותר לטעות.
בעת בניית הסוכן שלנו עבור SWE-bench, למעשה השקענו יותר זמן באופטימיזציה של הכלים שלנו מאשר בפרומפט הכללי. לדוגמה, גילינו שהמודל יעשה טעויות עם כלים המשתמשים בנתיבי קבצים יחסיים לאחר שהסוכן יצא מספריית השורש. כדי לתקן זאת, שינינו את הכלי לדרוש תמיד נתיבי קבצים מוחלטים – וגילינו שהמודל השתמש בשיטה זו ללא דופי.



