Copilot × Clean Architecture | プロンプト効率化

Copilot × Clean Architecture

エピソード紹介

こんな方へ特におすすめ

  • プロンプトを使って日常のコーディング作業を自動化したい開発者
  • Copilotがプロジェクトの独自ルールを無視したコードを出してくるとお悩みの方
  • チーム開発におけるAIの活用方針をルール化したい方
  • Copilotにもクリーンアーキテクチャで実装させたい方

概要

こんにちは。サイオステクノロジーのはらちゃんです!

GitHub Copilotは非常に便利ですが、そのままコードを生成させると「動くけど、プロジェクトの規約違反になっているコード」を出力してしまい、修正に手間取ることがよくあります。

本シリーズでは、Copilotを活用しつつ、クリーンアーキテクチャに沿って小規模なプロダクト「RepoScanner」を設計・実装した経緯をまとめます。

このエピソードでは、私が実践したCopilotを使った作業を高速化するための「ルールの二層管理」と、AIとの対話ログの適切な運用方法について解説します。

解決方法

ルールは「機械向け」と「人間向け」に分ける

2つのディレクトリを用いてCopilotの実装を調整します。

Copilotにプロジェクトのルールを認識させる際、すべてのルールを長々と一つのドキュメントに書いても、AIは重要なポイントを拾い切れません。

また、ドキュメントは参照され得るが優先度は低いため、ドキュメントだけだと自動適用は保証されません。

そこで、以下の2つのディレクトリを用いて、ルールを役割ごとに分割します。

  1. .github/instructions/
    Copilotへ機械的に適用する「実効ルール」
  2. docs/reference/...
    人間も読むための「解説ルール」

Step1. 機械向けの実効ルール

Copilotへ機械的に適用する「リポジトリ固有の指示/ガードレール」です。

.github/
└── instructions/  

.github/instructions/ 配下には、自動補完やCopilotエージェントの振る舞い制約・除外ルールなどを書きます。

ここは英語で、短く明確に書くのが鉄則です。

英語はAIモデルが最も安定して解釈できる言語であり、指示を短くすることでAIがルールを見落とすのを防ぎます。

実効ルールの活用法

各ファイルの先頭にYAML フロントマター(例: applyToexcludeAgent)を付けることで、「どのファイル群に対してこのルールを適用するか」を細かく制御できます。

これにより、フロントエンドのルールがバックエンドのコード生成に悪影響を与えるのを防げます。

applyTo適用例

ファイル適応範囲
*/*.py特定の拡張子にのみ
src/components/**/*.tsxUIコンポーネント
-**/*.js
-**/*.jsx
複数のパターン

最初に、クリーンアーキテクチャの思想に則らせるために書いたファイルは以下の通りです。

指示には依存方向や禁止事項など実装で守りたい制約を書いています。

この記述により、リポジトリ全体に適用するエージェント向けガードレールの役割を持っています。

記述例

repo-common-guardrails.instructions.md
---
applyTo: "**/*"
---

# Repository Common Guardrails

## Scope

- Apply these rules across the repository for all agents.
- Enforce only the minimum rules required to preserve clean architecture.

## Dependency Direction

- Keep dependency flow from outer layers to inner layers.
- Do not import infrastructure implementations from domain or use-case layers.
- Introduce or use interfaces at boundaries when connecting inner logic to outer implementations.

## Layer Integrity

- Respect declared layer boundaries and dependency direction in existing architecture docs.
- Review imports in modified files to avoid accidental auto-import drift.

## Validation

- Validate changed behavior with targeted checks.
- Run architecture-related checks when dependency direction may have changed.

※もっと .github/instructions/ について詳しく知りたい方はこちらのブログ

Step2. ドキュメントで人間とAI向けの解説ルール

機械向けの短い英語ルールだけでは、背景や具体的なコード例が伝わりません。

そこで、人が読んでも分かりやすいように、補助説明 / 背景を docs/reference/... に日本語で詳細を書きます。

解説ルールの活用法

AIは作業時に、①の短いガードレールで「やってはいけないこと」を把握し、詳細が必要な場合は②のドキュメントを参照しにいきます。

記述例(抜粋)

docs/reference/copilot/clean-architecture.md
# クリーンアーキテクチャ

このプロジェクトでは、変更に強くテストが容易な設計を実現するためにクリーンアーキテクチャを採用しています。コード作業の際は本ドキュメントをガイドラインとしてご参照ください。

## 目次

---

## 1. 詳細ドキュメント

以下はこのドキュメントおよび関連ファイルの責務です。

| ファイル                                                  | 責務                                                                |
| --------------------------------------------------------- | ------------------------------------------------------------------- |
| `docs/reference/copilot/clean-architecture.md`            | 概要・原則・索引                                                    |
| `docs/reference/copilot/clean-architecture-migration.md`  | 実装例、移行手順、`migration-backlog.md` の運用ルール               |
| `docs/reference/copilot/clean-architecture-testing-ci.md` | テスト戦略、CI / lint スニペット、注意点                            |
| `docs/reference/copilot/migration-backlog.md`             | `migration-backlog.md` の運用ルール(作業時の一時ファイル作成手順) |
| `.github/copilot-instructions.md`                         | AI が実行時に参照する全体の実効ルール(Single Source of Truth)     |
| `.github/instructions/*.instructions.md`                  | パス単位の実効ルール(対象ファイル群ごとの行動制限)                |

## 2. AIガードレール総覧

このプロジェクトの AI ガードレールは、次の 2 層で運用します。

- 実効ルール(enforceable): `.github/copilot-instructions.md` と `.github/instructions/*.instructions.md`
- 解説ルール(explanatory): `docs/reference/copilot/*.md`

重要なのは、同じルール本文を両方へ重複記載しないことです。実効ルールの一次ソースは `.github` 側とし、`docs` 側は背景、判断基準、運用手順を説明します。

### 2.1 初期適用範囲(2026-02-20時点)

初期フェーズでは次を優先します。

- repo 共通ルール(依存方向保護、最小変更、検証必須)
- docs ルール(記述品質、リンク整備、SoT更新)

初期適用範囲と `.github/instructions` の対応は次のとおりです。

| 適用範囲  | 実効ルールファイル                                            |
| --------- | ------------------------------------------------------------- |
| repo 共通 | `.github/instructions/repo-common-guardrails.instructions.md` |
| docs      | `.github/instructions/docs-common-guardrails.instructions.md` |

backend / frontend / functions の個別ルールは、運用上の失敗事例が蓄積したタイミングで段階的に追加します。

### 2.2 変更フロー


-- 中略 --


## 7. 各層のつながり(依存方向)

このプロジェクトでは、依存方向を常に外側から内側へ保ちます。

```text
functions(最外部)
  -> infrastructure(外側実装)
    -> use-cases(アプリ手順)
      -> domain(最内部ルール)
```

重要なのは「実行時の呼び出し方向」と「コードの依存方向」を区別することです。

- 実行時の呼び出しは、外側から内側へ流れます(例: HTTP Trigger -> Use Case)。
- コードの依存も、同じく外側から内側へ向けます。
- `domain` / `use-cases` は `infrastructure` 実装を直接 `import` しません。
- 永続化や外部APIは、`domain` 側のインターフェースを `infrastructure` が実装して接続します。

### 接続イメージ

- `domain`: ルールとインターフェース(例: `IUserRepository`)を定義する
- `use-cases`: `domain` のインターフェースを受け取って業務フローを実行する
- `infrastructure`: `domain` のインターフェースを実装してDBや外部サービスへ接続する
- `functions`: エントリポイントで実装を組み立て(DI)て `use-cases` を呼び出す

| 層             | 主な接続先(実行時)       | コード依存 | 補足                                      |
| -------------- | -------------------------- | ---------- | ----------------------------------------- |
| functions      | infrastructure / use-cases | 外 -> 内   | 依存を組み立ててユースケースを起動する    |
| infrastructure | use-cases / domain         | 外 -> 内   | `domain` のインターフェース実装を提供する |
| use-cases      | domain                     | 内側のみ   | 業務フローを実行し、実装詳細は知らない    |
| domain         | なし(最内部)             | 内側のみ   | ルールと抽象のみを持つ                    |

## 8. 用語集(クリーンアーキテクチャ)

| 用語                               | 説明                                                                     |
| ---------------------------------- | ------------------------------------------------------------------------ |
| Entity(エンティティ)             | ドメインの中核概念。ビジネスルールを表すオブジェクト。                   |
| Use Case(ユースケース)           | アプリケーション固有の手順。入力を受けて業務フローを実行する。           |
| Interface(インターフェース)      | 層の境界で依存を抽象化する契約。実装詳細を内側に持ち込まないために使う。 |
| Dependency Direction(依存方向)   | 依存の向き。外側の層が内側へ依存し、内側は外側へ依存しない。             |
| Dependency Inversion(依存性逆転) | 内側が抽象(interface)を定義し、外側がその抽象を実装する考え方。        |
| DI(Dependency Injection)         | 必要な依存を外から注入すること。テスト容易性と交換容易性を高める。       |
| Adapter(アダプター)              | 外部ライブラリやSDKを内側の契約へ合わせる実装。                          |
| Source of Truth(SoT)             | 仕様の一次情報源。構造ルールは `docs/spec` を正とする。                  |

プロンプトの実践

上記の「二層管理」のドキュメントが整備されていると、日常のプロンプトによる指示が劇的に簡略化されます。

作業テンプレート

チャットに以下のような短い指示を投げるだけで、AIは裏でドキュメントを読み込み、正確な実装を行ってくれます。

@workspace @clean-architecture.md に従って、
`ListSnapshotSummariesUseCase` を実装してください。

出力: items, total_count
依存: SnapshotQueryRepository.list_snapshots(limit, offset, filter) -> (items, total)

適用前後

Before

手作業でクリーンアーキテクチャの制約を意識しながら、インターフェースを作成し、ユースケースの骨格を書き、依存関係を修正し、テストを手書きする必要があります。

BEFORE

時間がかかり、ミスも起きやすいです。

After

テンプレート化された短いプロンプトを投げるだけで、プロジェクトの規約に沿った一貫した構造のユースケースと、それに紐づくテストコードが自動生成されます。

AFTER

開発者は「コードを書くこと」から「AIが出力したロジックのレビュー」に集中できるようになります。

+α: AIとの「対話ログ」を記録

設計に関する議論などCopilotとのチャット履歴をdocs/history/...に出力して保持することをお勧めします。

あとでどのような意図で設計をしたかが明確になり、中断作業の再開やレビューのハードルが下がります。

さらに、テンプレートをREADMEに追記すると一貫したログになります。

記録用のマークダウンテンプレート例

# Copilot History

## 目的

- `docs/history/copilot/` は、Copilot 関連の判断履歴を残すための場所です。
- 実装の背景と意思決定の経緯を、後から追跡できる形で記録します。

## 命名ルール

- 形式: `YYYY-MM-DD-<topic>.md`
- 日付は作成日(`YYYY-MM-DD`)を使用します。
- `<topic>` は英小文字のケバブケースで、内容を短く表す語にします。
- 1ファイルにつき1つの主要決定を記録します。

## 記載テンプレート

# <タイトル>

```
- 日付: YYYY-MM-DD
- ステータス: Proposed | Accepted | Superseded
- 対象: (対象範囲。例: docs/history/copilot)
```

## 背景

(なぜこの判断が必要になったか)

## 決定

(何を決めたか)

## 影響

(期待される効果・制約・運用上の注意)

## フォローアップ

(次に必要な作業。なければ「なし」)

まとめるのが面倒な場合は、JSONでそのままのチャット記録を出力することもできます。

Copilot Chatに「JSONでそのままのチャット記録を出力」と指示してください。

出力例

[ { "role": "user", "content": ".github/instructions配下に配置したdocsはCopilotに必ず参照される?どういう仕組み? (See <attachments> above for file contents. You may not need to search or read the file again.)" }, { "role": "assistant", "content": "簡潔に説明します — .github/instructions 配下の docs は「Copilot のリポジトリ固有指示(repository instructions)」として拡張機能に読み込まれ、候補生成時のコンテキストに組み込まれます。仕組みと注意点は以下です。\n\n- どう作用するか...

このように記録を残すことで、レビュアーに対して「Copilotとこういう議論をした結果、この実装になっています」と背景を共有でき、レビューのコミュニケーションコストが大幅に下がります。

ログをマージすべきか

しかし、ここで疑問が生じます。

出力したチャットログは、すべてメインブランチにマージして残すべきなのか?」

結論から言うと、すべてのログを蓄積すべきではありません。 ログには「資産」と「ノイズ」が混在しているため、適切に仕分けて昇華する必要があります。

  1. 作業中ログ
    開発のプロセスが分かる →コードが動いた後は期限切れ
  2. 重要な決定
    なぜこの設計にしたのか分かる資産
  3. ルール
    2から抽出した常に守るべきもの

資産かノイズか…

分類ログの内容アクション
資産 (残すべき)決定の背景ドキュメントや実効ルールに昇華してマージする
採用しなかったアプローチとその拒絶理由ドキュメントに昇華してマージする
プロジェクト独自の固有名詞や概念ドキュメントに昇華してマージする
横断的なルール実効ルールに昇華してマージする
ノイズ (消すべき)コードを見ればわかることPRに記載するか破棄し、ファイルとしては残さない
一時的なタスクリストやエラーの修正過程PRに記載するか破棄し、ファイルとしては残さない

情報の適材適所

どこに残すかでマージの是非を決めるログの内容に応じて、最終的にどこに記載するかを振り分けます。

必要な情報

決定セクションに書かれるようなリポジトリに残すべき内容を指します。

  • 実効ルール(.github/instructions): 常に守るべき横断的なルール
  • README / docs配下: 画面の仕様、詳細な背景、アーキテクチャの決定事項

不要な情報

フォローアップセクションに書かれるような一時的に利用して破棄する内容を指します。

  • GitHub Issue: 未着手の課題
  • PRの説明文: 実装時の思考プロセス(マージ後はPR上に残れば十分)
  • フィーチャーブランチのみ: 単なる作業ログファイル(メインブランチにはマージしない)

ログの昇華ルール

チャットログを整理する際は、以下の2つの問いを自分に投げかけてください。

  • このログの中で、他の開発者が知らないと困る『独自の禁止事項』はある?
    → ある場合は、.github/instructions にルールとして追加する。
  • このログは、将来コードをリファクタリングする時の助けになる?
    → ある場合は docs/history/ にマークダウンとして残す。
    → ない場合は PR の説明欄にコピペして、ログファイル自体は削除する。

まとめ

今回は、Copilotを使って設計やリファクタリングを高速化し、出力のブレを無くすための仕組み作りについて解説しました。

  • ルールの二層管理
    機械向けの短い英語ルールと、人間向けの詳細な日本語ルールを分ける。
  • 短いプロンプトで実行
    ルール基盤を整えれば、指示は極端に短くて済む。
  • ログの保持
    AIとの対話は資産とノイズに分け、必要なルールだけを抽出してリポジトリに還元する。

「Copilotが言うことを聞いてくれない!」と感じている方は、ぜひ指示書の整備とログの昇華から始めてみてください。

開発体験が劇的に向上するはずです!

参考

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。
エンジニア募集中!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です