BLOG

Tech Teardown 026|esp32-iphone-agent:Un ESP32 à 7 $ permet à l'IA de manipuler un véritable iPhone

Kael Zhang
Tech Teardownesp32-iphone-agentAgent mobileESP32Protocole BLE
广告 · Advertisement

Le 11 octobre, le développeur individuel onehumanbeing a ouvert le projet esp32-iphone-agent sur GitHub. En quatre jours, il a atteint 2418★ et 322 forks (données de GitHub API, snapshot du 10-16). La popularité provient principalement des publications trending sur GitHub et des répétitions dans les communautés techniques : sur Hacker News, il n’y a que 2 likes et 0 commentaires pour cette publication (verifié par Algolia), ce qui indique une faible capacité de diffusion. Le point fort du projet peut être exprimé en une phrase : une puce ESP32-S3 d’environ 7 dollars, utilisée comme « œil » et « main », avec un cerveau d’IA fonctionnant dans l’application d’un iPhone, permettant aux modèles visuels de contrôler un iPhone réel sans besoin de ordinateur, de jailbreak ou d’un compte de développeur. Licence MIT. Ce texte suit la tradition en divisant le contenu en six parties.

I. Qu’est-ce que c’est ?

Dans la liste des miroirs d’écran d’iPhone, un récepteur appelé « ESP32 Agent » est ajouté. Il s’agit d’un point de réseau Wi-Fi autonome de la puce, combiné avec un récepteur AirPlay intégré. L’iPhone transmet le miroir de l’écran à la puce, qui ne décode pas le signal et renvoie le flux H.264 via BLE à l’application sur l’iPhone. L’application envoie les captures d’écran à un modèle visuel compatible OpenAI, lequel décide des actions, puis les instructions sont renvoyées à la puce via BLE. La puce se connecte à nouveau à l’iPhone en tant que souris et clavier HID USB standard, et coopère avec AssistiveTouch pour effectuer des clics et des glissades. Un trio d’équipements : œil, main, cerveau. Le coût matériel est d’une puce de 7 dollars, tandis que le coût logiciel réside dans l’application construite par le développeur.

Les projets similaires permettent de voir clairement sa position distincte. boboabw/phone-agent est très proche : il utilise également ESP32-S3, Bluetooth HID, AssistiveTouch et une application iPhone comme cerveau, mais il ne dispose pas d’« œil » et le modèle ne peut donc pas voir l’écran. VersaiOS utilise UxPlay pour effectuer le miroir sur ordinateur, nécessitant un ordinateur et exécutant une commande une seule fois. ja1chen/actell utilise le canal de débogage Apple CoreDevice, nécessitant un mode développeur et une image disque de développement. Des solutions comme mobile-mcp et Midscene, qui utilisent WebDriverAgent, nécessitent un Mac et une signature du code. La particularité de ce projet est que le récepteur AirPlay est également intégré dans la puce, éliminant ainsi le rôle de l’ordinateur au niveau matériel.

II. Structure du repository

Faisons d’abord une petite recherche historique : les tags linguistiques de GitHub ne correspondent pas à la réalisation effective du projet. Selon les statistiques locales (excluant .git et 190 fichiers), Swift contient 11 621 lignes, ce qui représente la majorité absolue des lignes, correspondant aux applications dans le dossier ios/ ainsi qu’à 13 fichiers de test ; C ne contient que 2 793 lignes, concentrées dans hardware/, principalement liées à la transplantation du récepteur AirPlay de UxPlay et à la réalisation de la certification FairPlay de playfair ; les 800 lignes de C++ sont liées au pont HID du firmware ESP32 ; 1 793 lignes de Python se trouvent dans le dossier server/, mais le CHANGELOG indique clairement « server/ n’est plus nécessaire », ce qui est un résidu de la version client v0.1.0, ne le considérez pas comme du code actif. Ce phénomène est similaire à celui rencontré lors de la rénovation des tags linguistiques de pg_vectorsearch lors de la période 025.

L’évolution de l’architecture est la narration la plus intéressante de ce projet. La version v0.1.0 était une solution pour le client : UxPlay, un serveur Python et une interface web. ESP32 n’était qu’un pont USB HID sur Wi-Fi, nécessitant un ordinateur Mac ou Linux pour le passage de données. La branche principale a récemment terminé la réorganisation de « disparition du client » : la plateforme fonctionne comme un récepteur AirPlay, crée son propre point de chute et communique via BLE avec une nouvelle application iPhone. Les phrases d’aide sont stockées dans le dossier prompts/, et le nom du produit est désigné ESP32 Agent. En quatre jours, il a reçu 2 400 points, ce qui correspond à cette forme minimaliste.

Un autre chiffre à honnêtement mentionner : un total de 29 commits, avec le API des contributeurs indiquant un seul contributeur principal. Il s’agit d’un projet individuel, pas d’un projet communautaire.

III. Rénovation des mécanismes

Voyons les trois mécanismes clés un par un.

Le premier point concerne la transmission vidéo via BLE. Le processeur de la plateforme est peu puissant, ce qui rend l’interprétation physique de H.264 irréaliste. La solution choisie par l’auteur est de ne pas décompresser du tout : le flux H.264 reçu par AirPlay est coupé en morceaux et transmis via une notification BLE au téléphone, la décompression étant effectuée par l’iPhone lui-même. Le document docs/ble-protocol.md décrit cette méthode de manière très claire : la plateforme fonctionne comme un périphérique BLE, avec cinq caractéristiques distinctes sous un service. cmd reçoit les commandes ligne de commande, reply renvoie les résultats, status envoi une notification JSON par seconde pour maintenir la vie du service (et également pour le back-end de l’application), video transmet les morceaux H.264, et net utilise un canal crypté pour la réception des données. La sécurité est assurée grâce à LE Secure Connections et bonding. Chaque notification video contient un numéro de 16 bits et des bits de marqueage ; si une paquete est perdue, l’application détermine le numéro du cadre suivant pour réaligner les données. Dans le mode stream, les frames P dépassant 800 millisecondes sont simplement ignorés ; en cas de manque de bande passante, la configuration se transforme automatiquement en transmission uniquement de cadres clés, évitant ainsi une augmentation de l’attente. La notification status par seconde est également intéressante à examiner : elle contient dans un seul fichier JSON la durée de fonctionnement, les raisons du redémarrage, les réserves de mémoire et de PSRAM, l’état du USB, le nombre de connexions hotspot, le taux de compression actuel, le taux de délivrance réel, le MTU de BLE et la vitesse de la couche physique, ainsi que le nombre de paquets perdus. Cela permet à l’application de suivre en temps réel l’état de la voie de données. Si le MTU est trop bas, le firmware dégrade automatiquement pour transmettre des objets raccourcis ; en lisant status, on obtient toujours la version complète. La priorité de transmission est également définie : reply et status sont toujours prioritaires devant video. Video peut compresser jusqu’à 8 paquets ACL dans le contrôleur, évitant ainsi que les commandes soient oubliées par le flux vidéo. Le firmware contient également une commande coex pour réguler la coexistence des signaux Wi-Fi et BLE sur la même antenne ; c’est un détail technique inévitable pour ESP32-S3. Par défaut, le système revient à l’état de balance après chaque démarrage.

Le deuxième point concerne le retour d’information pour l’ajustement de la pointeuse. Les souris USB HID fonctionnent avec une position relative sur iOS, tandis que les modèles fournissent des coordonnées absolues sur les images prises à l’écran. Il y a donc un écart entre ces deux systèmes : la position actuelle de la pointeuse ne peut être déterminée que par l’application en calculant l’évolution historique, ce qui entraîne une accumulation des erreurs. La solution de l’auteur consiste à transformer l’ajustement en action continue : l’application suit constamment la pointeuse et la “réaligne” dans un coin de l’écran. Avant de cliquer avec précision, l’application effectue une petite oscillation de la pointeuse, afin de trouver sa position dans la dernière image prise à l’écran, corriger les erreurs de calcul et finalement atteindre le point de clic. Dans le fichier actor.md, la commande tap contient un paramètre precise ; les petits objectifs et les éléments disposés en série (listes, commutateurs, boîtes de sélection) suivent cette voie plus lente mais plus précise. Après chaque action, l’écran doit se stabiliser avant de fournir des informations sur les changements effectués ; si rien ne change, cela signifie que le clic n’a pas été atteint. L’application exige explicitement de ne pas supposer qu’un clic a été effectué, et doit donc réajuster sa cible ou choisir une autre méthode. Si la plateforme, un hotspot ou une image est déconnectée, la tâche est suspendue ; une fois reconnectée, elle continue à partir du même point. Le README qualifie cela de “self-healing”.

Le troisième point concerne l’ingénierie des instructions, qui est la partie la plus précieuse pour toute l’application. Le fichier planner.md exige que le modèle écrive un plan de 6 étapes au maximum basé sur ce qu’il voit, sans inventer de comptes, d’adresses e-mail ou des pages de connexion que l’on n’a pas vus. Le fichier actor.md est plus détaillé : il produit deux parties, THINK et DO. Dans THINK, il faut vérifier avec des mots anglais compréhensibles par un non-technique si la dernière étape a fonctionné. Les coordonnées sont des nombres entiers de 0 à 1000. La règle principale est « regarder avant d’agir » : il faut décrire seulement ce qui existe réellement sur l’écran, uniquement les éléments visibles sur les captures d’écran. Le swipe n’a pas d’inertie ; on préfère des glissements courts de 100 à 250 unités et une vérification des résultats. Le curseur de temps doit être cliqué sur la ligne centrale avant de saisir les chiffres (par exemple, type 0700). La recherche dans la liste ne doit pas dépasser une page à la fois, et une fois chaque élément visible lu, si elle n’est pas atteinte, le programme échoue et rapporte l’option la plus proche. Les ensembles d’actions couvrent tap, swipe, path (deux à 20 points de traçage continu pour dessiner), circle, type, key, home, back, wait, replan, done, fail. Ces instructions définissent presque toutes les erreurs liées à la manipulation fiable du GUI par un agent visuel.

Quant au motif permettant à l’iPhone de reconnaître une cible AirPlay légitime : le code playfair dans hardware/ (omg_hax.c, hand_garble.c, sap_hash.c, etc.) est une implémentation inverse de la certification FairPlay transférée de UxPlay. La lignée et les termes sont interprétés comme « transféré/inverse ». UxPlay est lui-même un projet reconnu d’接收eur AirPlay open source.

IV. Chiffres et vérification

La liste des équipements est courte : l’auteur a utilisé le Seeed Studio XIAO ESP32S3 standard pour la vérification, avec une PSRAM de 8MB, environ 7 dollars. Le README indique que tout ESP32-S3 équipé d’une USB native (port USB-C) et d’une PSRAM devrait être utilisable. La résolution par défaut est 480×1040, 5fps, qui peut être modifiée avec les commandes res et fps. Le BLE affiche une bande passante d’environ 300 à 500 kbps, ce qui constitue la limite de résolution et de fréquence d’image. Chaque action de l’agent prend quelques secondes, et la majeure partie du temps est consacrée à l’inférence du modèle. Lorsque l’application fonctionne, le Wi-Fi du téléphone se connecte au point de réseau de la carte, sans connexion Internet. Les appels au modèle se font via les données cellulaires.

La liste des restrictions est tirée du README original, qui est plus long que la liste des points de vente. Elle est reproduite ici : la bande passante BLE entraîne une petite résolution et une faible fréquence d’image ; iOS ne affiche pas la saisie de mots de passe, Apple Pay, les vidéos DRM, et l’affichage s’arrête lors du verrouillage de l’écran dans ces scénarios, où l’agent est inutile ; l’application utilise des API iOS privées (suspend) pour fonctionner en arrière-plan, ce qui est sans problème pour la création de l’application, mais il faut les remplacer avant de l’mettre en vente sur l’App Store ; la saisie avec le clavier ne prend que des caractères ASCII ; l’application ne prend pas en compte l’écran horizontal. Les points non achevés du plan de développement incluent : l’écran horizontal, la saisie non ASCII (comme les chinois pinyin), et la rapide exécution de plusieurs actions lors d’une seule appel à modèle. Les versions doivent être compatible avec iOS 18 ou plus, car elles sont sensibles aux mises à jour du système.

Vérifier les dimensions en ajoutant trois autres chiffres : HN story 2▲ 0 commentaires, la faible capacité de diffusion est une réalité ; 29 contributions, un seul contributeur principal, la durabilité reste à observer ; les dossiers iOS contiennent 13 fichiers de test, un projet individuel qui en arrive là montre que l’équipe est modérée et sérieuse. Le README contient également une section sur l’utilisation responsable : utiliser uniquement les appareils et comptes que vous possédez ou êtes autorisé à utiliser, l’agent fonctionne avec vos actions, il faut le surveiller pendant son exécution, la touche arrêt doit être à portée de main.

V, Jugement

Trois points méritent attention.

Premièrement, il s’agit d’un travail ingénieux plutôt que d’une brèche physique. L’ensemble du plan ne touche aucune limite de sécurité d’iOS : l’image AirPlay est une fonctionnalité système, le protocole USB HID est un standard pour les périphériques externes, AssistiveTouch est une fonction de facilitation, traduire « l’intention de cliquage du modèle » en « entrée de souris acceptée par iOS » respecte les interfaces autorisées par le système à chaque étape. Le reverse de FairPlay de playfair provient d’une implémentation publique existante de UxPlay, ce n’est pas une nouvelle découverte pour ce projet. Cette approche de « construire des ponts dans les failles légales d’une écosystème fermé » est plus proche d’un modèle pérenne que toute autre solution de jailbreak.

Deuxièmement, la division du travail « renforcer le modèle avec un matériel faible » mérite d’être copiée. Le matériel ne fait aucun travail intelligent, il sert simplement de canal avec une bande passante limitée et d’agent fidèle ; la décodage, la vision et la planification se font entièrement sur le téléphone et dans le cloud. Le transfert de données BLE sans décodage, la calibration relative des pointeurs, et le retour d’information à chaque étape sur les changements de l’écran, ces trois mécanismes résolvent la même question : comment construire un circuit de retour fiable sur des canaux incertains. Ceux qui développent des agents sur le côté du matériel peuvent s’inspirer directement, et les fichiers prompts/actor.md peuvent même être utilisés tels quels.

Troisièmement, il faut définir clairement les limites. Un projet individuel, 29 contributions, presque aucune activité sur HN, l’augmentation rapide du nombre de stars repose sur la capacité de diffusion de l’histoire « 7 dollars pour manipuler un vrai iPhone », ce qui ne signifie pas que le projet bénéficie d’un soutien communautaire ou commercial. Chaque grande version d’iOS peut modifier le comportement AssistiveTouch ou AirPlay, et l’installation permanente de APIs privées est une menace constante. C’est une expérience de développement personnel sophistiquée, il faut évaluer selon cette mesure, et non selon celle de l’« infrastructure open-source ».

Une observation : le README mentionne six restrictions en place, l’auteur ne prétend pas que le projet soit un solution générale. Un README avec une liste de restrictions plus longue que celle des points forts est généralement un signe d’un projet open-source sain.

VI. Qui peut l’utiliser et comment

Profils adaptés : possédant un iPhone (iOS 18+) et un ESP32-S3 avec USB native et PSRAM, désireux de compiler vous-même des applications iOS (besoin de Xcode et d’une Apple ID gratuite pour le téléchargement, pas besoin d’un compte développeur payant), et souhaitant étudier le développement de GUI pour l’action sur des appareils réels avec des modèles visuels. Avant d’utiliser ce logiciel pour automatiser vos actions quotidiennes, lisez d’abord l’utilisation responsable : utilisez uniquement les appareils et comptes que vous possédez ou êtes autorisé à utiliser, ne quittez pas le projet pendant son exécution.

Voici les étapes à suivre selon le README : lire la documentation sur l’enregistrement du hardware et du firmware, puis ouvrir la carte avec des points de contrôle. Sur l’écran de l’iPhone, choisissez ESP32 Agent, connectez la câble USB, activez AssistiveTouch, scannez ou synchronisez avec le BLE à l’aide de l’application, et saisissez un point de connexion d’un modèle visuel compatible OpenAI pour passer les commandes. Chaque exécution est enregistrée sur votre téléphone, pouvant être réplayée progressivement. Les touches Tap et Swipe sont affichées sur les diapositives correspondantes, ce qui facilite le suivi. Lorsque l’application travaille en arrière-plan, la Live Activity affiche les progrès, ainsi que des widgets, Siri et des Shortcuts.

Ceux qui ne souhaitent pas procéder par eux-mêmes devraient également lire deux documents : docs/ble-protocol.md est un document de protocole BLE privé de niveau scolaire, décrivant en détail l’allocation des UUID, le maintien en activité grâce aux battements de cœur, la récupération des paquets perdues et la coexistence avec les radiofréquences ; le dossier prompts/ contient des phrases de référence publiques rarement vues qui décrivent en détail les règles d’utilisation des agents GUI. La valeur de ces deux documents ne varie pas en fonction de la durabilité du projet lui-même.

Sources d’information

  • Identité du repository (2418★/322 forks/date de création et de publication/MIT/topics) : GitHub API repos/onehumanbeing/esp32-iphone-agent, snapshots du 10-16
  • Taille du code (190 fichiers, 11.621 lignes en Swift, 2.793 lignes en C, 800 lignes en C++, 1.793 lignes en Python) : clone local /tmp/eia-1016, statistiques par extension avec find+wc, sans étiquettes linguistiques GitHub
  • Architecture et flux de données, liste des restrictions, utilisation responsable, liste des composants matériels, comparaison avec des projets similaires : le README original (y compris la version chinoise README.zh-CN.md)
  • Détails du protocole BLE (cinq caractéristiques, perte de numéro de paquet, écrasement de frames P à 800ms, coexistence, stockage NVS) : docs/ble-protocol.md
  • Règles des phrases de référence : prompts/planner.md, prompts/actor.md original
  • Évolution de l’architecture (de v0.1.0 au main « disappearance du ordinateur ») : CHANGELOG
  • Origine de playfair/UxPlay : le dossier hardware/hid_bridge/src/airplay/playfair et la mention dans CHANGELOG « porté de UxPlay »
  • Force de diffusion de HN (histoire 50102527, 2▲ 0 commentaires) : vérification par HN Algolia
  • Distribution des contributeurs et nombre total de commits (29) : GitHub contributors API et commits Link header
广告 · Advertisement

Questions fréquentes

Quel est le coût matériel de ce projet ?

Le coût matériel est d'une puce ESP32-S3 d'environ 7 dollars.

Comment fonctionne l'ESP32 Agent dans ce projet ?

L'ESP32 Agent est un point de réseau Wi-Fi autonome qui reçoit le miroir de l'écran de l'iPhone, le décode et renvoie le flux H.264 via BLE à l'application sur l'iPhone.

Quelles sont les différences entre ce projet et d'autres projets similaires ?

Ce projet utilise une puce ESP32-S3 comme œil et main, tandis que d'autres projets comme boboabw/phone-agent ne disposent pas de cette fonctionnalité d'œil, et VersaiOS nécessite un ordinateur pour le miroir d'écran.