はじめに
みなさんこんにちは。インプルの岩崎です。
さて、これまで2つの記事でデザインチェックの内容を取り扱いました。今回は、これら二つのものを使って、本格的なデザインチェックを作っていこうと思います!
まだご覧になっていない方は、ぜひご覧ください。
今回やること
前回は、マルチモーダルAIであるGPT-4-miniを使って、デザインガイドラインの抽出を行いました。そこで今回は、これを使ってデザインカンプの色・フォントデータの抽出、差分の検出まで一気にやらせてみようと思います。
前回の差分検出では、JSONファイルのコンポーネント情報から比較をしていたので、これによりより多くの情報で差分検出をすることができるようになるはずです!
作ってみよう!
準備するもの
まず、今回は次のものを使うので準備していきましょう!
取得できたら、下記のように.envファイルにまとめておきます。
FIGMA_TOKEN=figd_XXXXXXXX #Figma APIキーの取得
FILE_KEY=XXXXXXX #FigmaのファイルIDの取得
OPENAI_API_KEY=sk-proj-XXXXXXXX #OpenAPIキーの取得
Figma APIキーの取得
下記リンクより、Figma Personal Access Token を発行します。
FigmaのファイルのID取得
下記URLのように、FILE_IDの部分の文字列を抽出します。URLでは figma.com/file/FILE_ID としていますが、fileの部分は、デザインファイルの場合design、FigJamの場合はboard、など違いますので、ご注意ください。
https://www.figma.com/file/<span class="bold-blue">FILE_ID</span>/Your-Design-Name
OpenAPIキーの取得
OpenAIのAPIキーも準備しましょう!
APIキーからPNG画像を取得する
まずはAPIキーを使ってPNG画像を取得します。
今回は、デザインカンプとデザインガイドライン、2つとも同じファイルに入っていますので、同時に取り出してしまいます。ファイルの中には、フレームごとに分かれてデザインカンプとデザインガイドラインが入っています。

フレームに名前をつけていたので、それでガイドラインかカンプかを判断させ、抜き出すことにしました。
# 1. ファイル構造を取得
url = f"https://api.figma.com/v1/files/{FILE_KEY}"
response = requests.get(url, headers=headers)
data = response.json()
def find_node_id(node, keywords):
"""ノード名にkeywordsが含まれるものを探す"""
if any(k.lower() in node["name"].lower() for k in keywords):
return node["id"]
if "children" in node:
for child in node["children"]:
nid = find_node_id(child, keywords)
if nid:
return nid
return None
# 2. ガイドライン用ノードを探索
guideline_id = find_node_id(data["document"], ["guideline", "style", "ガイドライン"])
# 3. デザインカンプ用ノードを探索
camp_id = find_node_id(data["document"], ["comp", "design", "カンプ"])
print("✅ ガイドラインID:", guideline_id)
print("✅ デザインカンプID:", camp_id)
# 4. PNG書き出し
if guideline_id and camp_id:
url = f"https://api.figma.com/v1/images/{FILE_KEY}?ids={guideline_id},{camp_id}&format=png"
res = requests.get(url, headers=headers).json()
for node_id, img_url in res["images"].items():
img_data = requests.get(img_url).content
filename = f"output_{node_id.replace(':','-')}.png"
with open(filename, "wb") as f:
f.write(img_data)
print(f"📂 {filename} を保存しました")
else:
print("❌ 対象のノードが見つかりませんでした")
こちらを実行すると、問題なく画像ファイルが書き出されました!
.png?resize=510%2C287&ssl=1)
.png?resize=510%2C287&ssl=1)
プロンプトを作る
それでは、書き出されたファイルを使って差分を検出していきます。
APIキーを使ってGPTに下記のプロンプトを投げていきます。まずは1. デザインガイドラインから色とフォントのルールを抽出(前回の記事でやった部分)、続けて2. デザインカンプからも同様に情報を抽出していきます。この際は、ただ抽出するのではなく、セクションごとにそれぞれの情報を抽出してほしいと細かく指定しました。最後に3. 差分検出をマークダウンで出力ということをしました。
今回の差分は、主に色とフォントに焦点を当てています。(というか、ガイドラインのルールには、それしかメインで載っていませんので・・・!)
prompt = """
あなたはデザインチェックAIです。
1. guideline.png から色とフォントのルールを抽出
2. design.png から以下の情報を抽出
- sectionName: セクション名(TOP / NEWS / ABOUT / CONTACT)
- elements: 各UI要素の配列。要素ごとに以下の情報を含めてください。
- type: 要素の種類(title, text, button, input, line, logo, menu など)
- content: テキストがある場合はその文字列。なければ null
- fontFamily: フォントファミリー。わからない場合は "unknown"
- fontSize: フォントサイズ。わからない場合は "unknown"
- color: カラーコード(例: "#FFFFFF")。わからない場合は "unknown"
### 注意事項
- 不明な場合は必ず "unknown" と出力してください
- デザインをセクション(TOP / NEWS / ABOUT / CONTACT)ごとに分けて出力してください
- 各セクションの主要なUI要素のみを対象にしてください
3. 両者を比較し、差分を **Markdown** 形式で出力してください。
"""
response = client.chat.completions.create(
model="gpt-4o-mini", # 画像対応モデル
messages=[
{"role": "system", "content": "あなたは厳密なデザイン監査AIです。"},
{
"role": "user",
"content": [
{"type": "text", "text": prompt},
{"type": "image_url", "image_url": {"url": f"data:image/png;base64,{guideline_img}"}},
{"type": "image_url", "image_url": {"url": f"data:image/png;base64,{design_img}"}},
],
},
],
)
差分検出を実行してみる
それでは上記プロンプトで実行をしてみましょう。
すると、マークダウンで下記のような表を作ってきてくれました!
### 3. 差分の比較
```markdown
| 要素タイプ | デザイン要素 | ガイドライン番号 | 差分 |
|---------------|-------------------------------|---------------------------|--------------------------------|
| title | ニュース | text-color: #000000 | 一致 |
| text | ニュースのタイトルがこちらになります | text-color: #000000 | 一致 |
| button | MORE | button-text-color: #FFFFFF| 一致 |
| title | Revolutionize With New Technology | text-color: #000000 | 一致 |
| text | 先進技術で革命を起こす | text-color: #000000 | 一致 |
| title | CONTACT | text-color: #000000 | 一致 |
| input | お名前 | font-family: unknown | 不明 |
| input | メールアドレス | font-family: unknown | 不明 |
| input | 本文 | font-family: unknown | 不明 |
| button | SEND | button-text-color: #FFFFFF| 一致 |
今回は、差分検出ではエラーが起きないように作ってきました。
差分の欄を見ると、問題なく「一致」という字が並んでいますね。しかし、一部には「不明」という字も。これは、フォントサイズがマルチモーダルAIの解析では理解できなかったということが原因でした。
まだまだ改善の余地はあるものの、概ね問題なく差分検出できているようです!
さいごに
いかがだったでしょうか?
今回作ったコードはGitHubにもありますから、ぜひご覧ください。
今後はさらに検出の範囲を増やしたり、JSONデータを活用したハイブリット検出システムも作っていきたいと思います。ぜひご覧ください!
本日もご覧いただき、ありがとうございました!