Log in to leave a comment
No posts yet
أدوات مثل Cursor أو Devin مريحة للغاية، لكن من الصعب معرفة ما يحدث بالضبط في الداخل، وأحيانًا تقوم بتقطيع الكود بطرق لا تريدها. بالنسبة لمطور الخلفية (Backend)، فإن إنشاء وكيل (Agent) مخصص ومحسّن باستخدام مكتبة بايثون القياسية وواجهات برمجة تطبيقات LLM هو أمر أكثر اقتصادية وموثوقية بشكل أكبر.
لجعل الوكيل يتجاوز مجرد كتابة الكود ليقوم بتنفيذ أوامر الطرفية (Terminal) مباشرة، يجب التعامل مع وحدة subprocess بدقة. استخدام خيار shell=True دون حذر يعرضك لهجمات حقن الشيل (Shell Injection)، أو قد يترك عمليات "زومبي" لا تموت عند حدوث مهلة زمنية (Timeout).
عند التنفيذ اليدوي، قم بضبط shell=False في استدعاء subprocess.run() ومرر الأوامر كقائمة. اجعل المهلة الزمنية قصيرة، حوالي 30 ثانية، وإذا حدث استثناء TimeoutExpired فقم باستدعاء process.kill() فورًا لاستعادة الموارد. وعند إرسال نتائج التنفيذ إلى النموذج، لا داعي لإرسال المحتوى بالكامل؛ إذا تجاوز النص 1000 حرف، قم بقصه لإرسال آخر 20 سطرًا فقط. هذه معلومات كافية للنموذج لتحديد سبب الخطأ مع تجنب هدر التوكنز (Tokens).
كلما طالت المحادثة، تراكمت البيانات في نافذة السياق (Context Window)، مما يؤدي إلى انفجار في التكاليف. وفقًا لإعلان Anthropic، يمكن توفير ما يصل إلى 90% من تكلفة قراءة البيانات المخزنة مؤقتًا عند استخدام علامات cache_control في نماذج Claude 3.5، حيث تبلغ التكلفة حوالي 0.30 دولار لكل مليون توكن.
لتقليل التكاليف، افصل بدقة بين رسائل النظام ومدخلات المستخدم. ثبت المعلومات التي لا تتغير، مثل هيكل شجرة ملفات المشروع بالكامل، في الجزء العلوي من رسالة النظام وقم بتعيينها كنقطة تخزين مؤقت. عندما تتراكم سجلات المحادثة وتتجاوز التوكنز الحد المسموح، استخدم tiktoken لحساب الكمية، ثم اعتمد أسلوب التلخيص الهرمي بتلخيص الرسائل القديمة عبر استدعاء منفصل للـ LLM. من خلال تطبيق نافذة منزلقة (Sliding Window) تحافظ على هذا السياق الملخص في الأعلى وتضيف الرسائل الأحدث، يمكنك خفض التكاليف بنسبة تزيد عن 40% مع الحفاظ على دقة استدلال النموذج حتى في جلسات التطوير الطويلة.
إجبار الوكيل على إعادة طباعة الملف بالكامل هو أسلوب بدائي وبطيء. فكلما زادت توكنز المخرجات، زاد احتمال قيام النموذج بحذف أجزاء من الكود أو الهذيان. ما يسمى بـ "خدعة التحرير" (Edit Trick) توجه النموذج لتغيير النصوص المحيطة (Anchor) بالجزء المطلوب تعديله فقط. هذا التكتيك يقلل من كمية توكنز المخرجات بنسبة تصل إلى 86% في البيانات الفعلية.
استخدم re.sub() في بايثون لتنفيذ ميزة تطبيق التعديلات الواردة عبر علامات XML معينة أو تعبيرات نمطية على الملفات المحلية. أيضًا، بدلاً من وضع جميع المستندات التقنية في البرومبت، صمم النظام ليربط بقاعدة بيانات متجهة (Vector DB) خفيفة مثل LanceDB لجلب قصاصات المستندات الضرورية فقط. هذا الهيكل يجعل سرعة تعديل الملفات أسرع بنسبة 79% تقريبًا، ويحل المشكلة المزمنة المتمثلة في ارتباك النموذج عند العمل على ملفات كبيرة.
يجب أن يتوقف البشر عن عناء نسخ رسائل تصحيح الأخطاء (Debugging) ولصقها للنموذج. اجعل الوكيل يكتب أكواد اختبار تعتمد على pytest قبل أن يبدأ بكتابة كود البرنامج نفسه.
إذا فشل الاختبار، ما عليك سوى بناء حلقة تغذية راجعة تعيد إرسال كامل الـ Traceback الناتج عن الخطأ إلى النموذج دون معالجة ليقوم بإصلاحه بنفسه. ومع ذلك، بالنسبة للأوامر الخطيرة مثل rm أو deploy، يجب إدخال حواجز حماية (Guardrails) تتطلب موافقة المستخدم باستخدام دالة input() في بايثون. بمجرد اكتمال هذه البنية الدورية، لن يحتاج المطور إلا لمراجعة ملخص git diff الذي قدمه الوكيل والضغط على زر الـ Commit.
في النهاية، يكمن جوهر بناء الوكيل في مدى دقة تنقية البيانات وتخزينها مؤقتًا بين الطرفية والـ LLM، وليس في استخدام أطر عمل (Frameworks) براقة. إن 600 سطر من كود بايثون الذي كتبته بنفسك سيعكس نواياك بشكل أفضل من أدوات "الصندوق الأسود" التي تحتوي على عشرات الآلاف من السطور.