SSD Nodes Learn Hosting plans →
الأدلة Matt Connorبقلم Matt Connor · آخر تحديث في 2026-10-28

ما هي هندسة الحلقات في الذكاء الاصطناعي؟

تعرّف إلى هندسة الحلقات: تصميم المُشغّل والحدود والتحقق والميزانية التي يكررها وكيل الذكاء الاصطناعي، بدلاً من كتابة مطالبة ذكية واحدة.

ما المقصود بهندسة الحلقات

هندسة الحلقات هي تصميم الدورة المتكررة التي يعمل فيها وكيل الذكاء الاصطناعي: ما الذي يوقظه، وما الموارد التي يمكنه الوصول إليها، وكيف تتحقق من مخرجاته، وما الذي يوقفه. تصوغ هندسة المطالبات رسالة واحدة تُرسل إلى النموذج، بينما تصوغ هندسة الحلقات العملية التي ترسل آلاف الرسائل أثناء نومك. تنتقل وحدة العمل من المطالبة إلى الحلقة.

باختصار: تتوقف عن كتابة التعليمات، وتبدأ بكتابة نظام تحكم. لا يزال الوكيل يحتاج إلى تعليمات جيدة، لكنها تصبح مكوّناً واحداً داخل دورة تعمل وفق جدول زمني، وتنفّذ العمل في نسخة معزولة من شفرتك، وتثبت صحة نتيجتها باختبار، وتتوقف عند نفاد الميزانية.

سبب ظهور المصطلح في 2026

يُثبَّت الاسم علناً في الوقت الحالي. تجاوز مستودع GitHub cobusgreyling/loop-engineering عدد 9,600 نجمة خلال شهرين من ظهوره الأول (حتى يوليو 2026)، ووصل إلى نحو 11,600 في 2026-10-27، تحت العبارة "Stop prompting. Design the loop. Get a score." في يوليو 2026، جمعت وثيقة README الخاصة به هذا التحول في ستة مكوّنات أساسية: الجدولة، وworktrees، والمهارات، والإضافات والموصلات، والوكلاء الفرعيون، والذاكرة الدائمة المحفوظة خارج المحادثة. لم تعد وثيقة README الحالية تتضمن تلك القائمة (تم التحقق في 2026-10-27)، لكنها لا تزال تحفظ حالة الحلقة في ملف خارج المحادثة.

ينسب المستودع الفضل إلى Boris Cherny، الذي يقود Claude Code في Anthropic، باعتباره أحد مصادر الإلهام. وعبارته التي أُبلغ عنها على نطاق واسع هي:

لم أعد أكتب prompts إلى Claude. لدي حلقات تعمل وتكتب prompts إلى Claude.

يوجد مستودع ثانٍ، AI-Builder-Club/skills، بالقرب من 1,300 نجمة (حتى 2026-10-27)، ويسمي الدورين مباشرة: "codebase harness" يجعل المستودع آمناً لكي يشغّل الوكيل الاختبارات وعمليات النشر فيه، و"loop engineer" يبني workflows تستيقظ عند حدوث trigger، وتنفذ العمل، وتكتب ما تعلمته في ملف مشترك حتى تتمكن الحلقة التالية من قراءته.

لم يخترع أي من المستودعين هذه الممارسة. كل من شغّل nightly build، أو linter في continuous integration، أو cron job يفتح تذكرة، يعرف هذا النمط مسبقاً. الجديد هو أن العامل داخل الحلقة أصبح الآن غير حتمي، وهذا يغيّر ما يجب أن تفعله الآليات المحيطة به.

الأجزاء الأربعة للحلقة

تحتوي كل حلقة عاملة على هذه الأجزاء الأربعة. وإذا تجاوزت الحلقة أحدها، فقد توقظك الساعة 3 صباحاً.

  • المشغِّل. الحدث الذي يبدأ التنفيذ: مؤقّت، أو webhook، أو طلب سحب جديد، أو تنبيه.
  • النطاق. الملفات وبيانات الاعتماد والشبكة التي يمكن للوكيل الوصول إليها أثناء ذلك التنفيذ.
  • التحقق. فحص يُرجع exit code يحدد ما إذا كان سيتم الاحتفاظ بمخرجات التنفيذ أو التخلص منها.
  • الميزانية. حد الرموز المميّزة والوقت والمال الذي ينهي التنفيذ سواء نجح أم لا.

حوّل هذه الأجزاء الأربعة إلى أسئلة، وستحصل على مراجعة تصميم لأي وكيل تستعد لتركه قيد التشغيل.

المشغّل: ما الذي يوقظ الوكيل

المؤقّت هو أبسط مشغّل. وعلى خادم Linux، يتفوق مؤقّت systemd على cron لهذا الغرض لأنه يسجل الأحداث، ويعيد المحاولة وفق ما تحدده، ولا يبدأ نسخة ثانية من وحدة لا يزال تشغيلها قائماً. تزيل هذه الخاصية أكثر أخطاء التداخل شيوعاً في حلقات الوكلاء: تشغيلين يعدّلان الفرع نفسه.

أنشئ مستخدماً خاصاً بالوكيل أولاً. هذا المستخدم جزء من حد العزل، ولذلك يملك /srv/agent ولا يملك شيئاً غيره:

sudo useradd --system --home-dir /srv/agent --shell /usr/sbin/nologin agent
sudo chown -R agent:agent /srv/agent

ثم اكتب الوحدة في /etc/systemd/system/agent-loop.service:

[Unit]
Description=Agent loop: triage open issues
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
User=agent
WorkingDirectory=/srv/agent/repo
ExecStart=/srv/agent/bin/loop.sh
TimeoutStartSec=1800

واكتب المؤقّت في /etc/systemd/system/agent-loop.timer:

[Unit]
Description=Run the triage loop every 30 minutes

[Timer]
OnBootSec=5min
OnUnitActiveSec=30min
Unit=agent-loop.service

[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now agent-loop.timer
systemctl list-timers agent-loop.timer

يجب أن يعرض systemctl list-timers عمود NEXT يتضمن وقتاً مستقبلياً، وعمود LEFT يعرض العد التنازلي. تعني النتيجة الفارغة أن المؤقّت غير مفعّل، لأن enable من دون --now يجدوله للإقلاع التالي فقط. تبدو TimeoutStartSec=1800 أقل أهمية مما هي عليه فعلاً. تُعد خدمة Type=oneshot قيد البدء حتى يخرج البرنامج النصي منها، ويعطّل systemd مهلة البدء للوحدات من نوع oneshot افتراضياً. لذلك، من دون هذا السطر، يبقى الوكيل الذي يتوقف منتظراً إدخالاً عالقاً في حالة التفعيل إلى الأبد، وتجد كل إشارة لاحقة من المؤقّت أنه لا يزال قيد التشغيل فلا تبدأ شيئاً. عند وضع السطر، ينهي systemd التشغيل بعد 30 دقيقة ويضع علامة فشل عليه. إذا غيّرت الوحدة في أي وقت إلى Type=simple الافتراضية، فلن يغطي TimeoutStartSec التشغيل نفسه بعد ذلك، ويصبح RuntimeMaxSec= هو الإعداد الذي يحدد حده الأقصى. اقرأ تشغيلًا باستخدام journalctl -u agent-loop.service -n 50.

إذا شغّلت الحلقة من cron بدلاً من ذلك، فأضف آلية منع تداخل خاصة بك، لأن cron سيبدأ نسخة ثانية دون تردد:

*/30 * * * * /usr/bin/flock -n /tmp/agent-loop.lock /srv/agent/bin/loop.sh

يخرج flock -n فوراً بالحالة 1 عندما يكون القفل مشغولاً، ولذلك يختفي التشغيل الثاني بهدوء بدلاً من منافسة التشغيل الأول. ينطبق إعداد خدمة systemd والمؤقّت نفسه على أي مهمة طويلة التشغيل على الخادم، سواء كانت وكيلاً أم لا.

الحد الفاصل: امنح كل تشغيل نسخته الخاصة

الوكيل الذي يحرّر شجرة العمل لديك يمكنه فقدان عملك غير المُلتزم به. تحل Git worktrees هذه المشكلة بتكلفة منخفضة: يحصل كل تشغيل على مجلده وفرعه الخاصين، مع مشاركة مخزن كائنات واحد.

cd /srv/agent/repo
git worktree add -b loop/triage-01 /srv/agent/work/triage-01 origin/main
git worktree list

يطبع git worktree list سطراً واحداً لكل شجرة، يتضمن مسارها وcommit والفرع. عند انتهاء التشغيل، يزيل git worktree remove /srv/agent/work/triage-01 شجرة العمل، ولكن فقط إذا كانت نظيفة. إذا احتوت الشجرة على ملفات غير متتبعة أو ملفات متتبعة معدّلة، أو تضمنت submodules، يرفض git المتابعة حتى تضيف --force. لذلك يفرض script البوابة أدناه الإزالة فقط على المسار الذي سيُلغي التشغيل. يمسح git worktree prune الإدخالات التي اختفى مجلدها. تصبح الحلقات المتوازية آمنة في هذه المرحلة، لأن وكيلين يعملان على فرعين وفي مجلدين مختلفين لا يمكنهما الكتابة فوق عمل أحدهما الآخر.

يتعلق هذا الحد الفاصل أيضاً ببيانات الاعتماد. تحتفظ الحلقة التي تعمل دون إشراف بـtokens طويلة الأجل، وكل تشغيل يتيح فرصة لتسريب أحدها إلى سجل أو commit أو سياق النموذج. قيّد token بالمستودع الوحيد الذي تلمسه الحلقة، وأبعده عن البيئة التي تراها shell الخاصة بالوكيل نفسه حيثما أمكنك ذلك، واقرأ كيفية إبقاء الأسرار خارج وكلاء AI قبل منح حلقة صلاحية الوصول إلى بيئة الإنتاج. ولإنشاء عزل أقوى، ضع الحلقة بأكملها على VM مؤقتة يمكنك إتلافها بعد كل تشغيل. كما تحدد الأداة التي تشغّلها جزءاً من هذا الحد الفاصل قبل أن تكتب أي شيء، لذلك من المفيد قراءة كيفية مقارنة sandbox المُدار في Cowork مع Claude Code على جهازك الخاص قبل أن تقرر مقدار العزل الذي تحتاج إلى بنائه بنفسك.

التحقق: البوابة التي تجعل الحلقة آمنة

هذا هو الجزء الذي يميّز الحلقة عن cron job يكتب الأوامر فقط. مخرجات الوكيل اقتراح. أما البوابة فهي التي تقرر.

#!/usr/bin/env bash
set -euo pipefail

repo=/srv/agent/repo
branch="loop/$(date -u +%Y%m%dT%H%M%SZ)"
tree="/srv/agent/work/$(basename "$branch")"

cd "$repo"
git fetch --quiet origin
git worktree add -b "$branch" "$tree" origin/main
cd "$tree"

# the agent's own command runs here, in non-interactive mode

if ! npm test; then
  echo "gate failed: discarding $branch" >&2
  cd "$repo"
  git worktree remove --force "$tree"
  exit 1
fi

git push origin "$branch"
cd "$repo"
git worktree remove "$tree"

تؤدي set -euo pipefail وظيفة فعلية في ذلك البرنامج النصي. من دون -e، يتم تجاهل فشل git fetch ويستمر التنفيذ باستخدام origin/main قديم. ومن دون -u، يتم توسيع الخطأ الإملائي في اسم متغير إلى سلسلة فارغة، ثم تُنفَّذ عملية التنظيف على المسار الخطأ بدلاً من إيقاف التنفيذ مع إظهار الخطأ. لا يحتوي السطر الأخير على --force عن قصد: إذا خلّف التنفيذ ملفات غير متتبعة أو غير مُثبتة في شجرة العمل، يرفض git حذفها، وتنهي -e التنفيذ بخطأ بعد عملية push بدلاً من حذف عمل لم يثبّته أحد بصمت.

كتلة if ! npm test هي جوهر الفكرة. يحدد رمز الخروج من فحص موثوق لديك، مثل مجموعة الاختبارات أو مدقق الأنواع، ما إذا كان سيتم دفع الفرع أو حذفه. تنتج الحلقة التي لا تحتوي على بوابة عملاً لا يملك أحد وقتاً لمراجعته، وهذا أسوأ من عدم إنتاج أي عمل. أما الحلقة التي تحتوي على بوابة فتنتج فرعاً اجتاز مسبقاً المعيار نفسه الذي يجب أن يجتازه فرع المساهم البشري. لا توضح البوابة الخضراء مقدار الشيفرة التي عدّلها الوكيل للوصول إلى هذه النتيجة، لذلك من المفيد دمج الفحص مع توجيه دائم مثل القاعدة التي تجعل الوكيل ينفذ أصغر تغيير ينجح، إذ يحافظ ذلك على صغر diff بما يكفي لتبقى مراجعته منخفضة التكلفة.

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

الميزانية: ما الذي يوقف التشغيل

الوكيل الذي يعيد المحاولة بلا نهاية هو وكيل بتكلفة غير محدودة. حدّد سقفاً زمنياً لكل حلقة، وطبّقه عبر TimeoutStartSec أعلاه؛ وأضف عدّاداً لعدد المحاولات داخل البرنامج النصي؛ وطبّق حداً أقصى للإنفاق عبر حساب المزوّد. ثم سجّل تكلفة كل تشغيل، حتى تكتشف انحراف الحلقة قبل ظهور أثره في الفاتورة. يشرح التحكم في تكلفة VPS لوكيل يعمل دائماً جانب المحاسبة، بينما يشرح إدارة السياق الذي يحتفظ به الوكيل بين الأدوار أكبر عامل منفرد في تكلفة كل تشغيل، لأن الحلقة التي تعيد قراءة المستودع نفسه كل 30 دقيقة تدفع تكلفته كل 30 دقيقة.

التكلفة هي سبب تفوّق الحلقات عادةً على جلسة طويلة واحدة. يبدأ التشغيل من جديد، وينفّذ مهمة محددة، ثم ينتهي، وبذلك يبقى سياقه صغيراً. أما الجلسة التي تظل مفتوحة لمدة ثماني ساعات فتحمل في سجلها كل خطأ سابق، وتدفع تكلفة النص الكامل في كل دور.

الأنماط التي توثّقها المستودعات الرائجة

يسرد مستودع loop-engineering ثمانية أنماط للإنتاج (حتى 2026-10-27)، ومن المفيد قراءتها كقائمة خيارات لا كبيان. الفرز اليومي. حلقة بسيطة تعمل كـGitHub Action ولا تحتفظ بملف حالة. أداة تتابع pull requests، وتراقب تعليقات المراجعة، وتجيب عنها. أداة تفحص continuous integration وتلتقط عمليات البناء الفاشلة. أداة تفحص التبعيات. أداة تعد مسودة changelog. تنظيف ما بعد الدمج. فرز Issues.

ما تشترك فيه هذه الأنماط هو مهمة محددة ذات بوابة واضحة. يملك "إصلاح عملية البناء الفاشلة" شرط نجاح يمكن للآلة قراءته. أما "تحسين قاعدة الشيفرة" فلا يملك هذا الشرط، ولذلك لا يتحول أبداً إلى حلقة. بل يتحول إلى فوضى لها جدول زمني.

كما تشترك في سجل مكتوب. يدفع كلا المستودعين الحالة خارج المحادثة إلى ملفات داخل المستودع: ما الذي شُغّل، وما الذي عُثر عليه، وما القرار الذي اتُخذ. هذا الملف هو ذاكرة الحلقة، وهو السبب الذي يسمح لحلقة ثانية بالبناء على عمل الحلقة الأولى بدلاً من اكتشافه من جديد. وهو أيضاً الطريقة التي تراجع بها عمل الوكيل لاحقاً، لأن سياق النموذج يختفي لحظة انتهاء التشغيل. التنسيق المباشر قناة منفصلة، ويمكن لـجلسة Claude Code واحدة تسليم العمل إلى جلسة أخرى على الجهاز نفسه بينما لا تزال كلتاهما تعملان، لكن لا شيء في ذلك التبادل يستمر بعد انتهاء أي من الجلستين، ولذلك يبقى الملف هو الجزء الذي تقرؤه لاحقاً.

عندما تفشل الحلقات

الإخفاقات مملة، وتتكرر بين الفرق.

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

الحل واحد في كل حالة: صغّر المهمة، وشدّد الفحص، وسجّل عملية التشغيل. إذا لم تتمكن من وصف شرط النجاح في جملة واحدة، فالمهمة غير جاهزة للأتمتة.

البدء دون المصطلحات

لا تحتاج إلى إطار عمل. يكفي خادم Linux صغير يعمل دائماً، ومستودع git تفشل مجموعة اختباراته عند وجوب الفشل، ومؤقت systemd واحد، وبرنامج shell نصي واحد يتضمن if لإنشاء حلقة عمل مكتملة. هذا هو المكان الذي ينبغي لمعظم الناس أن يبدأوا منه فعلاً، لأنك تجيب عن أسئلة التصميم بتشغيل النظام، لا باختيار أداة. بعد استقرار حلقة واحدة، يصبح تشغيل حلقة ثانية مسألة إضافة مؤقت آخر وworktree آخر في الغالب. راجع كيفية تشغيل وكيل برمجة بالذكاء الاصطناعي على VPS للإعداد الأساسي، وراجع خيارات وكلاء الذكاء الاصطناعي ذاتية الاستضافة الحالية إذا أردت تشغيل الوكيل نفسه على عتاد تتحكم فيه.

FAQ

هل تختلف هندسة الحلقات عن هندسة المطالبات؟

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

هل أحتاج إلى إطار عمل لبناء حلقة وكيل؟

لا. يغطي مؤقّت systemd، وgit worktree لكل تشغيل، وبرنامج shell نصي ينتهي بأمر اختبار، وحد إنفاق في حساب موفر الخدمة، كل جزء من التعريف. تضيف أطر العمل واجهات للجدولة، وتنسيقات للذاكرة المشتركة، وتوجيهات متعددة الوكلاء. وتصبح هذه الميزات مفيدة عند تشغيل عدة حلقات. لكنها ليست شرط البدء بأول حلقة.

ما هي بيئة تشغيل قاعدة الشيفرة؟

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

كيف أوقف حلقة وكيل من تراكم فاتورة كبيرة؟

ضع لها حدوداً في ثلاثة مواضع. عيّن TimeoutStartSec في وحدة systemd من نوع Type=oneshot مثل الوحدة أعلاه، لكي يُنهى التشغيل العالق بالقوة. وفي خدمة Type=simple، يكون المكافئ هو RuntimeMaxSec. حدّد عدد مرات إعادة المحاولة داخل البرنامج النصي بدلاً من التكرار حتى النجاح. ضع حداً صارماً للإنفاق في حساب API، لأن هذا هو الحد الوحيد الذي لا يستطيع الوكيل تجاوزه بالحجج. ثم سجّل تكلفة كل تشغيل، لأن الحلقة التي تتضاعف تكلفتها تكون عادة حلقة اتسع نطاقها بهدوء.

ما المهام التي تستحق تحويلها إلى حلقة أولاً؟

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

هل كان هذا المقال مفيدًا؟