تخطَّ إلى المحتوى

دورة حياة إرسال الوكيل

الإرسال تشغيل واحد لوكيل واحد، في محادثة واحدة، وعلى محوّل واحد. يحدث كله على cc_server. يرسل العميل رسالة، ثم يتابع الأحداث وهي تعود بثًا. لا مسار إرسال في أي عميل.

يُوقَظ الوكلاء لستة أسباب، ويحملها التشغيل في سياق الإيقاظ حتى يعرف الوكيل لماذا هو مستيقظ:

سبب الإيقاظ المشغّل
userMessage أرسل أحدهم رسالة في مساحة، أو أشار إلى الوكيل
assignment أُسنِدت تذكرة إلى الوكيل
pipelineStep أرسلته خطوة في خط أنابيب
childCompleted اكتملت تذكرة فرعية
followUp نبضة متابعة مجدولة
recovery أعاد مسار الاستعادة الإرسال بعد إخفاق

يحمل سياق الإيقاظ المعرّفات الملازمة للسبب، التذكرة والمساحة والرسالة وتشغيل خط الأنابيب، وتُحقَن في بيئة الوكيل وفي مطالبته.

تُبنى المطالبة طبقات، وكل طبقة قسم بعنوان:

  • الهوية: معرّف الوكيل واسمه ومعرّف مساحة عمله، مع تعليمة صريحة بتمرير هذه القيم UUID كما هي إلى الأدوات العاملة في نطاق مساحة العمل. مساحة العمل أصيلة في الوكيل، فهي حاضرة دائمًا.
  • فهرس الأدوات وبروتوكولات الموارد، ثم تخطيط مساحة العمل.
  • تجاوز موجّه النظام، إن وُجد للوكيل، ثم الشخصية (تُضبَط حسب الدور) وموجز الفريق.
  • المهارات: الأسماء المحمولة على الوكيل.
  • عقد التنفيذ والإجراء للوضع الحالي.
  • سياق الإيقاظ وسياق الإشارة: من استدعى الوكيل، والكشف من حوله.
  • كتلة الوضع: تُولَّد من ملف قدرات الوضع ومن قائمة أدواته المُحقَّقة، فلا تسمّي المطالبة أداة لا يملكها التشغيل فعلًا.
  • سياق الذاكرة: وقائع تُجلب للمهمة.
  • سياق المحادثة: أحدث ما في المساحة، بسقف 50,000 حرف من النافذة الحرفية، أيًّا كان حجم السياق المضبوط للوكيل. التاريخ الأقدم لا يُبتر: يسترجعه الوكيل عند الطلب بـ get_messages، وتظل الرسائل الأقدم ذات الصلة في المعنى تظهر.

تنقسم الأوامر على موضعين. يُعترَض /todo و/compact في حقل الكتابة، وعن عمد لا يُحفظان رسائل ولا يُرسلان إلى الوكيل. حفظ /compact كان سيؤخّر حد الضغط جولة ويلوّث نص المحادثة. يُعالَج /plan في الموضعين: يبدّل حقل الكتابة وضع المساحة، فيتفق سطح الأدوات والضبط المسبق للضوابط والمطالبة لهذه الجولة ولكل جولة بعدها. تُعالَج /goal و/loop و/skill:<name> داخل التشغيل نفسه، وعلى الإطار المضمّن وحده. يبدأ /goal و/loop عملًا مستقلًا بميزانية تكلفة، والاسم المسبوق بـ skill: يُحلّ على مهارة يصير متن SKILL.md فيها توجيه الجولة. النطاق هو ما يفصل المفرداتين: كان حلّ الاسم بلا بادئة على المهارات يُبقي مهارة اسمها plan أو compact محجوبة دائمًا بالأمر المضمّن. والاسم بلا بادئة، إن لم يكن أمرًا مضمّنًا، يظل يُحَل في الرسائل المكتوبة قبل وجود النطاق. والاسم الذي لا يُعرَف يمر نصًا عاديًا.

قبل أن يجري شيء، تحصل المحادثة على جذر عمل خاص بها، وتحته شجرة عمل معزولة بالنسخ عند الكتابة لكل مستودع. افتراضيًا يشمل ذلك كل مستودع مرتبط بمساحة العمل. مساحة طلب سحب، أو مساحة أُنشئت باختيار صريح، تجهّز المستودعات المسموح بها فقط. ومحادثة مراجعة طلب السحب تثبّت مستودعها الوحيد على مرجع head للطلب، وتُبقي سائر المستودعات على فرعها الافتراضي. لا تُمَس نسخة المصدر أبدًا، ويُسترد مجلد المحادثة كله عند حذف المساحة.

النسخ عند الكتابة هو التنفيذ الوحيد أينما يُشحَن rift، وتسنده المكتبة الأصلية المضمّنة. إذا عجز نظام الملفات عن reflink، أو كان دليل البيانات على وحدة تخزين غير وحدة المستودع، فشل التجهيز ولم يُرجَع إلى بديل. git worktree هو الخلفية على Windows، حيث لا تُبنى خلفية للنسخ عند الكتابة، وليس ذلك تراجعًا صامتًا على المضيفات الأخرى. غياب rift على منصة تشحنه تثبيت معطوب. يرفض الخادم الإقلاع بدل أن يرجع في صمت، لأن الرجوع الصامت يخفي العطب إلى الأبد خلف مسار أبطأ.

تُحَل هويتان في كل تشغيل، قبل إطلاق أي عملية.

تأليف Git. إيداعات الوكيل تُؤلَّف باسم الوكيل، بالصيغة <Name> (agent) <agentId@agents.control-center.local> في GIT_AUTHOR_* وGIT_COMMITTER_* معًا، ومن غير انتحال إنسان. الجزء المحلي هو UUID الوكيل، لا اسم مساره. تُنسَب مشاركة الإنسان الطالب في تذييل Co-Authored-By: يُحمَل في البيئة وتذكره تعليمات موجّه النظام. هوية يضبطها المستدعي صراحةً تغلب الاثنتين دائمًا.

هوية مضيف الشفرة. بيانات اعتماد GitHub للتشغيل هي ما لدى الوسيط لا غير: رمز تثبيت 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، فيغطي سطر أوامر 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 أن يبدأ عمل متابعة من الحدث نفسه.

يمكن لكل سجل تشغيل أن يحمل نسب إعادة المحاولة: معرّف تشغيل أب، وعدّاد محاولات، وملخص استئناف. تعرض شجرة تشغيل المحادثة رقم المحاولة إذا لم يكن صفرًا. «حاول مرة أخرى» من الدردشة إرسال جديد بسجل تشغيل جديد.