إجابة سريعة: لإصلاح فشل اختبارات التكامل المستمر (CI) باستخدام وكيل ذكاء اصطناعي، أرسل حدث الفشل إلى رابط خطاف الويب (Webhook)، ودع وكيل البرمجة يتحقق مما إذا كان قادراً على التعامل مع المشكلة، ثم يعيد إنتاجها محلياً في شجرة عمل (Worktree) نظيفة، ويرفع الإصلاح إلى فرع على هيئة طلب سحب مسودة (Draft PR). بعد ذلك يتولى شخص مراجعته ودمجه. القاعدة الذهبية: إن لم يتمكن الوكيل من إعادة إنتاج الخطأ محلياً، فلن يدفع أي كود.
يكلف البناء البرمجي المتعثر (Red Build) عند الساعة الرابعة مساءً أكثر بكثير من مجرد كتابة الإصلاح نفسه. إذ يضطر المهندس إلى إيقاف ما بيده، وفتح سجلات التشغيل، والتمرير عبر 900 سطر من مخرجات الإعداد، ليكتشف في النهاية خطأ فحص التنسيق (Lint error) أو لقطة شاشة قديمة (Stale snapshot). لا يستغرق الإصلاح سوى دقيقتين، لكن تشتت الانتباه وتبديل السياق يستهلك عشرين دقيقة كاملة.
وهنا تحديداً تكمن القيمة الحقيقية لوكيل البرمجة. فمن المحتمل أنك تستخدم بالفعل Claude Code أو Codex أو وكيلاً آخر على جهازك. الجزء المفقود هو الربط التلقائي: آلية ترصد الفشل، وتمرره إلى الوكيل مع توفير السياق المناسب، وتمنعه من رفع تخمينات غير مؤكدة إلى مستودع الكود. يشرح هذا الدليل كيفية بناء هذا الربط عبر GitHub Actions وميزة أتمتة Sharkly، وتعمل نفس البنية مع أي نظام تكامل مستمر يمكنه إرسال طلبات HTTP.
ما يبرع وكيل الذكاء الاصطناعي في إصلاحه في الـ CI وما يعجز عنه
يحقق الوكيل أفضل النتائج مع الأخطاء التي يمكن إعادة إنتاجها على حاسوب محمول ويكون إصلاحها بسيطاً وقابلاً للتحقق. بينما يقدم أداءً سيئاً مع المشكلات المتعلقة بالبنية التحتية، أو بيانات الاعتماد، أو الخدمات الخارجية التابعة لأطراف أخرى. لذلك صنف الأخطاء أولاً قبل البدء بالأتمتة:
| نوع الفشل | مدى ملاءمة الوكيل | السبب |
|---|---|---|
| أخطاء التحليل الساكن والتنسيق (Lint and format) | ممتاز | محددة بدقة وحتمية، وتتحقق أداة التحليل الساكن من صحة الإصلاح |
| أخطاء الأنواع (Type errors) | ممتاز | يتحقق المترجم البرمجي (Compiler) من صحة الإصلاح |
| تعطل لقطات الواجهة (Broken snapshot) بعد تعديل مقصود في الواجهة | جيد | يسهل إعادة إنتاجها، ولكن يجب على شخص تأكيد أن التغيير مقصود |
| الاختبارات المتذبذبة (Flaky tests) | متفاوت | تتطلب إعادة الإنتاج جولات تشغيل متعددة؛ وغالباً ما يكون الإصلاح مرتبطاً بحالة تسابق حقيقية (Race condition) |
| فشل اختبارات الوحدة بعد تعديل منطق العمل البرمجي | متفاوت | قد يكون الاختبار صحيحاً والخطأ في الكود البرمجي نفسه |
| امتلاء مساحة القرص، أو انقطاع مهلة الشبكة في جهاز التشغيل (Runner) | ضعيف | لا يوجد ما يمكن إصلاحه داخل مستودع الكود |
| أخطاء الصلاحيات، أو فقدان الأسرار والمفاتيح السرية وانتهاء صلاحيتها | غير مناسب تماماً | يجب منع الوكيل تماماً من التعامل مع بيانات الاعتماد السرية |
القاعدة الأساسية المستخلصة من هذا الجدول هي: لا يقدم الوكيل حلاً إلا بعد أن يرى الفشل بنفسه ثم يتحقق من نجاحه على بيئة حاسوبه (Computer) الخاصة. في مقال تصميمي نشره فريق DeepSeek Harness على منصة X، أُطلق على هذا النمط اسم "إعادة الإنتاج والإصلاح الصامت": حيث يراقب المشغّل الأحداث، ويبقى ساكناً افتراضياً، ولا يظهر سوى الإصلاح البسيط والمؤكد. يصف المقال تصميماً أولياً وليس منتجاً نهائياً، لكن المبدأ يظل سارياً على أي بنية تبنيها بنفسك.
كيف تعمل حلقة إصلاح الـ CI
تتكون الحلقة من خمس مراحل: حدث الفشل، وخطاف ويب (Webhook) موقّع، ومصفاة سريعة وغير مكلفة، وبيئة معزولة لإعادة إنتاج المشكلة، وبوابة مراجعة بشرية.

- ينتهي تشغيل التكامل المستمر بفشل في البناء.
- يقوم سير عمل صغير بإرسال كائن JSON موقّع إلى رابط الـ Webhook.
- يقرأ الوكيل محتوى الطلب ويتجاهل أي شيء خارج نطاقه، مثل المستودع غير المعني أو الفشل الواقع على فرع إطلاق (Release branch).
- ينشئ الوكيل مهمة، ويستنسخ شجرة عمل (Worktree) جديدة تماماً، ويعيد إنتاج الفشل، ثم يصلحه.
- يرفع الوكيل فرعاً جديداً ويفتح طلب سحب على هيئة مسودة. ثم يتولى مراجع بشري دمجه أو إغلاقه.
تُنفّذ الخطوتان 3 و4 كأتمتة داخل Sharkly (Sharkly Automation). والأتمتة عبارة عن مجموعة تعليمات محفوظة مع الوكيل أو الفريق البرمجي (Crew) المكلف بتنفيذها، وتعمل وفق مشغّل محدد: كجدول زمني، أو تغيير حالة مهمة، أو عبارة في تعليق، أو استدعاء Webhook.
الخطوة 1: إرسال فشل الـ CI إلى Webhook
تتيح منصة GitHub Actions حدثاً باسم workflow_run ينطلق عند اكتمال تشغيل سير عمل آخر. وبما أنه ينطلق عند كل نتيجة، فيمكنك تصفيته ليقتصر على حالة failure باستخدام شرط على المهمة. نقطة مهمة تشير إليها وثائق GitHub: يجب أن يكون ملف سير العمل موجوداً على الفرع الافتراضي للمستودع، وإلا فلن يعمل مطلقاً.
يراقب سير العمل التالي مسار عمل يحمل اسم CI، وينشئ حمولة JSON صغيرة، ثم يوقعها ويرسلها:
name: Report CI failure
on:
workflow_run:
workflows: [CI]
types: [completed]
jobs:
notify:
if: ${{ github.event.workflow_run.conclusion == 'failure' }}
runs-on: ubuntu-latest
steps:
- name: Send signed webhook
env:
WEBHOOK_URL: ${{ secrets.SHARKLY_WEBHOOK_URL }}
SIGNING_SECRET: ${{ secrets.SHARKLY_SIGNING_SECRET }}
REPO: ${{ github.repository }}
RUN_ID: ${{ github.event.workflow_run.id }}
RUN_URL: ${{ github.event.workflow_run.html_url }}
BRANCH: ${{ github.event.workflow_run.head_branch }}
SHA: ${{ github.event.workflow_run.head_sha }}
run: |
BODY=$(jq -nc --arg repo "$REPO" --arg run_id "$RUN_ID" \
--arg url "$RUN_URL" --arg branch "$BRANCH" --arg sha "$SHA" \
'{event:"ci_failure",repo:$repo,run_id:$run_id,run_url:$url,branch:$branch,sha:$sha}')
TS=$(date +%s)
SIG=$(printf '%s\n%s' "$TS" "$BODY" \
| openssl dgst -sha256 -hmac "$SIGNING_SECRET" -binary | base64)
curl -fsS -X POST "$WEBHOOK_URL" \
-H "Content-Type: application/json" \
-H "X-Webhook-Timestamp: $TS" \
-H "X-Webhook-Signature: v1=$SIG" \
--data-raw "$BODY"
نظراً لأن أسماء الفروع تأتي من المساهمين، فإن سير العمل يمررها عبر متغيرات البيئة env وأداة jq بدلاً من حقنها مباشرة داخل نص الصدفة البرمجي (Shell script). احرص على تخزين كلتا القيمتين كـ أسرار مستودع مشفرة (Repository secrets)، ولا تضعهما داخل الملف أبداً.
الخطوة 2: إنشاء الأتمتة ومشغّل الـ Webhook الخاص بها
داخل مساحتك (Space)، أنشئ أتمتة جديدة، وأسندها إلى الوكيل المعني بالإصلاح، ثم أضف مشغّل Webhook. يعرض Sharkly الرابط كاملاً لمرة واحدة فقط عند إنشاء المشغّل أو إعادة إنشائه، لذا انسخه مباشرة إلى أسرار GitHub.

قم بتفعيل سر التوقيع (Signing secret). فمن دونه، يعمل الرابط كمفتاح وصول مباشر (Bearer secret): أي طرف يحصل عليه يمكنه إطلاق عملية التشغيل. أما مع تفعيله، وبحسب وثائق الأتمتة، يجب أن يحتوي كل طلب على ترويسة X-Webhook-Signature بقيمة v1= متبوعة بترميز Base64 لتوقيع HMAC-SHA256 للطابع الزمني، وسطر جديد، وجسم الطلب الخام، باستخدام المفتاح السري الذي يبدأ بـ whsec_. يرفض Sharkly الطوابع الزمنية التي تنحرف بأكثر من 300 ثانية، ويقبل التوقيع لمرة واحدة فقط خلال 10 دقائق، مما يمنع هجمات إعادة إرسال الطلبات (Replay attacks).
يجب تفعيل المشغّل وجعل الأتمتة في حالة نشطة (Active) قبل أن يتمكن أي طلب صالح من بدء التشغيل. يمكنك إجراء اختبار مبدئي عبر خيار "Run now" أولاً.
الخطوة 3: كتابة تعليمات تبدأ بالتصفية أولاً ثم الإصلاح ثانياً
لا يؤدي تشغيل الأتمتة عبر Webhook إلى إنشاء مهمة تلقائياً، إذ ينفذ التشغيل دون مهمة مرتبطة به. لذا، يجب أن تتضمن تعليماتك إنشاء مهمة جديدة؛ فهذا يمنح كل فشل سجلاً مخصصاً، ومساحة حوار للاستفسارات، وحالة واضحة يراها فريقك. ضع الفحوصات البسيطة والسريعة في البداية حتى تنتهي معظم الأحداث غير المعنية خلال ثوانٍ معدودة:
You receive a CI failure webhook. The trigger payload is JSON with
event, repo, run_id, run_url, branch, sha.
1. Stop with no output unless event == "ci_failure" and repo is
acme/web. Stop if branch starts with "release/".
2. Search open tasks for run_id. If one exists, stop.
3. File a task titled "CI fix: <repo> run <run_id>" with run_url in
the body. Do all further work under that task.
4. Read the failed steps: gh run view <run_id> --log-failed
5. If the cause is a secret, permission, runner, or network problem,
comment the diagnosis on the task and stop. Change nothing.
6. Check out sha in a fresh worktree. Run the failing command and
confirm it fails the same way. If it does not reproduce, comment
what you tried and stop. Never push an unreproduced fix.
7. Make the smallest change that fixes it. Do not edit CI config,
lockfiles, or tests you were not asked to fix. Rerun the command
and the nearest test suite.
8. Push to branch ci-fix/<TASK-ID> and open a draft PR with
gh pr create --draft, task ID in the title. Comment the PR link
on the task and hand it to a human for review.
هناك تفصيلان بالغا الأهمية هنا. أولاً: تنطبق مشغلات الحالات والتعليقات حالياً على مستوى المؤسسة بالكامل، ولهذا السبب توصي الوثائق بالتحقق من صحة المدخلات داخل التعليمات؛ ورغم أن الـ Webhook يقتصر على رابطه المحدد، فإن الخطوة 1 توفر حماية إضافية ضد الطلبات الخاطئة. ثانياً: يؤدي تضمين معرّف المهمة (Task ID) في اسم الفرع دوراً وظيفياً عملياً؛ فعند تفعيل تكامل GitHub، يربط وجود معرّف المهمة في اسم الفرع أو عنوان طلب السحب أو وصفه طلب السحب بالمهمة المعنية تلقائياً.
الخطوة 4: التشغيل على بيئة حاسوبية في شجرة عمل معزولة
تُمثّل بيئة الحاسوب (Computer) الجهاز المتصل الذي يعمل عليه الوكيل، بما يحتويه من بيئات تشغيل (Runtimes) وملفات وبيانات اعتماد Git خاصة به. اضبط مستودع الوكيل على الوضع المؤقت (Temporary mode) ليحصل كل تشغيل على دليل مهمة مستقل وشجرة عمل منفصلة. وبذلك، إذا حدث إخفاقان في دقيقة واحدة، فلن تتداخل ملفات كل منهما مع الآخر. للاطلاع على التفاصيل التقنية، راجع مقال تشغيل الوكلاء المتوازيين في أشجار عمل معزولة ومرجع git worktree.
تُستمد صلاحيات الوصول إلى Git من الحاسوب نفسه، وليس من تطبيق GitHub App. يقتصر دور التكامل على ربط طلبات السحب ومزامنة المشكلات (Issues)، بينما تعتمد عمليات الاستنساخ والرفع على مفتاح SSH، أو رمز HTTPS المميز، أو تسجيل الدخول عبر gh المتوفر على ذلك الجهاز. امنح بيانات الاعتماد تلك صلاحية الرفع إلى الفروع فقط، واحمِ الفرع الافتراضي بحيث تتطلب أي عملية دمج مراجعة بشرية معتمدة.
التكلفة وضوابط الحماية
تُحسب تكلفة كل جولة تشغيل وفقاً لخطة الاشتراك الخاصة ببيئة التشغيل (Runtime) نفسها. لا تبيع منصة Sharkly رموزاً معالجة (Tokens)، لذا فإن تكلفة تشغيل إصلاح الـ CI تماثل ما تدفعه لجلسة Claude Code أو Codex بنفس المدة. وتُعد مصفاة الفحص السريع في الخطوة 1 هي وسيلتك الأساسية لضبط النفقات: فالحدث الذي يتوقف عند الخطوة 1 لا يستهلك سوى مئات قليلة من الرموز، بدلاً من تكبد تكلفة إعادة إنتاج كاملة للمشكلة.

يُمثّل التحكم بالتزامن (Concurrency) وسيلة الحماية الثانية؛ إذ يمتلك كل حاسوب (Computer) حداً أقصى للمهام المتزامنة، ويكون الحد الافتراضي للمهام المشغلة في أدلة مؤقتة نصف هذا الرقم. وعند اكتمال السعة، تنتظر المهام الإضافية في قائمة انتظار بدلاً من أن تتراكم على جهاز واحد. وهكذا، فإن أي صباح يتعرض فيه المستودع لـ 30 إخفاقاً يتحول إلى قائمة انتظار منظمة بدلاً من انهيار مفاجئ.
أما بقية القواعد فيمكنك صياغتها مرة واحدة:
- طلبات سحب على هيئة مسودات فقط: لا يدمج الوكيل أي كود تلقائياً. راجع مقال وكلاء البرمجة مع إشراك العنصر البشري لمعرفة الموضع الصحيح لبوابة المراجعة.
- محاولة واحدة لكل تشغيل: إذا فشل الإصلاح الأول في جولة إعادة الاختبار الخاصة به، يكتفي الوكيل بكتابة تعليق ويتوقف.
- قائمة الحظر (Deny list): إعدادات الـ CI، والمفاتيح السرية، وملفات القفل (Lockfiles)، وترقيات قواعد البيانات (Migrations).
- أوقف الأتمتة مؤقتاً من صفحتها عند تعديل التعليمات، ثم استأنفها بعد التحقق عبر تجربة "Run now".
تحقق دائماً قبل أن تمنح الثقة الكاملة. تنطبق هنا دورة التخطيط والملاحظة والتحقق لوكلاء البرمجة: طالع سجل التشغيل لمدة أسبوع كامل قبل توسيع نطاق المستودعات المدعومة.
خيارات بديلة
يمكنك إنشاء مهمة لكل حالة فشل بدلاً من الاعتماد على أتمتة الـ Webhook. وذلك بتوجيه سير العمل نحو برنامج نصي يستدعي أمر sharkly task create، ثم ترك الوكيل المحدد يلتقطها. لكن هذا الأسلوب ينشئ مهمة لكل تعثر في البناء، بما في ذلك الحالات التي ينبغي للوكيل تجاهلها، لذا يلائم هذا الحل المستودعات ذات وتيرة العمل المنخفضة. كما يمكن للفرق التي تدير مشاكلها عبر GitHub البدء من دليل إسناد مشكلة في GitHub إلى وكيل ذكاء اصطناعي.
ابدأ بمستودع واحد
اختر المستودع الأكثر تعرضاً لأخطاء التنسيق (Lint) والأنواع (Type)، وقم بإعداد سير العمل الموضح أعلاه، وشغّل الأتمتة يدوياً ثلاث مرات قبل السماح للـ Webhook بالانطلاق تلقائياً. وعندما تكون مستعداً للتوسع لأكثر من وكيل، يقدم دليل كيفية تشغيل 10 وكلاء برمجة بالذكاء الاصطناعي في وقت واحد كل ما تحتاجه. البدء مع Sharkly مجاني تماماً: اربط حاسوبك ودع وكيلك الحالي يتولى معالجة التعثر البرمجي القادم.
الأسئلة الشائعة
هل يمكن لوكيل الذكاء الاصطناعي إصلاح عمليات بناء الـ CI المتعثرة بمفرده؟
يمكنه إصلاح أخطاء التنسيق والأنواع ولقطات الواجهة التي ينجح في إعادة إنتاجها محلياً. لكن لا ينبغي له دمج الكود بنفسه. أبقِ مخرجاته كطلب سحب مسودة، ودع المطور يتولى الاعتماد والموافقة.
كيف أقوم بتشغيل وكيل الذكاء الاصطناعي عند فشل سير عمل GitHub Actions؟
أضف سير عمل يستجيب للحدث workflow_run مع ضبط types: [completed] وشرط على الوظيفة يفحص conclusion == 'failure'. ترسل هذه الوظيفة طلباً موقّعاً إلى رابط Webhook الخاص بالوكيل.
ما الذي يمنع الوكيل من رفع إصلاح غير صحيح؟
قاعدة إعادة الإنتاج الإلزامية. يجب أن يشهد الوكيل الفشل محلياً، ثم يطبق التعديل، ويتأكد من نجاح نفس الأمر. إن عجز عن إعادة إنتاج الخطأ، فعليه إضافة تعليق على المهمة والامتناع عن رفع أي كود.
هل يفتح تكامل Sharkly مع GitHub طلبات السحب تلقائياً؟
لا، إذ يقتصر دوره على ربط طلبات السحب بالمهام ومزامنة المشكلات. أما فتح طلب السحب فيتولاه الوكيل نفسه مستخدماً صلاحيات Git وgh المتوفرة على الحاسوب التابع له.
ماذا عن الاختبارات المتذبذبة (Flaky tests)؟
اجعل الوكيل يعيد تشغيل الاختبار الفاشل عدة مرات قبل اتخاذ أي قرار. وإذا نجح الاختبار في بعض المرات وفشل في أخرى، فيتعين عليه تسجيل تقرير بالتذبذب داخل المهمة بدلاً من محاولة ترقيع الكود عشوائياً.
كم تبلغ تكلفة جلسة إصلاح الـ CI؟
تساوي تكلفة الرموز التي تستهلكها بيئة التشغيل (Runtime) خلال تلك الجلسة. حيث تُحسب تكلفة جلسات Sharkly خصماً من خطة اشتراكك في Claude Code أو Codex أو واجهة برمجة التطبيقات (API) المستعملة.



