דלגו לתוכן

מחזור חיי שליחת סוכן

שליחה היא הרצה אחת של סוכן אחד, בשיחה אחת, על מתאם אחד. כל מה שקשור בה קורה ב-cc_server: הלקוח שולח הודעה ואז צופה באירועים שזורמים בחזרה. אין מסלול שליחה באף לקוח.

סוכנים מתעוררים משש סיבות, וההרצה נושאת אותן כהקשר ההתעוררות שלה, כך שהסוכן יודע למה הוא ער:

סיבת התעוררות טריגר
userMessage מישהו שלח הודעה במרחב, או אזכר את הסוכן
assignment כרטיס הוקצה לסוכן
pipelineStep שלב פייפליין שלח אותו
childCompleted כרטיס בן הסתיים
followUp פעימת מעקב מתוזמנת
recovery מסלול ההתאוששות שלח מחדש לאחר כשל

הקשר ההתעוררות נושא את המזהים שמתלווים לסיבה — כרטיס, מרחב, הודעה, הרצת פייפליין — והם מוזרקים לסביבה של הסוכן ולהנחיה שלו.

ההנחיה נבנית בשכבות, שכל אחת מהן היא מקטע מתויג:

  • זהות — המזהה, השם ומזהה סביבת העבודה של הסוכן עצמו, עם הוראה מפורשת להעביר את אותם UUIDs בדיוק לכלים שמוגבלים לסביבת עבודה. סביבת העבודה טבועה בסוכן, ולכן היא תמיד נוכחת.
  • קטלוג הכלים ופרוטוקולי המשאבים, ואחריהם פריסת סביבת העבודה.
  • עקיפת הנחיית המערכת, אם לסוכן יש כזו, ואחריה פרסונה (המקבלת פרמטרים לפי תפקיד) ותדריך הצוות.
  • מיומנויות — השמות הרשומים על הסוכן.
  • חוזה ההרצה והנוהל של המצב הנוכחי.
  • הקשר ההתעוררות והקשר האזכור: מי זימן את הסוכן והסגל שמסביבו.
  • מקטע המצב — נוצר מפרופיל היכולות של המצב וכן מרשימת הכלים הממומשת שלו, כך שההנחיה לעולם לא תזכיר כלי שלהרצה אין אותו בפועל.
  • הקשר הזיכרון — עובדות שאוחזרו עבור המשימה.
  • הקשר השיחה — היסטוריית המרחב האחרונה, מוגבלת לחלון של 50,000 תווים מילוליים בלי קשר לגודל ההקשר המוגדר של הסוכן. היסטוריה ישנה יותר אינה נחתכת: הסוכן שולף אותה לפי דרישה עם get_messages, והודעות ישנות יותר רלוונטיות מבחינה סמנטית עדיין צפות.

הפקודות מפוצלות בין שני מקומות. /todo ו-/compact נלכדות בתיבת הכתיבה ולעולם, במכוון, אינן נשמרות כהודעות ואינן נשלחות לסוכן — שמירת /compact הייתה דוחפת את חיתוך הדחיסה אחורה תור אחד ומזהמת את התמלול. /plan מטופלת בשניהם: תיבת הכתיבה מחליפה את מצב המרחב, וזה מה שגורם למשטח הכלים, לקבוצת מעקות הבטיחות ולהנחיה להסכים בתור הזה ובכל תור שאחריו. /goal, /loop ו-/skill:<name> מטופלות בתוך ההרצה עצמה ורק במנגנון ההרצה המובנה — /goal ו-/loop מתחילות עבודה אוטונומית עם תקציב עלות, ושם עם קידומת skill: מאותר כמיומנות שגוף ה-SKILL.md שלה הופך לדירקטיבה של התור. מרחב השמות הוא מה שמפריד בין שני מכלולי השמות: איתור שם חשוף מול המיומנויות גרם לכך שמיומנות בשם plan או compact הוצללה לצמיתות על ידי הפקודה המובנית. שם חשוף שאינו מובנה עדיין מאותר, עבור הודעות שנכתבו לפני שמרחב השמות נוצר. שם שאינו מזוהה פשוט נופל דרך כטקסט רגיל.

לפני שדבר כלשהו רץ, השיחה מקבלת שורש עבודה משלה, ומתחתיו עץ עבודה מבודד בהעתקה בזמן כתיבה לכל מאגר. כברירת מחדל אלו כל המאגרים המקושרים לסביבת העבודה; מרחב PR — או מרחב שנוצר עם בחירה מפורשת — מקצה רק את אלה שברשימת ההיתר, ושיחה לסקירת PR מצמידה את המאגר האחד שלה ל-head ref של בקשת המשיכה בעוד שהאחרים יושבים על ענף ברירת המחדל שלהם. הצ׳קאאוט המקורי לעולם אינו משתנה, וכל תיקיית השיחה מפונה כשהמרחב נמחק.

העתקה בזמן כתיבה היא היחידה שמיושמת בכל מקום שבו rift נשלח, בגיבוי רכיב נייטיב מצורף. מערכת קבצים שלא יכולה לבצע reflink — או תיקיית נתונים שנמצאת בכרך אחר מהמאגר — מכשילה את ההקצאה במקום ליפול חזרה. git worktree הוא המנוע ב-Windows, שם אין מנוע העתקה בזמן כתיבה שאפשר לבנות, והוא אינו נסיגה שקטה במארחים אחרים. rift חסר בפלטפורמה שהוא נשלח בה הוא התקנה שבורה — השרת מסרב לעלות במקום ליפול חזרה בשקט, מפני שנפילה לאחור שקטה מסתירה את הקלקול מאחורי מסלול איטי יותר לנצח.

שתי זהויות נקבעות בכל הרצה, לפני שכל תהליך עולה.

בעלות Git. קומיטים שסוכן יוצר נכתבים בשם הסוכן — <Name> (agent) <agentId@agents.control-center.local> בשני המשתנים GIT_AUTHOR_* ו-GIT_COMMITTER_* — ולעולם לא בהתחזות לאדם. החלק המקומי הוא ה-UUID של הסוכן, לא ה-slug של שמו. האדם המבקש נזקף בנספח Co-Authored-By:, שנישא בסביבה ומונחה בהנחיית המערכת. זהות מפורשת שנקבעה על ידי הקורא תמיד גוברת על שתיהן.

זהות מארח הקוד. פרטי הגישה של ההרצה ל-GitHub הם תמיד ורק של המתווך — אסימון התקנת App בהיקף מאגר, או נפילת ה-PAT שלו לסביבה — ולעולם לא האסימון השמור של החבר המבקש עצמו. actingUserId תוחם את נפילת ה-PAT כך שחבר שאינו בעל השרת לא יורש את הטווח של השרת; הוא אינו מניח אסימון אישי על גבי סביבת הסוכן.

פרטי הגישה של ספק המודל נקבעים בסדר קבוע, והסדר חשוב:

  1. עקיפת סביבה לפי מתאם,
  2. הסביבה של הקורא,
  3. מאגר פרטי הגישה של השרת (רענון אסימון OAuth אם הוא קרוב לפקיעה),
  4. סביבת התהליך.

מכיוון שעקיפת המתאם באה ראשונה, היא גוברת בשקט על חשבון ספק שמחובר באפליקציה. אם הרצה מחויבת לחשבון הלא נכון, שם כדאי לחפש קודם. פרטי הגישה של הספק הם גלובליים למארח — משותפים לכל סביבות העבודה בהתקנה.

אסימון ה-GitHub של ההרצה מגיע ממתווך פרטי הגישה: אסימון לקריאה בלבד שמוגבל למאגר של עץ העבודה. דחיפות עוברות דרך שער הרצת הסוכן, ששואל את הכלל דחיפה למאגר מרוחק לפני שהוא מעביר אותן, ושום מפתח כרטוס אינו מוזרק. ראו ארגז חול ואבטחה.

ההרצה מופעלת כשעץ העבודה שלה משמש כתיקיית העבודה, ועבור Claude Code — עם תצורת MCP מחוללת, כדי שהסוכן יוכל להגיע למשטח הכלים של Control Center. ACP וה-bash של מנגנון ההרצה מקבלים סביבה מסוננת; Claude Code דרך NoSandboxAdapter יורש את סביבת המארח.

ההרצה מזרימה בחזרה רצף אירועים בעל טיפוסים, שמעבד הזרימה שומר כדלתות של הודעות, מקפל למקטעי תמלול והופך לאירועי הודעות:

אירוע מה שהוא נושא
thinking פלט החשיבה, מוצג בתוך השורה
text פלט גלוי
toolCall הפעלה של כלי, עם המזהה והארגומנטים המובנים שלו
toolResult התוצאה המתאימה, מסומנת כשיש שגיאה או כשהיא זרם חלקי
usage ספירת אסימונים ועלות עבור חלון מדידה
error שגיאה, עם הקוד המובנה של המתאם כשהוא דיווח על אחד
sandboxViolation מערכת ההפעלה חסמה קריאת מערכת. נפלט רק במקום שבו ארגז חול באמת עוטף את התהליך — ראו את ההערה למעלה
debug אבחון זמן ריצה (סמני הפעלה, הכרעות מעקות הבטיחות, תזכורות חוזה)
done ההרצה הסתיימה

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

  • המודל עוצר מעצמו;
  • אדם עוצר אותה, או משתלט על השיחה (דבר שמשהה את מנגנון ההרצה המובנה בגבול התור הנקי הבא שלו — הרצת Claude Code, שאין לה גבול בטוח, נעצרת במקום זאת);
  • מנגנון ניטור השקט מופעל. אין פלט לאורך הסף, וההפעלה מופסקת עם כשל silentRun. ברירת המחדל היא 15 דקות, ויורדת ל-10 במצבים שהם בעיקר קריאה (סקירה ותוכנית); סוכן יכול לעקוף אותה בין 1 ל-240 דקות. מנגנון ניטור השקט נדרך כשתהליך בן מדווח על ה-PID שלו, ולכן הוא מכסה את ה-CLI של Claude Code — ולא את מנגנון ההרצה המובנה, שאינו מפעיל דבר;
  • תקרת עלות נכנסת לפעולה — אבל רק בפקודות אוטונומיות.

מעקה לולאת האבדון אינו מסיים: שלוש קריאות כלי זהות ברצף והלולאה מנווטת את הסוכן לשנות גישה.

ביחד, לתור אינטראקטיבי רגיל במנגנון ההרצה המובנה אין תקרת תורים, אין תקרת עלות ואין מנגנון ניטור שקט. הוא מסתיים כשהמודל עוצר או כשאתם עוצרים אותו. זהו ויתור מכוון — כל החלופות הורגות עבודה ארוכה לגיטימית — אבל הוא אכן אומר שהרצה אינטראקטיבית ללא השגחה אינה תחומה על ידי דבר מלבד שיקול הדעת של המודל עצמו.

באמצע הרצה, הודעה שנשלחת לסוכן פעיל נכנסת לתור כהיגוי ומנוקזת בגבול התור הבא, כך שאתם יכולים לכוון הרצה בעדינות בלי להרוג אותה. היגוי, השהיה, סוכני משנה וחוזה ההשלמה הם תכונות של מנגנון ההרצה המובנה; ל-Claude Code אין אף אחת מהן.

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

  • סטטוס הוא גס: pending, running, completed, error.
  • מצב החיות הוא הקריאה העדינה יותר: alive, productive, completed, blocked, empty, looping, failed, stalled, dead.
  • משפחת שגיאות מקבצת כשלים בצורה מועילה: transientUpstream, sandboxInfrastructure, budgetExceeded, processLost, silentRun, unknown.

סגירת ההרצה מפרסמת AgentRunCompleted והרבה תלוי בו: צבירת עלויות הפייפליין, חידוש שלב פייפליין שחיכה להרצה, השלמת הכרטיס המגבה, מיפוי תזמור למצב סופי, החלטת ההמשך-או-עצירה של מפקח המטרה, תפקיד הבודק והערכת התקציב שלאחר ההרצה. סגל הנוכחות מגיע בנפרד, בכך שהוא צופה ביומני ההרצה האחרונים ולא באירוע. ההתראה “הסוכן סיים” אינה ברשימה הזו: האירוע נורה כשזרם התהליך מסתיים, לפני שהתשובה נכתבת, ולכן ההתראה היא ה-MessageReceived של התור, שמתפרסם ברגע שההודעה נשמרת.

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

שושלת ניסיונות חוזרים

קטע בשם “שושלת ניסיונות חוזרים”

כל יומן הרצה יכול לשאת שושלת ניסיונות חוזרים — מזהה הרצת אב, מונה ניסיונות וסיכום המשך. עץ ההרצות של השיחה מציג את מספר הניסיון כשהוא שונה מאפס. “נסו שוב” מהצ׳אט הוא שליחה חדשה עם יומן הרצה חדש.