→ المدونةأدلة عملية

وكيلك البرمجي يعيد إصلاح كود مُصلَح سلفًا

وكلاء الذكاء الاصطناعي يرقّعون كودًا صحيحًا في 35 إلى 65 بالمئة من التذاكر القديمة. ما الذي يجب أن تحمله التذكرة كي تميّز جلسة جديدة المنجز من المفتوح.

The Taskfolk team

10 د قراءة11 مشاهدة

XLinkedIn

تترك تشغيلة وكيل على تذكرة فروقات بأربعمئة سطر. والخلل الذي تصفه تلك التذكرة أُصلح قبل تسعة أيام على يد أحد أفراد فريقك، في commit مستقر على main منذ ذلك الحين. الاختبارات تنجح، وكانت تنجح قبل التشغيلة أيضًا. والآن على إنسان أن يقرأ الفروقات كاملةً ليكتشف أنها لا تغيّر شيئًا أراد أحدٌ تغييره.

وليست هذه التشغيلة صدفة شاذة. ففي مارس 2026 نشر مختبر SRI في ETH Zurich معيار FixedBench، وهو 200 مهمة أُصلح فيها الخلل سلفًا، ثم أتبعه في 8 مايو بورقة Coding Agents Don't Know When to Act (اطُّلع على المصدرين في 27 يوليو 2026). خمسة نماذج عبر أربع بيئات تشغيل أجرت تعديلات لا لزوم لها على كود صحيح في 35 إلى 65 بالمئة من الحالات. ويقولها المؤلفون بلا تلطيف: «واحد على الأقل من كل ثلاثة بلاغات قديمة ينتهي بتعديلات زائفة على كود يعمل».

وكل ما كُتب عن هذا تقريبًا ينتهي عند إعدادات الوكيل نفسه: أعِد إنتاج الخلل قبل أن ترقّعه، وضَع قاعدة في ملف الإعدادات، وثبّت خادم ذاكرة. النصيحة صحيحة، وهي نصف العمل. أما النصف الذي لم أرَ أحدًا كتبه فهو ما يجب أن تحمله التذكرة ذاتها.

القياس، ولماذا هو أسوأ مما يبدو

يأخذ FixedBench 200 حالة من SWE-bench Verified، ويطبّق الرقعة الذهبية (golden patch) الآتية من pull request الأصلي، ثم يسلّم الوكيل نصّ البلاغ الأصلي. والجواب الصحيح رقعة فارغة. تعديل الاختبارات أو التوثيق مسموح، أما مسّ الكود التنفيذي فإخفاق.

النموذج وبيئة التشغيل ترك الكود دون مساس، وهو الصواب
‏GPT-5.3 Codex داخل Codex 68%
‏Sonnet 4.6 داخل Claude Code 65.0%
‏GPT-5.4 mini داخل Codex 60.5%
‏Qwen3.5 122B داخل Qwen Code 50.3%
‏Gemini 3 Pro داخل Gemini CLI 36.5%

خذ الصف الأول على أنه تقريبي: مخطط المدوّنة يعرض 68 بالمئة لـ GPT-5.3 Codex، بينما يقول نص الورقة إن أفضل النماذج لا تتجاوز 67 بالمئة. والرقم الوحيد المنشور بمجال ثقة هو Sonnet 4.6 عند 65.0 زائد أو ناقص 6.6.

وهذه هي الظروف الجيدة. فأفضل حالات الورقة فيها «سجل Git متاح وآخر commit فيه يحل المشكلة»، مع بيئة مهيأة بالكامل، وتسمّيها الورقة «وضعًا واقعيًا يكون فيه الوكيل جزءًا من خط نشر». أي أن الـ commit المُصلِح كان أحدث سطر في السجل، ومع ذلك رقّع الوكيل فيما بين ثلث التشغيلات وثلثيها. واحذف مجلد .git فيهبط Sonnet 4.6 إلى 50.0 بالمئة.

لماذا يعدّل والإصلاح على بُعد git log واحد

التفسير البديهي أنه لم ينظر أصلًا، وهو صحيح جزئيًا. قرأ المؤلفون بأيديهم 50 أثرًا من آثار تشغيل Sonnet 4.6 ليعرّفوا منها عشر فئات سلوكية، ثم استعانوا بنموذج حَكَمٍ على بقية الآثار، بدقة 80.5 بالمئة مقارنةً بحكم البشر. الآثار التي انتهت بامتناع عن التعديل كانت قد فحصت سجل git في 63.8 بالمئة من الحالات. أما التي انتهت بتعديل، ففي 31.4 بالمئة.

والمعرفة لا توقفه، وهنا تحديدًا يجب أن يتغير تصرفك. فمع مُوجِّه (prompt) يطلب إعادة إنتاج الخلل أولًا، أدرك الوكيل أن الخلل مُصلَح سلفًا في 79.5 بالمئة من الحالات. ومع مُوجِّه يعرض عليه الامتناع بوصفه نتيجة مقبولة، 81.0 بالمئة. الفرق لا يكاد يُذكر.

أما الامتناع الصحيح فكان 65.5 بالمئة مقابل 80.5 بالمئة. الفهم واحد، والسلوك بينهما بون شاسع. وبعبارة المؤلفين: «المسألة الجوهرية ليست قدرة الوكيل على إعادة إنتاج المشكلة وإدراك أنها محلولة سلفًا، بل ما يظنه معايير نجاحه».

وللآثار الفاشلة بصمة تعرفها. فهي تعدّل كودًا لا صلة له بالبلاغ في 87.1 بالمئة من الحالات، و47.1 بالمئة منها تُدخل تغييرات لا تغيّر السلوك فعليًا. والرقم الثاني هذا هو الفروقات العديمة الأثر، كما تبدو من الداخل. لا سبيل أمام الوكيل ليبلّغ عن نجاح، فينتج تغييرًا بدلًا من ذلك.

flowchart TD
  A["Fresh session opens a stale ticket"] --> B{"Does the item name the resolving commit?"}
  B -->|"No"| C["Agent infers state from the repo"]
  C --> D{"Reproduces the defect first?"}
  D -->|"No"| E["Patches working code"]
  D -->|"Yes"| F["Usually realises it is fixed"]
  B -->|"Yes"| F
  F --> G{"Is a no change outcome available?"}
  G -->|"No"| E
  G -->|"Yes"| H["Reports back with evidence"]

مطالبته بإعادة إنتاج الخلل أولًا لا تنفع

معظم النصائح هنا خاطئة، ومنها نصيحتي أنا قبل أن أقرأ الأرقام. فمُوجِّه إعادة الإنتاج وحده حرّك Sonnet 4.6 من 65.0 إلى 65.5 بالمئة، بقيمة p تساوي 1.0. ومع GPT-5.4 mini سار في الاتجاه المعاكس، من 60.5 إلى 47.5. أي أسوأ بثلاث عشرة نقطة من ألا تقول شيئًا. أما المُوجِّه الذي نجح فقد صاغ «لا تغيير» بوصفه مهمة مكتملة: 80.5 بالمئة لـ Sonnet، و88.5 بالمئة لـ GPT-5.4 mini.

وهذا المُوجِّه ينكسر في الاتجاه الآخر. ففي المهمة الجزئية، حيث تكون رقعة خاطئة مطبّقة أصلًا وعلى الوكيل أن يُتمّ العمل، دفعت التعليمة نفسها النموذجين إلى السلبية. أجرى Sonnet تعديلًا ذا معنى في 18.7 بالمئة من تلك الحالات، وGPT-5.4 mini في 6.4 بالمئة. والورقة صريحة: «يمكنه كبح نزعة التصرف على الكود المُصلَح، لكن بثمن استحداث سلبية أمام الكود المعطوب».

وزيادة التفكير لا تنقذه. فعبر أربعة مستويات من جهد الاستدلال تحرّك GPT-5.4 mini من 61.5 إلى 65.8 بالمئة، أي داخل مجال ثقة يقارب سبع نقاط. ويخلص المؤلفون إلى أن نزعة التصرف «ليست إخفاقًا في التروّي يعالجه مزيد من الحوسبة، بل إخفاق في صياغة المهمة».

فسقف ما تبلغه بالمُوجِّهات يقع بين تشغيلة سيئة من كل خمس وواحدة من كل تسع، وثمنه أن يصير الوكيل أسوأ أمام الكود المعطوب. وما بعد هذا السقف يقتضي أن تغيّر ما يقرؤه الوكيل.

ما الذي يجب أن تحمله التذكرة

افتح أي تذكرة في أداة التتبع لديك، واسأل: هل تستطيع جلسة جديدة، لا ذاكرة لها عن فريقك، أن تميّز «غير منجزة» من «منجزة وقديمة» دون أن تسأل إنسانًا؟ في معظم التذاكر لا تستطيع، وما ينقصها أمور مملّة.

ما تحمله التذكرة ما تستنتجه جلسة جديدة ما يحدث بدونه
الـ commit المُصلِح، مثبّتًا على التذكرة الإصلاح في هذا الـ sha، بيد هذا المؤلف، في هذا الوقت الوكيل يخمّن من حالة المستودع
حالة نهائية لـ «مُصلَحة ومُتحقَّق منها» منفصلة عن «ملغاة» أحدهم تحقق من الإصلاح بعد نزوله المغلق والمهجور يبدوان سواء
ملاحظة تسليم تُكتب لحظة توقف العمل ما جُرّب، وما تُرك، ولماذا الكود يبقى، والتعليل يضيع
خطوة قبول تسمّي طريقة إعادة الإنتاج ما الذي يُشغَّل قبل تعديل أي ملف أي مجموعة اختبارات خضراء تُقرأ تأكيدًا
نتيجة «لا تغيير» يمكن بلوغها التبليغ نفسه مهمة منجزة لا شيء يُحتسب إنجازًا إلا الرقعة

الصف الأول هو الذي يفترض الناس أنه متوفر لديهم. تحقق منه. فكلمات الإغلاق في GitHub لا تُفسَّر، بحسب توثيق GitHub نفسه الذي اطُّلع عليه في 27 يوليو 2026، إلا حين يستهدف الـ pull request الفرع الافتراضي. استهدف فرع إصدار وستجد أن «هذه الكلمات تُتجاهَل، ولا تُنشأ أي روابط، ودمج الـ PR لا أثر له على البلاغات». ودمج squash تسقط رسالته المفتاح لا يترك شيئًا كذلك. وفريق يدمج في develop قد يطلق إصلاحات غير مربوطة سنوات دون أن ينتبه، لأن قرّاء تلك التذاكر، حتى اليوم، كانوا بشرًا يتذكرون.

والصف الأخير هو الذي لا يبنيه أحد. فإذا كانت الحالة النهائية الوحيدة على لوحتك هي «منجزة»، و«منجزة» تعني عملًا أُطلق، فالوكيل الذي لا يجد شيئًا يصلحه ليست أمامه نقلة تُحتسب. فيكتب الرقعة.

تركيب هذا في Taskfolk

ابدأ من الحدود. ‏Taskfolk لا يقرأ مستودعك ولا فروقاتك أبدًا. هو يخزّن ما أخبره به إنسان أو عملية آلية، وكل ما يلي يجعل ذلك السجل جديرًا بالقراءة.

تصل مراجع الـ commit إلى المهمة عبر webhook الدفع في GitHub. أي رسالة تحتوي #WEB-118 في أي موضع، أو WEB-118 في أولها تمامًا، تربط ذلك الـ commit بـ sha ورسالته ومؤلفه ووقته، وتكتب سطر نشاط لا يُعدَّل ولا يُحذف. والإعداد اتصال واحد لكل مشروع (طريقة ربط GitHub). والمرجع يعيش على التذكرة، فحذف الفرع لا يأخذ الدليل معه.

Your coding agent re-fixes code that was already fixed - issue linked commits بطاقة الـ commits المرتبطة على المهمة WEB-118، وفيها سطران يحملان sha مختصرًا ورسالة ومؤلفًا وتاريخًا، تحت عنوان المهمة وحالتها.

BASE=https://taskfolk.ai/api/v1/workspaces/acme
curl -H "Authorization: Bearer tfk_live_a1b2..." \
  "$BASE/projects/WEB/issues/WEB-118/commits"

ثم افصل الحالات النهائية. يحتفظ Taskfolk بسبع فئات ثابتة للحالة تحت اللوحة، ويتيح لك أن تسمّي فوقها أي عدد من الأعمدة، كل عمود مرتبط بفئة واحدة. فحالة «مُصلَحة ومُتحقَّق منها» ترتبط بـ done، و«لا حاجة إلى تغيير» ترتبط بـ cancelled، وكلاهما عمود حقيقي على اللوحة. والتقارير وتقسيم المفتوح والمغلق تظل تعمل، لأنها تقرأ الفئة لا الاسم (حالات سير العمل المخصصة، وكذلك سير عمل تتبع الأخطاء الأشمل).

Your coding agent re-fixes code that was already fixed - board terminal columns لوحة فيها عمودا إغلاق، «مُصلَحة ومُتحقَّق منها» بالأخضر و«لا حاجة إلى تغيير» بالأحمر، وفي كل منهما بطاقات.

والانتقالات المسموحة هي الضابط الذي يُفرض فعلًا، وتعمل على كل مسار كتابة: اللوحة، والتعديلات الجماعية، وإجراءات الأتمتة، وواجهة REST API. امنح «قائمة الانتظار» وجهتين، «للتنفيذ» و«قيد التنفيذ»، وسيُرفض أي استدعاء من وكيل يقفز ببطاقة مباشرةً إلى «لا حاجة إلى تغيير»، وتعود رسالة الخطأ ومعها اسما الحالتين. أما حد WIP لكل عمود فليس كذلك. تستطيع ضبطه، لكن لا مسار كتابة يقرؤه، وشارة العدد والترويسة الحمراء على اللوحة مجرد مفتاح عرض. لا شيء يرفض بطاقة.

Your coding agent re-fixes code that was already fixed - status transition rules إعدادات المشروع، وبطاقة حالات اللوحة مفتوحة مع توسيع حالة واحدة تعرض انتقالاتها المسموحة وفئتها.

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

والآن النتيجة التي تقول الأبحاث إنها غائبة. إسناد مهمة إلى وكيل يُنشئ جلسة pending يستلمها الوكيل حين يبدأ. وحين لا يجد شيئًا يصلحه، تكون الصورة النهائية تعليقًا يحمل الدليل، وجلسة انتقلت إلى review، وبطاقة في عمود «لا حاجة إلى تغيير». فلا يبقى فرع ولا شيء في طابور المراجعة.

curl -X POST -H "Authorization: Bearer tfk_live_a1b2..." \
  -H "Content-Type: application/json" \
  "$BASE/projects/WEB/issues/WEB-118/comments" \
  -d '{"body_md":"No change needed. Reproduction passes on main at 4f0c9ae. Fix landed in 2b71d3c."}'
await fetch(`${BASE}/projects/WEB/issues/WEB-118/comments`, {
  method: "POST",
  headers: {
    Authorization: "Bearer tfk_live_a1b2...",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ body_md: "No change needed. Passes on main at 4f0c9ae." }),
});
requests.post(
    f"{BASE}/projects/WEB/issues/WEB-118/comments",
    headers={"Authorization": "Bearer tfk_live_a1b2..."},
    json={"body_md": "No change needed. Passes on main at 4f0c9ae."},
)
{
  "id": "0199f3c1-6b2a-7c41-9f0d-2c8a1e5b7d33",
  "issue_id": "0199e07a-4c11-7a92-b3d6-8f1c2a4e9b05",
  "author_id": "0199c4d8-9b30-7e15-8a71-5d0b3f6c2e44",
  "body_md": "No change needed. Passes on main at 4f0c9ae.",
  "body_html": "<p>No change needed. Passes on main at 4f0c9ae.</p>",
  "created_at": "2026-07-26T09:14:22.000Z",
  "updated_at": "2026-07-26T09:14:22.000Z"
}

ثم حرّك البطاقة. يستقبل POST .../issues/WEB-118/transition فئة حالة، فالقيمة {"status":"cancelled"} تضع المهمة في عمود الإلغاء الافتراضي لذلك المشروع. وللنزول على عمود مسمّى بعينه، عدّل المهمة عبر PATCH مع status_id المطلوب. وكلا المسارين يمر بفحص الانتقال نفسه الذي يمر به سحب البطاقة بيد إنسان. ويستوثق الوكيل بمفتاح API يخصّه وحده، فيُنسب التعليق وتغيير الحالة إلى هويته كعضو، وهذا ما يُبنى منه سجل التدقيق.

وملاحظة أخيرة عن التحقق من العمل، شرحناها بتفصيلها في إدارة فريق من وكلاء الذكاء الاصطناعي. الجلسة التي تصل إلى review أو done بلا سطر نشاط منسوب إليها وبلا تعليق على مهمتها تُوسَم «غير متحقَّق منها». وهذه قاعدة استدلالية لا برهان، ويكفي تعليق واحد لتجاوزها. ومع ذلك تنفع هنا: الوكيل الذي لم يجد شيئًا فعلًا يزيل الوسم بأن يكتب تقريره.

حدود ما يفعله هذا

لا يستطيع Taskfolk أن يكتشف أن إصلاحًا قد نزل سلفًا. لا رؤية له على مستودعك ولا فروعك ولا فروقاتك، ولا يقرؤها أبدًا.

‏GitHub هو تكامل المستودعات الوحيد. لا GitLab، ولا Bitbucket، ولا Azure DevOps.

ولا يظهر مرجع الـ commit إلا إذا كان مفتاح المهمة في رسالة الـ commit. فاستخدم دمج squash برسالة مولّدة، أو ضع المفتاح في عنوان الـ pull request وحده، وستحصل على بطاقة فارغة وإحساس زائف بالتغطية. والـ webhook يستمع إلى أحداث الدفع، فيربط commits لا pull requests.

كما أن Taskfolk لا يشغّل وكيلك. هو يمرّر المحفّزات ويخزّن سجل الجلسة. أما قرار الامتناع فيقع في بيئة تشغيل تملكها أنت، ولهذا يبقى نصف المُوجِّهات مسؤوليتك.

فاتورة التجاهل

التشغيلة المهدورة هي الجزء الرخيص. الجزء الباهظ هو ما يحدث للفروقات بعدها.

فحص Alam وMondal وRoy ما مجموعه 8,106 من طلبات الإصلاح التي كتبها وكلاء في مجموعة بيانات AIDev، ضمن دراسة أُعدّت لمؤتمر MSR 2026 (29 يناير 2026، اطُّلع عليها في 27 يوليو 2026). دُمج منها 65.0 بالمئة، وأُغلق 26.1 بالمئة دون دمج. وراجعوا يدويًا 326 من المغلقة في نحو 100 ساعة عمل بشرية. وكان السبب الأشيع للإخفاق أن المشكلة كانت قد حُلّت أصلًا في pull request آخر، بنسبة 22.1 بالمئة. و8.0 بالمئة أخرى تراجعت أولويتها أو فقدت صلاحيتها قبل أن ينظر فيها أحد.

ثم يأتي المضاعِف. نظر Xu وSubramanian وKarthik في 33,596 طلبًا فتحها وكلاء عبر 2,807 مستودعات، فوجدوا أن 79.4 بالمئة منها كانت مفتوحة بالتزامن مع طلب وكيل آخر في المستودع نفسه، وترتفع النسبة إلى 95 بالمئة خلال أسبوع (7 يوليو 2026، اطُّلع عليها في 27 يوليو 2026). التذكرة لا تتقادم عبر شهور، بل خلال بعد ظهيرة واحدة، لأن وكيلًا ثانيًا من وكلائك أصلحها قبلك. وهذه هي الحالة الاعتيادية وراء باكلوج مشترك لفريق من وكلاء البرمجة وتنسيق وكيلين عبر حالة المهمة كوسيلة تسليم.

كل تشغيلة تكلّفك رموزًا (tokens) من المزوّد، وفرعًا، ودورة CI، وقراءة بشرية. والقراءة هي ما لا تستطيع أتمتته، وهي تُنفَق على فروقات كان يجب أن تكون فارغة.

اختر خطأً واحدًا أغلقته الأسبوع الماضي. واقرأ ما على التذكرة وحده، كما يقرؤه وكيل. فإن لم تجد الـ commit الذي أصلحه، أو لم تستطع أن تعرف هل تحقق أحد من الإصلاح أم لا، فأنت تعرف سلفًا ما ستفعله به تشغيلة وكيلك القادمة.

أسئلة شائعة

لماذا يعيد وكيل الذكاء الاصطناعي كتابة كود أُصلح سلفًا؟

لأن الرقعة هي النتيجة الوحيدة التي يحتسبها نجاحًا. وجد معيار FixedBench من ETH Zurich أن الوكلاء يعدّلون كودًا صحيحًا سلفًا في 35 إلى 65 بالمئة من الحالات، وأظهر تحليل آثار التشغيل أنهم كانوا يعرفون في كثير من الأحيان أن الخلل مُصلَح ويعدّلون رغم ذلك. امنح التشغيلة نتيجة معرّفة بلا تعديل، وتهبط النسبة هبوطًا حادًا.

هل تكفي مطالبة الوكيل بإعادة إنتاج الخلل أولًا لحل المشكلة؟

لا تكفي وحدها. في دراسة FixedBench حرّك مُوجِّه إعادة الإنتاج أولًا نموذج Sonnet 4.6 من 65.0 إلى 65.5 بالمئة (p = 1.0)، وزاد الأمر سوءًا مع GPT-5.4 mini، من 60.5 إلى 47.5. والمُوجِّه الوحيد الذي نفع هو الذي صاغ الامتناع بوصفه نتيجة ناجحة، لكنه جعل النموذجين بعدها سلبيَّين أكثر مما ينبغي أمام كود معطوب فعلًا.

هل يستطيع Taskfolk أن يعرف أن الإصلاح قد نزل سلفًا؟

لا. ‏Taskfolk لا يقرأ مستودعك ولا فروقاتك أبدًا. هو يخزّن مراجع الـ commit التي تصله من webhook الدفع في GitHub حين تحتوي رسالة الـ commit مفتاح المهمة، إضافةً إلى ما يكتبه الناس والوكلاء على المهمة. وهذا السجل هو ما تقرؤه الجلسة الجديدة.

ماذا يجب أن تحتوي التذكرة المغلقة كي لا يعيد الوكيل العمل نفسه؟

الـ commit المُصلِح مربوطًا بالمهمة، وحالة نهائية تفصل «مُصلَحة ومُتحقَّق منها» عن «ملغاة»، وملاحظة تصف أين توقف العمل، وخطوة قبول تسمّي طريقة إعادة الإنتاج التي تُشغَّل قبل تعديل أي شيء. وأضف حالة يستطيع الوكيل نقل البطاقة إليها حين لا يجد شيئًا يصلحه.

قراءات ذات صلة

أضف تعليقًا

ابدأ النقاش.