Energent AI
لوحة تحكم احترافية لوكيل الذكاء الاصطناعي مع استخدام الحاسوب مباشرةً
التحدي
يُقدّم عرض Vercel AI SDK التجريبي لاستخدام الحاسوب إثباتاً مبدئياً للمفهوم، لكنه غير جاهز للإنتاج. حالة VNC ومحادثة الدردشة مرتبطتان، مما يُعيد تهيئة العارض مع كل رسالة. الحدود بين حزم SDK غير متسقة مما يُفرز تأكيدات للأنواع في جميع أنحاء قاعدة الكود. ولا توجد رؤية على مدة استدعاءات الأدوات الفردية أو دورة حياة الجلسة.
التقنيات المستخدمة
النهج الهندسي
عزل المخازن بالتصميم
فصلت حالة جلسة VNC عن حالة الدردشة والأحداث في مخزنَين مستقلَّين تماماً في Zustand قبل كتابة أي واجهة مستخدم. كانت حدود المخازن قراراً معمارياً اتُّخذ مسبقاً، لا إعادة هيكلة بعد اكتشاف مشاكل الأداء.
تتبّع نظام الأنواع لا تجاوزه
بدلاً من قمع أخطاء TypeScript بتأكيدات الأنواع، تتبّعت التسلسل الهرمي الكامل لأنواع AI SDK عبر @ai-sdk/ui-utils لإيجاد حدود النوع الصحيح. أعدت هيكلة معالجة الرسائل لاستخدام UIMessage باتساق في طبقة واجهة المستخدم.
تحكم صريح في إعادة الرسم
لفّفت VNCViewer في React.memo مع مُقارن مساواة مخصص بدلاً من الاعتماد على المقارنة السطحية الافتراضية، مما يمنح تحكماً دقيقاً في موعد إعادة تهيئة اتصال VNC.
منع الإغلاقات القديمة
استخدمت useRef لتتبّع مدة كل استدعاء أداة بدلاً من useState، مما يضمن أن ردود الاتصال تقرأ دائماً القيم الحالية دون إثارة إعادات رسم أو التقاط إغلاقات قديمة.
القرارات التقنية الرئيسية
الخيارات التي شكّلت الهندسة وحددت قابلية الصيانة على المدى البعيد.
مخزنان منفصلان في Zustand
خط الأحداث وإدارة الجلسة في مخزنَين منفصلَين تماماً دون اشتراكات متقاطعة.
إعادات رسم VNC مكلفة ومُضطربة — فهي تقطع الاتصال المباشر. المخزن المشترك يعني أن أي تحديث للدردشة يُشغّل فرق VNC. العزل يضمن أن العارض يُعاد رسمه فقط عند تغيّر حالة الجلسة فعلياً.
React.memo مع مُقارن مخصص
VNCViewer مُلفَّف في React.memo مع دالة مساواة صريحة بدلاً من المقارنة السطحية الافتراضية.
المقارنة السطحية الافتراضية لا تزال تُشغّل إعادات رسم عند تغيّر هوية خصائص الكائن حتى لو كانت القيم متطابقة. المُقارن الصريح يمنح تحكماً حتمياً في إعادة التهيئة.
UIMessage في طبقة واجهة المستخدم
توحيد استخدام UIMessage من @ai-sdk/ui-utils كنوع في جميع مكونات واجهة المستخدم التي تتعامل مع الرسائل.
نوع Message موجود في طبقة SDK الأساسية ولا يحمل حقولاً خاصة بواجهة المستخدم. استخدامه في طبقة UI يُفرض تأكيدات الأنواع. UIMessage هو نوع الحدود الصحيح ويُزيل التعارض كلياً.
useRef لتتبّع المدة
تُخزَّن طوابع بداية استدعاءات الأدوات في مرجع، ويُحدَّث عبر أجزاء رسالة onFinish.
تخزين الطوابع في الحالة سيُشغّل إعادات رسم مع بداية كل استدعاء أداة. المرجع يحتفظ بقيم قابلة للتغيير دون التأثير على دورة الرسم، ويمنح ردود الاتصال دائماً وصولاً للقيمة الحالية.
التحديات والحلول
كان عارض VNC يُعاد تهيئته مع كل رسالة دردشة، مما يتسبب في انقطاع الاتصال المباشر أثناء جلسات الوكيل النشطة.
عزلت حالة جلسة VNC في مخزن Zustand مخصص دون اشتراكات لحالة الدردشة. وأضفت React.memo مع مُقارن صريح لـ VNCViewer لضمان إعادة الرسم فقط عند تغيّرات الجلسة الحقيقية.
تعارض النوعين Message وUIMessage بين @ai-sdk/react و@ai-sdk/ui-utils أحدث أخطاء TypeScript في خط معالجة الرسائل بأكمله.
تتبّعت التسلسل الهرمي الكامل للأنواع عبر حزم AI SDK لتحديد حدود النوع الصحيح. أعدت هيكلة جميع معالجة الرسائل في طبقة واجهة المستخدم لاستخدام UIMessage باتساق، مما أزال كل تأكيدات الأنواع.
كان تتبّع مدة استدعاءات الأدوات عبر ردود الاتصال يقرأ طوابع بداية قديمة بسبب التقاط الإغلاق عند وقت التسجيل.
نقلت تخزين الطوابع من الحالة إلى useRef، مما يمنح جميع ردود الاتصال مرجعاً قابلاً للتغيير يشير دائماً للقيمة الحالية بغض النظر عن وقت إنشاء الإغلاق.
النتائج والأثر
تعمل لوحة التحكم بجلسات وكيل مستقرة مع صفر انقطاعات لاتصال VNC عند تحديثات الدردشة، وخط رسائل آمن بالكامل من الناحية النوعية دون تأكيدات، وبيانات دقيقة لمدة كل استدعاء أداة مرئية في الجدول الزمني للأحداث.
الدروس المستفادة
القرارات المعمارية حول حدود الحالة يجب اتخاذها قبل كتابة واجهة المستخدم، لا بعدها. إعادة هيكلة عزل المخازن في نظام مترابط تكلف أكثر بكثير من تصميم الحدود مسبقاً.
