メインコンテンツへ移動
AIチュートリアル

ESP32-S3でAI搭載iPhoneエージェントを構築する

ESP32-S3の書き込み、UxPlayによるiPhoneのミラーリング、OpenAI互換の画像認識モデルの接続、ポインター操作のキャリブレーション、自動タスクの実行方法を解説します。Xcode、開発者アカウント、脱獄、iPhoneへのアプリのインストールは不要です。

ESP32-S3でAI搭載iPhoneエージェントを構築する

ESP32 iPhone Agentの機能

ESP32 iPhone Agentを使うと、AIモデルで実際のiPhoneの画面を見て操作できます。視覚入力にはAirPlayの画面ミラーリングを使用し、安価なESP32-S3ボードをUSBマウスおよびキーボードとして利用します。画面とポインターを介して操作するため、Xcode、Apple開発者アカウント、脱獄、デベロッパモード、iPhoneにインストールする補助アプリは必要ありません。

ESP32 iPhone Agentのインターフェースと接続されたiPhone

コンピューターはmacOSまたはLinuxで動作します。UxPlay、Pythonサーバー、Webインターフェース、OpenAI互換の視覚モデルへの接続をホストします。ESP32-S3はWi-Fi経由でコンピューターに接続し、iPhoneには標準USBヒューマンインターフェースデバイスとして認識されます。

システムの仕組み

AirPlayが目の役割を担う

iPhoneはコンピューター上のUxPlayに画面をミラーリングします。GStreamerパイプラインがそのストリームをJPEGフレームに変換し、AIエージェントとブラウザベースのライブビューの両方で使用します。

ESP32-S3が手の役割を担う

iPhoneに接続すると、ボードはUSBマウスおよびキーボードとして動作します。iOSのAssistiveTouchを有効にすると、マウスクリックはタップに、ポインターのドラッグはスワイプに変換され、スクロールホイールでインターフェースをスクロールできます。また、キーボードコマンドでテキストを入力したりショートカットを実行したりできます。

ファームウェアには意図的にほとんどロジックを含めていません。サーバーはmove、click、scroll、type、keyなどの行単位のコマンドをTCP経由で送信します。ボードはokまたはエラーメッセージを返します。

プランナーとアクターが頭脳を担う

プランナーモデルは、要求された目標と現在の画面から短い計画を作成します。アクターモデルは新しいスクリーンショットを確認し、タップ、スワイプ、経路の描画、入力、キーの押下、ホームへの移動、完了など、次のアクションを選択します。同じ視覚モデルで両方の役割を担うことができます。

閉ループ検証で信頼性を向上

ポインターの移動は相対的であるため、サーバーは推定位置を追跡します。タップの前にポインターを小刻みに動かし、ミラーリングされた画像内でポインターを特定し、外れを補正してキャリブレーションを調整できます。アクションの後、エージェントは画面が変化したかを確認します。そのため、失敗したアクションを検出して再試行でき、後続のステップが誤った状態を前提に進むのを防げます。

また、同じアクションが繰り返された後に再計画したり、接続切断やモデルからの無効な応答から復旧したりできます。Wi-Fi接続が切断されると、ボードはマウスボタンを解放して自動的に再接続します。

主な機能

  • Apple開発環境不要: Xcode、開発者アカウント、コード署名、デベロッパモード、テスト実行用アプリは必要ありません。
  • 幅広いアプリに対応: アクセシビリティツリーに依存せずピクセルを操作するため、一般的なアプリやゲームで利用できます。
  • MacまたはLinuxをホストに使用: サーバーはmacOSに限定されません。
  • 柔軟なモデル対応: 画像を受け付けるOpenAI互換のチャットAPIなら利用できます。
  • 手動・自律操作: Webインターフェースから、直接のタップ、スワイプ、スクロール、入力、ホーム、戻る操作、AIによるタスクを実行できます。
  • 実行状況を確認可能: ライブのiPhone画面、計画、ログ、スクリーンショット、アクション、推論、タイミング情報を表示します。
  • 安全制御: 緊急停止でエージェントを停止し、ポインターを解放できます。

必要なもの

  • ESP32-S3ボード: このプロジェクトは、基板のみのSeeed Studio XIAO ESP32S3でテストされています。USB-CポートがチップのネイティブUSBインターフェースに接続されていれば、別のESP32-S3ボードも使用できます。
  • iPhone: USB-Cモデルは直接接続できます。LightningモデルにはLightning - USBカメラアダプタが必要です。
  • コンピューター: iPhoneと同じネットワーク上にあるmacOSまたはLinuxマシン。
  • Wi-Fi: ボードの設定には2.4 GHzネットワークの名前とパスワードが必要です。
  • 視覚モデル: 画像入力を受け付けるクラウドまたはローカルのOpenAI互換エンドポイント。

iPhoneからボードに電力を供給します。iPhoneを同時に充電する必要がある場合は、電力パススルー対応のUSB-Cハブを使用してください。

エージェントのインストールと設定

1. リポジトリをクローンする

git clone https://github.com/onehumanbeing/esp32-iphone-agent.git
cd esp32-iphone-agent

2. ESP32-S3を準備して書き込む

arduino-cliと3.xのESP32コアをインストールします。ESP32-S3をUSB経由でコンピューターに接続し、サンプルのシークレットファイルをコピーして、新しいファイルを編集します。

cp hardware/hid_bridge/secrets.example.h hardware/hid_bridge/secrets.h

hardware/hid_bridge/secrets.hに、2.4 GHz Wi-Fiネットワークの名前、Wi-Fiパスワード、サーバーを実行するコンピューターのIPアドレスを入力します。その後、ボードに書き込みます。

hardware/flash.sh

フラッシュスクリプトでは、シリアルポートと--debugフラグを任意で指定できます。デバッグファームウェアを使用すると、コマンドとその実行時間がUSBシリアル経由でエコーされます。

3. UxPlayをインストールする

macOSでは、HomebrewでUxPlayをインストールします。

brew install uxplay

DebianまたはUbuntuでは、UxPlayと必要なGStreamerパッケージをインストールします。

sudo apt install uxplay gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-libav

4. Python環境を作成する

サーバーディレクトリに移動し、仮想環境を作成してプロジェクトをインストールします。

cd server
python3 -m venv .venv
.venv/bin/pip install -e .

Python 3.10以降が必要です。

5. モデルを設定する

環境変数のテンプレートをコピーします。

cp .env.example .env

server/.envを編集し、少なくともOpenAI互換エンドポイント、モデル名、APIキーを設定します。

LLM_BASE_URL=https://your-endpoint.example/v1
LLM_MODEL=your-vision-model
LLM_API_KEY=your-api-key

選択したモデルは画像に対応している必要があります。クラウドAPIで十分です。ローカルモデルの実行は任意です。

6. サーバーを起動する

set -a && . ./.env && set +a && .venv/bin/python -m hidagent

ブラウザーでhttp://<computer-ip>:8890を開きます。コンピューターのIPは、ボードが接続されているネットワークから到達可能でなければなりません。

iPhoneをセットアップする

以下のiPhone設定が必要になるのは通常1回だけです。

  1. 設定を開き、アクセシビリティ、タッチ、AssistiveTouchの順に移動します。
  2. AssistiveTouchをオンにします。
  3. 書き込み済みのボードをコンピューターから取り外し、iPhoneに接続します。
  4. 丸いポインターが表示され、Webページでコントローラーが接続済みと表示されることを確認します。
  5. iPhoneでコントロールセンターを開き、画面ミラーリングを選択します。
  6. iPhone Agentを選択します。WebインターフェースにiPhoneのライブ画面が表示されます。
  7. Webインターフェースで手動操作を開き、キャリブレーションを選択します。
  8. ライブ画面に表示されているポインターを正確にクリックします。

後でAssistiveTouchの追跡速度を変更した場合は、再度キャリブレーションしてください。

最初のタスクを実行する

Webインターフェースに目標を入力し、開始を押します。例:

Open Settings and go to Wi-Fi

プランナーが短い計画を作成し、アクターが現在のスクリーンショットを繰り返し確認してアクションを選択します。タスクの実行中は、iPhoneのライブ画面とログを確認してください。

ステップウォールには、各判断に使用されたスクリーンショットが記録されます。また、選択したタップやスワイプを画像上に描画し、モデルの推論と所要時間を表示します。ステップカードを選択すると、拡大表示が開きます。

手動操作を使用する

  • ライブのiPhone画像をクリックすると、その位置をタップします。
  • 画像上をドラッグするとスワイプを実行します。
  • スクロール入力を使用してiPhoneをスクロールします。
  • ホーム、戻る、テキスト入力、キー用の各コントロールを使用します。

エージェントの動作が予期せずおかしくなった場合は、緊急停止を有効にするか、Escを押してください。実行が停止し、ポインターが解放されます。インターフェースには実行履歴を消去するコントロールもあります。

重要な設定オプション

  • LLM_BASE_URL:OpenAI互換エンドポイント。デフォルトはhttp://localhost:8000/v1です。
  • LLM_MODELとLLM_API_KEY:モデル名とAPI認証情報。
  • LLM_EXTRA_BODY:すべてのモデルリクエストにマージされるJSON。モデルの思考モードを無効にする設定などに使用します。
  • ACTOR_*とPLANNER_*:対応するLLM_*設定の役割別上書き。
  • AIRPLAY_NAME:iPhoneの画面ミラーリング一覧に表示されるレシーバー名。デフォルトはiPhone Agentです。
  • PORT:Webインターフェースのポート。デフォルトは8890です。
  • DEVICE_PORT:ESP32-S3が使用するポート。デフォルトは7300です。
  • HIDAGENT_DATA:キャリブレーションとトレースのディレクトリ。デフォルトは~/.hidagentです。
  • HIDAGENT_DEBUG:1に設定すると、サーバー側のデバッグログを有効にします。

高度な使用方法とトラブルシューティング

プランナーとアクターに別々のモデルを割り当てる

プランナーとアクターには同じモデルを使用できますが、役割別の環境変数を使うと、モデル設定を個別に上書きできます。別々のエンドポイントやモデルが必要な場合は、該当するLLM_*変数のPLANNER_*形式とACTOR_*形式を使用します。

ローカルモデルサーバーに接続する

vLLM、SGLang、llama.cpp、Ollamaなど、ビジョンモデルを備えたOpenAI互換サーバーは、同じ方法で設定できます。このプロジェクトは、テンソル並列処理を使用して2台のNVIDIA DGX Sparksで提供されるNVIDIA Qwen3.8-Flash-Next-NVFP4を使って開発および測定されました。

この構成の設定例:

LLM_BASE_URL=http://<dgx-spark-ip>:8888/v1
LLM_MODEL=Qwen3.8-Flash-Next
LLM_EXTRA_BODY='{"chat_template_kwargs": {"enable_thinking": false}}'

報告された開発環境では、思考モードを無効にした場合、1アクションあたり約1.3秒、1プランあたり2秒を達成しました。これらの数値は特定のハードウェアとモデル構成に関するものであり、他の環境での速度を保証するものではありません。

トレース収集を有効にする

server/.envに次の値を設定します。

HIDAGENT_DEBUG=1

デバッグモードでは、すべてのボードコマンドとそのレイテンシがログに記録されます。また、エージェントの実行ごとに~/.hidagent/traces/以下に1つのディレクトリが作成されます。このディレクトリには、モデルのプロンプト、生の応答、レイテンシの測定値、アクションを含むsteps.jsonlと、モデル呼び出しで表示されたスクリーンショットが保存されます。

ボードプロトコルを理解する

  • ping はヘルスチェックを実行します。
  • home は既知の位置を確立するため、ポインターを左上隅に移動します。
  • move <dx> <dy> は、一定の速度でポインターを相対的に移動します。
  • press、release、click は左マウスボタンを操作します。
  • scroll <v> <h> は、垂直および水平方向のスクロールホイール入力を送信します。
  • type <text> は ASCII テキストを入力します。
  • key <combo> は、enter、cmd+h、cmd+space などのキーまたはキーの組み合わせを送信します。

Linux で AirPlay の検出問題を解決する

コンピューターに複数のネットワークインターフェースがあり、iPhone にレシーバーが表示されない場合は、Avahi の mDNS アドバタイズを、iPhone のネットワークに接続されているインターフェースに限定します。

既知の制限事項

  • iOS はパスコードの入力、Apple Pay、DRM で保護されたビデオなど、一部の保護された画面をミラーリングしないため、エージェントはそれらを認識できません。
  • iPhone がロックされると画面ミラーリングが停止します。エージェントの実行中は自動ロックを無効にしてください。
  • キーボードによるテキスト入力は ASCII に限定されます。
  • AssistiveTouch のトラッキング速度を変更した後は、ポインターのキャリブレーションをやり直す必要があります。
  • エージェントは、ボードとサーバー間のネットワーク経路が正常に機能し、iPhone とコンピューター間で利用可能な AirPlay ストリームが存在することを前提とします。

責任ある運用

自分が所有している、または使用を許可されたデバイスとアカウントのみを自動化し、使用するアプリケーションの利用規約に従ってください。

エージェントは人間と同じ種類の入力で操作できるため、実行中の処理を監視し、緊急停止をすぐに使える状態にしておいてください。

まとめ

ESP32 iPhone Agent は、AirPlay ミラーリング、低コストな ESP32-S3 USB HID ブリッジ、OpenAI 互換のビジョンモデルを組み合わせ、Apple の従来の開発ツールチェーンを使わずに物理的な iPhone を自動化します。ファームウェア、サーバー、モデルエンドポイント、AssistiveTouch、ミラーリング、ポインターのキャリブレーションを設定すると、自然言語で目標を指定し、すべての判断を確認し、手動で介入し、デバッグ用の詳細なトレースを収集できます。