AIエージェントに画面を理解させる:Jetpack Compose Semantics設計の実践ガイド

AIエージェントに画面を理解させる:Jetpack Compose Semantics設計の実践ガイド

AIエージェントに画面を理解させる:Jetpack Compose Semantics設計の実践ガイド

はじめに

Jetpack ComposeでAIエージェントやテスト自動化ツールに「このボタンは何をするものか」を正確に理解させるには、Semantics(セマンティクス)の適切な設計が鍵になります。

Composeは内部的に「Semantics Tree」を持っており、アクセシビリティ・UIテスト・自動操作AI(Appium/UIAutomator/MCPなど)が参照する意味構造として機能します。いわばWebのARIAやDOMに相当するものです。

Semanticsの主要属性

contentDescription

アイコンだけのボタンに意味を付与する最も基本的な属性です。

IconButton(
    onClick = onDelete,
    modifier = Modifier.semantics {
        contentDescription = "削除"
    }
) {
    Icon(Icons.Default.Delete, contentDescription = null)
}

AIやアクセシビリティ側には「削除ボタン・クリック可能・Button role」として認識されます。

role

カスタムUIにUI種別を明示します。ただの Box(clickable) だと「クリック可能な何か」になりますが、roleを付けることでButton・Switch・Checkbox・Tabなどの意味が明確になります。

Modifier.semantics {
    role = Role.Button
}

stateDescription

UIの現在状態をAIに伝えます。

Modifier.semantics {
    stateDescription =
        if (subscribed) "購読中"
        else "未購読"
}

testTag

MCP・Appium・自動UIエージェントで最も重要な識別子です。座標・OCR・テキスト変更に依存しない安定した識別が可能になります。

Modifier.testTag("login_button")

UIAutomator連携のための設定

ComposeはView階層を直接作らないため、UIAutomatorから testTag が見えないことがあります。ルートに以下を付けることで解決できます。

Scaffold(
    modifier = Modifier.semantics {
        testTagsAsResourceId = true
    }
)

testTag がresource-id的に認識され、UIAutomatorから直接取得できるようになります。

AIに最も理解されやすい実装パターン

複数の属性を組み合わせるのがベストプラクティスです。

Button(
    onClick = login,
    modifier = Modifier
        .testTag("login_button")
        .semantics {
            contentDescription = "ログイン"
            role = Role.Button
        }
) {
    Text("ログイン")
}
属性 AI理解
testTag 一意識別
contentDescription 意味理解
role UI種別理解
clickable 実行可能理解

複雑なUIを1つの意味にまとめる

アイコン・テキスト・Badgeなど複雑な構成を、AIには1つのボタンとして見せる場合は clearAndSetSemantics を使います。

Modifier.clearAndSetSemantics {
    contentDescription = "商品をカートに追加"
    role = Role.Button
}

内部のネスト構造やアイコン群を無視して、意味だけをAIに渡せます。

Semantics設計でできること

自動操作の安定化

testTagがあれば座標・OCR不要で安定した操作が可能になります。UIのリデザイン後も testTag が同じなら自動化が壊れません。多言語対応にも強くなります。

トークン量の削減

スクリーンショットだけの場合は画像解析に大量トークンが必要ですが、Semantics Treeなら構造化データとして軽量に扱えます。

[
  {"type": "Button", "label": "ログイン"},
  {"type": "TextField", "label": "メール"},
  {"type": "TextField", "label": "パスワード"}
]

長時間の自動操作や大規模な画面解析で特に効果的で、context overflowの抑制にも寄与します。

AIの状態理解

stateDescriptionにより、AIが画面の現在状態を推定して「今は停止中だから再生ボタンを押そう」といった判断ができるようになります。画面をステートマシンとして理解させることが可能です。

MCP連携での構造化解析

Semantics TreeをMCP Serverで取得し、LLMエージェントに渡すことで画面全体の意味理解・次の操作候補の推定・状態遷移解析が可能になります。

Compose UI → Semantics Tree → MCP Server → LLM Agent

Semantics属性の使い分けまとめ

属性 用途
testTag 一意識別
contentDescription 意味
role UI種別
stateDescription 状態
collectionInfo リスト構造
traversalIndex ナビゲーション順
customActions AI用カスタム操作

まとめ

Composeは「見た目」と「意味」を分離できます。Semantics設計の本質は、人間向けUIとAI向け意味構造を独立して設計できる点にあります。

AIエージェント・MCP・UIAutomator・自動E2Eテストを活用するなら、各コンポーネントへの以下の標準化が高い投資対効果をもたらします。

Modifier
    .testTag(...)
    .semantics {
        contentDescription = ...
        role = ...
    }

色・位置・サイズより「何のボタンか・押すと何が起きるか・今どんな状態か」をSemanticsで渡す——これがAIに強いUI設計の核心です。