تقنية

بالتفاصيل: شرح الحلقة التشغيلية لوكيل Codex خطوة بخطوة | يلاخبر

شهدت الساعات الماضية:

أكدت جهات معنية أن:

تعد واجهة Codex CLI⁠(يفتح في نافذة جديدة) وكيلاً برمجيًا محليًا متعدد المنصات، صُممت لإنتاج تغييرات برمجية عالية الجودة وموثوقة، مع العمل بأمان وكفاءة على جهازك. ومنذ إطلاق واجهة CLI في أبريل⁠، اكتسبنا قدرًا كبيرًا من الخبرة حول كيفية بناء وكيل برمجي على مستوى عالمي. ولتفصيل هذه الرؤى، يقع هذا المقال كأول جزء في سلسلة مستمرة نستعرض فيها الجوانب المختلفة لآلية عمل Codex، إلى جانب الدروس العملية التي تعلمناها عبر التجربة. (ولمن يرغب في الاطلاع على مستوى أكثر تفصيلًا لكيفية بناء واجهة Codex CLI، يمكنه الرجوع إلى مستودعنا مفتوح المصدر على GitHub، عبر الرابط: https://github.com/openai/codex⁠(يفتح في نافذة جديدة)، حيث جرى توثيق العديد من قرارات التصميم الدقيقة ضمن القضايا البرمجية وطلبات الدمج، لمن يود التعمق أكثر).

في مستهل هذه السلسلة، سنركّز على الحلقة التشغيلية للوكيل، وهي المنطق الأساسي في Codex CLI والمسؤولة عن تنسيق التفاعل بين المستخدم، والنموذج، والأدوات التي يستدعيها النموذج لتنفيذ مهام برمجية ذات معنى. ونأمل أن يمنحك هذا المقال تصورًا واضحًا للدور الذي يؤديه وكيلنا (أو ما نُطلق عليه “harness”) في الاستفادة من النموذج اللغوي الكبير (LLM).

قبل أن نتعمّق في التفاصيل، نقدم ملاحظة سريعة حول المصطلحات: في OpenAI، يشير مصطلح “Codex” إلى مجموعة من عروض الوكلاء البرمجيين، وتشمل Codex CLI وCodex Cloud وامتداد Codex لبيئة VS Code. يركّز هذا المقال على Codex harness، وهو المكوّن الذي يوفّر الحلقة التشغيلية للوكيل والمنطق التنفيذي الأساسي الذي ترتكز عليه جميع تجارب Codex، ويُتاح للمستخدمين عبر Codex CLI. ولتسهيل القراءة، سنستخدم مصطلحي “Codex” و”Codex CLI” بالتبادل في هذا المقال.

الحلقة التشغيلية للوكيل

تشكل “الحلقة التشغيلية للوكيل” جوهر عمل أي وكيل ذكاء اصطناعي، ويوضح الشكل التالي آليتها بصورة مبسّطة:

في البداية، يأخذ الوكيل الإدخالات من المستخدم ليضمّنها ضمن مجموعة التعليمات النصية التي يُعدّها للنموذج، ويطلق على هذه التعليمات اسم المطالبة.

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

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

كنتيجة لخطوة الاستدلال، ينتج النموذج إما (1) استجابة نهائية لمدخل المستخدم الأصلي، أو (2) طلب استدعاء أداة يُتوقع من الوكيل تنفيذها (مثل: “تشغيل أمر ls وعرض النتيجة”). في حالة الخيار (2)، ينفذ الوكيل استدعاء الأداة ويضيف نتائجها إلى المطالبة الأصلية. تُستخدم هذه النتائج لإنشاء إدخال جديد يُرسل لإعادة استعلام النموذج، ما يتيح للوكيل أخذ المعلومات الجديدة في الاعتبار والمحاولة من جديد.

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

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

تُعرف الرحلة من إدخال المستخدم إلى استجابة الوكيل، كما يوضح الرسم التخطيطي، باسم دورة محادثة واحدة (أو thread “سلسلة” في Codex). ومع ذلك، قد تتضمن دورة المحادثة هذه عدة تكرارات بين استدلال النموذج واستدعاءات الأدوات. وفي كل مرة تُرسل فيها مطالبة جديدة ضمن محادثة قائمة، يُدرج سجل المحادثة السابق ضمن المطالبة للدورة الجديدة، بما يشمل جميع المطالبات واستدعاءات الأدوات من الدورات السابقة:

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

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

استدلال النموذج

ترسل واجهة Codex CLI طلبات HTTP إلى واجهة برمجة Responses API⁠(يفتح في نافذة جديدة) لتشغيل استدلال النموذج. سنستعرض كيفية تدفق المعلومات عبر Codex، الذي يستخدم واجهة برمجة Responses API لإدارة الحلقة التشغيلية للوكيل.

دعونا نستكشف كيف ينشئ Codex المطالبة للدورة الأولى من استدعاء الاستدلال في المحادثة.

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

في المطالبة الأولية، يرتبط كل عنصر في القائمة بدور محدد. يشير الدور إلى مقدار الأهمية التي يجب إعطاؤها للمحتوى المرتبط، ويأخذ أحد القيم التالية (من الأعلى إلى الأقل أولوية): النظام، المطور، المستخدم، المساعد.

يمثل حقل الأدوات قائمة بتعريفات الأدوات التي تتوافق مع المخطط الذي تحدده واجهة برمجة Responses API. في حالة Codex، يشمل ذلك الأدوات التي يوفرها Codex CLI، والأدوات المتاحة من Responses API والتي ينبغي إتاحتها لـ Codex، وكذلك الأدوات التي يقدمها المستخدم عادةً عبر خوادم MCP:

1 رسالة بصيغة role=developer تصف بيئة الحماية الخاصة بأداة shell المقدمة من Codex فقط والمحددة في قسم الأدوات. أما الأدوات الأخرى، مثل تلك المقدمة من خوادم MCP، لا تخضع لهذه البيئة المحمية، ويكون كل منها مسؤولًا عن تطبيق ضوابط الأمان الخاصة به.

2. (اختياري) رسالة بصيغة role=developer، يستند محتواها إلى قيمة developer_instructions الموجودة في ملف config.toml الخاص بالمستخدم.

بمجرد أن ينتهي Codex من جميع الحسابات المذكورة أعلاه لتهيئة حقل الإدخال، فإنه يضيف رسالة المستخدم في النهاية لبدء المحادثة.

ركزت الأمثلة السابقة على محتوى كل رسالة، ولكن يرجى ملاحظة أن كل عنصر في حقل الإدخال عبارة عن كائن JSON يحتوي على النوع (type)، والدور (role)⁠(يفتح في نافذة جديدة)، والمحتوى (content) كما يلي:

بعد أن يُنشئ Codex الحمولة الكاملة بصيغة JSON لإرسالها إلى واجهة برمجة Responses API، تُرسل طلب HTTP POST مع رأس التفويض (Authorization header) وفقًا لكيفية تكوين نقطة نهاية واجهة برمجة Responses API في ‎~/.codex/config.toml (كما تُضاف رؤوس HTTP ومعاملات الاستعلام الإضافية إذا تم تحديدها).

عند استلام خادم واجهة برمجة Responses API من OpenAI الطلب، يستخدم بيانات JSON لاستخلاص المطالبة الموجهة للنموذج كما يلي (للتوضيح، يمكن لتطبيق مخصص لواجهة Responses API أن يتخذ خيارًا مختلفًا):

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

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

الآن بعد أن تلقينا مطالبتنا، نحن على استعداد لاستخراج استجابة من النموذج.

يبدأ هذا الطلب عبر HTTP إلى واجهة برمجة Responses API أول “دورة” لمحادثة في Codex. يرد الخادم عبر تدفق من “الأحداث المرسلة من الخادم” (SSE⁠(يفتح في نافذة جديدة)). وتحتوي بيانات كل حدث على حمولة JSON بحقل النوع (type) يبدأ بالاستجابة (response)، ويمكن أن تكون على الشكل التالي (لمزيد من التفاصيل، راجع مستندات واجهة برمجة API⁠(يفتح في نافذة جديدة) لدينا للحصول على القائمة الكاملة للأحداث):

يتعامل Codex مع تدفق الأحداث⁠(يفتح في نافذة جديدة) ويحوّلها إلى كائنات أحداث داخلية قابلة للاستخدام من قبل العميل. تُستخدم أحداث مثل response.output_text.delta لدعم البث المباشر في واجهة المستخدم، بينما تُحوّل أحداث أخرى مثل response.output_item.added إلى كائنات تُضاف إلى حقل الإدخال للاستفادة منها في استدعاءات واجهة برمجة Responses API التالية.

لنفترض أن الطلب الأول المرسل إلى Responses API يتضمن حدثين من نوع response.output_item.done: أحدهما مع type=reasoning والآخر مع type=function_call. يجب تمثيل هذه الأحداث في حقل الإدخال ضمن JSON عند الاستعلام من النموذج مرة أخرى باستخدام استجابة استدعاء الأداة: 

ستأخذ المطالبة الناتجة شكلها التالي عند استخدامها لاستخراج استجابة من النموذج في الاستعلام التالي:

رسم تخطيطي بعنوان "Snapshot 2" يوضح حالة الوكيل الذكي بعد استدعاء أداة. يستقبل النموذج ملاحظة من الأداة، وينتج عنها فكرة جديدة وخطوة عملية جديدة. تربط الأسهم الإدخالات والملاحظات والمخرجات لتوضيح كيفية تكرار الوكيل لحلقة استدلاله.

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

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

في Codex CLI، نعرض رسالة المساعد للمستخدم ونوجه المحرر للإشارة إلى أنه قد حان دور المستخدم لمواصلة المحادثة. إذا استجاب المستخدم، فيجب إضافة كل من رسالة المساعد من الدورة السابقة ورسالة المستخدم الجديدة إلى حقل الإدخال في طلب واجهة برمجة Responses API لبدء الدورة الجديدة:

ومجددًا، نظرًا لاستمرار المحادثة، يواصل حجم بيانات الإدخال المُرسلة إلى واجهة برمجة Responses API التزايد مع كل دورة جديدة:

رسم تخطيطي بعنوان "Snapshot 3" يوضح المرحلة النهائية من الحلقة التشغيلية للوكيل الذكي. بعد استلام نتائج الأدوات، ينتج النموذج فكرة ختامية ويقدّم الإجابة النهائية للمستخدم. تشير الأسهم إلى عملية الانتقال من نتائج الأدوات إلى الاستجابة المكتملة.

لنلقِ نظرة على تأثير هذه المطالبة التي يزداد طولها باستمرار على الأداء.

قد يتبادر إلى ذهنك السؤال: “مهلًا، أليست الحلقة التشغيلية للوكيل ذات تعقيد تربيعي من حيث حجم بيانات JSON المُرسلة إلى واجهة Responses API على مدار المحادثة؟” والإجابة هي: نعم، هذا صحيح. فعلى الرغم من أن واجهة Responses API تدعم معامِلًا اختياريًا يُسمّى previous_response_id⁠(يفتح في نافذة جديدة) للتخفيف من هذه المشكلة، فإن Codex لا يستخدمه حاليًا، وذلك أساسًا للحفاظ على الطلبات عديمة الحالة بالكامل، ولدعم إعدادات عدم الاحتفاظ بالبيانات (ZDR).

تجنّب استخدام previous_response_id يبسط الأمور لمزوّد واجهة برمجة Responses API لأنه يضمن أن تكون كل طلبية مستقلة عن الطلبات السابقة. وهذا يجعل من السهل أيضًا دعم العملاء الذين اختاروا عدم الاحتفاظ بالبيانات (ZDR)⁠(يفتح في نافذة جديدة)، إذ أن تخزين البيانات المطلوبة لدعم previous_response_id سيكون متعارضًا مع سياسة ZDR. لاحظ أن عملاء ZDR لا يتخلون عن إمكانية الاستفادة من رسائل الاستدلال المملوكة من الأدوار السابقة، إذ يمكن فك تشفير encrypted_content المرتبط بها على الخادم. (تحتفظ OpenAI بمفتاح فك تشفير العملاء المشتركين في ZDR، لكنها لا تحتفظ ببياناتهم). انظر إلى طلبات السحب رقم ‎#642⁠(يفتح في نافذة جديدة) و‎#1641⁠(يفتح في نافذة جديدة) للاطلاع على التغييرات التي أُجريت على Codex لدعم ZDR.

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

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

مع وضع ذلك في الاعتبار، دعونا نراجع أنواع العمليات التي قد تؤدي إلى “فشل التخزين المؤقت” في Codex:

  • تغيير الأدوات المتاحة للنموذج في منتصف المحادثة.
  • تغيير النموذج المستهدف في طلب واجهة برمجة Responses API (فعليًا، هذا يغيّر العنصر الثالث في المطالبة الأصلية، لأنه يحتوي على تعليمات خاصة بالنموذج).
  • تغيير إعدادات بيئة الحماية، أو وضع الموافقة، أو الدليل العامل الحالي.

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

نسعى جاهدين لضمان نجاح التخزين المؤقت بهدف تعزيز كفاءة الأداء. كما يوجد مورد رئيسي آخر يتطلب إدارتنا الدقيقة: نافذة السياق.

تتمثل استراتيجيتنا العامة لتجنب نفاد نافذة السياق بالكامل في ضغط المحادثة بمجرد تجاوز عدد الرموز الحد المسموح به. وعلى وجه التحديد، نستبدل الإدخال الحالي بقائمة جديدة أصغر من العناصر تمثّل جوهر المحادثة، ما يتيح للوكيل متابعة عمله مع الاحتفاظ بفهم لما جرى حتى تلك اللحظة. وفي إحدى النسخ المبكرة من تنفيذ آلية الضغط⁠(يفتح في نافذة جديدة)، كان يتعين على المستخدم تنفيذ الأمر ‪‫ ‏/compact يدويًا، والذي كان يرسل استعلامًا إلى واجهة برمجة Responses API باستخدام المحادثة الحالية مضافًا إليها تعليمات مخصصة للتلخيص⁠(يفتح في نافذة جديدة). ثم يستخدم Codex مطالبة المساعد الناتجة عن التلخيص كإدخال جديد⁠(يفتح في نافذة جديدة) للدورات التالية في المحادثة.

في الجزء التالي

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

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

تفاصيل إضافية حول الخبر

ويحظى هذا الموضوع باهتمام واسع بين المواطنين.

فيما يرى البعض أن هذا الحدث قد يحمل دلالات مهمة.

خلفية عن الموضوع

ويأتي ضمن سلسلة من الأحداث التي حظيت باهتمام واسع مؤخرًا.

توقعات الفترة القادمة

ومن المتوقع أن تشهد الفترة المقبلة مزيد من التطورات المتعلقة بهذا الموضوع، خاصة في ظل الاهتمام المتزايد من قبل الجمهور ووسائل الإعلام.


🔍 الكلمات المفتاحية: #شرح #الحلقة #التشغيلية #لوكيل #Codex #خطوة #بخطوة

مقالات ذات صلة

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

زر الذهاب إلى الأعلى