はじめに
こんにちは、アイスタイルのメディア開発部に所属している渡辺です。
会社でGitHub Copilotの利用推奨があり、ぼちぼち使い始めて数ヶ月が経ちますが、
「なんとなく使えている気がするけど、本当に活用できているのか?」
という疑問を抱えていました。
そこで思いついたのが、
「GitHub Copilot自身に、Copilotの使い方を学ぶアプリを作ってもらう」
という発想です。
この記事では、GitHub Copilotとの対話を通じて
実践的な学習プラットフォーム「Copilot Skill Builder」を開発した経験と、
その過程で得られた知見を共有します。
この記事で得られること
- GitHub Copilotを使った実践的なアプリケーション開発の全体像
- Copilotとの効果的な対話方法とプロンプティング技術
- TypeScript実行環境の構築やVS Code拡張機能開発など、技術的な実装の詳細
- GitHub Copilotを最大限活用するための具体的なTips
【とりあえず成果物】
なぜこのアプリを作ろうと思ったか
GitHub Copilot活用の違和感
GitHub Copilotを導入して使い始めたものの、次のような課題を感じていました:
- 活用方法が分からない: 「何ができるのか」は分かるが、「どう使えば効果的か」が掴めない
- 体系的な学習機会の不足: 実践的なスキルを段階的に学べる場がない
- 進捗が可視化されない: 自分がどれだけ上達しているのか実感できない
解決のアイデア
そこで考えたのが、GitHub Copilot自身に学習アプリを作ってもらうというアプローチでした。
このアイデアには以下のメリットがありました:
- 実践的な学習: アプリを通じてCopilotの使い方を体験できる
- メタ学習: Copilotで作る過程そのものが学習になる
- カスタマイズ可能: 自分に必要な機能を追加していける
アプリケーションの全体像
システムアーキテクチャ
Copilotが作成してくれたアプリ(Copilot Skill Builderと命名)は、
WebアプリケーションとVS Code拡張機能の2つのディレクトリがあり、
Webアプリケーションの中にデータベースという構成になっています。
主要コンポーネント:
-
Webアプリケーション (Next.js 14)
- コース・ミッション管理
- 進捗トラッキング
- 認証・API提供
-
VS Code拡張機能
- ミッションの自動セットアップ
- コード実行・テスト
- リアルタイム進捗同期
-
データベース (SQLite + Prisma)
- ユーザー情報
- コース・レッスン・ミッションデータ
- 進捗状況
学習フロー
ユーザーは以下の流れで学習を進めます:
- Webアプリでコースを選択
- レッスンで基礎知識を学習
- VS Code拡張でミッションに挑戦
- コードを書いてテスト実行
- 進捗がWebアプリに自動反映
GitHub Copilotとの開発プロセス
フェーズ1: 要件定義とプロンプティング
最初のステップは、Copilotに「何を作りたいか」を明確に伝えることでした。
そのためにGeminiを使ってCopilotに与えるプロンプトを生成しました。
なんとなく実現したいことを伝えて、
「AIコーディングするのでCopilotに与えるプロンプトを生成してください。」
という感じで頼むと技術スタックなどはGeminiが適切なものを考えてプロンプトを生成してくれました。
初期プロンプト例:
GitHub Copilotの使い方を段階的に学べる学習プラットフォームを作りたい。
以下の機能が必要:
- ユーザー認証
- コース・レッスン・ミッション管理
- VS Codeでミッションに挑戦できる機能
- 進捗トラッキング
技術スタック:
- Next.js 14 (App Router)
- TypeScript
- Prisma + SQLite
- NextAuth.js v5
このように、具体的な機能要件と技術スタックを明示されていることで、Copilotは一貫性のある提案をしてくれました。
フェーズ2: データベース設計
Copilotに以下のプロンプトでデータベーススキーマを提案してもらいました:
Prismaスキーマを設計してください
必要なモデル:
- User (ユーザー)
- Course (コース)
- Lesson (レッスン)
- Mission (ミッション/課題)
- UserMissionProgress (ミッション進捗)
- UserCourseProgress (コース進捗)
- ApiToken (VS Code拡張用認証トークン)
Copilotが生成したスキーマ(抜粋):
model User {
id String @id @default(cuid())
email String @unique
password String
name String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
missionProgress UserMissionProgress[]
courseProgress UserCourseProgress[]
apiTokens ApiToken[]
}
model Mission {
id String @id @default(cuid())
title String
description String
difficulty String
starter String
solution String
test String
hints String[]
lessonId String
lesson Lesson @relation(fields: [lessonId], references: [id])
progress UserMissionProgress[]
}
model UserMissionProgress {
id String @id @default(cuid())
userId String
missionId String
status String @default("not_started")
code String?
completedAt DateTime?
user User @relation(fields: [userId], references: [id])
mission Mission @relation(fields: [missionId], references: [id])
@@unique([userId, missionId])
}
Copilotの提案の良かった点:
- リレーションが適切に設定されている
-
@@unique制約で重複を防止 - タイムスタンプが自動設定される
フェーズ3: 実装の進め方
開発は以下の順序で進めました:
- 基本構造の構築(Copilotに全体を生成してもらう)
- 個別機能の実装(アプリを触りながら追加機能など段階的にプロンプトを与える)
- 統合とデバッグ(エラーメッセージをCopilotに渡して修正)
この段階的アプローチにより、Copilotは文脈を保ちながら一貫した実装を提供してくれました。
技術的な実装の詳細
1. ブラウザでTypeScriptを実行する仕組み
ミッションのコードをブラウザで実行するために、最も苦労したのがTypeScriptからJavaScriptへの変換でした。
課題:
- ブラウザはTypeScriptを直接実行できない
- ビルドツール(webpack, esbuild等)は重たい
- リアルタイムで変換する必要がある
Copilotと議論した解決策:
// 正規表現ベースのTypeScript→JavaScript変換
function transpileTypeScript(code: string): string {
return code
// 型アノテーションを削除
.replace(/:\s*\w+(\[\])?(?=\s*[=,)\n])/g, '')
// インターフェース・型定義を削除
.replace(/interface\s+\w+\s*{[^}]*}/g, '')
.replace(/type\s+\w+\s*=\s*[^;\n]+[;\n]/g, '')
// import文を削除
.replace(/import\s+.*?from\s+['"].*?['"];?\n?/g, '')
// export文を処理
.replace(/export\s+(default\s+)?/g, '');
}
学んだこと:
- 完璧な変換は不要で、学習用途なら正規表現で十分
- Copilotに「シンプルな解決策」を求めることが重要
2. VS Code拡張機能との連携
VS Code拡張機能からWebアプリのAPIを呼び出す仕組みを実装しました。
認証フロー:
- ユーザーがWebアプリでAPIトークンを生成
- VS Code拡張の設定にトークンを入力
- 拡張機能が全てのAPI呼び出しにトークンを付与
// VS Code拡張: APIクライアント
export class ApiClient {
private token: string;
constructor(token: string) {
this.token = token;
}
async getMissions() {
const response = await fetch('http://localhost:3000/api/missions', {
headers: {
'Authorization': `Bearer ${this.token}`
}
});
return response.json();
}
async submitMission(missionId: string, code: string) {
const response = await fetch(
`http://localhost:3000/api/missions/${missionId}/submit`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${this.token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ code })
}
);
return response.json();
}
}
3. リアルタイム進捗同期
ユーザーの進捗をリアルタイムで同期する仕組みです。
// API Route: progress更新
export async function POST(request: Request) {
const session = await auth();
if (!session?.user?.id) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const { missionId, status, code } = await request.json();
// 進捗を更新または作成
const progress = await prisma.userMissionProgress.upsert({
where: {
userId_missionId: {
userId: session.user.id,
missionId: missionId
}
},
update: {
status,
code,
completedAt: status === 'completed' ? new Date() : null
},
create: {
userId: session.user.id,
missionId,
status,
code
}
});
return NextResponse.json(progress);
}
VSCode側でmissionを選択してCopilotを使ってコードを書き、
ファイル保存するとブラウザ画面の「あなたのコード」に同期される。
その後「テストを実行」を押下することでAPI経由でテストが走り、
全パターン通ればミッションクリアとなりユーザーの進捗に反映されます。
テスト結果は期待値・実際の値というように表示されます。
GitHub Copilotとの協働で学んだこと
効果的なプロンプティング技術
開発を通じて、以下のプロンプティング技術が有効だと分かりました
1. コンテキストを明確に提供
❌ 悪い例:
認証機能を作って
✅ 良い例:
NextAuth.js v5を使ってメール/パスワード認証を実装したい。
- Prismaアダプターを使用
- CredentialsProviderでbcryptjs使用
- セッションはJWT方式
- 既存のUserモデルと連携
具体的な技術選定は一発で指示できなくてもAIと相談しながら決めるでもいいと思います。
2. 段階的に詳細化
大きな機能を一度に求めず、小さなステップに分割:
Step 1: Prismaスキーマを設計
Step 2: NextAuth設定ファイルを作成
Step 3: ログイン/サインアップAPIを実装
Step 4: ミドルウェアで認証チェック
3. エラーメッセージを共有
エラーが発生したら、そのまま Copilotに渡す:
以下のエラーが発生しました。修正方法を教えてください:
Error: Cannot find module '@/lib/auth'
at /Users/.../app/api/auth/[...nextauth]/route.ts:1:1
Copilotは的確にimportパスの修正やファイル配置の提案をしてくれます。
Copilotとの対話パターン
探索的な質問:
TypeScriptをブラウザで実行する方法は何がありますか?
メリット・デメリットも教えてください
実装の確認:
この実装で正しいですか?
セキュリティ上の問題はありますか?
代替案の要求:
もっとシンプルな実装方法はありますか?
パフォーマンスを改善できますか?
Copilotが得意なこと・苦手なこと
(自分で思ったこと、Copilot本人に聞いたことを含めて)
得意:
- 定型的なコード生成(CRUD操作、API Routes等)
- 既存コードのパターンを踏襲した実装
- エラーメッセージからの修正提案
- ドキュメント作成
苦手:
- アーキテクチャ全体の設計判断
- トレードオフの評価
- 複雑なビジネスロジック
- セキュリティの深い考慮
→ 戦略: Copilotに判断を丸投げせず、方向性は人間が決める
ハマったポイントと解決策
1. NextAuth.js v5の情報不足
問題:
Copilotが提案するコードがv4の古い書き方だった。
解決:
公式ドキュメントを参照しながら、明示的にバージョンを指定:
NextAuth.js v5 (next-auth@beta) の最新の書き方で実装してください。
auth()関数を使った方式でお願いします。
2. TypeScript型エラーの連鎖
問題:
一箇所の型定義を変更すると、連鎖的にエラーが発生。
解決:
型定義を先に完全に整備してから実装:
// types/next-auth.d.ts
declare module "next-auth" {
interface Session {
user: {
id: string;
email: string;
name?: string;
};
}
}
成果と学び
GitHub Copilotの使い方:
- プロンプトの書き方で生成品質が大きく変わる
- 段階的なアプローチが最も効果的
- エラー修正のサイクルが高速化
技術的な学び:
- Next.js 14のApp Router
- VS Code拡張機能開発
- TypeScriptの型システムの理解
開発プロセスの変化:
- 「調べる」→「実装する」のサイクルが圧倒的に速くなった
- 定型的なコードを書く時間がほぼゼロに
- アイデアから動くプロトタイプまでの時間が大幅短縮
今後の展開
AIがコーディングをかなりしてくれるようになりましたが、
人間がそれを添削する必要がまだまだあるのでコードリーディングで力をつけたい。
今回のようなAIが書いたコードを読んで学び、また別のものを作ってみるというサイクルを回したいと思います。
GithubCopilotで/explainのようなコマンドを使えばコードの解説をしてくれるので
AIが書いたコードを読む学習のお供にもAIを使い倒したいと思います。
まとめ
GitHub Copilotを使って「Copilot学習アプリ」を作ることで、以下を実現できました
- 実践的なスキル習得: アプリ開発を通じてCopilotの使い方を体得
- メタ学習の効果: Copilotで作る過程自体が最高の学習
- 開発生産性の向上: 従来と比べ物にならんくらい速度で開発可能に
最大の学び:
GitHub Copilotは「何でも自動で作ってくれる魔法の杖」ではなく、
「開発者の意図を汲んで高速に実装してくれる優秀なペアプログラマー」
であるということ。
適切なプロンプトと対話を通じて、Copilotとの協働はこれまでにない開発体験を提供してくれます。
この記事が、この世の誰かのGitHub Copilotをより効果的に活用するヒントになれば幸いです。
最後まで読んでいただき、ありがとうございました!
質問やフィードバックがあれば、コメント欄でお気軽に🙌
GitHubリポジトリ: https://github.com/Watanabe-Keita-wk/copilot-skill-builder
※動かすにはNode.js 18.x 以上, pnpm 8.x 以上が必要になります。




