目次
はじめに
主にフロントエンド領域の開発を担当している加納英樹と申します。 本日は、Figma→Reactの自動生成の精度向上のために考案した仕組みを公開します。 実運用の効果については、後日別の記事で紹介する予定です。
こちらがまとめになります。
- LLM に一発生成させるのではなく、観測→評価→修正のループを設計することで精度を上げる
- Figma スクショ vs Storybook スクショのピクセル比較を評価軸に、Claudeが自律的にコードを修正し続ける仕組みを構築
- 「ぱっと見わかるズレ」から「ほぼ気にならないズレ」まで改善
- このパターンは Figmaに限らず「観測と評価を設計できる問題」に汎用的に適用できる
背景
フロントエンド開発では Figma のデザインを実装に落とす作業が発生します。LLM を使えばコンポーネントのコードはすぐ出てきます。しかし生成されたコードを Figma と並べると、余白が数 px ズレていたり、ボーダーの色が微妙に違ったりします。
このズレを直すために人間がプロンプトを調整し、また生成して確認して……という作業を繰り返していないでしょうか。
この作業に思いの外工数がかかっていることに気づきました。
課題
問題はプロンプトではありません。フィードバックループが設計・実装されていないことです。
Figma と実装の乖離には、定量的な評価が難しいという問題もあります。「なんとなく合ってる」のか「本当に合っている」のかを判断するのに、これまで人間の目が必要でした。この「評価できない」状態が、ループを回せない根本原因です。
解決策
人間のエンジニアがコードを書くとき、一発で完璧なコードは書きません。書いて、動かして、差分を見て、直す。AI エージェントに同じ仕組みを与えればいいのです。
生成 → 観測(スクリーンショット)→ 評価(diff)→ 分析 → 修正 → 観測 → ...
Figmaスクリーンショット vs Storybook スクリーンショット のピクセル比較を評価軸にして、このループを自動化しました。コマンド一発で Claude が自律的に動きます。
/auto-pilot-figma [FigmaのノードURL] [コンポーネント名] -- max-iterations [繰り返し回数]
ループの全体像:

結果
1回目(初回生成直後)
Figma

実装

diff

一致率 91.3%。diff を見ると、ラベルとフィールドが赤く二重になっています。縦方向にずれているのがわかります。line-height や padding の調整が必要な状態です。
5回目(最終)
Figma

実装

diff

一致率 95.2%。diff の赤みがほぼ消えました。残る差分はフォントレンダリングのアンチエイリアス差のみで、コードで直せる差分は解消しています。
数値で見ると大きな変化はないものの、人間が見た時に「ぱっと見わかるズレ」から「ほぼ気にならないズレ」まで改善していることがわかります。
工夫したところ
FigmaはAIへの指示書として扱う
Figmaのデザインデータには数値的な矛盾が含まれることがあります。「100文字」というラベルが表示されているのに実際のテキストが99文字だったり、コンポーネントのサイズが内部要素の合計と合わなかったりします。
最初の実装では「テキストは正確に100文字にすべき」と考えてストーリーの文字数を調整しました。しかしFigmaのスクリーンショットと比較すると当然99文字と100文字でdiffが出ます。
ここで気づいたのは、Figmaは「デザインデータ」ではなく「AIが実装を生成するための指示書」だということです。スクリーンショット・ノード構造・デザイントークンはすべて生成の根拠となる情報源であり、AIで活用される前提で書かれる必要があります。
そのため、Figma側の不整合の修正をデザイナーに依頼しました。
Figmaとのズレはどうしても出てしまう
上記の修正を入れたとしても、FigmaのキャプチャとStorybookのキャプチャは環境が異なるため、どうしても差分が出てしまいます。同じフォント・同じサイズでも文字の輪郭が微妙に異なり、そのまま画像比較するとノイズとして検知されてしまいます。このノイズが、AIによる修正の判断を妨げることに気づきました。
アンチエイリアスのオプションや実行環境の調整を試みましたが、根本的な解決には至りませんでした。そこで、キャプチャ画像に対してCannyエッジ処理と膨張処理を加え、構造のみに注目して比較する方式を採用しました。
Figma(処理前)

実装(処理前)

Figma(エッジ処理後)

実装(エッジ処理後)

フォントのアンチエイリアスや塗り色の違いが除去され、フォームの構造(枠線・行の配置)だけが白線として現れています。この処理を加えることで、環境差分に引きずられずに構造のズレだけを検出できるようになりました。
考察:実はこれ、貪欲法では?
このループを眺めていると、最適化問題として定式化できることに気づきました。
目的関数: matchRate(s) を最大化する(pass 閾値 ≥ T が制約)
状態: s = (index.tsx, style.module.css, index.stories.tsx) というコード空間の1点
遷移: 各ステップで diff 画像と matchRate をもとに「最も大きな差分原因」を1つ選んで修正する
これはまさに貪欲法の構造です。「今見えている最大の差分を潰す」を繰り返して目的関数を最大化しようとしています。
ただし、貪欲法には既知の弱点があります。
- 局所最適への収束: 余白を直すとボーダーがズレる、といった変数間の干渉が起きます
- 勾配情報が粗い: diff 画像は「どこがズレているか」はわかりますが、「どう直せば改善するか」は LLM の推論に依存しています
- 予算制限: iteration ≤ N という 上限があります。
この性質を理解した上で設計すると、ループの限界も見えてきます。matchRate が高原状態(iteration を重ねても改善が止まる)になったとき、貪欲法では脱出できません。別の探索戦略——たとえば一度悪化を許容して別の解空間を探す——が必要になるかもしれません。
このループの拡張性
「何を観測するか」「どう評価するか」を設計すれば、AI はそのループで自律的に動けます。このパターンは Figma に限りません。
| 場面 | 観測 | 評価 |
|---|---|---|
| Figma → React | Storybook スクリーンショット | ピクセル diff |
| API レスポンス整合 | 実際のレスポンス JSON | スキーマバリデーション |
| テスト修正 | テスト実行結果 | pass/fail |
このパターンを再現することができれば、同様にエージェントの作業精度を向上させることができると考えられます。
本アプローチの成果
体感では工数を半分以上削減できていると感じています。「ぱっと見でわかるズレ」を人間が探して直すという作業がなくなり、Claudeに任せられるようになったのが大きいです。
実運用はこれからのため、正確な工数削減の数値についてはまた別の記事で紹介したいと思います。
参考
- Figma — デザイン・プロトタイピングツール
- React — フレームワーク
- pixelmatch — 画像比較ライブラリ
- Figma REST API — Images — ノード PNG の取得
- Canny エッジ検出 — エッジ検出アルゴリズム
- 膨張処理 — モルフォロジー演算