system-design について
system-designは、検証済みのソフトウェア要件をアーキテクチャやコンポーネントの判断に落とし込む、個人開発者向けスキルです。診断状態に沿って設計不足や過剰設計、統合漏れ、未記録のリスクを特定し、最小限のエンドツーエンド構成を定めます。
主な機能
- 017種類の設計状態を診断
- 02アーキテクチャのトレードオフを明確化
- 03コンポーネントとインターフェースの整理
- 04ADRによる意思決定の記録
- 05統合計画と最小構成の策定
- 06設計成果をファイルに保存
活用シーン
- 01検証済み要件に照らした設計確認
- 02外部との統合漏れの発見
- 03リスクの高い判断と代替案の記録
- 04最初のエンドツーエンド実装経路の決定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jwynia/ agent-skills --skill system-designインストール後、Claude Code で/system-designを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
assets/adr.mdcomponent-map.mddesign-context.mdwalking-skeleton.md詳細
システム設計:検証済みのニーズからアーキテクチャへ
ソフトウェアプロジェクトのシステム設計に関する問題を診断します。個人開発者が、過剰な設計や重要な統合ポイントの見落としを避けながら、検証済みの要件をアーキテクチャの決定、コンポーネント設計、インターフェース定義へと落とし込めるよう支援します。
基本原則
設計は制約から生まれます。アーキテクチャ上の決定は、いずれも何かとのトレードオフです。トレードオフがバグになる前に、明確にしましょう。
状態
状態 SD0:要件が明確でない
症状:
- 要件が明確になる前にアーキテクチャに着手する
- 「作りながら考えます」
- アーキテクチャがどの問題に役立つのか説明できない
- 背景のない設計上の決定
- ニーズを理解する前に技術を選ぶ
重要な質問:
- このシステムはどのような問題を解決しますか?
- 解決策にはどのような制約がありますか?
- システムが必ず実現しなければならないことと、できれば実現したいことは何ですか?
- 要件分析は完了していますか?
対処法:
- 要件分析のスキルに戻る
- 要件分析が大げさに感じられる場合でも、最低限、次のことを行う:
- 解決策には触れず、問題を説明する段落を1つ書く
- システムが必ず行うべきことを3~5個挙げる
- 現実的な制約(時間、スキル、統合)を列挙する
- 何を、なぜ作るのか説明できるまで先に進まない
状態 SD1:設計不足
症状:
- 関心事が分離されていない
- データベーススキーマについて「後で考えます」となる
- データフローやエラー処理について検討していない
- 何に対しても「後でリファクタリングします」と言う
- 各要素がどうつながるのか、全体像を把握せずに構築する
重要な質問:
- X が失敗したらどうなりますか?(エラーケース)
- データはどこから来て、どこへ向かいますか?
- どのような変更が起こりそうですか?それが起きたら何が壊れますか?
- 最も複雑な処理は何ですか?その仕組みを検討しましたか?
- 誰かにアーキテクチャを説明するとしたら、説明できますか?
対処法:
- データフローのマッピング:データの入口から出口まで追跡する
- 重要な経路についてエラーケースを列挙する
- 変更の可能性を評価する:何が安定していて、何が変わりやすいか?
- コンポーネントを特定する:主な構成要素は何か?
- コンポーネントマップのテンプレートを使う(簡易版でも可)
状態 SD2:過剰設計
症状:
- 仮定上の将来に備えて抽象化する
- 「いつか必要になるかもしれない」という理由で決定する
- 個人プロジェクトにマイクロサービスを導入する
- 解決する問題がないのにパターンを使う
- 変わる予定のないものまで設定可能にする
- 価値をもたらさず複雑さだけを増すフレームワークを選ぶ
重要な質問:
- この抽象化は、今日どのような問題を解決しますか?
- 実際のユーザーに向けて設計していますか。それとも想像上のユーザーに向けて設計していますか?
- 機能するものの中で、最もシンプルなものは何ですか?
- この複雑さのうち、現在の問題を解決しているものと、仮定上の問題を解決しているものはそれぞれどれくらいですか?
- この柔軟性が必要になると確信できますか?
対処法:
- YAGNI の監査:仮定上のニーズに応えるものを見つける
- 複雑さの予算:注力する部分を決め、それ以外はシンプルにする
- 「何が壊れるか」テスト:もっとシンプルにした場合、実際に何が失敗するかを考える
- 抽象化の数を数える:それぞれにコストがかかる
- 3回のルール:パターンを3回確認するまでは抽象化しない
状態 SD3:統合ポイントの欠落
症状:
- 何と接続するかを考慮せずに、単独で構築している
- クライアントを考慮せずに API を設計している
- 認証、ロギング、デプロイについて考えていない
- 「接続方法は後で考えます」
- 外部依存関係の発見が遅れている
主な質問:
- このコンポーネントには、外部から何が必要ですか?
- 外部のシステムには、このコンポーネントから何が必要ですか?
- システムへのデータの出入りは、どのように行われますか?
- 認証、ロギング、モニタリング、デプロイはどうしますか?
- このコンポーネントは、どの外部サービスに依存していますか?
介入策:
- 重要な境界について、インターフェースファーストで設計する
- 依存関係を洗い出す:外部依存は何ですか?
- 統合チェックリスト:認証、設定、ロギング、エラー、デプロイ
- 境界を特定する:コードはどこで外部と接しますか?
- 外部統合のセクションを含む Component Map テンプレートを使用する
状態 SD4:リスクの高い決定が特定されていない
症状:
- 明示的なアーキテクチャ決定記録がない
- 他の選択肢ではなく、この方法を選んだ理由を説明できない
- 決定が暗黙のうちに、または既定の選択肢として行われている
- 変更にかかるコストを把握していない
- 「慣れている方法を選んだだけです」
主な質問:
- 変更に多大なコストがかかる決定はどれですか?
- 他の選択肢ではなく、この方法を選んだのはなぜですか?
- どのような場合に、この決定は誤りとなりますか?
- 知識ではなく、前提に頼っている箇所はどこですか?
- 最も不確実な決定はどれですか?
介入策:
- 重要な決定について ADR(アーキテクチャ決定記録)を作成する
- 変更コストを評価する:容易/中程度/困難
- 検証方法を含む前提の記録を作成する
- 決定事項を監査する:すべての技術やパターンの選択とその理由を列挙する
- 変更すると大きな負担になる決定には、ADR テンプレートを使用する
状態 SD5:ウォーキングスケルトンがない
症状:
- 統合する前に、すべてのコンポーネントの設計を完成させている
- システム全体を通るエンドツーエンドの経路がない
- 複数の要素が連携して動作する様子をデモできない
- 水平方向に構築している(まずレイヤー 1 をすべて作り、次にレイヤー 2 をすべて作る)
- 「すべての準備が整う」まで統合を先送りしている
主な質問:
- システム全体を通る、最も小さな経路は何ですか?
- 何か1つでもエンドツーエンドで動作する様子をデモできますか?
- どの要素を最初に接続する必要がありますか?
- アーキテクチャが妥当だと、何によって検証できますか?
- 最もリスクの高い統合は何ですか?早期にテストできますか?
介入策:
- ウォーキングスケルトンを定義する:最小限のエンドツーエンド経路
- 統合の順序を計画する:何を最初に接続しますか?
- 最初の垂直スライスを特定する
- リスク優先で統合する:リスクの高い接続を早期に検証する
- Walking Skeleton テンプレートを使用する
状態 SD6:設計が検証済み
症状:
- アーキテクチャが、過剰なものを加えずに要件を満たしている
- リスクの高い決定が、根拠とともに記録されている
- 統合ポイントが特定されている
- ウォーキングスケルトンが定義されている
- 実装に向けた明確な道筋がある
指標:
- アーキテクチャを誰かに説明すれば、その理由も理解してもらえる
- 誤っている可能性のある決定と、それを明らかにする方法を把握している
- 最初に何を構築するか、またその理由を特定している
- 複雑さが仮定上の要件ではなく、現在のニーズによって正当化されている
次のステップ: ウォーキングスケルトンから実装を開始する
診断プロセス
システム設計を始める際(要件が明確になった後):
- 要件がそろっていることを確認する - RA5 に到達していない場合は、戻る
- 状態の症状に注意を払う - 現在の設計上の考え方に当てはまる状態はどれですか?
- 最も初期の問題状態から始める - 先に進みすぎない
- 主な質問をする - 該当する状態の質問を使う
- 介入策を適用する - 演習とテンプレートに取り組む
- 成果物を作成する - 重要な決定を記録する
- ウォーキングスケルトンを定義する - 最初に何を構築するか把握する
フェーズ別の主な質問
要件の取り込み
- 検証済みの要件はありますか?
- 重要な品質特性は何ですか?(シンプルさ、パフォーマンス、柔軟性)
- ソリューションに対する実際の制約は何ですか?
アーキテクチャの意思決定
- どの決定を覆すには多大なコストがかかりますか?
- それぞれの決定にはどのような選択肢がありますか?
- それぞれの選択肢にはどのようなトレードオフがありますか?
- 他の選択肢ではなく、この選択肢を選ぶ理由は何ですか?
コンポーネント設計
- 主なコンポーネントは何ですか?
- 各コンポーネントの責任は何ですか?
- コンポーネント同士はどのように通信しますか?
- 境界はどこにありますか?
統合計画
- 統合ポイントはどこですか?
- 各統合ポイントで何が問題になる可能性がありますか?
- エンドツーエンドで最も薄い経路は何ですか?
- 最初に何を構築し、統合すべきですか?
アンチパターン
アーキテクチャの空中楼閣
問題: 必要になることのない規模、柔軟性、拡張性を想定して設計すること。週末のプロジェクトにマイクロサービスを導入すること。ファクトリーを作るファクトリーを作ること。 対策: YAGNI の観点で見直します。抽象化ごとに「これは今日、どんな問題を解決するのか?」と問いかけます。答えに「万が一に備えて」が含まれるなら、先送りを検討します。現在のニーズに合わせて構築しましょう。
暗黙の意思決定
問題: 偶然に任せたアーキテクチャです。トレードオフを理解せず、既定の選択肢を採用したり、チュートリアルをそのまま模倣したりすること。「チュートリアルで使われていたから X を使った」という状態です。 対策: 覆すのに多大なコストがかかる決定には ADR を作成します。「他の選択肢ではなく、これを選ぶ理由は?」に答えられないなら、まだ決定できていません。
ビッグバン統合
問題: すべてのコンポーネントを個別に構築してから、最後に接続しようとすること。「すべての準備が整ったらつなぎ込みます」という考え方です。 対策: まずウォーキングスケルトンを作ります。すべてのレイヤーに触れる、最も薄い経路です。機能を作り込む前に、統合が機能することを確認します。早い段階から頻繁に統合しましょう。
金づち症候群
問題: 適合性に関係なく、使い慣れた技術を使うこと。「React を知っているから、この CLI ツールにも React を使う」という考え方です。適切さよりも使い慣れていることを優先します。 対策: 技術を問題に合わせます。この状況で本当に必要なものは何でしょうか?使い慣れているかどうかではなく、制約に基づいて選択します。選択理由を正直に考えましょう。
時期尚早な最適化
問題: 実際には存在しないパフォーマンス問題に備えて設計すること。あらゆるものをキャッシュすること。どこでも非同期処理にすること。必要のない速度のために複雑さを持ち込むこと。 対策: まず明瞭さを重視して設計します。パフォーマンスが本当に重要な箇所(通常は全体の一部)を特定し、その部分を最適化します。最適化する前に計測しましょう。
依存関係の否認
問題: 外部依存関係や統合要件を認識しないまま、問題が発生するまで放置すること。「API については後で考えます」という状態です。 対策: 早い段階で統合チェックリストを作成します。どの外部サービスが必要ですか?何を設定する必要がありますか?何が失敗する可能性がありますか?境界を把握しましょう。
履歴書のための開発
問題: 問題への適合性ではなく、学びたいという理由で技術を選ぶこと。学習プロジェクトを実際のプロジェクトに見せかけることです。 対策: 正直に考えましょう。学習が目的なら、それでも構いません。ただし、そのコストを認識しましょう。構築が目的なら、問題に適した、地味で実績のある技術を選びましょう。
ヘルスチェックの質問
システム設計中に、自分自身に問いかけてください。
- この設計は、過剰な要素を加えずに要件を満たしていますか?
- 覆すのに多大なコストがかかる決定は何ですか?文書化されていますか?
- うまく機能する最もシンプルなものは何ですか?
- 統合ポイントはどこですか?何が問題になる可能性がありますか?
- アーキテクチャが機能することを実証するウォーキングスケルトンを構築できますか?
- 今日の問題に対応していますか、それとも仮定上の将来に備えていますか?
- 他の選択肢ではなく、この技術/パターンを選ぶ理由は何ですか?
- 誰かに説明するとしたら、納得してもらえる内容ですか?
やり取りの例
開発者:「静的サイトジェネレーターの要件は決まりました。次はアーキテクチャを考える必要があります。」
進め方:
- 要件があるか確認します:「要件分析で明らかになった主なニーズは何ですか?」
- 開発者が回答します:「Markdown を HTML に変換すること、フロントマターに対応すること、ディレクトリに出力することです」
- 過剰設計の兆候がないか確認します:「プラグイン、テーマ、拡張性について考えていますか?」
- 開発者:「プラグインシステムを検討していました……」
- State SD2(過剰設計)を特定します:「現在の問題にプラグインは必要ですか?最もシンプルな方法、つまり Markdown から HTML への変換だけにした場合、どうなりますか?」
- よりシンプルな設計へ導きます:「今作っているものを文書化して、プラグインは『再検討する条件』の項目として記録しましょう」
- 重要な決定について ADR を作成します:Markdown パーサーの選択、ファイル構成、ビルドプロセス
- ウォーキングスケルトンを定義します:「最も細い経路は何ですか?Markdown ファイル 1 つから HTML ファイル 1 つを生成することでしょうか?」
出力の永続化
このスキルでは、作業をセッションをまたいで保持できるよう、主な出力をファイルに書き込みます。
出力先の確認
他の作業を始める前に、次のことを行います。
- プロジェクト内に
context/output-config.mdがあるか確認します - ファイルがある場合、このスキルの項目を探します
- ファイルがない場合、またはこのスキルの項目がない場合は、まずユーザーに尋ねます:
- 「システム設計の出力はどこに保存すればよいですか?」
- 候補として
docs/design/またはdocs/architecture/を提案します
- ユーザーの希望を保存します
主な出力
このスキルでは、次の成果物を永続化します:
- 設計コンテキストの概要
- アーキテクチャ決定記録(ADR)
- コンポーネントマップ
- ウォーキングスケルトンの定義
- 検証済み設計ドキュメント
会話とファイルの使い分け
| ファイルに保存 | 会話に残す |
|---|---|
| ADR | トレードオフの検討 |
| コンポーネントマップ | インターフェースの反復 |
| ウォーキングスケルトン | ビルド順序の議論 |
| 設計コンテキスト | 制約の明確化 |
ファイル名
パターン:概要には design-{project-name}.md、ADR には adr/ フォルダーを使用します
例:design-static-site-generator.md、adr/001-markdown-parser-choice.md
行わないこと
- 実装コードは書きません
- 要件を飛ばしません(不明確な場合は requirements-analysis に差し戻します)
- 仮定上のニーズに対する過剰設計を推奨しません
- 暗黙の決定を文書化しないままにしません
- ウォーキングスケルトンを定義せずに設計を承認しません
- 診断し、問いかけ、導きます。決定するのは開発者です
requirements-analysis との連携
| requirements-analysis の出力 | system-design への入力 |
|---|---|
| 問題の記述 | 設計コンテキスト:解決する課題 |
| ニーズの階層 | アーキテクチャがサポートすべきこと |
| 制約の一覧 | 設計上の選択肢に対する絶対的な制限 |
| 検証済み要件 | すべての設計判断の基盤 |
requirements-analysis から引き継ぐ条件:
- 解決策を含めずに問題が明確に記述されている
- ニーズが具体的で検証可能である
- 制約が一覧化されている(実際の制約か、想定上の制約かを区別)
- V1 の定義が明示され、スコープが限定されている
他のスキルとの連携
| スキル | タイミング | 連携内容 |
|---|---|---|
| requirements-analysis | 要件の検証後 | 設計への主な入力 |
| brainstorming | 複数のアーキテクチャが有力な場合 | 決定前にアプローチを検討 |
| research | 技術的な決定に調査が必要な場合 | ADR の作成前に調査 |
参考資料
このスキルは、次の概念を実践に活用します:
references/development-process.md(アーキテクチャのトレードオフの三角形、ADR、品質特性)- ウォーキングスケルトンのパターン(Alistair Cockburn)
- YAGNI の原則(エクストリームプログラミング)
- アーキテクチャ決定記録(Michael Nygard)