ما وراء القائمة: هندسة التنقل التنبئي القائم على النية باستخدام Expo Router و Local LLMs
أستكشف في هذا المقال كيفية الانتقال من القوائم الثابتة نحو التنقل القائم على النية. يغطي هذا المنشور دمج Expo Router مع Local LLMs على الجهاز لبناء واجهات مستخدم لتطبيقات الجوال تتوقع الخطوة التالية للمستخدم.

ما وراء القائمة: هندسة التنقل التنبئي
لقد قضيت جزءًا كبيرًا من مسيرتي المهنية وأنا مهووس بـ "click depth" (عمق النقرات). لقد مررنا جميعًا بذلك — محاولة معرفة ما إذا كانت الميزة مدفونة بعمق في تسلسل تنقل متداخل. لكن مؤخرًا، أدركت أننا نحل المشكلة الخاطئة. لا ينبغي لنا فقط تسهيل قراءة الخرائط؛ بل يجب أن نبني تطبيقات تعرف أين يريد المستخدم الذهاب قبل أن يفعل ذلك.
مع إصدار Expo Router وزيادة جدوى استخدام Local LLMs (التي تعمل مباشرة على الجهاز)، أصبح لدينا أخيرًا مجموعة الأدوات اللازمة للانتقال من واجهات المستخدم الساكنة والتفاعلية (reactive) إلى تجارب استباقية قائمة على النية.
هيكلية النية (The Architecture of Intent)
التنقل التقليدي هو عبارة عن finite state machine. أنت في /home ثم تضغط على زر لتنتقل إلى /settings/profile. أما التنقل التنبئي، فيضيف طبقة استنتاج (inference layer) بين سياق المستخدم الحالي والـ router.
منهجي يتضمن ثلاث ركائز أساسية:
- Context Tracking (تتبع السياق): جمع إشارات غير محددة للهوية (الوقت، الشاشات السابقة، استعلامات البحث، الميزات النشطة).
- On-Device Inference (الاستنتاج على الجهاز): استخدام local LLM مكمّم (quantized) (مثل Llama 3 أو Mistral عبر
react-native-wllama) لربط هذا السياق بالمسار (route). - Typed Routing (التنقل المعتمد على الأنواع): الاستفادة من نظام Expo Router المعتمد على الملفات للتنقل ديناميكيًا مع ضمان سلامة الأنواع (type safety) بالكامل.
لماذا الـ Local LLMs؟
أنا مدافع قوي عن الذكاء الاصطناعي المحلي (local-first AI) لسببين: Latency (زمن الاستجابة) و Privacy (الخصوصية). إذا كان عليّ الانتظار لمدة ثانيتين لطلب API من OpenAI لمجرد اقتراح مسار تنقل، فإن تجربة المستخدم (UX) ستكون فاشلة منذ البداية. عبر تشغيل نموذج بـ 3 مليار بارامتر (3B parameter model) على الجهاز، يمكنني الحصول على الاستنتاج في أجزاء من الثانية دون أن يغادر سجل تنقل المستخدم الجهاز أبدًا.
التنفيذ: usePredictiveRouter
إليك نسخة مبسطة من hook قمت بنمذجته أولياً. يقوم بمراقبة حالة التطبيق ويجهز "أفضل إجراء تالي".
ربط النقاط مع Expo Router
جمال Expo Router يكمن في أنه يتعامل مع العناوين (URLs) كمصدر للحقيقة. ولأنه مبني فوق React Navigation ولكن يتم إدارته عبر نظام الملفات، لا يحتاج الـ LLM الخاص بي لفهم هياكل كائنات معقدة — كل ما يحتاجه هو إخراج مسار نصي (string path).
في تجاربي، وجدت أن تزويد الـ LLM بسياق "Sitemap" — وهو تمثيل JSON بسيط لمجلد app/ — سمح له بربط نوايا اللغة الطبيعية بالمسارات بدقة مذهلة.
مثال على جزء من الـ Prompt:
"المستخدم في تبويب 'Analytics'. قضى 5 دقائق في عرض 'Revenue'. لقد ضغط للتو على أيقونة 'Help'. المسارات المتاحة: /docs/revenue-metrics, /support/ticket, /settings/billing."
مخرجات الـ Local LLM: /docs/revenue-metrics
التحديات: مشكلة الـ "Magic"
واجهة المستخدم التنبئية قد تكون محبطة إذا كانت خاطئة. خلال محاولاتي الأولى، حاولت جعل التطبيق يتنقل تلقائيًا. لا تفعل ذلك. إنه أمر مربك للمستخدم.
طريقة "المهندس الخبير" (Senior Engineer) للتعامل مع هذا هي عبر التنقل الناعم (Soft Navigation):
- تمييز الزر المتوقع.
- إظهار "رابط سريع" في bottom sheet.
- جلب البيانات مسبقًا (Pre-fetch) للمسار المتوقع باستخدام
react-queryبحيث عندما يضغط المستخدم فعليًا عليه، يكون الانتقال فوريًا.
اعتبارات الأداء
تشغيل LLM بجانب تطبيق React Native هو أمر ثقيل. لقد وجدت أن ترحيل عملية الاستنتاج إلى Web Worker (إذا كان للويب) أو خيط خلفي منفصل (separate background thread) عبر وحدة JSI (JavaScript Interface) هو أمر غير قابل للتفاوض. لا يمكنك حظر خيط واجهة المستخدم (UI thread) بينما يقوم النموذج بحساب المسار التالي.
خاتمة
نحن نتحرك نحو مستقبل تكون فيه "قائمة الهامبرغر" مجرد خيار احتياطي، وليس المحرك الأساسي. من خلال الجمع بين نظام التنقل القوي في Expo Router مع خصوصية وسرعة الـ Local LLMs، يمكننا بناء تطبيقات تشعر وكأنها تفكر مع المستخدم.
إذا كنت لا تزال تبني أشجار تنقل ثابتة، فقد حان الوقت للبدء في التفكير في "طبقة النية" (intent layer). الأدوات موجودة؛ كل ما نحتاجه هو ربطها معًا.