【Github Copilot】Agentモードを使ってみる

GitHub

Github Copilotは有料プランかあるいは学生/教員用の無料プランでしか使えないため、筆者もお財布と相談した上でついにGithub Copilot Proプラン(月額10USD)を使ってみることにしました。

もはやAIを使った開発ができないエンジニアは淘汰される時期も遠くないと感じます。

スキルシートも、「AIの利用経験」や「利用可能なAIツール/モデル」が必須項目になるかもしれません。

ここでいう「AIを使った開発」は、「ChatGPTと会話して提示してもらったコードをコピペする」ことではなく、「AIにコード補完してもらう」ことでもなく、「AIに指示を出してコードを自動生成させ、AIにテストを実行させ、必要に応じてAIに改善提案をさせ、AIにリポジトリにPRをオープンさせ」といったように、「AIのコーディングエージェントをコントロールして一連の開発作業をAIに行わせる」ことを指しています。

ここでいう「AIのコーディングエージェント」とは、人間からの指示に従ってプログラムコードを自動生成してファイルに保存し、必要に応じてテスト等の開発に関わるコマンドを自動実行するAIツールを指します。

執筆時点では、Claude CodeやGithub Copilot のVS Code拡張の「Agentモード」がこれに相当します。

前提条件

  • Githubアカウント取得済
  • VS Code
  • Ubuntu24.04.2 LST(WSL2 on Windows11)を使っています

Github Copilotのプランアップグレード

Github Copilotの「Proプラン」(30日間無料、月額10USD、年額100USD)にアップグレードします。

30日間の無料期間終了前ならいつでもキャンセルできるようです。

Githubにサインインしている状態で、アカウントのメニューから「Your Copilot」を選択します。

※「Settings」⇒「Copilot」⇒「Features」と同じです。

「Upgrade」ボタンをクリックします。

「Try for 30 days free」ボタンを押下します。

年額100USDの方が、年間20USDの節約になりますが、継続するかどうか不明なので、

筆者は「月額10USD」を選択してみます。

※2025/09/23追記:請求時には、10%の税が加算され、月額11USDになります。

「Upgrade now」ボタンを押下します。

「Billing Information」の必須項目を埋めて「Save billing information」を押下します。

支払情報を入力して「Save payment information」を押下します。

チェック欄はターゲット広告やキャンペーンの効果測定に個人情報を使用することを許可するかどうかなので、筆者はチェックを入れずに「Activate now」を押下します。

Copilot Pro (30 days free trial)にアップグレードが完了してCopilotの画面に遷移します。

Copilotの設定

再度、「Your Copilot」の画面に移動します。

「Select an option」となっている項目を根こそぎ設定していきます。

※設定はリアルタイムで保存されます。

VS Code拡張インストール

Github CopilotをVSCode上で使うために、次の2つの拡張機能をインストールする必要があります。

  • GitHub Copilot
  • GitHub Copilot Chat

GitHub Copilot Chatを開いてみる

上記のVS Code拡張機能をインストール後にVS Codeを開くと、

ウィンドウ上部にGitHub Copilotのメニューが配置されます。

チャットを開く方法は3つ:

1.アイコンをクリック

2.アイコン右のプルダウンから「チャットを開く」を選択

3.ショートカット [Ctrl] + [Alt] + I (アイ)

下図のようなチャットベインが開きます。

初期状態はベイン下部左側にあるように「Ask」(質問)モードになっており、

使用するモデルは「GPT-4.1」になっています。

モードは3種類あります:

1.Askモード:普通のチャット

2.Agentモード:Github Copilotが指定モデルを介して人間の指示に沿って作業を進める

3.Editモード:編集中のコードのアシスタント

それぞれの使い分けについてGitHub Copilotに訊いてみました。

使用可能なモデル

デフォルトで使用可能なモデルは、大別して2種類あります。

1.「Standard Models」無制限で利用可能

2.「Premium Models」契約プランによる上限あり(Proだと300Premium Requests/月)

執筆時点の2025/07/07では、Askモードでは次のようになっています。

Agentモードの場合、functionコールに対応したモデルのみとなる為、対象が絞られます。

モデルリスト最下部にある「Manage Models…」をクリックすると、他のモデルを追加できます。

ウィンドウ上部にモデルプロバイダーのリストが表示されるので、該当のものを選択します。

外部のモデルプロバイダーの場合、APIキーの入力を求められます。

筆者はローカルのOllamaを選択してみます。

利用対象のモデルを選択して「OK」をクリックすると設定完了です。

これでチャットベイン下部のモデル選択リストに表示されるようになります。

「Premium Models」に属するモデルは、「Github Copilot Proプラン」の場合、

「月300Premiumリクエスト」の上限設定があります。

この上限に達すると、「Premium Models」はその月は利用できなくなります。

翌月1日に制限がリセットされます。

※筆者の場合、1日12時間程ゴリゴリ作業させて約6日間でこの上限に達しました。

※というわけで、30日間ゴリゴリ作業させたい場合は月額39USDの「Copilot Pro+プラン(月1500Premiumリクエスト)」にアップグレードした方がよさそうです。

「Copilot Pro+プラン」にすると「Claude Opus4」が利用可能になるようです。

※「Standard Models」は無制限で使えるようですが、「GPT4」系のモデルでは正直仕事になりません。やっていないことをやったというし、指示に従わないことが多いし、コード壊し始めるし。。その点、Claudeのモデルは非常に優秀です。

Agentモードを使う前に

Agentモードを使っての開発に進む前に、準備をしておくのが良いでしょう。

基本的には、何となくな感覚で「こんなものを作って欲しい」という指示だけで、ある程度「それっぽい」プロダクトを構築してくれます。

が、やはり曖昧な指示しか与えていないと、AIは頑張って作業してくれますが、良かれと思って余計な物凄く壮大なものを作り上げてしまったり、「それじゃない!」的な得体のしれないものを作り上げてしまったりします。

それは、決してAIが悪いわけではなく、曖昧な指示しか与えてない人間側に問題があります。

まあ、利用するモデルによっては壮大な嘘をついた挙句、指示に従わないものもあるのですが。。

この辺は、米マイクロソフトで活躍している牛尾氏も書いている通りだと思います。

 LLMを使ったアプリの開発を実際にしていると、Stabilize が一番難しかったり、LLMが簡単にあほにゃんにゃんになったり、Stable vs Creative のタスクで、何を LLM にやらせて、何を Program にやらせるかとか結局のところゴリゴリにノウハウが必要になってくるわけです。
 実装したら、結局分散システムの知識やデプロイメント、テストの知識が必要になってくるわけで、くっそど素人がVibe Coding でできるのはせいぜいプロトでしょう(しかしそれでも世界が進歩して素晴らしいですね!)

AI 時代にプログラマが持ってたら良いだろうたった一つの考え方|牛尾 剛
私は、アメリカのシアトルでソフトウェアエンジニアをやっていますが、AIに起因するソフトウェアエンジニアの大量レイオフがあったり、Visual Studio Code Agent などの エージェントがコードをゴリゴリに書いていく様を観て、と...

ここで重要になってくるのは、

1.利用するモデル

2.与える指示の具体性

となってきます。

1の利用するモデルですが、これがAIの頭脳に当たるわけで、この頭脳が開発精度に大きく影響を与えるのは必然でしょう。筆者は基本的にデフォルトの「GPT4*」系のモデルは情報収集とおしゃべり以外には使いません。

執筆時点では、コーディングに於いてはClaude系のモデル1択(特にSonnet4が一番素晴らしい)です。

2の与える指示の具体性ですが、これは作るものによってかなり変わると思います。

Claude系のモデルに与える指示なら、やはり「CLAUDE.md」を使うのが良いのではないでしょうか?

今回準備した指示ファイル

どういった内容がベストプラクティスになるのかは、まだ手探り段階ですが、

先人達の公開している情報を基にある程度自分用にまとめてから使ってみて、

結果を見ながら調整して「CLAUDE.mdを育てていく」のが良いと思われます。

筆者がここ2週間程使ってみた感じでは、AIが理解し易い形式に簡潔にまとめる必要があるなと感じます。

ポイントとしては、次のような感じでしょうか。

1.CLAUDE.mdは100行以内を目途に別ファイル(100行以内推奨)に分割する。

2.分割ファイルを読ませる指示に「全行読むこと」を含める。

3.指示内容を明確なセクションに分ける

4.セクションには明確な指示内容をタイトルとして記述する(# で始めるやつ)

5.セクション内の指示内容は具体的に箇条書きにする(- で始めるやつ)

6.ファイル名や変数名、名前空間、クラス名等の指定はバッククオートで括る

といったところでしょうか。

ちなみに、筆者が事前に準備したファイルは次のようなものです。

AIが理解し易いこともポイントですが、別の人が見ても理解しやすいこともポイントです。

▼「CLAUDE.md」68行

# 🏗️ CLAUDE.md - Login system

このファイルはAIや開発者向けの詳細設計・運用指示書です。README.mdは利用者向けです

## 概要

これは、外部ライブラリーやフレームワークを使用しない、PHPで書かれた簡単なログインシステムです。
ユーザーはメールアドレスとパスワードでサインアップできます。
ユーザーはサインアップで登録されたメールアドレスとパスワードでログインできます。

## AIアシスタントへの注意事項

When working on this codebase:

1. **Always run `php -l [PHPファイル名]` and fix warnings** before suggesting code
2. **Test your changes** - don't assume code works
3. **Preserve existing behavior** unless explicitly asked to change it
4. **Follow PSR-1, PSR-2 and PSR-12*** - basically follow other PSRs, too. But ignore the PSRs abandoned.
5. **Maintain predictable defaults** - user should never be surprised
6. **Document any new features** in both code and README
7. **Consider edge cases** - empty states, missing files, permissions

Remember: This tool is about speed and simplicity.
Every feature should make context switching faster or easier, not more complex.
**Predictability beats cleverness.**

## 設計

### モデル定義

- `設計_モデル.md`の内容に従う。(最終行まで読み取ること)

### アプリケーションの仕様

- `設計_仕様.md`の内容に従う。(最終行まで読み取ること)

### システム

#### プロジェクトフォルダ

- `システム_フォルダ構成.md`の内容に従う。(最終行まで読み取ること)

#### 開発コマンド

- `システム_開発コマンド.md`に従う(最終行まで読み取ること)

#### システム構成

- `システム_構成.md`に従う(最終行まで読み取ること)

#### テスト

- `システム_テスト.md`に従う(最終行まで読み取ること)

#### ワークフロー

##### 初回

1. Dockerコンテナを構築して開始: `docker compose up -d`
2. `bin/`フォルダ内のコマンド作成
3. データベースマイグレーションファイル作成
4. データベースマイグレーション実行
5. WEBサーバーコンテナにPHPUnit 12をcomposerでインストール
6. `html/`フォルダ内のソースコード作成
7. WEBサーバーコンテナ上でPHPUnitのUnitテスト実行
8. Unitテストが全てpassするまでソースコードを修正してUnitテスト実行
9. Unitテストが全てpassしたらgitでコミットをする

▼「設計_モデル.md」32行

# やってほしいこと
- モデル定義に基づき、マイグレーションファイルをPHPクラスで作成してください。

## マイグレーションファイルのルール
- 設置場所:`html/database/migration/`
- ファイル名:[作成日時(書式:Y_m_d_His)]_[アクション名]_[テーブル名のスネークケース].php
    - アクション名:次のいずれか。不足があれば随時確認する。
        - テーブル作成: `create_table`
        - カラム追加: `add_column`
        - カラム定義変更: `change_column`
        - カラム削除: `remove_column`
- マイグレーション実行方法:プロジェクトトップにてCLIコマンドを実行する
    `php migrate.php`

## モデル定義

### Userモデル
- id: int, 主キー, 自動採番
- username: string, ユーザー名, 必須, 一意
- password: string, ハッシュ化されたパスワード, 必須
- email: string, メールアドレス, 必須, 一意
- created_at: datetime, 登録日時
- updated_at: datetime, 更新日時

### Login履歴モデル
- id: int, 主キー, 自動採番
- user_id: int, ユーザーID, 必須, 外部キー(Userモデルのidを参照)
- ip: string, IPアドレス, 必須
- user_agent: string, User Agent, 必須, デフォルト: ""
- created_at: datetime, 登録日時
- updated_at: datetime, 更新日時

▼「設計_仕様.md」26行

# アプリケーションの仕様

## サインアップ
- ランディングページから「サインアップ」リンクをクリックするとサインアップページに遷移する。
- サインアップページにてメールアドレスとパスワード、パスワード(確認)を入力して「登録」ボタンを押下するとユーザー登録処理が行われる。
- ユーザー登録処理では、事前にバリデーションが実施される。
- バリデーション内容:
    - メールアドレスの2文字目以降に`@`が含まれており、`@`で終わらなければOK。
    - パスワードに英小文字と数字だけが含まれ、8文字以上12文字以下であればOK。
    - パスワード(確認)がパスワードと一致すればOK。
- すべてのバリデーションが`OK`のときだけユーザー登録を実施し、ログイン済の状態にしてダッシュボードへ遷移する。
- バリデーションが`OK`でないものがある場合はユーザー登録をせず、サインアップページでエラーメッセージを表示する。

## ログイン
- ランディングページから「ログイン」リンクをクリックするとログインページに遷移する。
- ログインページにて「メールアドレス」と「パスワード」を入力し「ログイン」ボタンを押下すると認証が行われる。
- 認証前に、サインアップと同じバリデーションを実施する。
- すべてのバリデーションが`OK`のときだけ認証処理を実施する。
- バリデーションが`OK`でないものがある場合はログインページでエラーメッセージを表示する。
- 認証成功したらサイトトップに遷移する。
- 認証失敗したらログインページにリダイレクトしてエラーメッセージを表示する。

## ログアウト
- ログイン後の画面右上にアカウントアイコンを置き、ポップアップメニューから「ログアウト」を選択するとログアウトする。
- ログアウト後はログインページに遷移する。

▼「システム_フォルダ構成.md」100行

# プロジェクトのフォルダ構成

- フォルダ構成:
[ghc-agent-claude-app]・・・プロジェクトトップ
 ├─ .vscode/ ・・・VS Code用設定保存フォルダ
 ├─ bin/ ・・・コンテナ操作用コマンド保存フォルダ
 │  ├─ change-permissions ・・・WEBサーバー用パーミッション変更コマンド
 │  ├─ mariadb-connect ・・・DBサーバー接続コマンド
 │  ├─ mariadb-export ・・・DBダンプコマンド
 │  ├─ mariadb-import ・・・DBインポートコマンド
 │  ├─ mariadb-root ・・・DBコンテナへrootでshell接続するコマンド
 │  ├─ start ・・・コンテナ群起動コマンド
 │  ├─ stop ・・・コンテナ群停止コマンド
 │  ├─ web-root ・・・WEBコンテナへrootでshell接続するコマンド
 │  └─ web-user ・・・WEBコンテナへユーザー権限でshell接続するコマンド
 ├─ docker/ ・・・dockerコンテナ構築用ファイル群保存フォルダ
 │  ├─ mariadb/ ・・・DB用dockerコンテナ構築ファイル保存フォルダ
 │  │  ├─ Dockerfile ・・・DB用dockerコンテナ構築ファイル
 │  └─ web/ ・・・WEBサーバー用dockerコンテナ構築ファイル保存フォルダ
 │    ├─ Dockerfile ・・・WEBサーバー用dockerコンテナ構築ファイル
 ├─ dump/ ・・・DBダンプファイル保存フォルダ(DBダンプの出力先)
 ├─ html/ ・・・WEBサーバー用ソースファイル保存フォルダ(WEBサーバーコンテナ内の /var/www/html)
 │  ├─ app/ ・・・アプリケーション保存フォルダ
 │  │  ├─ Controllers/ ・・・コントローラー保存フォルダ
 │  │  │  ├─ ControllerBase.php ・・・コントローラー基底クラス
 │  │  │  ├─ DashboardController.php ・・・ダッシュボードコントローラー
 │  │  │  ├─ IndexController.php ・・・サイトトップコントローラー
 │  │  │  ├─ LoginController.php ・・・ログインコントローラー
 │  │  │  ├─ LogoutController.php ・・・ログアウトコントローラー
 │  │  │  ├─ SignUpController.php ・・・サインアップコントローラー
 │  │  ├─ Logics/ ・・・ロジック保存フォルダ
 │  │  │  ├─ LogicBase.php ・・・ロジック基底クラス
 │  │  │  ├─ LoginLogic.php ・・・ログイン処理
 │  │  │  ├─ LogoutLogic.php ・・・ログアウト処理
 │  │  │  ├─ SignUpLogic.php ・・・サインアップ処理
 │  │  ├─ Models/ ・・・モデル保存フォルダ
 │  │  │  ├─ ModelBase.php ・・・モデル基底クラス
 │  │  │  ├─ UserModel.php ・・・ユーザーモデル
 │  │  │  └─ LoginHistoryModel.php ・・・ログイン履歴モデル
 │  │  ├─ Validators/ ・・・バリデータ保存フォルダ
 │  │  │  ├─ ValidatorBase.php ・・・バリデータ基底クラス
 │  │  │  ├─ UserValidator.php ・・・ユーザーバリデータ
 │  │  │  ├─ LoginHistoryValidator.php ・・・ログイン履歴バリデータ
 │  │  ├─ Views/ ・・・ビュー保存フォルダ
 │  │  │  ├─ errors/ ・・・エラービュー保存フォルダ
 │  │  │  │  ├─ 401.view.php ・・・HTTP401エラービュー
 │  │  │  │  ├─ 404.view.php ・・・HTTP404エラービュー
 │  │  │  │  ├─ 500.view.php ・・・HTTP500エラービュー
 │  │  │  ├─ layouts/ ・・・共通ビュー保存フォルダ(ヘッダー、フッター、メニュー等)
 │  │  │  ├─ login/ ・・・ログインフォームビュー保存フォルダ
 │  │  │  │  ├─ index.view.php ・・・ログインフォームビュー
 │  │  │  ├─ sign_up/ ・・・サインアップビュー保存フォルダ
 │  │  │  │  ├─ index.view.php ・・・サインアップフォームビュー
 │  │  │  ├─ dashboard.view.php ・・・ダッシュボードビュー
 │  │  └─ Routes.php ・・・ルーティング定義
 │  ├─ config/ ・・・アプリケーション設定ファイル保存フォルダ
 │  ├─ database/ ・・・DB関連ファイル保存フォルダ
 │  │  ├─ factory/ ・・・DB Factoryファイル保存フォルダ
 │  │  ├─ migration/ ・・・DBマイグレーションファイル保存フォルダ
 │  │  │  ├─ 0000_00_00_000000_create_table_users.php ・・・usersテーブル作成ファイル
 │  │  │  └─ 0000_00_00_000000_create_table_login_history.php ・・・login_historyテーブル作成ファイル
 │  │  └─ seeder/ ・・・DBシーダーファイル保存フォルダ
 │  ├─ libs/ ・・・MVCシステムクラスライブラリ設置フォルダ
 │  ├─ public/ ・・・nginxのドキュメントルート(WEBコンテナ上では`/var/www/html/public/`)
 │  ├─ storage/ ・・・各種ファイル保存フォルダ
 │  │  ├─ app/ ・・・アプリケーション用ファイル保存フォルダ
 │  │  └─ logs/ ・・・ログ保存フォルダ
 │  ├─ test_coverage/ ・・・PHPUnit Coverage Result HTML保存フォルダ
 │  ├─ tests/ ・・・PHPUnitテストファイル保存フォルダ
 │  │  ├─ Extensions/ ・・・PHPUnit拡張保存フォルダ(必要ならば)
 │  │  ├─ Http/ ・・・HTTPテスト保存フォルダ
 │  │  │  ├─ HttpTestCase.php ・・・HTTPテストケースクラス
 │  │  ├─ Unit/ ・・・Unitテスト保存フォルダ
 │  ├─ vendor/ ・・・Composerパッケージ保存フォルダ
 │  ├─ composer.json
 │  ├─ migrate.php
 │  └─ phpunit.xml
 ├─ .gitignore
 └─ docker-compose.yml

- `html/` はWEBコンテナ側で `/var/www/html` にボリュームアタッチする
- `html/` はUbuntu(WSL2)側のVS Codeで編集できるようにする
- `dump/` は、DBコンテナ側の`/dump`にボリュームアタッチする
- `bin/mariadb-export`コマンドは、`mariadb-dump`の出力結果を`dump/`に保存する
- `bin/mariadb-import`コマンドは、インポート先のデータベース名をCLIの標準入力からユーザーに入力させる。その後、`dump/`内のファイルをリスト表示し、ユーザーがリストから選択したファイルをDBにインポートする。
- `html/database/migration/`内のファイル命名規則:[アクション]_[テーブル名].php
    - アクション:
        - create_table: テーブル作成
        - add_column: カラム追加
        - rename_table: テーブル名変更
        - change_column: カラム定義変更
        - remove_column: カラム削除
        - drop_table: テーブル削除
    - テーブル名:英小文字と数字とアンダースコアのみを用いたスネークケース
- `html/config/`内はファイルを平置きし、サブフォルダは作らない。
- `html/config/`内のファイル名は英小文字のみとし、内容を推測しやすい簡潔な名前を付ける。
- `html/config/`内のファイルは名前空間を持たず、文字列キーのハッシュ配列を返すreturn文だけで構成するものとする。
- `html/config/`内のファイルが返すハッシュ配列の内容は、グローバル関数`config(string $key)`で参照できるものとする。引数の`$key`はハッシュ配列が多次元の場合、ドット記法でアクセスできるものとする。
- `html/tests/`内に設置するテストファイルのファイル名は末尾を`Test.php`とする。

▼「システム_開発コマンド.md」15行

# 開発コマンド

## Ubuntu (WSL2) 上で実行するコマンド
- `bin/start` - 開発用コンテナ群起動
- `bin/stop` - 開発用コンテナ群停止
- `bin/web-user` - WEBサーバー用コンテナへユーザー権限でshell接続
- `bin/web-root` - WEBサーバー用コンテナへroot権限でshell接続
- `bin/mariadb-root` - DBサーバー用コンテナへroot権限でshell接続
- `bin/mariadb-connect` - DBサーバー用コンテナのDBへrootユーザーで接続

## WEBサーバー用コンテナのshell上で実行するコマンド
- `composer test-unit` - Unitテストの実行: "XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-html test_coverage --testsuit Unit"
- `composer test-http` - HTTPテストの実行: "vendor/bin/phpunit --testsuit Http"
- `php migrate.php` - DBマイグレーションの実行

▼「システム_構成.md」62行

# システム構成

## フレームワーク

- PHPUnit 12

IMPORTANT: PHPUnitとその依存関係のみを使用する。他の外部ライブラリやフレームワークは使用しない。

## スタイリング

- Bootstrap v5.3:CDNは利用禁止。ファイルセットをローカルに保存して利用する。

## 言語

- PHP 8.4(下位バージョンは不可とする)
- jQuery最新バージョン:CDNは利用禁止。ファイルセットをローカルに保存して利用する。

## WEBサーバー

- nginx
- ローカルではDockerイメージを利用して、docker-compose.yml に追加
- 一般ユーザーアカウント:`ec2-user`を作成する
- `ec2-user`のumaskは0000とする
- `/var/www/html`配下のすべてのフォルダ、ファイルは`ec2-user`が所有権を有する。

## DB

- mariadb:11.8.2
- ローカルではDockerイメージを利用して、docker-compose.yml に追加
- `docker/mariadb/data`をデータフォルダとして設置し、docker-compose.ymlでvolumeバインドする。
- `docker/mariadb/data/.gitignore`を設置し、このフォルダはgit管理下に置くが、`.gitignore`以外のフォルダ内の全ファイルをgit管理の対象外とする。

## SMTP

- axllent/mailpit:v1.26.2
- ローカルではDockerイメージを利用して、docker-compose.yml に追加

## 認証

- サインアップあるいはログインに成功した場合、セッションの `authenticated` の値を `true` とする。
- 認証に失敗した場合、セッションの `authenticated` の値を `false` とする。
- ログアウトした場合、セッションの `authenticated` の値を `false` とする。
- セッションの `authenticated` の値が `true` の場合は認証済とする。

## PHPのセッション

- セッションIDはPHPの `session_start()` で自動発行されるセッションIDを `session_id()` で取得し利用する。
- `session_start()`の実行回数は、一連の処理開始から処理終了までの間に1度だけとする。
- すべてのセッション関連の処理は`session_start()`の実行ステップの後に記述する。
- セッションはローカルファイルシステムに保存する形式とする。
- セッションの保存場所はデフォルトの`/tmp`とする。
- Dockerでの永続化は不要。
- セッションには必要最低限の値のみを記録し、不要になったら削除すること。
- セッションに保存するデータが肥大化しないように注意する。

## セキュリティ

- パスワードのハッシュ化:DBへパスワードを保存する際には`sha256`を使ってハッシュ化する
- 認証等、パスワードの照合時には、ハッシュ化した文字列を比較して判断する。
- CSRF対策:フォーム等、POSTメソッドでのアクセス時には必ず、FORMの値として`_token`をtype="hidden"でPHPSESSIDの値を埋め込んでおき、POSTされた`_token`と、Cookieの`PHPSESSID`とを照合する。`_token`の値が無いか、あるいは`_token`の値と`PHPSESSID`の値が一致しない場合は、HTTPステータスコード419(Page Expired)として処理する。
- XSS対策:テキストの入力値を画面表示に使う際には、XSS対策として必ずHTMLエンティティのエスケープ処理を施す。

▼「システム_テスト.md」42行

# テスト

すべてのテストはPHPUnitを使用して実行する。

## テストの実行

- `phpunit.xml`内に設定する内容:
    - 出力形式は`testdox`とする
    - Errorsの内容出力を有効にする
    - Warningsの内容出力を有効にする
    - Deprecationsの内容出力を有効にする
    - Noticesの内容出力を有効にする
    - 環境変数`APP_ENV=testing`を設定する
    - Unitテスト、HTTPテストをそれぞれ testsuite として設定する

## Unitテスト
- テスト対象ファイル:
    - `html/libs/`内のファイル
    - `html/app/*/*Base.php`
- カバレッジ測定:Unitテストにおいてのみ実施する
- 実行コマンドは`composer.json`の`script`のセクションに`test-unit`の名称で登録する:
    ```
    "scripts": {
        "test-unit": "XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-html test_coverage --testsuite Unit"
    }
    ```
- 実行コマンドはWEBコンテナ上で実行する:`docker compose exec web composer test-unit`
- Unitテスト実行後は`test_coverage/`に出力された最新のカバレッジレポートの内容を自動で読み取って結果を判断すること。
- 目標カバレッジ:ラインカバレッジ100%(メソッドカバレッジとクラスカバレッジは無視する)
- カバーしきれないラインやコードブロックは、適宜`@codeCoverageIgnore`かあるいは`@codeCoverageIgnoreStart`、`@codeCoverageIgnoreEnd`を適用する。

## Httpテスト

- `curl`関数、または`file_get_contents()`関数を用いて実際にHTTP/HTTPSアクセスを実施してHTTPレスポンスを取得するクラスを作成して使用する。
- PHPUnitの拡張アサーションを作成する:
    - `assertStatus(int $status)`: HTTPステータスコードの検証
    - `assertOk()`: HTTPステータスコードが200であることを検証
    - `assertRedirect(?string $url)`: HTTPステータスコードが300,301のいずれかであるか、また`$url`が指定された場合は、`Location:`の値が`$url`と一致するかを検証
    - `assertSee(string $needle)`: HTTPレスポンスボディ内に`$needle`が含まれることを検証
    - `assertDontSee(string $needle)`: HTTPレスポンスボディ内に`$needle`が含まれないことを検証
- カバレッジは測定しない

結構長々と書いていますが、長いと、やはり「無視」されます。。

ただし、ファイルに分けておくと、無視された際にファイル指定で再指示を与えれば良いというメリットがあります。

再指示の際に、忠実に指定ファイルを読み込んで解釈してくれるのですが、

数百行に及ぶファイルだと、読込の単位が100行毎になり、読込にかなり時間が掛かります。

場合によっては、与えたい指示は120行目にあるのに、100行だけ読み込んで、その気になって勝手に作業を進めてしまうという事象がまま見受けられました。

ということがあったため、指示ファイルは100行以内にし、読込ファイルの指定では「最終行まで読み込むこと」の指示を追記した方が良いと思われます。

Agentモードを使ってみる

では、本題のAgentモードを使った開発作業に進みましょう。

VS CodeのGitHub Copilotチャットベイン最下部のモードを「Ask」から「Agent」に変更し、

モデルを「GPT-4.1」から「Claude Sonnet 4」に変更した状態で

「CLAUDE.mdの内容に従って、簡単なログイン機能をPHP8.4で作成してください。」との指示を与えてみます。

「CLAUDE.md」をベースに一気に分割ファイルの方も読み込んでくれていますが、一部の行が無視されているようです。。

まあ、後で確認して、ダメなら再指示の方向で。

GitHub Copilotが自動作成したファイルは、VS Code内の「エクスプローラベイン」内で、ファイル名の右側に日の丸のようなアイコンが表示されます。(すみません、ここの画像なし。)

Agentモード稼働中でも、編集済のファイルは内容確認できるため、この時間でレビューしておきましょう。

エディタ内に「保持」「元に戻す」ボタンが出てくるので、問題なければ「保持」ボタンを押下して確定していきます。

問題がある場合には、Agentモードを一時停止させるか、作業が終わって待ち状態になってから再指示を与えれば良いでしょう。

ちなみに、一気に作業を進めてもらおうと思っても、

Agentモードの自動作業が数分間に及ぶと、途中でGitHub Copilotが「反復処理を続行しますか?」と確認を求めてきます。

Agentモードでは、たまに無限ループのような状態に陥ることがあるので、

それを防止するための確認機能なのでしょう。

この場合は、人間が選択をしないと先に進めません。

また、自動作業とはいいつつも、CLIでのコマンド実行などは、毎回必ず人間側に実行の許可を求めてきます。

この辺は、CLIツールのCLAUDE CODEとは異なる、GitHub Copilotの安全設計なのでしょう。

というわけで、CLAUDE用の「settings.json」(使用コマンドの可否設定等)は無用と思われます。

その分、CLAUDEでは可能だった、「入浴中に作業を進めてもらう」が無理だということが判ります。

一応、初回ということもあり、一旦、AIが一息つくまで作業を進めてもらいました。

ここまで約15分。ある程度の概形はできています。(30%程度)

一見、完成したかのように見せていますが、実は作業指示に従っていません。

一番最初の「Dockerコンテナを構築して開始」という指示が無視されており、

「Dockerコンテナ内にPHPUnit」をインストールする指示が完了したかのようになっています。

テストコードは一切実装されておらず、他のファイルの配置も指示通りではないので、

「再度CLAUDE.mdを読み取って、指定したフォルダ構成に沿っているか照合してください。」

と指示を与えてみました。

ちゃんと指示ファイルを再読み込みして、現状の構成を確認した上で修正案を提示して作業を進めてくれます。また、「ここのコードを修正したので、関連するこちらのコードも修正しておきます。」などの判断も自動で実施して修正してくれます。

この辺は、さすがコーディング用のモデルです。対応の精度が非常に高い。

「GPT-4.1」は残念ながら、この辺は「やったふり」や「指示に従わない」ことが多い印象です。挙句の果てには、既存の正常なコードを壊し始めたりします。。やめて(涙

AIが作業している間、人間は「ヒマ」なのですが、遊んでいてはいけません。

「ヒマ」な時間は有効活用しましょう。やるべきことは山ほどあります。

  • AI作業の監視(あらぬ方向に進み出したら即停止、再指示!)
  • コードレビュー(これ重要:サボるとレジェンド級のファンタジー物が出来上がります)
  • OKなコードの受け入れ(「保持」ボタン押下、あるいは差戻し)
  • なんならAIの補助、あるいはAIとは別のファイルの編集等
  • なんなら指示ファイルの再検討・修正等

などなど。

ちなみに、指示ファイルを修正したら指示を出し直しましょう。

ファイル構成の再整理、未実装のコード実装、テスト実施、カバレッジ100%に向けての修正作業などなど、諸々の作業を繰り返して一通りまっとうに動くようになるまで約12時間かかりました。

フレームワークや外部ライブラリを禁止して、MVCをゼロベースで作らせたので、筆者がやれば何日か掛かったことでしょう。

それを思うと圧倒的な速さです。一番の問題はその品質なのですが。。

ちなみに、あまり細かいレビューはしていません。(反省)

出来上がった代物を確認してみる

で、ブラウザで確認してみたら、思った以上に豪華なものが出来ていたのですよw

極々質素なものを想定していた筆者としてはここまで豪華にされると恥ずかしい。

「ようこそ」とかいらない。。

やっぱり、デザインのモックアップは用意すべきでしょうね。。次への教訓。

今回の成果物は、今後の教訓として筆者のGithubリポジトリで晒しておきます。

GitHub - macocci7/ghc-agent-claude-app: An experimental app created by the github copilot agent mode using the `claude-sonnet4` model(so clever!) with a few instruction files and minor reviews and corrections. I should probably review it more thoroughly though.
An experimental app created by the github copilot agent mode using the `claude-sonnet4` model(so clever!) with a few ins...

後で確認してみたら、やはり完成はしていませんでした。。

無理矢理まとめと所感

▼1.CLAUDEモデルは優秀、Sonnet-4の一択でしょう。GPT系は遠慮したい。

▼2.指示ファイルは準備しよう。内容は簡潔に、目的別にファイル分割。

▼3.AI作業中はヒマではないよ。人間がやるべき作業を進めよう。

▼4.AIは作業が速い!人間のレビューと再指示のサイクルを含めても数倍の効率!

▼5.業務利用なら「GitHub Copilot Pro+」(1500Premium Request/月, 39USD/月)がおすすめ

▼6.AIはプログラマーの代替えではなく相棒。人間にはより高度な技術力と知識や経験に基づいた「判断」と「指示」が求められる。

 ⇒ さらなる技術の研鑽が求められる。。

参考サイト

GitHub Copilotでバイブコーディング:エージェントモードとMCPサポートがVS Codeユーザーに提供開始
MCPをサポートしたエージェントモードをすべてのVS Codeユーザーに展開します。また、新しい GitHub Copilot Pro+ プラン (プレミアム リクエスト付き)、Anthropic、Google、OpenAI のモデルの一般...
CLAUDE.mdのテンプレートを作りました
Claude 4 プロンプトエンジニアリングのベストプラクティス - Anthropic
Claude 4モデルに最適なプロンプトエンジニアリング手法

  • 2
  • 0
  • 1
  • 0

コメント

Copied title and URL