الطبقة الأولى لا تغيّر الـ agent أبدًا. هي فقط تُكمل الـ runs أو توقفها.
والطبقة الثانية تقترح تغييرات على الـ agent لكنها لا تُجريها أبدًا.
هذه الصفحة نظرة عامة. كل قسم يربط بالصفحة التي فيها التفاصيل الكاملة.
استعادة الـ run الآن
أعطِ الـ agent مخزن checkpoints وشغّلagent.recover() مرة واحدة لكل process.
كل intervalMs (الافتراضي 30 ثانية) تسرد agent.pending() وتستأنف
كل run منقطع من آخر checkpoint له، فلا تُشغَّل الخطوات المكتملة
مرة أخرى.
recovery.stop()، أو ألغِ خيار signal، عند الإيقاف.
ما تفعله الحلقة مع حالات الفشل:
- التراجع (backoff). الـ run الذي فشل يُتخطّى حتى تنقضي مدة تراجعه:
intervalMsمضاعفةً لكل محاولة فاشلة متتالية، حتى 15 دقيقة. - العزل (quarantine). بعد
maxAttemptsحالات فشل متتالية (الافتراضي 10)، تتوقف الحلقة عن استئناف الـ run وتستدعيonQuarantined(run)مرة واحدة. وتظلagent.pending()تسرده، وتظلagent.resume()تشغّله، حتى يقرّر شخص. حفظ التقدّم يصفّر العدّاد. - إعادة المحاولة مع تشخيص. مع
retryWithDiagnosis: true(الافتراضيfalse)، يحصل الـ run الذي يبلغ الحد أولًا على محاولة أخرى: fork باسم<id>.heal، يُستأنَف من الخطوة نفسها، مع ملاحظة تقول لماذا فشل الـ run. تقتبس الملاحظة الخطأ كبيانات وتحدّ طوله. إذا اكتمل الـ fork، يُحذَف الأصلي ويُبلِّغonRecoveredبـ id الأصلي. وإذا بلغ الـ fork الحد هو أيضًا، يُعزَل الاثنان. ينطبق هذا على runs الـsend()، لا على دورات الجلسات، ويجب أن يحتفظ المخزن بـ سجل checkpoints. - الأخطاء التي لن تزول. الـ run الذي يحمل آخر خطأ له
retryable: false، مثل 400 من المزوّد، يُترك وشأنه. - انقطاعات المزوّد. بعد 3 حالات فشل متتالية من المزوّد، عبر أي runs، تتوقف
الحلقة مؤقتًا وتستدعي
onOutage(true). ثم تجرّب run واحدًا في كل مرة، على فترات متزايدة، وتستدعيonOutage(false)بمجرد أن ينجح أحدها. ولا تُعزَل الـ runs بسبب فشل المزوّد أثناء التوقف المؤقت. ومفتاح API الخاطئ لا يُحسَب انقطاعًا. - الموافقات. الـ run المتوقف على موافقة أو سؤال يُترك لشخص.
recover(): تضمن run leases
أن تستأنف واحدة منها فقط الـ run. راجع
الاستعادة التلقائية للسلوك
الكامل.
إيقاف الـ run الذي لا يحرز تقدّمًا
تعيد الاستعادة تشغيل الـ runs التي انقطعت. أما الـ run الذي ما زال يعمل لكنه عالق، مثل run يستدعي أداة فاشلة مرة بعد مرة، فيحتاج إلى hook بدلًا من ذلك. تضيفcreateProgressGuard() تلميحًا إلى نتيجة الأداة التي تظل تفشل بالطريقة
نفسها، ثم ترفض الأداة أو الاستدعاء المتكرر. وبعد أن ترفض maxDenials
استدعاءات (الافتراضي 3)، يوقف الرفض التالي الـ run بـ
LOUSHO_RUN_NO_PROGRESS. يُسجَّل هذا الخطأ
على أنه غير قابل لإعادة المحاولة، فلا تستأنف agent.recover() الـ run.
كل تلميح ورفض وإيقاف يُبَث كحدث heal.action:
createOutputCheck(). راجع Hooks
للاثنين، وأحداث البث لحقول heal.action.
مراقبتها
- استدعاءات
recover()الراجعة:onRecoveredوonQuarantinedوonOutageوonError. الاستدعاء الراجع الذي يرمي خطأ لا يوقف الحلقة. - تسرد
agent.pending()كل run غير مكتمل معlastErrorوattempts، بما في ذلك المعزولة. - النتيجة التي استبدلها حارس التقدّم تُعلَّم على span الأداة بـ
lousho.tool.replaced_by_hook، ويُسجَّل الرفض كخطأ الـ span. راجع التتبّع والمراقبة للـ spans ولـ daemon الـ observe المحلي.
اقتراح تعديلات لاحقًا
تبحثimproveAgent() من lousho/improve عن تعليمات ومهارات أفضل
مستخدمةً حالات فاشلة تعطيها لها. وهي تجريبية.
- تُرجع اقتراحًا فقط. الـ
outcomeبقيمةproposalيأتي معdiff. يراجعه شخص، مستعينًا بـformatImproveResult()للحصول على بطاقة مقروءة، ثم يطبّقه بنفسه. - لا تستطيع تغيير إلا التعليمات والمهارات. لا تستطيع تغيير الأدوات أو الصلاحيات أو الحدود.
- تختبر قبل أن تقترح. يُشغِّل كل مرشّح حالاتك مرة أخرى ويجب أن
يحسّن حالة تدريب واحدة على الأقل دون أن يجعل أي حالة أسوأ، بما في ذلك
الحالات المحجوزة (held-out) التي لا يراها المحرّرون أبدًا. وتفحص أيضًا التكلفة لكل run ناجح
مقابل
maxCostIncrease(الافتراضي 0.5). - الـ
probeالخاص بك يشغّل الـ agent، فهو المسؤول عن الآثار الجانبية. أضفcreateShadowHook({ readOnly: [...] })إلا إذا كانت كل أداة آمنة للتشغيل.
casesFromFailures(db) الـ runs الفاشلة في
قاعدة بيانات observe المحلية لديك إلى حالات. وتصل نتائج الأدوات فيها إلى المحرّرين
معلَّمة بأنها غير موثوقة.
ومن سطر الأوامر، يفعل lousho improve <agent> --check <module> ذلك ويطبع الاقتراح للمراجعة؛ راجع CLI.
راجع تحسين الـ agent للبوابة والنتائج وملاحظات
الأمان.
كيف تتكامل الطبقتان
الـ run الذي تتخلّى عنه الطبقة الأولى، معزولًا أو موقوفًا بـLOUSHO_RUN_NO_PROGRESS، علامة على أن شيئًا في الـ agent يحتاج إلى تغيير.
أصلِح الأداة، أو غيّر التعليمات. وإذا كان السبب في التعليمات أو
المهارات، فيمكن أن تصبح حالات الفشل تلك حالات لـ improveAgent()، ويقرّر شخص
ما إذا كان سيطبّق ما تقترحه.
الأدلة الحيّة (S29 وS30)
في إصدارات الـ SDK الحالية، تطبّق حلقة التعافي الذاتي (lousho improve على
مجلد agent) التعديلَ الذي يجتاز فحوصها تلقائيًا بشكل افتراضي (الوضع التلقائي)،
أما الوضع اليدوي فيضعه في قائمة انتظار ليقرّر فيه شخص.
في 2026-11-09 اختُبرت هذه الحلقة في تشغيل حيّ على حالات برمجية اصطناعية.
عمل الـ agent على qwen/qwen3.7-flash، وعمل نموذج تحرير منفصل،
stealth/crouton-alpha، على الحالات الاصطناعية فقط. شُغِّل كل سيناريو مرة
واحدة، وشُغِّل planted-editor ثلاث مرات.
- نجح كل سيناريو اختبر شيئًا فعلًا. نجح
planted-editorفي محاولتين من محاولتين، ولم تصل محاولة ثالثة إلى المحرّرين، فلم تُحتسَب. - تحقّق سجل التدقيق في كل مجلد محاولة.
- حكم التقرير هو INCOMPLETE (غير مكتمل)، لأن معايير القرار تتطلب من 5 إلى 10 محاولات لكل سيناريو.