احجز مكالمةتواصل معنا
العودة إلى جميع الملاحظات
٧ يونيو ٢٠٢٦

كيف بنينا مرحّلاً للذكاء الاصطناعي من الأجهزة غير المتصلة بالإنترنت إلى السحاب باستخدام البلوتوث و GPT-4o

كيف بنينا مرحّلاً للذكاء الاصطناعي من الأجهزة غير المتصلة بالإنترنت إلى السحاب باستخدام البلوتوث و GPT-4o

كيف بنينا مرحّلاً للذكاء الاصطناعي من الأجهزة غير المتصلة بالإنترنت إلى السحاب باستخدام البلوتوث و GPT-4o

في بيئات المؤسسات الآمنة - مثل صالات التداول المالي، ومختبرات البحث والتطوير الحساسة، وبيئات الدفاع والأمن - غالباً ما تُمنع أجهزة العمل من الوصول إلى شبكة الإنترنت العامة. وبينما تساهم بيئات العمل المعزولة شبكياً (air-gapped) أو التقسيم الصارم للشبكة في الحد من مخاطر تسريب البيانات، إلا أنها تجعل الوصول إلى نماذج اللغة الكبيرة (LLMs) المستضافة سحابياً أمراً مستحيلاً. ونتيجة لذلك، يُحرم المهندسون والمحللون من أدوات مثل GPT-4o من OpenAI، مما يعيق إنتاجيتهم.

في Seven Labs، كُلفنا بحل هذه العقبة بالتحديد لأحد عملائنا الذي يعمل في نطاق شبكة مقيد للغاية. كانت المتطلبات واضحة: تمكين محطات العمل التي تعمل في شبكة معزولة تماماً عن الإنترنت من الاستعلام بشكل آمن عن نماذج اللغة السحابية دون تعديل سياسات جدار الحماية الخاص بمحطة العمل أو إدخال أجهزة غير مصرح بها مثل وحدات USB اللاسلكية (Wi-Fi dongles).

كان حلنا هو مرحل الذكاء الاصطناعي عبر البلوتوث (Bluetooth AI Relay) - وهو جسر يربط الحافة بالسحاب (edge-to-cloud) يوجه طلبات الكمبيوتر المحلي عبر مرحل RFCOMM يعمل على نظام Android إلى نموذج GPT-4o باستخدام بروتوكولات البلوتوث القياسية. إليك التحليل التقني لكيفية تصميم هذا النظام وتنفيذه وتحصينه في بيئة الإنتاج.


1. بنية النظام: جسر الحافة إلى السحاب (Edge-to-Cloud Bridge)

تتكون البنية من ثلاثة مكونات رئيسية:

  1. العميل (Offline PC): خدمة محلية تعمل على محطة العمل المعزولة وتوفر واجهة برمجة تطبيقات محلية (loopback API) مثل http://localhost:8080/v1/chat/completions تتوافق مع مواصفات واجهة برمجة تطبيقات OpenAI القياسية.
  2. المرحّل (Android Mobile Device): تطبيق React Native يقوم بتشغيل خدمة Kotlin أمامية (foreground service) مخصصة. يمتلك جهاز Android اتصالاً بالبيانات الخلوية (LTE/5G) وبلوتوث في نفس الوقت، ليعمل كجسر اتصال.
  3. السحاب (OpenAI GPT-4o): خوادم نموذج اللغة الكبير المستهدفة والتي يتم الوصول إليها عبر بروتوكول HTTPS آمن.
+-------------+                     +---------------------------+                    +-----------------+
|             |      بلوتوث         | جهاز مرحل الأندرويد       |  شبكة خلوية WAN    |                 |
| كمبيوتر معزول| (RFCOMM Socket)    | (Android Relay Device)    |  (HTTPS Client)    |  OpenAI GPT-4o  |
|  [العميل]   |<==================>| [Kotlin Service]          |------------------->|  API Endpoint   |
|             |                     | [React Native Engine]     |                    |                 |
+-------------+                     +---------------------------+                    +-----------------+

لماذا اخترنا RFCOMM؟

عند إرسال بيانات JSON الخام لطلب الأوامر واستقبال الردود، كنا بحاجة إلى بروتوكول نقل موثوق وموجه نحو التدفق (stream-oriented). وبينما يعد بروتوكول البلوتوث منخفض الطاقة (BLE) مع سمات GATT ممتازاً لنقل بيانات القياس عن بعد منخفضة الحجم، إلا أنه غير مناسب إطلاقاً للمقاطع النصية الكبيرة بسبب القيود الصارمة على وحدة النقل القصوى (MTU) والعبء البرمجي الإضافي لتقسيم الحزم.

لذا اخترنا RFCOMM (Radio Frequency Communication)، الذي يحاكي منفذاً تسلسلياً RS-232 فوق بروتوكول L2CAP. ويتولى RFCOMM ترتيب الحزم، والتحكم في التدفق، وإعادة الإرسال بشكل أصلي، مما يوفر مقبساً موثوقاً وموجهاً نحو التدفق (واجهة شبيهة بـ java.net.Socket) قادراً على دعم التدفق المستمر للنصوص الكبيرة المطلوبة لنماذج اللغة.


2. بناء خادم RFCOMM لنظام الأندرويد باستخدام Kotlin

لضمان قدرة تطبيق Android على التعامل مع اتصالات البلوتوث الواردة بشكل موثوق، قمنا بتجاوز مكتبات React Native الجاهزة - والتي غالباً ما تعاني من تسريبات الذاكرة وتفتقر إلى استمرارية العمل في الخلفية - وقمنا بتنفيذ كود البلوتوث مباشرة بلغة Kotlin.

خيط عمل خادم البلوتوث (Bluetooth Server Thread)

يعمل خادم البلوتوث في خيط عمل مخصص، ويستمع على معرف فريد عالمياً (UUID) محدد:

package com.sevenlabs.airelay

import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothServerSocket
import android.bluetooth.BluetoothSocket
import android.util.Log
import java.io.IOException
import java.util.UUID

class BluetoothServerThread(
    private val adapter: BluetoothAdapter,
    private val onConnectionEstablished: (BluetoothSocket) -> Unit
) : Thread() {

    private val serverSocket: BluetoothServerSocket? by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
        adapter.listenUsingRfcommWithServiceRecord(
            "SevenLabsAIRelay",
            UUID.fromString("4a8b8c2d-9e0f-11ed-a8fc-0242ac120002")
        )
    }

    private var shouldKeepListening = true

    override fun run() {
        name = "SevenLabs-RFCOMM-Listener"
        Log.i("AIRelay", "RFCOMM Server Socket listening...")

        while (shouldKeepListening) {
            val socket: BluetoothSocket = try {
                serverSocket?.accept()
            } catch (e: IOException) {
                Log.e("AIRelay", "Server Socket accept failed", e)
                break
            }

            socket?.let {
                Log.i("AIRelay", "Incoming RFCOMM client connection accepted")
                onConnectionEstablished(it)
            }
        }
    }

    fun cancel() {
        try {
            shouldKeepListening = false
            serverSocket?.close()
        } catch (e: IOException) {
            Log.e("AIRelay", "Could not close server socket", e)
        }
    }
}

3. استمرارية التشغيل: إدارة خدمات Kotlin الأمامية و Wake-Locks

أحد أكبر التحديات الهندسية في إصدارات Android الحديثة (Android 12 فما فوق) هو تحسين استهلاك البطارية. إذا انطفأت شاشة الجهاز المحمول أو تم تصغير التطبيق، يضع نظام تشغيل Android المعالج (CPU) في حالة نوم عميق (Doze Mode) ويغلق مقابس الشبكة التي تعمل في الخلفية.

لضمان تشغيل الخدمة دون انقطاع، نفذت Seven Labs آليتين رئيسيتين:

  1. خدمة Kotlin الأمامية (Kotlin Foreground Service): تشغيل خادم RFCOMM وعميل API داخل خدمة أمامية. يسجل هذا التطبيق كعملية مستمرة معترف بها من قبل النظام، مما يظهر إشعاراً ثابتاً في شريط الحالة.
  2. أقفال اليقظة (Wake-Locks & Wi-Fi Locks): توجيه أمر صريح لمجدول نواة النظام لإبقاء المعالج نشطاً وموجات الاتصال الخلوي مستيقظة أثناء الجلسة النشطة.

تنفيذ الخدمة الأمامية (Foreground Service)

فيما يلي كود لغة Kotlin الأساسي للخدمة الأمامية التي تدير دورة حياة خيوط العمل والإشعارات:

package com.sevenlabs.airelay

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.IBinder
import android.os.PowerManager
import androidx.core.app.NotificationCompat

class AIRelayService : Service() {

    private var wakeLock: PowerManager.WakeLock? = null
    private var serverThread: BluetoothServerThread? = null

    override fun onCreate() {
        super.onCreate()
        acquireWakeLock()
        startForegroundService()
    }

    private fun acquireWakeLock() {
        val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
        wakeLock = powerManager.newWakeLock(
            PowerManager.PARTIAL_WAKE_LOCK,
            "SevenLabs::AIRelayWakeLock"
        ).apply {
            acquire(30 * 60 * 1000L) // 30-minute safety limit
        }
    }

    private fun startForegroundService() {
        val channelId = "seven_labs_ai_relay"
        val channelName = "AI Relay Foreground Service"

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_LOW)
            val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            manager.createNotificationChannel(channel)
        }

        val notificationIntent = Intent(this, MainActivity::class.java)
        val pendingIntent = PendingIntent.getActivity(
            this, 0, notificationIntent,
            PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
        )

        val notification: Notification = NotificationCompat.Builder(this, channelId)
            .setContentTitle("Seven Labs AI Relay Active")
            .setContentText("Routing Bluetooth RFCOMM data to GPT-4o...")
            .setSmallIcon(R.drawable.ic_notification)
            .setContentIntent(pendingIntent)
            .build()

        startForeground(1, notification)
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        // Start listening over Bluetooth
        val adapter = BluetoothAdapter.getDefaultAdapter()
        serverThread = BluetoothServerThread(adapter) { socket ->
            // Route stream data
            ConnectionHandler(socket).start()
        }
        serverThread?.start()
        return START_STICKY
    }

    override fun onDestroy() {
        serverThread?.cancel()
        wakeLock?.let {
            if (it.isHeld) it.release()
        }
        super.onDestroy()
    }

    override fun onBind(intent: Intent?): IBinder? = null
}

4. هيكلة حزم البيانات والبروتوكول

نظراً لأن RFCOMM يعمل كمجرى بايتات خام (raw byte stream)، كان علينا تحديد بروتوكول تأطير (framing protocol) على مستوى التطبيق لتقسيم حزم الطلبات والاستجابات الفردية.

قمنا بتصميم تنسيق إطار رسائل خفيف الوزن:

  • البايتات السحرية Magic Bytes (4 بايت): المعرف SLAR (Seven Labs AI Relay) للتحقق من أصل الحزمة.
  • طول الحمولة Payload Length (4 بايت): عدد صحيح يحدد الحجم الدقيق للحمولة.
  • نوع الحمولة Payload Type (1 بايت): يوضح ما إذا كانت الحزمة عبارة عن نص خام، أو جزء SSE (أحداث مرسلة من الخادم)، أو بيانات وصفية، أو رمز خطأ.
  • الحمولة المشفرة Encrypted Payload (متغير): بيانات JSON مشفرة باستخدام خوارزمية AES-GCM.
+------------+------------------+--------------+-----------------------+
| Magic (4B) | Length (4B, Int) | Type (1B, B) | Encrypted Payload (N) |
+------------+------------------+--------------+-----------------------+

عندما يرسل العميل الموجود على الكمبيوتر المعزول نص الطلب، يقوم الـ daemon المحلي بوضعه في هذا الإطار المشفر، ثم يرسله عبر مقبس RFCOMM، وينتظر إطارات الاستجابة.

على جانب جهاز Android، يقرأ قارئ مقبس Kotlin بادئة الطول، ثم يقرأ عدد البايتات المحدد، ويفك تشفير الحمولة، ويوجه طلب HTTP إلى واجهة OpenAI. ولدعم تدفق المخرجات (streaming)، نقوم بتحليل أجزاء بيانات SSE القادمة من OpenAI وتأطيرها كأجزاء من نوع SSE Chunk ثم كتابتها بالتتابع في مجرى مقبس البلوتوث.


5. البنية الأمنية: نموذج الثقة الصفرية عبر البلوتوث (Zero-Trust)

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

التشفير بين الطرفين (End-to-End Encryption - E2EE)

حتى لو تم اختراق طبقة اقتران البلوتوث الأساسية، تظل بيانات الحمولة آمنة:

  1. تبادل المفاتيح: عندما يبدأ الكمبيوتر المعزول الاتصال، فإنه ينفذ عملية تبادل مفاتيح Diffie-Hellman باستخدام المنحنيات الإهليلجية (ECDH) عبر مقبس البلوتوث مع جهاز Android.
  2. مفتاح جلسة مؤقت: يشتق كلا الطرفين مفتاحاً متناظراً مشتركاً (AES-256-GCM) يكون فريداً لجلسة الاتصال تلك بالتحديد.
  3. تشفير الحمولة: يتم تشفير حمولة كل إطار بيانات باستخدام مفتاح الجلسة، مع توليد ناقل تهيئة (IV) خاص بكل إطار، مما يمنع هجمات إعادة التشغيل (replay attacks) والتنصت.

6. ضبط الأداء ووقت الاستجابة (Latency)

أظهرت اختباراتنا القياسية مقاييس الأداء التالية في بيئة الإنتاج الفعلية:

المقياساتصال Wi-Fi مباشر (للمقارنة)مرحل RFCOMM (بدون تدفق مستمر)مرحل RFCOMM (مع تدفق SSE)
زمن استلام أول رمز (TTFT)~320ms~980ms~410ms
معدل النقل (رمز/ثانية)654258
أقصى حجم للحمولةغير محدود5 ميجابايتيتدفق تلقائياً

تحسين معدل النقل

بما أن نطاق البلوتوث الترددي محدود مقارنة بالـ Wi-Fi، فإن تدفق الاستجابة رمزاً برمز (streaming) يعد أمراً حيوياً. ومن خلال تمرير أجزاء SSE إلى العميل فور وصولها من OpenAI، قمنا بتقليل زمن الاستجابة الفعلي المدرك (TTFT) بنسبة تزيد عن 50%.

بالإضافة إلى ذلك، قمنا بتطبيق ضغط Gzip على نصوص الطلبات التي يتجاوز حجمها 20 كيلوبايت، مما قلل من زمن نقل البلوتوث وتجنب الاختناقات في مخزن RFCOMM المؤقت.


7. الأسئلة الشائعة للمؤسسات

هل ينتهك هذا مبدأ عزل الشبكة (Air-Gapping)؟

يعمل النظام كبروكسي صارم للبروتوكول. لا يملك جهاز الكمبيوتر المعزول أي مسار على مستوى بروتوكول الإنترنت (IP) إلى شبكة الهاتف الخلوي، مما يمنع الوصول العام إلى الإنترنت، أو مسح المنافذ الجانبية، أو ثغرات الأنفاق العكسية (reverse tunnel shells). يُسمح فقط بمرور إطارات SLAR المهيكلة بشكل صحيح على مستوى التطبيق.

كيف يستهلك هذا النظام بطارية جهاز المرحّل؟

يستهلك تشغيل راديو البلوتوث والاتصال الخلوي LTE معاً حوالي 8% من بطارية الجهاز في الساعة أثناء المعالجة المستمرة. من خلال الاستفادة من أقفال Wake-Locks في نظام الأندرويد بشكل انتقائي - أي إبقاء المعالج يقظاً أثناء جلسات المقابس النشطة فقط ودخول حالة الخمول خلال ساعات عدم العمل - تمكنا من تقليل استهلاك البطارية بشكل كبير.

كيف تُدار محاسبة الرموز (Tokens) والمصادقة؟

تُخزن جميع مفاتيح الاستخدام والتفويض على تطبيق مرحّل الأندرويد أو تُجلب من خادم مفاتيح خاص بالمؤسسة. ويمكن مصادقة تسجيل دخول المستخدمين بشكل فردي محلياً على الجهاز قبل عملية التفاوض عبر Diffie-Hellman.


مخطط تحسين محركات البحث التقني والروابط الداخلية


ابنِ أنظمة آمنة تربط الحافة بالسحاب مع Seven Labs

تتطلب المواءمة بين تقنيات الذكاء الاصطناعي المتقدمة وضوابط أمان الشركات الصارمة مهندسي أنظمة ذوي خبرة واسعة. سواء كنت بحاجة إلى تشغيل نماذج لغة في بيئة معزولة بالكامل، أو حوسبة عالية الأداء على الحافة، أو مرحلات إنترنت الأشياء (IoT) الآمنة، فإن Seven Labs تمتلك الخبرة الهندسية لتصميم ونشر الحلول المتوافقة مع معاييرك.

اتصل بفريق الهندسة في Seven Labs لمناقشة احتياجات الذكاء الاصطناعي والبنية التحتية المخصصة لمؤسستك.

خدمة سفن لابس

تطوير وكلاء الذكاء الاصطناعي ومسارات RAG

نبني مسارات RAG للإنتاج الفعلي. شاهد أعمالنا ←
Loading...

اقرأ التالي

Why Your VPN is a Liability: Zero-Trust Network Access in Modern SaaS

Implementing Zero-Trust Network Access in modern SaaS environments is hard but necessary. This techn...

اقرأ المقال

Implementing Redis Caching for Next.js 15 Apps

A direct, opinionated guide to implementing Redis caching in Next.js 15. We cover the architecture, ...

اقرأ المقال
Chat with us