こんにちは!Algomatic ネオセールスカンパニーで営業AIエージェント 「アポドリ」を開発しているGoです。
2023年にリリースされたCursorのような大規模言語モデルをベースにしたコーディングエージェントが登場して以来、フロントエンドのUI実装を自動化する可能性が現実味を帯びてきました。しかし、単に「これを作って」と命令するだけでは、期待通りの、あるいは「使える」UIの実装がなかなか得られないことが多くあります。
とくに状態設計が不十分な場合、エージェントはデータの型や構造を推測するしかなく、これが不安定な出力や意図しないUI構造、さらにはバグの温床となります。
【目次】
- 【仮説】プロンプト設計の3層構造がUI実装品質を決定する
- 実証的検証の概要と設定
- 【What】 UIは「状態の写像」である - スキーマ定義の効果
- 【How】 デザインルールがUIに「意味とふるまい」を与える - 実装品質の劇的向上
- 【Why】目的・要件がUIに「理由」を与える - 実装判断の最適化
- 仮説の実証:3層構造による設計情報伝達の効果
- 実用的な推奨事項
- まとめ
- エンジニアのみなさん、カジュアル面談させてください
【仮説】プロンプト設計の3層構造がUI実装品質を決定する
このような状況を改善するため、本記事では以下の仮説を提示し、実装検証を通じて実証します。
コーディングエージェントに高品質なUI実装を依頼するためには、「何を(What)」「どう(How)」「なぜ(Why)」という3層構造で情報設計を体系的に提供することが決定的に重要である。
3層構造の詳細
What(何を扱うか):状態構造(データスキーマ)
- TinyBaseなどによる型安全なスキーマ定義
- UIが参照するデータの形を明確化し、実装の骨組みを形成
How(どう見せるか):デザイン原則(設計ルール)
Why(なぜ必要か):目的・要件(意図)
- UIで何を伝えたいか、どんなユーザー体験を目指すのか
- エージェントに適切なUI設計判断のための理由や根拠を提供
この3層構造による設計情報の提供により、エージェントは単なるコード生成ツールから、設計の意図を理解する水準まで向上すると考えました。
本記事では、まずリアクティブローカルストアであるTinyBaseを用いて「状態スキーマ」を定義します。
そのうえで「デザインルール」「実装目的」といった設計情報をコーディングエージェントに的確に提供し、UI実装の品質がどのように向上するか、そしてこれらの情報提供が不可欠である理由を実装検証を通じて実証します。
実証的検証の概要と設定
コーディングエージェントにUI実装を依頼する際に、提供する情報によってどのような出力が得られるかを確認するため、以下の2つのケースで実際にコンポーネントを実装し、品質を定量的・定性的に比較検証しました。
技術スタックとしては、モダンフロントエンド開発の定番であるReactとTypeScriptを使用し、状態管理にはリアクティブローカルストアである TinyBase を利用します。実装対象はユーザー一覧を表示するUIとし、両ケースで同一のスキーマを使用します。
検証環境の詳細
// 共通のTinyBaseスキーマ定義 export const tablesSchema: TablesSchema = { users: { id: { type: 'string' }, name: { type: 'string' }, email: { type: 'string' }, age: { type: 'number' }, role: { type: 'string' }, isActive: { type: 'boolean' }, bio: { type: 'string' }, location: { type: 'string' }, } };
比較ケースの設定
- ケースA:高密度な設計情報
- 提供情報:TinyBaseによる明確なスキーマ定義、構造化モックデータ、デザイン原則(ノーマン原則、オブジェクト指向UI原則など)、具体的な実装目的・要件、WCAG 2.1準拠ガイドライン(ARIAラベル、セマンティックHTML、キーボードナビゲーション等)
- ケースB:低密度な設計情報
- 提供情報:基本的なスキーマ定義のみ、最小限のモックデータ、デザイン原則の明示なし、抽象的な実装指示
【What】 UIは「状態の写像」である - スキーマ定義の効果
モダンフロントエンドにおけるUIは、多くの場合「状態の関数」、すなわち UI = f(state) として表現されます。状態が変化すれば、UIもそれに応じて再描画されるというリアクティブな性質を持っています。したがって、コーディングエージェントに質の高いUIを実装させるためには、まずUIの基となる「状態」が正確に構造化されて定義されている必要があります。
曖昧なサンプルデータのみを提供した場合、エージェントは手探りでデータ構造を解釈することになり、結果として一貫性のないコードや予期しない動作を引き起こす原因となります。
TinyBaseスキーマの実証効果
TinyBaseによる明確なスキーマ定義を提供した場合と、基本的なJSONデータのみを提供した場合で、コーディングエージェントの出力品質を比較しました。その結果、スキーマ定義の有無が以下の3つの重要な領域で決定的な差が生じます。
以下の表は、各効果項目について「スキーマ定義ありの場合にどのような結果が得られたか」と「それによってどのような具体的改善が実現されたか」を示しています。
改善ポイント | スキーマ定義の効果 | 開発者にとってのメリット |
---|---|---|
型の明確化 | データ型が事前に確定 | エラーが発生しない |
構造の明示 | エージェントが迷わず実装 | 開発時間が短縮される |
自動更新 | リアクティブな実装を自動生成 | 複雑なコードが不要 |
型の明確化:TinyBaseでデータ型(文字列、数値、真偽値など)を事前に定義することで、エージェントが「このデータは何型?」と迷うことがなくなり、TypeScriptエラーが発生しなくなります。
構造の明示:スキーマでデータ構造を明確に示すため、エージェントは「このフィールドは何用?」「どんな値が入る?」を推測する必要がなく、確実な実装ができます。
自動更新:TinyBaseの仕組みにより、データが変わると自動的にUIも更新されるため、エージェントは面倒な状態管理コードを書かずに済み、シンプルなコードが生成されます。
TinyBaseの setTablesSchema()
を使えば、UIが扱うデータの構造をコードとして明示的に定義できます。
スキーマは人間にとっての設計図であると同時に、エージェントにとって「このデータはこういう形である」という型安全かつ明確な前提情報となります。
以下に、実際の検証で使用したユーザー情報を扱うストアのスキーマとモックデータをTinyBaseで定義する例を示します。
// state-schema.ts import { createStore } from 'tinybase'; const store = createStore().setTablesSchema({ users: { id: { type: 'string' }, name: { type: 'string' }, email: { type: 'string' }, age: { type: 'number' }, role: { type: 'string' }, isActive: { type: 'boolean' }, bio: { type: 'string' }, location: { type: 'string' }, }, }).setTable('users', { 'user-1': { id: 'user-1', name: '田中太郎', email: 'tanaka@example.com', age: 28, role: 'admin', isActive: true, bio: 'フロントエンド開発者として5年の経験があります。', location: '東京都' }, 'user-2': { id: 'user-2', name: '佐藤花子', email: 'sato@example.com', age: 32, role: 'user', isActive: true, bio: 'デザイナーとしてUI/UXに情熱を注いでいます。', location: '大阪府' }, 'user-3': { id: 'user-3', name: '鈴木一郎', email: 'suzuki@example.com', age: 25, role: 'user', isActive: false, bio: 'バックエンド開発に興味があります。', location: '福岡県' }, });
このような明確な構造定義があることで、エージェントはデータの型推論に悩むことなく、正確なUIコンポーネントを構築するための「足場」を得られます。
【How】 デザインルールがUIに「意味とふるまい」を与える - 実装品質の劇的向上
状態のスキーマが「何を扱うか」というUIの骨格を定義する一方で、UIを「どのように見せるか」「どのように振る舞うべきか」を規定するのがデザインルール(規約)です。
実装検証では、ノーマンの設計原則(アフォーダンス、シグニファイア、フィードバックなど)やオブジェクト指向UI(OOUI)原則を明示的に提供することで、UI実装の品質がどのように向上するのかを検証しました。
検証で使用した具体的なデザインルール
本検証では、以下の2つの体系的なデザインルールをコーディングエージェントに提供します。
1. ノーマン原則に基づくUI/UXデザイン規約
ドナルド・ノーマンの「誰のためのデザイン?」で提唱された設計原則を体系化したデザインガイドラインをエージェントに提供しました。以下に主要な原則の概要を示します。
ノーマン原則の主要項目(クリックで詳細表示)
発見可能性 (Discoverability) - ユーザーが操作方法を直感的に発見できるデザイン - 要素の見た目から機能や操作方法を推測可能にする
アフォーダンス (Affordance)
- UI要素の機能を視覚的に暗示する設計
- 例:ボタンは押せることが分かるデザイン、リンクは青色+下線で区別
シグニファイア (Signifier) - 操作方法を明示的に示すデザイン要素 - 色、形、ラベルによる操作手がかりの提供
マッピング (Mapping) - 操作と結果の論理的・空間的対応関係 - 例:フォーム入力欄の直後に送信ボタン配置、矢印アイコンの直感的な方向性
フィードバック (Feedback) - 全ての操作に対する即座の視覚的反応 - 例:ボタン押下時の色変化、ローディングアニメーション、成功メッセージ
制約 (Constraints) - 誤操作防止のための設計的制限 - 例:必須項目未入力時のボタン非活性化、確認ダイアログ、バリデーション
エラー防止・処理 - エラーを起こさせない設計と、発生時の適切な対処 - 例:具体的なエラーメッセージ、Undo機能、入力内容保持
注記: 上記は実際にエージェントに提供したデザインガイドラインの要約版です。実際の検証では、各原則について具体的な実装例や注意点を含む詳細なガイドライン(約2,000文字)を提供しています。
2. オブジェクト指向UI(OOUI)デザインガイドライン
本検証では、上野学氏の「オブジェクト指向UIデザイン」で提唱されたOOUI原則を体系化したガイドラインも併せて提供しました。以下に主要な原則の概要を示します。
OOUI原則の主要項目(クリックで詳細表示)
オブジェクトの抽出と明確化 - 主要な情報オブジェクト(エンティティ)の早期提示 - ユーザーのメンタルモデルに基づくオブジェクト定義
直接的な操作と知覚可能性 - オブジェクトの視覚的表現(アイコン、ウィンドウ、テキスト等) - 現実世界の操作モデルに近い直感的インタラクション
「オブジェクト選択 → アクション選択」の操作順序 - 「名詞 → 動詞」の自然な操作フロー - モードレスなインタラクションの実現
モードレスなインタラクション - 即座のフィードバック提供 - 自由な順序での作業実行
オブジェクトの性質と状態の体現 - オブジェクトの視覚的状態表現 - 情報の操作対象としての明確化
オブジェクトに基づいたナビゲーション - 関連オブジェクトへの論理的導線 - 名詞形でのナビゲーション項目表現
ビューの設計 - コレクションビューとシングルビューの適切な使い分け - オブジェクト中心のレイアウトパターン
注記: 上記は実際にエージェントに提供したOOUIガイドラインの要約版です。実際の検証では、各原則について具体的な実装指針や注意点を含む詳細なガイドライン(約1,500文字)を提供しています。
定量的な実装品質比較の結果
評価項目 | ケースA(ルールあり) | ケースB(ルールなし) | 差異 |
---|---|---|---|
実装の充実度(コード行数) | 344行 | 131行 | 約2.6倍の充実度 |
スタイル定義の豊富さ(CSS定義数) | 30個 | 6個 | 5倍の詳細度 |
アクセシビリティ対応 | 7個 | 0個 | 完全な対応 |
情報構造の階層化 | 4レベル | 2レベル | 2倍の構造化 |
ユーザーインタラクション要素 | 2個 | 1個 | 2倍の操作性 |
WCAG 2.1準拠検証の結果
実装されたUIコンポーネントについて、WCAG 2.1の主要な成功基準に対する詳細な準拠検証を実施しました。
準拠レベル | ケースA(高密度設計情報) | ケースB(低密度設計情報) | 差異 |
---|---|---|---|
レベルA準拠率 | 85% (17/20項目) | 45% (9/20項目) | 40ポイント差 |
レベルAA準拠率 | 75% (3/4項目) | 25% (1/4項目) | 50ポイント差 |
総合準拠率 | 83% | 42% | 41ポイント差 |
主要な検証項目別結果
WCAG 2.1 成功基準 | ケースA | ケースB | 詳細 |
---|---|---|---|
1.1.1 非テキストコンテンツ | ✅ 準拠 | ❌ 不準拠 | 状態アイコンの代替テキスト提供 |
1.3.1 情報及び関係性 | ✅ 準拠 | ❌ 不準拠 | セマンティックHTML、見出し構造 |
1.4.3 コントラスト(最低限) | ✅ 準拠 | ⚠️ 部分準拠 | 色による状態表示の明確性 |
2.1.1 キーボード | ✅ 準拠 | ✅ 準拠 | 基本的なキーボード操作 |
2.4.6 見出し及びラベル | ✅ 準拠 | ❌ 不準拠 | 説明的な見出しとラベル |
4.1.2 名前、役割及び値 | ✅ 準拠 | ❌ 不準拠 | ARIA属性による情報提供 |
この検証により、デザイン原則とアクセシビリティ配慮指針を明示的に提供することで、WCAG 2.1準拠率が約2倍向上することが分かります。
注記: コード行数の増加は、デザインルールに基づいた以下の要素が追加されたことによるものです。
- セマンティックHTMLの適切な使用(
<article>
,<header>
,<footer>
等) - アクセシビリティ属性の充実(
aria-label
,role
等) - 情報階層を明確にする構造化マークアップ
- ユーザーフィードバックのための状態表示要素
- 操作性向上のためのインタラクション要素
これらは単なるコード量の増加ではなく、UI品質の向上に直結する意味のある実装の結果です。
ケースA(高密度の設計情報)の実装特徴
デザイン原則を明示的に指示に含めることで、エージェントは以下のような特徴を持つUIコードを生成しました。
- 情報階層の明確化: 名前は太字で強調、メールアドレスは補助的に表示
- アフォーダンスの実現: 操作可能な要素が視覚的に区別される
- アクセシビリティ配慮: ARIAラベル、セマンティックHTMLの適切な使用
- オブジェクト指向構造: UI構造がオブジェクト単位でまとまる
以下は、ケースAで実装されたUIコードの抜粋例です。
// UserListCaseA.tsx - デザインルールを適用した実装 export const UserListCaseA = () => { const [users, setUsers] = useState<Record<string, Row>>({}); return ( <div className="user-grid" role="list" aria-label="ユーザー一覧"> {Object.entries(users).map(([userId, user]) => ( <article key={userId} className={`user-card ${user.isActive ? 'active' : 'inactive'}`} role="listitem" aria-labelledby={`user-name-${userId}`} > {/* 主情報(名前)の強調 - 情報階層の明確化 */} <header className="user-header"> <h3 id={`user-name-${userId}`} className="user-name"> {user.name} </h3> <span className={`status-badge ${user.isActive ? 'active' : 'inactive'}`} aria-label={`状態: ${user.isActive ? 'アクティブ' : '非アクティブ'}`} > {user.isActive ? '●' : '○'} </span> </header> {/* 補助情報 - 視覚的階層の明確化 */} <div className="user-details"> <p className="user-email"> <span className="label">Email:</span> <a href={`mailto:${user.email}`} className="email-link"> {user.email} </a> </p> <p className="user-role"> <span className="label">Role:</span> <span className={`role-badge ${user.role}`}> {user.role} </span> </p> </div> {/* 操作ボタン - アフォーダンスとシグニファイアの明確化 */} <footer className="user-actions"> <button className="edit-button primary-action" aria-label={`${user.name}さんの情報を編集`} onClick={() => handleEdit(userId)} > 編集 </button> <button className={`toggle-button ${user.isActive ? 'deactivate' : 'activate'}`} aria-label={`${user.name}さんを${user.isActive ? '非アクティブ' : 'アクティブ'}にする`} onClick={() => handleToggleActive(userId)} > {user.isActive ? '無効化' : '有効化'} </button> </footer> </article> ))} </div> ); };
ケースB(低密度の設計情報)の実装特徴
一方、デザインルールを提供しなかった場合、エージェントはスキーマに基づいてデータを表示する最低限のコードは生成できますが、UIとしての意味や意図が反映されにくい結果となりました。
- 情報構造がフラット: 主従や強調がない
- 操作性への配慮不足: ボタンの区別が曖昧
- アクセシビリティ配慮なし: ARIAラベルやセマンティックHTMLの欠如
- 単なるリスト表示: 意味や意図が伝わりにくい
// UserListCaseB.tsx - デザインルールなしの実装 export const UserListCaseB = () => { const [users, setUsers] = useState<Record<string, Row>>({}); return ( <div className="user-list"> {Object.entries(users).map(([userId, user]) => ( <div key={userId} className="user-item"> {/* 情報が平坦に並ぶ */} <div>{user.name} ({user.email})</div> <div>Age: {user.age}, Role: {user.role}</div> <div>Location: {user.location}</div> <div>Status: {user.isActive ? 'Active' : 'Inactive'}</div> {/* 操作要素の区別が曖昧 */} <div> <button onClick={() => console.log('Edit', userId)}> Edit </button> </div> </div> ))} </div> ); };
デザイン原則別の効果分析
デザイン原則 | ケースA | ケースB | 効果の差 |
---|---|---|---|
情報階層 | 🟢 明確(名前強調、補助情報区別) | 🔴 フラット | 大きな差 |
アフォーダンス | 🟢 操作要素が視覚的に区別 | 🟡 区別が曖昧 | 中程度の差 |
アクセシビリティ | 🟢 ARIAラベル、セマンティックHTML | 🔴 配慮なし | 大きな差 |
視覚的魅力 | 🟢 洗練されたデザイン | 🟡 基本的なスタイル | 中程度の差 |
デザインルールを提供するか否かで比較すると、出力されるUI実装は単なる「データ表示」から 「意図を含んだ、構造的で意味のあるUI」 へと質的に変化します。
【Why】目的・要件がUIに「理由」を与える - 実装判断の最適化
UIの目的や、ユーザーがそのUIを使って達成すべきタスクを明確にすることも重要です。「このUIの目的はユーザー情報を素早く確認し、必要に応じて編集することである」といった目的を明示することで、エージェントが適切なUI設計判断を行えるようにしなkればいけません。
実装目的の明確化による効果
ケースA(目的明確)では以下の最適化が実現
- ✅ 名前の強調表示: 確認のために最も重要な情報を視覚的に強調
- ✅ 編集ボタンの適切な配置: 操作への導線を分かりやすく配置
- ✅ 状態の視覚的表示: アクティブ/非アクティブの即座の判別
- ✅ 操作フローの最適化: ユーザーの行動パターンに沿った設計
ケースB(目的不明確)では以下の問題が発生
- ❌ 情報の優先順位なし: 何が重要かが伝わらない
- ❌ 操作導線が不明確: 次に何をすべきかが分からない
- ❌ ユーザー体験への配慮不足: 使いやすさが考慮されていない
仮説の実証:3層構造による設計情報伝達の効果
冒頭で提示した「プロンプト設計の3層構造」仮説について、実装検証を通じてその有効性が実証されています。コーディングエージェントにUI実装を依頼する際のプロンプトは、単なる命令ではなく、「設計図 + 開発ブリーフ」として扱うことで、劇的な品質向上が実現できることが確認されました。
以下の3層構造で設計情報を体系的に提供することの効果が定量的に観測されます。
1. What(何を扱うか):状態構造(データスキーマ)
- TinyBaseの
setTablesSchema()
で定義された構造やTypeScriptの型定義 - 構造化されたモックデータを含める
- UIが参照するデータの形を明確にし、UIの骨組みを形成
実証効果: 型安全性の確保、実装時間の短縮、バグの削減
2. How(どう見せるか):デザイン原則(設計ルール)
- ノーマン原則、OOUI設計ガイドラインなどの指針
- UIの構造、操作性、アクセシビリティ、振る舞い方のルール
- エージェントがUIの意味やふるまいについて判断する基準
実証効果: UI品質の劇的向上(約3倍の実装充実度)、アクセシビリティの確保
3. Why(なぜ必要か):目的・要件(意図)
- UIで何を伝えたいか、どんなユーザー体験を目指すのか
- 何を重視すべきかといった具体的な指示
- エージェントに出力の期待値を示し、適切なUI設計のための理由や根拠
実証効果: ユーザー中心的な設計、操作フローの最適化、情報優先順位の明確化
実用的な推奨事項
これまでの検証で明らかになった3層構造の効果を、実際の開発プロジェクトで活用するための具体的なガイドラインをまとめました。
TinyBaseの活用方法、デザインルールの適用効果、および段階的な実装アプローチについて、検証結果に基づく実践的な推奨事項を提案します。
TinyBaseスキーマ定義の効果
TinyBaseによるスキーマ定義の具体的な効果をまとめました。明確なデータ構造定義がコーディングエージェントの実装品質に与える影響は以下の通りです。
- スキーマファースト設計: データ構造を先に定義することで、UI実装の方向性が明確になる
- 型安全性: TypeScriptとの組み合わせにより、開発時エラーを大幅に削減
- リアクティブ性: 状態変更の自動反映により、UI実装の複雑性が軽減
デザイン原則提供の価値
デザイン原則を明示的に提供することで得られる具体的な効果が明らかです。ノーマン原則とOOUI原則をコーディングエージェントに伝達することで実現される主要な価値は以下の通りです。
- 判断基準の提供: エージェントが「なぜそうするか」を理解できる
- 一貫性の確保: 複数のコンポーネント間での統一感
- アクセシビリティの向上: 明示的な指針により包括的なUIが実現
段階別実装アプローチ
検証で実証された3層構造の効果を実際の開発で活用するため、段階別の具体的なアプローチを整理しました。コーディングエージェントに高品質なUI実装を依頼する際の推奨手順を以下に示します。
段階 | 推奨事項 | 期待効果 |
---|---|---|
スキーマ設計 | TinyBaseなどの型安全なスキーマ定義ツールを活用 | 型安全性、構造明確化 |
デザイン原則 | ノーマン原則(発見可能性、アフォーダンス、フィードバック等)、OOUI原則(オブジェクト選択→アクション選択、モードレス等)を明示 | UI品質向上、一貫性確保 |
目的明確化 | UIの使用目的、ユーザーフロー、期待成果を具体的に説明 | ユーザー中心設計 |
アクセシビリティ | WCAG 2.1準拠ガイドライン、ARIAラベル、セマンティックHTML、キーボードナビゲーション要件を明記 | 包括的なUI実現(83%準拠率達成) |
実践時の注意点
コーディングエージェントにデザインルールを効果的に伝達するためには、以下の点に注意することが重要です。
具体性を重視: 「使いやすく」といった抽象的な指示ではなく、「ボタンは視覚的にボタンと分かるデザインにし、クリックできる要素は他のテキストと明確に区別する」といった具体的な指示を提供することを推奨します。
原則の組み合わせ: ノーマン原則とOOUI原則を組み合わせることで、より包括的なUI設計指針を提供してください。
実装レベルでの指示: 「アフォーダンスを考慮する」といった概念的な指示だけでなく、「必須項目が未入力のうちは送信ボタンを非活性(グレーアウト)にする」といった実装レベルでの具体的な指示を含めることが重要です。
一貫性の確保: 複数のコンポーネントを実装する際は、同じデザインルールセットを継続的に適用することで、アプリケーション全体の一貫性を保つことを推奨します。
まとめ
本記事で提示した「プロンプト設計の3層構造」仮説は、実装検証により明確に実証しています。適切な設計情報を提供することで、コーディングエージェントは単なるコード生成ツールから真の開発パートナーへと変貌します。
TinyBaseによる状態スキーマ定義、ノーマン原則・OOUI原則に基づくデザインルール、そして明確な実装目的の3層構造で設計情報を伝達することで、UI実装はコードの充実さが195%向上し、WCAG準拠率は83% 程度まで向上しました。
この検証では、AI時代のUI開発において「何を作るか」よりも「どう伝えるか」が決定的に重要であると分かります。設計情報は単なる指示ではなく、エージェントの思考フレームワークとして機能し、人間の創造性を忠実にコードへと変換する共通言語となります。
設計情報の構造化伝達は、AI時代のUI開発において有効であり、開発者はより高次の創造的活動に集中できる可能性が高まります。
ぜひ、この記事を参考にして、より良いUIを作ってください。
エンジニアのみなさん、カジュアル面談させてください
AI駆動開発で異次元に開発速度を加速させたいWebエンジニアの方、ぜひ弊カンパニーCTOの菊池とカジュアル面談しましょう!