はじめに
GitHub Copilotを使ったバイブコーディング中に、しばしば不便を感じることがあります。例えば、下記のようなことが発生します。
- コーディング規約の不一致
typescript
// Copilotが生成したコード
function getUserData(id) { // ❌ TypeScript必須なのに型がない
return fetch('/api/users/' + id) // ❌ テンプレートリテラルを使うルール
}
// チームの規約に沿った正しいコード
async function getUserData(id: string): Promise<UserData> {
return await fetch(`/api/users/${id}`)
}
- 同じ説明を何度も繰り返す
開発者: 「Reactコンポーネントを作って」
GitHub Copilot: 「クラスコンポーネントを生成しました」
開発者: 「いや、関数コンポーネントで、TypeScript使って、propsは型定義して...」
# 次のコンポーネントでも...
開発者: 「また別のコンポーネントを...」
GitHub Copilot: 「クラスコンポーネントを...」
開発者: 「だから関数コンポーネントで!」
- プロジェクト固有の知識不足
開発者: 「ユーザー認証の実装を手伝って」
Copilot: 「JWT を使った一般的な実装を提案します」
開発者: 「うちはAuth0を使ってるんだけど...」
Copilot: 「わかりました。では Auth0 の実装を...」
開発者: 「しかも社内の認証フローがあって...」
GitHub Copilotは優秀なコーディングアシスタントですが、デフォルト設定のままでは、チームの開発スタイルやプロジェクト固有の要件に完全に適合しているとは言えません。
本記事では、VS CodeにおけるGitHub Copilotのカスタマイゼーション機能について、カスタムインストラクション、プロンプトファイル、カスタムエージェント、Agent Skills、そしてMCPサーバーの統合まで、実践的なサンプルコードとともに紹介していきたいと思います。サンプルコードは下記のものです。
https://code.visualstudio.com/docs/copilot/customization/overview
カスタマイゼーションの全体像
VS CodeのGitHub Copilotには、6つの主要なカスタマイゼーション方法があります:
| カスタマイゼーション方法 | 主な用途 | 特徴・適用範囲 |
|---|---|---|
| Custom Instructions | コーディング規約、開発標準の定義 | 全チャットリクエスト or 特定ファイルタイプ |
| Agent Skills | 専門的なワークフローや機能の教示 | 再利用可能な専門知識の定義(エージェント間で共有可能) |
| Prompt Files | 再利用可能なタスク用プロンプト | オンデマンド実行 |
| Custom Agents | 特定の役割に特化したアシスタント | チャットモード選択時 |
| Language Models | タスクに最適化されたAIモデル選択 | モデルピッカーで切替 |
| MCP Servers | 外部サービス・ツールとの連携 | エージェントモードで利用 |
1. Custom Instructions - コーディング規約の統一
基本設定
Custom Instructionsは、プロジェクト全体または特定のファイルタイプに対して、Copilotの動作方針を定義する機能です。
ワークスペース全体に適用する設定
# プロジェクト共通のコーディングガイドライン
## コードスタイル
- セマンティックなHTML5要素を使用する (header, main, section, article)
- モダンなJavaScript機能を優先 (const/let, アロー関数, テンプレートリテラル)
- TypeScriptの型定義を必ず記述する
## 命名規則
- コンポーネント名、インターフェース、型エイリアス: PascalCase
- 変数、関数、メソッド: camelCase
- プライベートクラスメンバー: アンダースコアプレフィックス (_)
- 定数: ALL_CAPS
## コード品質
- 意味のある変数名・関数名を使用
- 複雑なロジックにはコメントを追加
- ユーザー入力やAPI呼び出しにはエラーハンドリングを実装
- async/awaitを優先し、コールバックは避ける
## セキュリティ
- 機密情報をハードコーディングしない
- 入力値は必ずバリデーションを実施
- SQL インジェクション対策としてプレースホルダーを使用
言語別・フレームワーク別の設定
特定のファイルパターンに適用する場合は、frontmatterでapplyToを指定します。
---
applyTo: "**/*.tsx"
---
# React開発ガイドライン
- 関数コンポーネントを優先し、クラスコンポーネントは使用しない
- カスタムフックを活用して状態管理ロジックを分離
- propsは必ずTypeScriptインターフェースで型定義
- スタイリングはTailwind CSSのユーティリティクラスを使用
- 必要に応じてReact.memoでメモ化
---
applyTo: "src/server/**/*.ts"
---
# バックエンド開発ガイドライン
- コントローラーは `src/controllers/` に配置
- サービスロジックは `src/services/` に配置
- リポジトリパターンでデータアクセスを実装
- 環境変数は `.env` から読み込み
- エラーハンドリングミドルウェアで一元管理
- ロギングには Winston を使用
設定の有効化
- VS Code設定で
Chat > Use Instruction Filesを有効化 - または
settings.jsonに追加:
{
"github.copilot.chat.codeGeneration.useInstructionFiles": true
}
自動生成機能
VS Codeはワークスペースを分析して、プロジェクトに適したインストラクションファイルを自動生成できます:
- チャットビューで歯車アイコンをクリック
- "Generate Chat Instructions" を選択
- 生成されたファイルを確認・編集
2. Prompt Files - 再利用可能なタスクテンプレート
Prompt Filesは、頻繁に実行する開発タスクをテンプレート化し、チーム全体で共有できる機能です。
サンプル1: React コンポーネント生成
---
agent: 'agent'
model: 'GPT-4o'
tools: ['search/codebase']
description: 'Reactコンポーネントを生成'
---
以下の要件でReactコンポーネントを生成してください:
コンポーネント名: ${input:componentName:コンポーネント名を入力}
props: ${input:props:propsをカンマ区切りで入力 (例: title, onClick, isDisabled)}
## 生成ルール
- TypeScriptで実装
- 関数コンポーネントを使用
- propsはインターフェースで型定義
- Tailwind CSSでスタイリング
- 必要に応じてReact HooksでState管理
- プロップの説明をJSDocコメントで記述
サンプル2: API ルート生成
---
agent: 'agent'
description: 'RESTful APIルートを生成'
---
以下のエンティティに対するCRUD APIを生成してください:
エンティティ名: ${input:entity:エンティティ名}
フィールド: ${input:fields:フィールドをカンマ区切りで指定}
## 実装要件
- Express.jsを使用
- TypeScriptで実装
- ルーターは `src/routes/` に配置
- コントローラーは `src/controllers/` に配置
- バリデーションにはexpress-validatorを使用
- エラーハンドリングを適切に実装
- レスポンスは標準的なJSON形式
サンプル3: テストケース生成
---
agent: 'agent'
tools: ['search/codebase']
description: 'ユニットテストを自動生成'
---
選択されたコード: ${selection}
上記のコードに対して包括的なユニットテストを生成してください。
## テスト要件
- Jestを使用
- テストカバレッジを最大化
- 正常系・異常系の両方をカバー
- エッジケースを考慮
- モックやスタブを適切に使用
- 各テストケースに説明的なdescribe/it文を記述
サンプル4: コードレビュー
---
agent: 'agent'
description: 'コードレビューを実施'
---
選択されたコード: ${selection}
以下の観点でコードレビューを実施してください:
## レビュー観点
1. **セキュリティ**: 脆弱性の有無
2. **パフォーマンス**: 最適化の余地
3. **コード品質**: 可読性、保守性
4. **エラーハンドリング**: 適切な例外処理
5. **テスタビリティ**: テストのしやすさ
6. **コーディング規約**: プロジェクト標準への準拠
改善提案は具体的なコード例とともに提示してください。
Prompt Files の使い方
- コマンドパレットから:
Chat: Run Prompt→ プロンプト選択 - チャット入力欄で:
/create-react-componentのようにスラッシュコマンドで実行 - エディタから:
.prompt.mdファイルを開き、タイトルバーの再生ボタンをクリック
3. Agent Skills - ポータブルなAI機能拡張
Agent Skillsは、VS Code、GitHub Copilot CLI、Copilot coding agentで共通利用できるオープンスタンダードです。
Agent Skills の構造
.github/skills/
├── webapp-testing/
│ ├── SKILL.md
│ └── example-test.spec.ts
└── github-actions-debugging/
├── SKILL.md
└── troubleshooting-guide.md
サンプル1: Playwright テスト生成
---
name: webapp-testing
description: Playwrightを使用したE2Eテストを生成します。ユーザーインタラクションのテストが必要な場合に使用してください。
---
# Web Application Testing with Playwright
このスキルは、Playwrightを使用したエンドツーエンド(E2E)テストの生成をサポートします。
## テスト生成ルール
1. **セレクター優先順位**:
- `getByRole` を最優先
- 次に `getByLabel`
- 最後の手段として `getByTestId`
2. **テスト構造**:
- 各テストは独立して実行可能
- setup/teardownを適切に実装
- 明確なアサーションを記述
3. **ベストプラクティス**:
- Page Object Modelパターンを使用
- 待機処理は暗黙的に実行される
- スクリーンショット撮影は失敗時のみ
## テンプレート例
以下の example-test.spec.ts を参考にテストを生成してください。
```typescript
import { test, expect } from '@playwright/test';
test('user can log in successfully', async ({ page }) => {
await page.goto('/login');
await page.getByRole('textbox', { name: 'Email' }).fill('user@test.com');
await page.getByRole('textbox', { name: 'Password' }).fill('password123');
await page.getByRole('button', { name: 'Sign in' }).click();
await expect(page).toHaveURL('/dashboard');
await expect(page.getByRole('heading', { name: 'Welcome' })).toBeVisible();
});
import { test, expect } from '@playwright/test';
test('user can add item to cart', async ({ page }) => {
await page.goto('/products');
const product = page.getByRole('article').filter({ hasText: 'Product Name' });
await product.getByRole('button', { name: 'Add to Cart' }).click();
await expect(page.getByRole('status', { name: 'Cart' })).toContainText('1 item');
});
test('user can complete checkout', async ({ page }) => {
await page.goto('/cart');
await page.getByRole('button', { name: 'Checkout' }).click();
await page.getByRole('textbox', { name: 'Card Number' }).fill('4242424242424242');
await page.getByRole('button', { name: 'Place Order' }).click();
await expect(page.getByRole('heading')).toContainText('Order Confirmed');
});
サンプル2: GitHub Actions デバッグ
---
name: github-actions-failure-debugging
description: GitHub Actionsワークフローの失敗をデバッグします。CIが失敗した際に使用してください。
---
# GitHub Actions Failure Debugging
このスキルは、GitHub Actionsワークフローの失敗を効率的にデバッグするプロセスを提供します。
## デバッグプロセス
Pull Requestで失敗したGitHub Actionsワークフローをデバッグする際は、以下の手順に従ってください:
1. **ワークフロー実行状況の確認**
- `list_workflow_runs` ツールを使用してPRの最近の実行とステータスを確認
2. **ログの要約取得**
- `summarize_job_log_failures` ツールを使用して失敗したジョブのログのAI要約を取得
- コンテキストウィンドウを圧迫せずに問題を理解
3. **根本原因の特定**
- エラーメッセージから問題の種類を分類:
* 依存関係の問題
* テスト失敗
* ビルドエラー
* 権限エラー
* タイムアウト
4. **解決策の提案**
- 特定した問題に対する具体的な修正方法を提示
- 必要に応じてワークフローファイルの修正を提案
## よくある問題と解決策
### 依存関係の問題
- Node.jsバージョンの不一致
- パッケージのインストール失敗
→ `package-lock.json` の確認、キャッシュのクリア
### テスト失敗
- 環境変数の欠落
- テストデータの問題
→ 環境変数の設定確認、テストシードデータの検証
### 権限エラー
- GITHUB_TOKENのスコープ不足
- secretsの設定ミス
→ リポジトリ設定で権限とsecretを確認
Agent Skills の利点
- ポータビリティ: VS Code、CLI、coding agentで共通利用
- 文脈理解: Copilotが自動的に関連スキルを読み込み
- チーム共有: リポジトリに含めることで知識を共有
- オープンスタンダード: agentskills.io準拠
4. Custom Agents - 役割特化型アシスタント
Custom Agentsは、特定の役割やタスクに特化したチャットモードを定義します。
サンプル1: 計画専用エージェント
---
name: 'planner'
description: '実装前の計画立案に特化したエージェント'
tools:
- 'search/codebase'
- 'githubRepo'
toolsets:
- 'read-only'
model: 'GPT-4o'
---
# Implementation Planning Agent
あなたは実装計画の立案に特化したエージェントです。コードは書かず、実装計画のみを作成します。
## 役割
1. **要件分析**: ユーザーの要望を詳細に分析
2. **影響範囲調査**: 変更が必要なファイルとコンポーネントを特定
3. **タスク分解**: 実装を小さなタスクに分割
4. **リスク識別**: 潜在的な問題点を洗い出し
## 計画フォーマット
### 1. 概要
[実装の目的と期待される結果]
### 2. 影響範囲
- 変更が必要なファイル一覧
- 影響を受けるコンポーネント
### 3. 実装ステップ
1. [ステップ1の詳細]
- 必要な変更
- 注意点
2. [ステップ2の詳細]
...
### 4. テスト戦略
- ユニットテスト対象
- E2Eテストシナリオ
### 5. リスクと対策
| リスク | 対策 |
|--------|------|
| ... | ... |
計画承認後、実装エージェントにハンドオフしてください。
サンプル2: セキュリティレビューエージェント
---
name: 'security-reviewer'
description: 'セキュリティ観点でコードをレビューするエージェント'
tools:
- 'search/codebase'
model: 'Claude Sonnet 3.5'
---
# Security Review Agent
あなたはセキュリティの専門家として、コードの脆弱性を検出するエージェントです。
## レビュー項目
### 1. 認証・認可
- [ ] 適切な認証メカニズムの実装
- [ ] 認可チェックの漏れがないか
- [ ] セッション管理の安全性
### 2. 入力検証
- [ ] すべてのユーザー入力をサニタイズ
- [ ] SQLインジェクション対策
- [ ] XSS対策
- [ ] CSRF対策
### 3. データ保護
- [ ] 機密情報のハードコーディングがないか
- [ ] 暗号化の適切な使用
- [ ] ログに機密情報を出力していないか
### 4. 依存関係
- [ ] 既知の脆弱性を持つパッケージの使用
- [ ] 最新バージョンへのアップデート推奨
### 5. API セキュリティ
- [ ] レートリミットの実装
- [ ] CORS設定の適切性
- [ ] APIキーの安全な管理
## レポート形式
各検出事項について、以下を報告:
- **重要度**: Critical / High / Medium / Low
- **説明**: 何が問題か
- **影響**: 悪用された場合の影響
- **修正方法**: 具体的なコード例
Critical/Highの脆弱性は即座に修正が必要です。
サンプル3: フロントエンド開発エージェント
---
name: 'frontend-dev'
description: 'フロントエンド開発に特化したエージェント'
tools:
- 'search/codebase'
- 'terminal'
- 'edit'
model: 'GPT-4o'
---
# Frontend Development Agent
あなたはReact/TypeScript/Tailwind CSSを使用したフロントエンド開発の専門家です。
## 開発方針
### コンポーネント設計
- 再利用性を最優先
- 単一責任の原則を遵守
- propsは最小限に保つ
- 適切な抽象化レベル
### State管理
- ローカルstateはuseState/useReducerで管理
- グローバルstateは必要最小限
- 不要な再レンダリングを防ぐ
### スタイリング
- Tailwind CSSのユーティリティクラスを使用
- カスタムCSSは最小限
- レスポンシブデザインをモバイルファーストで実装
### パフォーマンス
- React.memoで不要な再レンダリングを防止
- useCallbackでコールバックをメモ化
- useMemoで重い計算をキャッシュ
- 画像の最適化(next/imageなど)
## 実装フロー
1. コンポーネントの責務を明確化
2. propsインターフェースを定義
3. 状態管理の設計
4. JSX構造を実装
5. スタイリング適用
6. アクセシビリティ確認(ARIA属性)
7. レスポンシブ対応
実装完了後は必ずブラウザでプレビューして動作確認してください。
Custom Agents の使い方
- チャットビューでエージェントセレクターを開く
- カスタムエージェントを選択
- 定義されたツールとインストラクションが適用される
5. MCP (Model Context Protocol) - 外部サービス統合
MCPは、CopilotがDBやAPIなど外部サービスと連携するためのオープンスタンダードです。
MCP Server の設定
ワークスペース設定
{
"inputs": [
{
"type": "promptString",
"id": "github-token",
"description": "GitHub Personal Access Token",
"password": true
},
{
"type": "promptString",
"id": "db-connection",
"description": "Database Connection String",
"password": true
}
],
"servers": {
"github-server": {
"type": "http",
"url": "https://github-mcp.com",
"headers": {
"Authorization": "Bearer ${input:github-token}"
}
},
"database-server": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"DATABASE_URL": "${input:db-connection}"
}
},
"filesystem-server": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/workspace"]
}
}
}
ユーザー設定
グローバルに使用するMCPサーバーは、settings.jsonに定義:
{
"chat.mcp.servers": {
"perplexity-search": {
"type": "http",
"url": "https://perplexity-mcp.com/api",
"env": {
"PERPLEXITY_API_KEY": "${env:PERPLEXITY_API_KEY}"
}
},
"slack-integration": {
"command": "docker",
"args": ["run", "-i", "slack-mcp-server"],
"env": {
"SLACK_TOKEN": "${env:SLACK_BOT_TOKEN}"
}
}
}
}
実装例1: GitHub MCP Server の利用
# プロンプト例
@agent GitHubリポジトリ contoso/my-app の最近のIssueを取得して、
優先度の高いものから順にリストアップしてください。
# Copilotの動作
1. GitHub MCP Serverの `list_issues` ツールを呼び出し
2. 取得したIssueを優先度でソート
3. マークダウン形式でレスポンス
実装例2: Database MCP Server の利用
# プロンプト例
データベースから全ユーザーを取得して、
アクティブユーザー数を集計してください。
# Copilotの動作
1. Database MCP Serverの `query` ツールを実行
2. SQL: SELECT COUNT(*) FROM users WHERE is_active = true
3. 結果を整形して表示
実装例3: カスタムMCP Server の作成
Node.jsでシンプルなMCPサーバーを作成:
// custom-mcp-server/index.ts
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new Server(
{
name: "custom-api-server",
version: "1.0.0",
},
{
capabilities: {
tools: {},
},
}
);
// ツールの定義
server.setRequestHandler("tools/list", async () => {
return {
tools: [
{
name: "fetch_user_data",
description: "ユーザーデータを取得",
inputSchema: {
type: "object",
properties: {
userId: { type: "string", description: "ユーザーID" },
},
required: ["userId"],
},
},
],
};
});
// ツールの実行
server.setRequestHandler("tools/call", async (request) => {
if (request.params.name === "fetch_user_data") {
const userId = request.params.arguments?.userId;
// APIリクエストの実装
const response = await fetch(`https://api.example.com/users/${userId}`);
const data = await response.json();
return {
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
};
}
throw new Error("Unknown tool");
});
// サーバー起動
const transport = new StdioServerTransport();
await server.connect(transport);
{
"name": "custom-mcp-server",
"type": "module",
"dependencies": {
"@modelcontextprotocol/sdk": "latest"
},
"bin": {
"custom-mcp-server": "./index.js"
}
}
MCPサーバーの管理
- サーバー一覧: Command Palette →
MCP: List Servers - ツール選択: エージェントモードでツールアイコンをクリック
- 自動承認: 信頼できるツールは自動承認設定可能
6. 実践的な統合例
ユースケース: マイクロサービス開発プロジェクト
ディレクトリ構成
my-microservice/
├── .github/
│ ├── copilot-instructions.md # 全体の開発規約
│ ├── instructions/
│ │ ├── backend.instructions.md # バックエンド固有
│ │ ├── frontend.instructions.md # フロントエンド固有
│ │ └── infra.instructions.md # インフラ固有
│ ├── agents/
│ │ ├── planner.md # 計画エージェント
│ │ ├── implementer.md # 実装エージェント
│ │ ├── reviewer.md # レビューエージェント
│ │ └── deployer.md # デプロイエージェント
│ ├── skills/
│ │ ├── api-testing/
│ │ │ ├── SKILL.md
│ │ │ └── sample-api-test.ts
│ │ └── k8s-deployment/
│ │ ├── SKILL.md
│ │ └── deployment-template.yaml
│ └── prompts/
│ ├── create-service.prompt.md
│ ├── add-endpoint.prompt.md
│ └── generate-migration.prompt.md
└── .vscode/
└── mcp.json # MCP設定
ワークフロー例
1. 新機能の計画
# @planner エージェントに依頼
ユーザー認証機能を追加したい。
OAuthとJWTトークンベースの認証を実装。
2. 実装の委譲
計画承認後、実装エージェントにハンドオフ:
# @implementer エージェントで実装
上記の計画に基づいて、認証ミドルウェアを実装してください。
3. テストの自動生成
# Prompt File を使用
/generate-tests
4. セキュリティレビュー
# @security-reviewer エージェントで確認
実装した認証ミドルウェアをセキュリティレビューしてください。
5. デプロイ準備
# MCP + K8s Skill を活用
@agent kubernetes-skillを使って、認証サービスのデプロイメント設定を生成。
7. Language Models - タスク別モデル選択
モデルの使い分け
VS Codeでは、タスクに応じて最適なAIモデルを選択できます。以下に例を示します(ただし、日々新しいモデルがリリースされているため、下記はあまり参考にならないと思います。):
| モデル | 推奨用途 | 特徴 |
|---|---|---|
| GPT-4o | 複雑な実装、アーキテクチャ設計 | 推論能力が高い |
| Claude Sonnet 3.5 | コードレビュー、リファクタリング | コンテキストウィンドウが広い |
| GPT-4o-mini | 簡単なコード生成、クイックQ&A | 高速・低コスト |
モデルの切り替え
- チャット入力欄の横にあるモデルピッカーをクリック
- タスクに適したモデルを選択
- 選択したモデルが現在のセッションに適用
独自モデルの利用 (BYOK: Bring Your Own Key)
{
"github.copilot.chat.models": [
{
"id": "my-custom-model",
"name": "Custom GPT-4",
"endpoint": "https://api.openai.com/v1/chat/completions",
"apiKey": "${env:OPENAI_API_KEY}",
"model": "gpt-4-turbo-preview"
},
{
"id": "local-llm",
"name": "Local LLaMA",
"endpoint": "http://localhost:8080/v1/chat/completions",
"model": "llama-3-70b-instruct"
}
]
}
8. ベストプラクティス
1. 段階的な導入
Week 1: Custom Instructions を設定
Week 2: よく使うタスクをPrompt Files化
Week 3: Custom Agents を試験導入
Week 4: MCPサーバーで外部連携
2. チームでの共有
- Custom Instructions と Prompt Files はリポジトリにコミット
- Agent Skills も
.github/skills/に配置 - MCP設定はプロジェクト固有のものを
.vscode/mcp.jsonで管理
3. セキュリティ
// APIキーは環境変数で管理
{
"chat.mcp.servers": {
"secure-api": {
"env": {
"API_KEY": "${env:MY_API_KEY}" // ハードコーディングしない
}
}
}
}
4. パフォーマンス最適化
- 不要なツールは無効化してコンテキストを節約
- 大規模なPrompt Filesは小さく分割
- MCPサーバーのタイムアウト設定を調整
5. ドキュメント化
# team-wiki/copilot-usage.md
## カスタムエージェントの使い分け
- `@planner`: 実装前の計画立案
- `@implementer`: コード実装
- `@reviewer`: コードレビュー
- `@deployer`: デプロイ作業
## Prompt Filesのクイックリファレンス
- `/create-component`: Reactコンポーネント生成
- `/add-api-route`: API エンドポイント追加
- `/generate-tests`: テストコード自動生成
まとめ
GitHub Copilotのカスタマイゼーション機能を活用することで、チームの開発スタイルに適合したAIアシスタントを構築できそうです。
また、現状では以下のような機能選択の方針になるだろうと思います。
| やりたいこと | 使う機能 |
|---|---|
| コーディング規約を統一したい | Custom Instructions |
| 繰り返しタスクを自動化したい | Prompt Files |
| 特化型のAIアシスタントを作りたい | Custom Agents |
| AIツール間でスキルを共有したい | Agent Skills |
| 外部APIやDBと連携したい | MCP Servers |
| タスク別に最適なモデルを使いたい | Language Models |
