実はGitHub Copilotに前提情報を渡すことができる (.github/copilot-instructions.md)

GitHub Copilotの[新しい機能（2024年10月に追加された）](https://github.blog/changelog/2024-10-29-multi-file-editing-code-review-custom-instructions-and-more-for-github-copilot-in-vs-code-october-release-v0-22/#file-based-custom-instructions-enabled-by-default-preview)によって、プロジェクト固有の前提情報やドメイン知識をファイルに記述しておけるようになりました。これによりChatのたびに情報を渡す必要がなくなり、より便利に活用できるようになります。本記事ではその使い方についてまとめます。

## 1. 事前準備

Visual Studio Codeであれば

- （既定で有効になっているので設定作業は不要です）
- 設定からUse Instruction Filesの項目を有効にする

Visual Studioであれば

- 設定からEnable custom instructionsの項目を有効にする

上記設定によりこの機能を使えるようになります。

## 2. ファイルの作り方

AIへの指示をまとめたファイルを「カスタム指示ファイル（Custom Instructions）」と呼びます。これを作ります。

1. リポジトリに`.github/copilot-instructions.md`というパスでファイルを作る
2. Markdown形式で自然言語の指示をファイルに書き込む

この`.github`ディレクトリは、GitHub Actionsの設定ファイルやPull Request / Issueのテンプレートファイルを配置する場所です。したがって、カスタム指示ファイルもソースコードと同じくGitによるバージョン管理が行われ、メンバー間でラクに共有できます。

## 3. ファイルの書き方

基本的なMarkdown形式の書き方でファイルを用意すれば問題ありません。

具体的には以下のような項目を中心に、実際に使いながら情報の不足を補っていくのが良いのかなと思います。

- 技術スタック（バージョン・アーキテクチャ）
- ディレクトリ構成
- ドメイン知識（ビジネスロジック・専門用語）
- コーディング規約（命名規則・コメント）

特に技術スタックのバージョン情報は、例えばVue2とVue3ではフックの名前が変更されておりAIが混同してコードを出力することがあるため、これが防げるだけでも快適さは段違いだと思います。

また[こちらの記事](https://tech.findy.co.jp/entry/2024/12/25/070000)によれば、不要な記述をしない・簡潔に構造的に記述する・曖昧な表現をしないことによってAIに理解されやすくなると述べられています。（ぜひ読んでみてください）

さらに[公式ドキュメント](https://docs.github.com/ja/copilot/customizing-copilot/adding-custom-instructions-for-github-copilot)によれば、以下のような指示は上手く機能しないと述べられております。

- 「応答を作成するときに外部リソースを参照するという要求」
    - 例：URLやファイルパス
- 「特定のスタイルで回答するという指示」
    - 例：フレンドリーに回答してください
- 「常に特定の詳細レベルで応答するという要求」
    - 例：1000文字以内で回答してください

外部リソースを参照できないため、すべての情報を詰め込んだオールインワンなファイルを作る必要がありますね。（コーディング規約とドメイン知識は分離して書くほうが望ましい気がしますが）

## 4. 実際に使ってみた

以下のようなカスタム指示ファイルを作成して、コードを生成させてみました。

```markdown
# 技術スタック
- Python 3.10

# ディレクトリ構成
./
├ utils/
│ └ exceptions.py
└ main.py

# ドメイン知識
- 消費税を20%と定め、小数点以下を切り上げる

# コーディング規則
- コメントは必要に応じて記述し、記述する場合は日本語で記述する
- 関数の引数・戻り値には型を明記する
- 定数はUPPER_SNAKE_CASEで記述する
- メソッド名は動詞から始める
- 数値を扱う変数名には単位がわかるような接尾辞をつける

## エラーハンドリング
エラーハンドリングは以下の原則に従ってください：
- バリデーションエラーは`/utils/exceptions.py`に定義されている「ValidationException」をインポートしてスローする
```

出力されたコードは以下の通りです。

Chatへの指示プロンプトは「Pythonで消費税計算を行う関数を実装してください。入力を定価、出力を税込みの価格とします。」です。

```python
### カスタム指示ファイル「あり」 ###
import math
from utils.exceptions import ValidationException

TAX_RATE: float = 0.20

def calculate_total_price(price_without_tax: float) -> float:
    if price_without_tax < 0:
        raise ValidationException("定価は0以上でなければなりません。")
    
    total_price: float = price_without_tax * (1 + TAX_RATE)
    return math.ceil(total_price)
```

```python
### カスタム指示ファイル「なし」 ###
def calculate_tax_included_price(price, tax_rate=0.10):
    """
    定価に消費税を加算した税込み価格を計算する関数

    :param price: 定価 (float)
    :param tax_rate: 消費税率 (float), デフォルトは10%
    :return: 税込み価格 (float)
    """
    tax_included_price = price * (1 + tax_rate)
    return tax_included_price

# 使用例
price = 1000
tax_included_price = calculate_tax_included_price(price)
print(f"定価: {price}円, 税込み価格: {tax_included_price}円")
```

カスタム指示ファイルをしっかり書くことで、プロジェクトの規約に沿ったコードや、既存の関数・クラスを活用したコードを簡単に生成できそうです。

## 5. まとめ

GitHub Copilotに前提情報を渡す方法について解説しました。Chatで毎回指示を与えても同様のコードを生成できますが、ファイルに1度書いておけば自動的に参照してくれる点が非常に便利です。積極的に活用していきたいです。

## 参考記事

- [GitHub Copilot のカスタム指示の追加 - GitHub Docs](https://docs.github.com/ja/copilot/customizing-copilot/adding-custom-instructions-for-github-copilot)
- [Multi-file editing, code review, custom instructions, and more for GitHub Copilot in VS Code October release (v0.22) - GitHub Blog](https://github.blog/changelog/2024-10-29-multi-file-editing-code-review-custom-instructions-and-more-for-github-copilot-in-vs-code-october-release-v0-22/#file-based-custom-instructions-enabled-by-default-preview)
- [GitHub Copilot in VS Code カスタムインストラクションの設定と効果検証【実践編】 - Findy Tech Blog](https://tech.findy.co.jp/entry/2024/12/25/070000)