AI駆動開発

Colorism v2: 色彩学習アプリを作り直した話

はじめに

2025年9月に、Kiro と Cursor を使った仕様駆動開発の記事を書きました。その中で作ったアプリのひとつが、色彩学習アプリ Colorism です。当時は「6色を選ぶと世界が変わる」体験はできたものの、正直、中身は薄く、学習アプリとしては未完成でした。

半年ほど経ち、Colorism は v2 として全面的に作り直し、2026年6月に本番公開しました。今回はその開発記です。色彩学習としての中身をどう厚くしたか、なぜ作り直したのか、どこで苦労したか。あわせて、複数のサブエージェントに実装と検証を分担させた進め方にも触れます。

AI駆動開発シリーズ — 本記事は Kiro×Cursor 仕様駆動開発 で作り始めた Colorism の v2 開発記です。読む順は 学習ハブ(/learn/)、完成物は Colorism v2 アプリ を参照してください。

v1でうまくいったことと、限界

v1(Kiro + Cursor で仕上げた版)で資産になったのは、主に「体験」と「技術の土台」でした。6色を選ぶとヒーロー画像やフォトギャラリーが変わるブランド体験、色相環や色彩心理学のインタラクティブ UI、Next.js App Router + Tailwind + Zustand という構成は、v2 でもそのまま活かしています。

  • 6色グローバルテーマ
    unified-colors.ts で全画面の色体験を統一
  • ヒーロースライダー
    選択色 × Unsplash。切替時のクロスフェードも v2 で改良
  • インタラクティブ図解
    色相環・色温度・色彩心理。ただし v1 ではホーム常設で説明が追いつかない
  • ドキュメント文化
    設計・要件の蓄積。v2 では docs を正本に一本化

一方で、v1 を触っていて「学習アプリとしては物足りない」と感じる点もはっきりしていました。

  1. コンテンツが UI の付属物になっていて、カリキュラムとして設計されていない
  2. リッチな TypeScript の DB と UI 内ハードコードの二重管理で、改善が線形に進まない
  3. 学習・作成・ツール・ギャラリーが並列メニューで、前提知識や到達目標が見えない
  4. 練習モードは問題数が少なく、難易度切替時の「次の問題」バグも残っていた
  5. 色彩検定対策の深度が足りない(色覚シミュレーション程度)
  6. color-practice-mode.tsx が約2,200行と巨大化し、改修コストが高い

見た目は豊かでも中身が薄い学習サイトではなく、初学者から検定・実務まで段階的に深まる「色彩の学習プラットフォーム」をつくる──これが v2 の目標です。

Colorism v2で目指したもの

v2 は、Cursor のエージェントモードで AI 駆動開発を行いました。v1 から意図的に継承したのは6色選択とヒーローだけで、それ以外はアーキテクチャとコンテンツモデルを先に定義し直しています。2026年6月公開時点での到達点はこんな感じです。

領域v2 の到達点
学習6コース・29レッスン(MDX)。各レッスンにミニクイズ
図解色相環・Kelvin スケール・感情マップ等をレッスン内 Interactive に配置
練習統一クイズエンジン・218問(4択・正誤・並べ替え・配色識別ほか)
検定対策/cert を新設。用語72語・ドリル・模擬テスト
作成/create パレット(5色生成・保存・CSS/HEX エクスポート)
ツール変換・コントラスト・色覚シミュレーション
品質WCAG 2.1 AA 目標・Lighthouse 85+・v1 URL 308 リダイレクト

軸にしたのは Learn first(ツールやギャラリーは学習の補助)、Single source of truth(表示テキストは MDX/JSON のみ)、Show, then tell(説明の直後に図解やインタラクション)の3つです。未実装や β 機能はラベルで正直に示す、というのも v2 で明文化しました。

開発の進め方

v1 のときと同様、仕様駆動の考え方は続けています。ただし v2 ではプロジェクト内のドキュメントを唯一の正本にして、Phase 0(基盤)→ Phase 1(学習コア)→ Phase 2(コンテンツ)→ Phase 2.5(図解)→ Phase 3(練習・検定)→ Phase 4(SEO・a11y・リダイレクト)と、フェーズごとに出口条件(その段階を終えて次へ進む前の完了条件)を決めて進めました。

  • プロジェクト憲章・要件・機能仕様・UI 設計・アーキテクチャを先に書く
  • 実装計画書で Phase とタスクを分解し、完了ごとにドキュメントを更新
  • 意思決定は decisions.md に ADR(Architecture Decision Record=決定記録)形式で残す(D1, D2 … と通し番号)
  • 不具合は issue ログに IR(Issue Resolution=不具合・手戻りの解決記録)として IR-001 以降で時系列記録
  • 実装は Cursor のエージェントが主担当。人間はレビュー・方針決定・コンテンツ監修

v1 では Kiro で仕様を起こして Cursor に引き継ぐ流れでしたが、v2 は最初から Cursor 単独で docs を読み込ませながら進めました。Kiro の Specs/Vibe 消費や UI 一貫性の問題は v1 の記事で書いた通りで、v2 では .cursor/rules とドキュメントの更新で一貫性を保つ方針に寄せています。

サブエージェントに実装と検証を分担させる

今回いちばん「やってよかった」と思っているのが、これです。v2 では1体のエージェントに全部やらせるのではなく、Cursor のサブエージェントを使って、調査・実装・検証を別々のエージェントに分けて回しました。簡単なハーネス(足場)を組むようなイメージです。

なぜ分けたか。理由はシンプルで、同じエージェントは自分が書いたものを自分で甘く採点しがちだからです。実装したエージェントに「レビューして」と頼んでも、どうしても「だいたい合ってます」になりやすい。そこで、実装と検証で文脈を切り、独立したエージェントにチェックさせるようにしました。

特に効いたのが、ドキュメントと実装の棚卸しです。本番公開後、「ドキュメントと実装がズレていないか」を確かめるために、観点を分けた4体のサブエージェントを独立に起動して、それぞれの結果を統合しました。

エージェント観点
A実装(src / content)を正として、docs の数値・契約・表示名のズレを検出
B.cursor/rules(プロジェクト規約)の遵守チェック
CAGENTS・CI・検証スクリプトの横断整合
Dドキュメント体系そのものの構造・運用観点の妥当性

各エージェントが Critical / Minor / OK で指摘を出し、それを優先度(P0〜)で1枚に統合 → 直す → また4体で再監査、というループを何度か回しました。前提として、機械的な検証はあらかじめ緑にしておきます。

npm run validate:lessons   # レッスン MDX(29本 / cert-prep 9)
npm run validate:quiz      # クイズ(218問)
npm run audit:cq           # コンテンツ品質(29/29)
npm run check:doc-sync     # doc と実装の数値同期
npm run test:unit:light    # ユニット(軽量モード)

自動チェックが緑でも、「02 のレッスン数が古い」「ルートのラベルがハードコードのまま」「索引 doc に新しい Phase が載っていない」みたいな、人間が読んで初めて気づくズレは必ず残ります。そこを4観点で炙り出して潰していった感じです。1回目の監査がいちばん収穫が多く、2回目以降は残課題が一気に小粒になっていきました。

  • 良かった点
    独立起動+観点分担で、単独レビューより見落としが減る。修正→再監査のループで「Critical 0」まで追い込める
  • 注意点
    毎回フル監査すると消費もレポートも膨らむ。回を重ねたら check:doc-sync の拡張+軽量監査に寄せるのが現実的
  • 結局のところ
    最終判断は人間。エージェント同士の相互検証は「人のレビュー時間の肩代わり」であって、置き換えではない

アーキテクチャ上の設計判断

v2 で効いたのは、機能を足す前に「データとルーティングの形」を固定したことです。代表例をいくつか。

コンテンツは MDX 単一ソース

v1 の color-theory-database.ts のような巨大 TS ファイルと、UI 内ハードコードの二重管理をやめ、content/lessons/**/*.mdx と courses.ts に集約しました。レッスン本文・Callout・MiniQuiz・Interactive は MDX 内で宣言し、next-mdx-remote + remark-gfm で GFM の表もそのまま使えます。

## HSL とは

<Callout type="info">色相・彩度・明度の3属性で色を説明します。</Callout>

| 属性 | 英語 | 意味 |
| --- | --- | --- |
| 色相 | Hue | 赤・青などの種類 |

<Interactive id="color-wheel" />

<MiniQuiz id="hsl-basics-01" />

図解はレッスン内に閉じる

v1 ではホームに大型の色相環を常設し、ヘッダーの6色と双方向同期させていました。見た目は派手なんですが、「環の色とサイトテーマが一致しない」という混乱も起きていました。v2 ではホームは入口に徹し、色相環・Kelvin スケール・感情マップは該当レッスン内の Interactive に移動。1レッスン1主役、静止図は補助1枚まで、というルールで読了フローを守っています。

クイズエンジン1本化

練習・検定ドリル・模擬テストは、すべて共通のエンジンと JSON から出題します。v1 の「次の問題」が初級プール固定になるバグは、難易度に関係なく getNextQuestion を通す設計で再発防止しました。問題形式も4択だけでなく正誤・並べ替え・配色識別などに広げ、合計218問まで増やしています。

つまずいた点(紆余曲折)

いやー、今回もスムーズには行かなかったですねー。v1 よりドキュメントは厚いのに、AI 実装特有の「局所は直るけど全体の整合が崩れる」現象は v2 でも何度も発生しました。特に印象に残っているのが次です。

  1. 開発環境の Node 増殖
    useSyncExternalStore の getSnapshot が毎回新オブジェクトを返し、無限再レンダー → Turbopack が暴走。親ディレクトリの lockfile 誤検出も重なった。対策は useState + イベント同期へ戻す、turbopack.root を明示、ブランチ切替後は reinstall 必須
  2. ヘッダー2行化とモバイルナビ欠如
    中幅でナビが消え、本文がヘッダーに被る。v1 同様の1行固定 + ハンバーガーメニューに戻した
  3. Unsplash まわり
    「画像を更新」が1時間キャッシュで同じ結果。紫の検索語 Royal Purple が城・バイク写真を返す。Purple に変えて API は no-store + ランダム page
  4. MDX の GFM 表が素のテキスト表示
    remark-gfm 未設定。比較表だらけのレッスンを書く前に気づけてよかった
  5. 図解 SVG の重なり・クリップ
    viewBox 不足で注釈が切れる、色相環で橙と黄が同時選択になる。単一選択化+生成スクリプトで規約化
  6. 検証ハーネスのメモリ枯渇
    Playwright 一括実行で PC がハング。日常は軽量ユニット + レッスン検証、E2E は CI 手動のみに
  7. /create パレットの URL ロック
    ?color= 付きで6色が固定されヘッダー連動できない。初回マウントのみ適用+スナップショットで6色⇔任意色を往復

これらはすべて issue ログに ID 付きで残してあり、再発防止チェックリストも添えています。v1 の記事では「UI とロジックの一貫性が難しい」と書いて終わりでしたが、v2 では「どの層で起きたか」(React フック、Turbopack、MDX パイプライン、SVG レイアウト、外部 API)まで分解して記録した分、次に似た問題が来たときの当たり所が早くなりました。

v1からv2への機能整理

v1v2 の扱い理由
/learn/theory?section=*6コース29レッスン MDXクエリ1画面 → カリキュラム型
ホーム常設色相環harmony レッスン内 InteractiveShow, then tell
/gallery 専用ホーム下部ギャラリーインスピレーションは入口に集約
/create/design テンプレ未移植(308 → /create)MVP はパレットに集中
ゲーミフィケーション見送り学習深度を優先
ユーザーアカウント未実装localStorage 進捗のみ
/test/* 開発ページ廃止Vitest + 手動チェックへ

v1 ユーザーのブックマーク救済のため、主要 URL は内部で 308 リダイレクトしています。外部 URL へのオープンリダイレクトは禁止し、テストで固定パスのみを検証するルールも決めました。

デプロイとパフォーマンス

本番は Vercel 上の既存ドメインを v2 に付け替えて、https://color.app.bau-haus.com/ で公開しました。v1 のときと同じく、ローカルの dev は重く感じることがありますが、本番ビルドはサクサク動く印象です。Next.js 16 + React 19 + Tailwind CSS 4 という比較的新しいスタックですが、静的生成と MDX コンパイルの組み合わせは Vercel との相性が良かったです。

所感──v1の記事から変わったこと

v1 で書いた「仕様を固めても Vibe コーディングの途中でブラッシュアップは必要」「ルールを増やすと複雑化する」という話は、v2 でもその通りでした。ただ v2 では、仕様書そのものを成果物の一部として扱い、実装と同じ粒度で更新し続けた点が大きく違います。

  • 機能一覧の表に「なぜ捨てたか」まで書いておいたので、AI への指示がブレませんでした
  • 決定ログ(D番号)は、同じ議論を蒸し返しそうになったときに助かりました
  • 不具合ログ(IR番号)のおかげで、エージェントを切り替えても文脈を引き継げました
  • Phase の出口条件を決めていたので、「とりあえず動く」で次に進まずに済みました
  • コンテンツ品質監査では、レッスンの深度を数値化できたのも大きかったです

AI によるコーディングで初速は確実に上がります。一方で、人によるレビュー時間も増える──このバランスは v1 のときより強く実感しました。今回サブエージェントに検証を分担させたのは、まさにこのレビュー負荷を少しでも肩代わりさせたかったからです。それでも最後は人の目が要りますし、特に MDX 執筆・SVG 図解・クイズ JSON のコンテンツ整合は、コードレビューとは別の目が必要でした。個人的には、エージェントに「実装して」と言う前に「ドキュメントのどの節を更新するか」まで指定しておくと、手戻りが減ると感じています。

今回強く感じたのは、生成物そのものより「正本のドキュメントと Phase(開発段階)の境界」「独立した検証エージェント」の有無で、直すスピードも安心感もまるで違うということです。

v1と比べて判断の仕方がどう変わったかは、仕様駆動で分かったことでもう少し具体的に書いています。

得たもの

  • 学習プラットフォームとしての骨格
    2026年6月時点で29レッスン・218問・検定ハブまで一気通貫。v1 では届かなかった「中身の厚さ」
  • v1 資産の選別基準
    「delight は残す・負債は捨てる」を表で可視化

まとめ

Colorism v2 は、v1 の「色を選ぶと世界が変わる」体験を残しつつ、中身を学習プラットフォームとして作り直したプロジェクトです。Kiro から Cursor へ、v1 から v2 へとツールもコードベースも変わりましたが、仕様駆動の考え方自体はむしろ強くなりました。さらに今回は、実装と検証を別々のサブエージェントに分けるという、簡単なハーネス運用も試せました。

これから AI エディタで個人アプリを育てる方には、「ドキュメントを正本にする」「Phase で出口を決める」「不具合を ID で管理する」、そして「検証は独立したエージェントに任せる」あたりが、長期戦では効いてくるのではないかと思います。Colorism はこれからもコンテンツの充実や設定画面など、バックログに積んだ機能を少しずつ足していく予定です。よければ https://color.app.bau-haus.com/ を触ってみてください。フィードバックも頂けると嬉しいです!

✅ シリーズの前編は KiroとCursorを活用した仕様駆動開発。他のチュートリアルや旗艦シリーズは 学習ハブ にまとめています。

この記事で使ったサービス

※ 一部リンクはアフィリエイトを含みます。

シリーズ一覧を見る