Design

AI の UI を「それっぽい」で止めない — DESIGN.md に値ではなく役割を書く

AI コーディングエージェントが吐く UI が「いかにも生成」に見えるのは、色や余白の値だけを渡して役割と理由を渡していないからです。DESIGN.md に値・役割・避けるべきパターンを先に固定してエージェントに参照させ、設計の一貫性を保つ運用を、AetherEchoes のトークン実例とともにまとめます。

2026年6月16日 09:07·8 min·SoraEndo
SoSoraEndo2026年6月16日 09:078 min1,897

動画で読む

まず結論 — AI の UI が「それっぽい」止まりなのは、値だけ渡しているから

結論から書きます。AI コーディングエージェント(コードを自律生成する AI ツール)が吐く UI が「いかにも生成」に見えるのは、色や余白の値だけを渡して、その値を「いつ・なぜ使うか」を渡していないからです。#0066CC という 1 行は、リンクの色なのか、ボタンの色なのか、フォーカスリングの色なのかをエージェントに教えてくれません。判断材料が無いまま、エージェントは無難な真ん中を選びます。だから余白も配色もバラつき、平均的な見た目に着地する。

きっかけは Zenn の「DESIGN.md」記事(53able) でした。著者は、色・間隔・形状の値そのものより「なぜそう見せるのか」を Markdown で先に固定し、エージェントに毎回それを参照させる運用を提案しています。私はこれを、自分が AetherEchoes で組んだデザイントークン(色や余白などを名前付きで管理する仕組み)体系と引き比べながら読み、「値より役割を先に書く」という一点は確かに効く、と腑に落ちました。

なぜ token の「値」だけでは足りないのか

トークンは値の名簿ではなく、判断の辞書であるべきです。--accent: #E63946 と書くだけでは、エージェントはその赤を見出しの下線に使ってよいのか、エラー表示に取っておくべきなのか分かりません。

少し前、Cursor に「クリーンなカードを並べて」と頼んだことがあります。出てきたのは、padding が 16px のカードと 20px のカードが混在し、影の強さも 3 段階にバラついた一覧でした。動いてはいる。けれど「クリーン」という言葉が値に翻訳される過程で、エージェントは毎回その場の最適解を選び直していたわけです。指示が抽象語だと、生成のたびに別の解釈が混ざる。これは AI が悪いのではなく、判断の前提を渡していない私の問題でした。この構図は、AI 生成コードを静的スキャンで検証する話 で書いた「動いた、は安全の証明ではない」とよく似ています。動く出力ほど、前提の不在が見えにくい。

DESIGN.md に書く 3 つ — token / 余白スケール / コンポーネント語彙

DESIGN.md に固定すべきは、値そのものではなく「値 + 役割 + 避けるべきパターン」の三点セットです。書く順番にも意味があります。

  1. token に役割を添える: {colors.primary} のような参照名で機械的に扱えるようにしつつ、各値の隣に「リンクと CTA に使う / フォーカスリングには使わない」と一文を書く。値だけの名簿にしない。
  2. 余白スケールを段階で固定する: 4 / 8 / 12 / 16 / 24 のように刻みを決め、「カード内は 16、セクション間は 24」と用途を縛る。これだけで、さっきの 16px と 20px が混ざる事故は消えます。
  3. コンポーネント語彙を Do / Don't で書く: 「premium」「modern」のような形容詞で終わらせず、「角丸は 8px 固定、影は 1 段階だけ、ホバーで影を足さない」と具体に落とす。避けるべきパターンを明記するほど、生成のブレ幅は狭まる。

Zenn の記事も「抽象語だけで終わらせない」点を一番強く押していて、ここは私の実感と一致しました。実装の見た目を「意図どおり」に寄せる話としては、ピクセルパーフェクトを意図の一致として捉え直す話 とも地続きです。

AetherEchoes の実例 — --ink は「本文・主役」、--cat-color は data-cat で解決

私のサイトでは、2026 年 5 月に採択したトークン体系で、値に必ず役割コメントを添えています。たとえば --ink: #0E0E0E には「本文・主役テキスト」、--ink-muted: #6E6E6A には「キャプション・メタ」と書いてある。色を選ぶ側(人でもエージェントでも)は、16 進の数字ではなく --ink-muted という名前で「これはメタ情報の色だ」と判断できます。

部門カラーはもう一歩進めて、5 部門の色を --cat-engineering などで定義しつつ、ページ側は data-cat="design" という属性から --cat-color を解決する形にしています。

--cat-design: #FFB020;
[data-cat="design"] { --cat-color: var(--cat-design); }

こうしておくと、記事ページのヒーロー番号・引用罫・目次のアクティブ色は全部 --cat-color を見るだけでよく、「この記事は design だからオレンジ」という判断をコンポーネント側が持たなくて済みます。値を直接書かせない、役割名だけを参照させる。DESIGN.md の思想を、CSS 変数の解決順でも体現しているわけです。配色の一貫性を別角度から詰めたコントラスト検証を要素×状態×テーマで総当たりする話 とも、根は同じ「状態を取りこぼさない」発想だと思っています。

運用に落とす — DESIGN.md と実装テーマを同じ PR で動かす

DESIGN.md は、作っただけだとすぐ実装と乖離します。だから私は、トークンの値を変えるときは DESIGN.md・Tailwind の @theme・CSS 変数を必ず同じ PR でまとめて触る、というルールにしています。

ドキュメントとコードが別 PR で進むと、片方だけ更新されて「DESIGN.md には残っているのに実装には無い色」が生まれる。これは半年後の自分が一番ハマる罠です。実際、過去の私が書いた token が実装のどこを探しても見つからず、30 分溶かしたことがあります。役割を書いた DESIGN.md は、AI に渡す前提であると同時に、人間のレビュー観点表でもある。ちなみにこの AetherEchoes 自体、記事は AI が下書きを書き、私が公開前に確認・編集して出していて、文章でもコードでも「AI が起稿し、人間が検証して通す」構図は同じです。設計を言葉で先に固定するほど、生成は速くなり、レビューは楽になる。

よくある質問

DESIGN.md と AGENTS.md や README は何が違うのですか?
READMEは人間向けの概要、AGENTS.mdはエージェント向けの作業手順、DESIGN.mdはエージェント向けの「視覚判断の根拠」を担います。同じトークンでも、値だけでなく役割と避けるべきパターンを書く点がDESIGN.mdの役割です。
トークンに値だけ書くと、なぜAIのUIがばらつくのですか?
値だけではAIがその色や余白をどの場面で使うべきか判断できず、生成のたびに無難な解釈を選び直すからです。役割と用途を添えると判断の前提が固定され、padding16pxと20pxが混在するようなブレが減ります。
DESIGN.mdと実装の乖離はどう防げばよいですか?
トークンの値を変えるときは、DESIGN.mdとTailwindのテーマ、CSS変数を必ず同じPRでまとめて触るのが有効です。別PRで進めると片方だけ更新され、ドキュメントにしか存在しない色が生まれて後で混乱します。

参考文献

  1. DESIGN.md — AIにUIの設計判断を渡すための前提ファイル(Zenn / 53able)
  2. Tailwind CSS — Theme variables(@theme でデザイントークンを定義する)
  3. Material Design 3 — Design tokens overview

Reaction

Share

X (Twitter)