Wie wir ein Offline-zu-Cloud-KI-Relay mit Bluetooth und GPT-4o gebaut haben
Wie wir ein Offline-zu-Cloud-KI-Relay mit Bluetooth und GPT-4o gebaut haben
In hochsicheren Unternehmensumgebungen - wie Handelsräumen im Finanzsektor, sensiblen F&E-Labors und verteidigungsnahen Einrichtungen - ist es Workstations häufig untersagt, auf das öffentliche Internet zuzugreifen. Obwohl dieses „Air-Gapping“ (physische Trennung vom Internet) oder eine strikte Netzwerksegmentierung das Risiko von Datenabflüssen verringert, macht es moderne, in der Cloud gehostete Large Language Models (LLMs) völlig unzugänglich. Ingenieure und Analysten sind von Tools wie GPT-4o von OpenAI abgeschnitten, was die Produktivität einschränkt.
Seven Labs wurde beauftragt, genau diesen Engpass für einen Kunden zu lösen, der in einer stark eingeschränkten Netzwerkzone arbeitet. Die Anforderung war klar: Ermöglichen Sie es Workstations in einem internetfreien Segment, sicher Abfragen an Cloud-basierte LLMs zu senden, ohne die Firewall-Richtlinien der Workstations zu ändern oder nicht autorisierte Hardware wie Wi-Fi-Dongles einzuführen.
Unsere Lösung war das Bluetooth AI Relay - eine Edge-zu-Cloud-Brücke, die lokale PC-Anfragen über ein Android-basiertes RFCOMM-Relay unter Verwendung von Standard-Bluetooth-Protokollen an GPT-4o weiterleitet. Hier ist die technische Analyse, wie wir dieses System in der Praxis entworfen, implementiert und gehärtet haben.
1. Systemarchitektur: Die Edge-zu-Cloud-Brücke
Die Architektur besteht aus drei Kernkomponenten:
- Der Client (Offline-PC): Ein lokaler Dienst, der auf der Workstation läuft und eine Loopback-API (z. B.
http://localhost:8080/v1/chat/completions) bereitstellt, die der Standard-OpenAI-API-Spezifikation entspricht. - Das Relay (mobiles Android-Gerät): Eine React Native-Anwendung, die einen spezialisierten Kotlin-Vordergrunddienst (Foreground Service) ausführt. Das Android-Gerät hat Zugriff auf Mobilfunkdaten (LTE/5G) und Bluetooth und dient als Brücke.
- Die Cloud (OpenAI GPT-4o): Das Ziel-LLM-Backend, das über HTTPS erreicht wird.
+-------------+ +-------------------------+ +-----------------+
| | Bluetooth | Android-Relay-Gerät | Mobilfunk WAN | |
| Offline-PC | (RFCOMM-Socket) | | (HTTPS-Client) | OpenAI GPT-4o |
| [Client] |<==================>| [Kotlin Service] |------------------->| API-Endpunkt |
| | | [React Native Engine] | | |
+-------------+ +-------------------------+ +-----------------+
Warum RFCOMM?
Bei der Übertragung von rohen JSON-Nutzlasten für Prompt-Abfragen und -Antworten benötigten wir ein stromorientiertes, zuverlässiges Transportprotokoll. Während Bluetooth Low Energy (BLE) mit GATT-Attributen hervorragend für Telemetriedaten mit geringem Durchsatz geeignet ist, eignet es sich aufgrund seiner strengen MTU-Beschränkungen (Maximum Transmission Unit) und des Paket-Fragmentierungs-Overheads überhaupt nicht für größere Textblöcke.
Wir haben uns für RFCOMM (Radio Frequency Communication) entschieden, das eine serielle RS-232-Schnittstelle über das L2CAP-Protokoll emuliert. RFCOMM übernimmt die Paketreihenfolge, Flusssteuerung und Wiederholung nativ. Es bietet einen zuverlässigen, stromorientierten Socket (ähnlich einer java.net.Socket-Schnittstelle), der in der Lage ist, das für LLM-Prompts und -Antworten erforderliche Streaming mit hohem Durchsatz aufrechtzuerhalten.
2. Implementierung des Android-RFCOMM-Servers in Kotlin
Um sicherzustellen, dass die Android-Anwendung eingehende Bluetooth-Verbindungen zuverlässig verarbeiten kann, haben wir auf Standard-Wrapper-Bibliotheken von React Native verzichtet - da diese häufig unter Speicherlecks leiden und keine Persistenz im Hintergrund unterstützen - und den Bluetooth-Stack direkt in Kotlin implementiert.
Der Bluetooth-Server-Thread
Der Bluetooth-Server läuft in einem dedizierten Thread und lauscht auf eine bestimmte UUID (Universally Unique Identifier):
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")
)
} vintage
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. Dauerhafter Betrieb: Kotlin Foreground Services & Wake-Lock-Management
Eine der größten Hürden auf modernen Android-Versionen (ab Android 12) sind die Akkuoptimierungen. Wenn sich der Bildschirm des Mobilgeräts ausschaltet oder die App minimiert wird, versetzt das Android-Betriebssystem die CPU in einen Tiefschlaf (Doze Mode) und beendet Hintergrund-Sockets.
Um einen unterbrechungsfreien Betrieb zu gewährleisten, hat Seven Labs zwei entscheidende Mechanismen implementiert:
- Kotlin Foreground Service: Platzierung des RFCOMM-Servers und des API-Clients in einem Android Foreground Service. Dadurch wird die App als systemweit anerkannter, dauerhafter Prozess registriert, der eine permanente Statusbenachrichtigung anzeigt.
- Wake-Locks und Wi-Fi-Locks: Explizite Anweisung an den Kernel-Scheduler, die CPU während einer aktiven Sitzung wach zu halten und die Mobilfunkschnittstellen aktiv zu lassen.
Die Implementierung des Foreground Services
Nachfolgend ist der Kern des Vordergrunddienstes dargestellt, der den Lebenszyklus des Threads und die Benachrichtigungen verwaltet:
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 Minuten Sicherheitslimit
}
}
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 Aktiv")
.setContentText("Leite Bluetooth RFCOMM-Daten an GPT-4o weiter...")
.setSmallIcon(R.drawable.ic_notification)
.setContentIntent(pendingIntent)
.build()
startForeground(1, notification)
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
// Bluetooth-Listening starten
val adapter = BluetoothAdapter.getDefaultAdapter()
serverThread = BluetoothServerThread(adapter) { socket ->
// Stream-Daten weiterleiten
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. Strukturierung der Nutzdaten und des Protokolls
Da RFCOMM als reiner Byte-Stream arbeitet, mussten wir ein Framing-Protokoll auf Anwendungsebene definieren, um die einzelnen Anfrage- und Antwortpakete zu segmentieren.
Wir haben ein leichtgewichtiges Format für Nachrichten-Frames entworfen:
- Magic Bytes (4 Bytes):
SLAR(Seven Labs AI Relay) zur Validierung der Paketquelle. - Nutzlastlänge (4 Bytes): Big-Endian-Integer zur Angabe der genauen Größe der Nutzdaten.
- Nutzlasttyp (1 Byte): Gibt an, ob das Paket roher Text, ein SSE-Chunk (Server-Sent Events), Metadaten oder ein Fehlercode ist.
- Verschlüsselte Nutzdaten (variabel): Mit AES-GCM verschlüsselte JSON-Daten.
+------------+------------------+--------------+-----------------------+
| Magic (4B) | Länge (4B, Int) | Typ (1B, B) | Verschlüsselt (N) |
+------------+------------------+--------------+-----------------------+
Wenn der Client auf dem Offline-PC einen Prompt sendet, verpackt der lokale Daemon diesen in einen solchen Frame, überträgt ihn über den RFCOMM-Socket und wartet blockiert auf Antwort-Frames.
Auf der Seite des Android-Relays liest der Kotlin-Socket-Reader das Längenpräfix, liest die angegebene Anzahl an Bytes, entschlüsselt die Nutzdaten und leitet die HTTP-Anfrage an den OpenAI-Endpunkt weiter. Um das Token-Streaming zu unterstützen, parsen wir die von OpenAI zurückgegebenen SSE-Daten-Chunks (Server-Sent Events), verpacken sie als Typ SSE Chunk und schreiben sie sequenziell zurück in den Bluetooth-Socket-Stream.
5. Sicherheitsarchitektur: Zero-Trust über Bluetooth
Die Übertragung von Unternehmensdaten über Bluetooth wirft erhebliche Sicherheitsbedenken auf. Bluetooth-Verbindungen sind anfällig für Abhören und Man-in-the-Middle-Angriffe (MitM). Um dieses Relay für den Unternehmenseinsatz tauglich zu machen, hat Seven Labs eine zusätzliche Verschlüsselungsschicht auf Anwendungsebene implementiert.
Ende-zu-Ende-Verschlüsselung (E2EE)
Selbst wenn die Bluetooth-Kopplungsschicht kompromittiert wird, bleiben die Nutzdaten geschützt.
- Schlüsselaustausch: Wenn der Offline-PC eine Verbindung initiiert, führt er einen Elliptic-Curve Diffie-Hellman-Schlüsselaustausch (ECDH) über den rohen Bluetooth-Socket mit dem Android-Gerät durch.
- Temporärer Sitzungsschlüssel: Beide Endpunkte leiten einen gemeinsamen symmetrischen Schlüssel (AES-256-GCM) ab, der für diese spezifische Sitzung gilt.
- Nutzdatenverschlüsselung: Jedes Datenframe-Paket wird mit dem Sitzungsschlüssel verschlüsselt, wobei für jeden Frame ein eigener Initialisierungsvektor (IV) erzeugt wird. Dies verhindert Replay-Angriffe und Schnüffeln.
6. Performance- und Latenz-Optimierung
Unsere Benchmarks in der Produktion zeigten die folgenden Performance-Metriken:
| Metrik | Direktes Wi-Fi (Kontrolle) | RFCOMM-Relay (Ohne Streaming) | RFCOMM-Relay (Mit SSE-Streaming) |
|---|---|---|---|
| Zeit bis zum 1. Token (TTFT) | ~320ms | ~980ms | ~410ms |
| Durchsatz (Token/Sek.) | 65 | 42 | 58 |
| Maximale Paketgröße | Unbegrenzt | 5 MB | Gestreamt |
Optimierung des Durchsatzes
Da die Bandbreite von Bluetooth im Vergleich zu Wi-Fi begrenzt ist, ist das Streamen der Antworten Token für Token von entscheidender Bedeutung. Indem wir die SSE-Chunks direkt an den Client zurückgeben, sobald sie an der Edge von OpenAI eintreffen, konnten wir die gefühlte Latenz (TTFT) um über 50 % senken.
Darüber hinaus haben wir eine Gzip-Komprimierung für Prompts eingeführt, die größer als 20 KB sind. Dies verkürzt die Bluetooth-Übertragungszeit und umgeht Engpässe im RFCOMM-Puffer.
7. Enterprise Frequently Asked Questions
Verletzt dieses System das Air-Gap-Prinzip?
Das System fungiert als strikter Protokoll-Proxy. Die offline Workstation hat keine IP-Verbindung zum Mobilfunknetz. Dies verhindert allgemeinen Internetzugang, Port-Scans oder Schwachstellen durch Reverse-Tunnel-Shells. Es sind ausschließlich wohlgeformte SLAR-Frames auf Anwendungsebene über die Schnittstelle zulässig.
Wie verhält sich der Akkuverbrauch des Relay-Geräts?
Der gleichzeitige Betrieb von Bluetooth und LTE verbraucht etwa 8 % Akku pro Stunde bei kontinuierlicher Verarbeitung. Durch den gezielten Einsatz von Android-PowerManager Wake-Locks - die wir nur bei aktiven Socket-Sitzungen halten - konnten wir den Akkuverbrauch minimieren.
Wie wird das Token-Accounting verwaltet?
Alle Nutzungsdaten und Autorisierungsschlüssel sind in der Android-Relay-App gespeichert oder werden von einem Enterprise-Key-Server abgerufen. Einzelne Benutzeranmeldungen können lokal auf dem Gerät authentifiziert werden, bevor die Diffie-Hellman-Aushandlung stattfindet.
Technische SEO-Schemata & interne Links
- Keywords: AI Relay, Offline Bluetooth AI, React Native Android, Kotlin foreground service, GPT-4o RFCOMM, secure AI systems.
- Interne Links:
- Erfahren Sie mehr über unsere Dienstleistungen im Bereich maßgeschneiderter KI-Entwicklung und wie wir maßgeschneiderte Systeme entwerfen.
- Lesen Sie mehr über unsere Kompetenzen bei der Netzwerkhärtung durch VAPT-Audits und Penetrationstests.
- Sehen Sie sich unser umfassendes Portfolio an Fallstudien zur Unternehmenssoftware-Entwicklung an.
Entwickeln Sie sichere Edge-zu-Cloud-Systeme mit Seven Labs
Die Verknüpfung von moderner KI mit strengen Sicherheitskontrollen in Unternehmen erfordert erfahrene Systemarchitekten. Ob air-gapped LLM-Deployments, hochperformantes Edge Computing oder sichere IoT-Relays - Seven Labs verfügt über die Engineering-Expertise, um konforme Lösungen zu entwerfen und zu implementieren.
Kontaktieren Sie das Engineering-Team von Seven Labs, um die maßgeschneiderten KI- und Infrastrukturanforderungen Ihres Unternehmens zu besprechen.
Seven Labs Dienstleistung
KI-Agenten-Entwicklung & RAG-Pipelines

