概要
AI エージェントは短時間で大量のコードを生成できますが、それが増えるほどプルリクエスト(PR)も増え、コード品質保証の仕組みが必要になります。バックエンドでは統合テストで十分なことが多い一方、モバイル(iOS/Android)の UI を生成するコードは目で確認しないと見落としが生じやすいです。
この記事では、追加コストをかけず既存ツールだけで Expo アプリ向けの軽量な QA エージェントを作る方法を紹介します。EAS Workflows を使うことで、既存のビルドを再利用し、Android/iOS 上で自動的に UI 検証(スクリーンショット取得など)を行い、結果を PR にコメントするワークフローを数分で構築できます。
テンプレートリポジトリ: callstackincubator/eas-agent-device
このセットアップの構成(意図的に小さく)
- Expo アプリ(CNG と EAS Workflows でオーケストレーション)
- agent-device を使った小さな Node.js QA エージェント(Android/iOS 自動化)
- Android と iOS の QA 結果を 1 件の GitHub コメントで投稿
重要なのは「AI」ラベルではなく、数分で動くベースラインから始めて、必要に応じてカバレッジを広げられる点です。
目標
プルリクごとに以下を実現します:
- 可能であれば既存のリリースビルド(最新の JS を含む)を再利用
- エミュレータ/シミュレータを起動
- アプリをインストールして起動
- エージェントに UI を検査させ、スクリーンショットを取得
- PR に短い QA サマリを投稿
巨大なテストフレームワークは不要。すべての E2E を置き換える必要もありません。モバイル UI 変更に対する実用的な QA ループを提供することが目的です。
なぜ EAS Workflows が適しているか
EAS Workflows はモバイル特有の CI を既に理解しており、次のことが容易にできます:
- native の変更検知のための fingerprint
- get-build による再利用可能なビルドの取得
- repack による、JS だけの変更時のネイティブ再ビルド回避
- Android と iOS 用の仮想化可能な linux/macos ランナー
- github-comment による PR への結果反映
そのため、モバイル向けのパイプラインをわざわざ汎用 CI に押し込む必要がなく、既存のモバイル要素の上に自然に組み立てられます。
注: Android ジョブでは Android Emulator を起動するために linux-medium-nested-virtualization イメージが必要です(エミュレータは最初からインストールされていないため自前でインストールします)。iOS は macos-medium(以上)のイメージを使ってシミュレータを利用します。
ワークフローの基本形
コアのワークフローは単純で 1 画面に収まります。例(YAML):
jobs:
fingerprint:
type: fingerprint
android_get_build:
type: get-build
params:
platform: android
profile: qa-release
android_repack:
type: repack
android_build:
type: build
qa_android:
runs_on: linux-medium-nested-virtualization
steps:
- uses: eas/checkout
- uses: eas/install_node_modules
- uses: eas/download_build
- id: provision_android_emulator
run: bash ./scripts/agent-qa/provision-android-emulator.sh
- id: run_agent_qa
run: bash ./scripts/agent-qa/run-and-export.sh "${{ steps.download_build.outputs.artifact_path }}"
env:
AGENT_DEVICE_SESSION: qa-android
AGENT_DEVICE_PLATFORM: android
qa_comment:
type: github-comment
iOS についても同様の考え方で、macOS ワーカー上でシミュレータビルドを使って実行します。Android と iOS を並列で動かす完全な例はリポジトリの .eas/workflows/agent-qa-mobile.yml にあります。
設計上の重要な選択: ブートストラップと QA を分離する
強く推奨するのは「ブートストラップ(決定論的にスクリプト化できる準備)」と「エージェント駆動の可変フロー」を分けることです。最初からエージェントにすべて任せると、インストールパスやフラグを誤解したり、手順を読み飛ばしたりして不安定になります。
ブートストラップ部分はスクリプトで確実に実行して、アプリのインストールや起動に必要なパラメータを常に正しく渡すようにします。例(bash):
#!/usr/bin/env bash
agent-device install "${APP_ID}" "${APP_PATH}"
agent-device open "${APP_ID}" --relaunch
agent-device は AGENT_DEVICE_PLATFORM 環境変数でどのプラットフォームかを判断します。
可変部分(受け入れ基準の推測、アクセシビリティツリーの読み取り、ナビゲーション、スクリーンショット取得、要約生成など)はエージェント側で行わせます。例:
# Phase 2: variable agent-driven flow
npm run agent-qa
この分割により、エージェントはアーティファクトパスやインストールコマンドを推測する必要がなくなり、ワークフローの信頼性が飛躍的に向上します。
エージェントは小さく保てる
アプリが起動済みであれば、エージェントが必要とするツールは最小限です:
- PR コンテキストの読み取り
- agent-device スキルの読み込み
- agent-device を使った UI 操作(snapshot、press、screenshot など)
- 最終レポートの出力
簡易なエージェント例(TypeScript/SDK ベース):
import { ToolLoopAgent } from
const agent = new ToolLoopAgent({
model:
instructions: `You are a mobile QA agent running inside EAS Workflows. Treat the app as a black box. Infer acceptance criteria from the PR. The app is already installed and launched. Use agent-device to inspect the UI, navigate, take screenshots, and write a report. If the result is visually plausible but not fully confirmed from structured UI output, use "unsure". You must call write_report exactly once.`,
tools: { get_pr_context, load_skill, read_skill_file, agent_device, write_report },
});
この例では Vercel の AI SDK を使っていますが、OPENAI_API_KEY を使った openai プロバイダなど、好きなプロバイダに差し替えることもできます。
フル実装はリポジトリ内の scripts/agent-qa/index.ts にあります。
レポートは必要最小限にする
出力は小さく有用に保ちます。本テンプレートでは各プラットフォームごとに検証ステータスを次のいずれかで出力します: passed、failed、blocked、unsure。
出力内容例:
- 短いサマリ
- 実行したチェックの一覧
- 発見した問題点
- スクリーンショット
- デバッグ用の詳細な JSON レポート(折りたたみブロック)
unsure ステータスは重要です。構造化された UI 出力だけでは視覚的な確認が難しい場合があり、その場合はスクリーンショットを添えて「断定できない」ことを明記するのが正直で有益です。
最終ステップ: PR へのコメント
人間による確認と同様に、PR に短いコメントで結果を残すだけで十分なことが多いです。例:
#
| Platform | Status |
| -------- | ------ |
| Android | ✅ passed |
| iOS | 🤔 unsure |
#
Short summary...
Screenshots
#
Short summary...
Screenshots
コメントはレビュワーが既に見る場所に結果とビジュアルを置くため、レビューの負荷を下げます。
補足: GitHub コメントへ直接スクリーンショットをアップロードする公式 API が無いため、例では Vercel Blob を 3rd-party の画像ストレージとして使用しています。AWS S3 など、プロジェクトに合ったストレージに置き換えてください。
今日試すための推奨手順
- Expo ダッシュボードから GitHub プロジェクトを EAS Workflows に接続
- まずは一つのプラットフォーム(例: Android)から始める
- CNG を使い、ネイティブビルドの再利用を有効にする
- QA 用のビルドプロファイルは本番と分ける
- ブートストラップは決定論的にスクリプト化する
- エージェントはブラックボックスに保つ
- PR コメントは 1 件にまとめる
- 早めにスクリーンショットを追加する(視覚確認に非常に有用)
その後、動いたら拡張します:
- iOS を追加
- スクリーンショットを Blob ストレージにアップロード
- より良いセレクタを導入
- 探索的チェックで成功したフローをより決定論的なチェックに変換
まとめ
大規模な AI テストプラットフォームは不要です。Expo と EAS Workflows が次の要素を既に提供してくれます:
- ビルド再利用と repack(高速な反復・最新の JS バンドル)
- 仮想化可能なモバイル CI ワーカー(シミュレータ/エミュレータ利用可)
- ワークフローのオーケストレーション
- GitHub 統合(PR 内で検証を完結)
これらを組み合わせれば、カスタム QA エージェントは驚くほど小さく保てます。TypeScript ベースの AI SDK を使えば柔軟に拡張できますし、このセットアップは「今日すぐに」テンプレートから作って数分で動かせます。
スタートはこちら: callstackincubator/eas-agent-device