前回は GitHub Copilot Agent Mode の概要と、VS Code 上での基本的な有効化手順を紹介しました(第1回はこちら)。「なんとなく動かせるようになった」という状態からが、実はここからが本番です。
Agent Mode、使い始めると「思ったのと違う動きをした」「余計なファイルまで書き換えられた」みたいなことが割とすぐ起きます。自分もやらかしました。というか今も油断するとやらかします。
今回はその原因のほとんどが「指示の書き方」と「タスクの渡し方」にあるという話を、実際に使いながら気づいたことを交えて書きます。
この記事でわかること
- Agent Mode に曖昧な指示が危ない理由
- 「よい指示」の4つの要素構造(目的・対象・制約・出力イメージ)
- タスクを段階的に分割して渡す方法
- copilot-instructions.md で共通ルールを管理する方法
- Prompt Files でテンプレートを活用する方法
- うまくいかないときの確認ポイント
Agent Mode は「察してくれる AI」ではない
まず最初に認識を合わせておきたいのですが、Agent Mode は優秀ですが「空気を読む」タイプではないです。曖昧な指示を出すと、それなりに解釈して動いてしまうので、意図と違う結果になりやすい。
たとえば「このファイルをリファクタリングして」と投げると、呼ばれてもいない関数の命名まで変えてきたり、「ついでにこっちのファイルも直しました」をやってくれたりします。親切なんですが、こちらが望んでいないタイミングで範囲を広げられると困る。
Agent Mode が自律的にタスクを分解して動ける分、指示が曖昧だと「自律」の方向がズレやすいんだと思います。Edit モードよりも自由度が高い代わりに、指示の質がそのまま結果の質に直結する感じです。
じゃあどう書けばいいのか、というのが今回のテーマです。
「よい指示」の構造を分解してみる
いろいろ試した結果、Agent Mode への指示は大きく4つの要素で構成されていると整理しています。
- 目的:何を達成したいか(What)
- 対象:どのファイル・関数・範囲に対してか(Where)
- 制約:やってほしくないこと、触らないでほしいもの(Not)
- 出力イメージ:完了状態をどう判断するか(Done)
全部書かないといけないわけじゃないですが、少なくとも「目的」と「対象」はほぼ必須で、「制約」を書くかどうかで結果の安定感がかなり変わります。Out of Scope を明示することが重要で、Copilot は「ついでにこっちも直しました」をやりがちなので、やらないでほしいことを明示するのが地味に効きます。まさにそれを体感しています。
悪い例と良い例
たとえば DynamoDB から取得したデータを整形する Python 関数を修正したいとします。
❌ よくない指示
このコードをきれいにして
これだと Agent が「きれい」を自分で定義して動いてしまう。型ヒントを追加したのか、ロジックを変えたのか、変数名を変えたのか、全部まとめてやられると差分を追うのが大変です。
✅ よい指示
utils/dynamo_helper.py の get_item 関数に Python の型ヒントを追加してください。
ロジックの変更や他の関数への影響は不要です。型アノテーションの追加だけでお願いします。
「どのファイルの」「どの関数を」「何をするか」「何はしないか」が明示されているので、Agent の動きが予測しやすくなります。
そういえば最近、Cursor でも同じような工夫を重ねている人の話を聞きました。プロンプトの書き方の勘所はツールの種類を問わず共通しているみたいです。
タスクを「分割して渡す」という発想
Agent Mode にはコンテキストウィンドウの上限があります。たとえば最新モデルは 100万トークンのコンテキストをサポートするなど、使っている製品や設定・モデルによって変わるようです。なので「大きすぎるタスクは途中で情報が欠落し、意図しない変更が入ることがある」という前提だけ押さえて、段階的に進めると品質が上がりやすいというのが実感です。
なので、大きな作業ほど意図的に細かく分割して渡すのが基本方針になります。自分がよくやるのはこんな順番です:
- まず「現状を把握させる」指示を出す(コードを読ませる・構造を説明させる)
- 次に「方針だけ提案させる」(コードは書かせない)
- 方針を確認してから「実装する」
- 最後に「確認・テストコードを書く」
いきなり「全部やって」を投げると何が起きているかわからなくなるんですよね。ステップを分けると、どこで意図がズレたかも追いやすい。分割したタスクの結果を、次のタスクの追加コンテキストとして使うことができますし、途中からの再開やリトライもしやすくなります。これが地味にありがたいです。
実際の流れ(Lambda 関数のリファクタリング例)
たとえば AWS Lambda の関数を整理したいとき、こういう順番で投げています。
Step 1: 現状把握
#file:lambda_function.py を読んで、この関数が何をしているか100文字以内で説明してください。
コードの変更は一切不要です。
Step 2: 方針確認
この関数をリファクタリングするとしたら、どのような点を改善できますか?
変更案を箇条書きで提示してください。コードの編集はまだしないでください。
Step 3: 実装(範囲を絞って)
先ほどの提案のうち、「エラーハンドリングの追加」だけを実装してください。
他の変更は今回は不要です。
「まだしないでください」「今回は不要です」という制約ワードが地味に効きます。Agent は親切なので、言わないと勝手にやってしまいがち。
ファイル編集は最もコストの高い操作とされており、編集前に必ず関連箇所を読み、変更箇所を一意に特定できるよう前後のコンテキストを含めることが推奨されています。また、同じファイルで3回以上失敗した場合は別のアプローチを検討するよう設計されているようです。なので Agent がループしているように見えたら、指示を変えてみるのが正解だと思います。
copilot-instructions.md でプロジェクトのルールを仕込む
毎回同じ制約を書くのは面倒なので、プロジェクト固有のルールは .github/copilot-instructions.md に書いておくのが便利です。VS Code はワークスペース直下の .github/copilot-instructions.md を自動検出して、その指示をワークスペース内のチャットリクエストに適用します。Instructions ファイル(*.instructions.md)は YAML フロントマターの applyTo などで適用範囲を制御できるのに対し、.github/copilot-instructions.md は「プロジェクト全体」に対して使う指示を書いておく場所、という整理がわかりやすいです。
# プロジェクトルール
## 言語・フレームワーク
- Python 3.12
- AWS Lambda(ランタイム: python3.12)
- DynamoDB アクセスは boto3 を使用
## コーディング規約
- 型ヒントを必ず付ける
- docstring は Google スタイルで書く
- 関数は 30 行以内を目安にする
## 触れてはいけないファイル
- legacy/ 以下のファイルは変更しない
- .env ファイルは絶対に編集しない
これを入れておくと、毎回「型ヒントを付けて」「legacy は触らないで」と書かなくて済むので楽になります。ただ正直なところ、自分は copilot-instructions.md を書きすぎて逆にコンテキストが太りすぎた失敗もしています。全部書けばいいわけじゃなくて、本当に毎回適用したいルールだけ書くのが肝心みたいです。
Prompt Files でよく使う指示をテンプレート化する
Prompt Files(*.prompt.md)は、頻繁に行うタスクをテンプレート化して再利用可能にする機能です。対話形式で必要な変数を確認するよう記述すれば、動的な入力に対応した定型処理を自動化できます。
たとえば「テストコードを書く」という作業を毎回 Agent に頼むなら、こんなファイルを作っておけます。
---
mode: 'agent'
description: '指定したモジュールの pytest テストを生成する'
---
# テストコード生成
以下のモジュールに対して pytest を使ったテストコードを作成してください。
## 要件
- テスト対象: ${input:テスト対象のファイルパスを入力してください}
- カバーすべき観点: 正常系、異常系(例外処理)、境界値
- モックが必要な外部依存は pytest-mock を使う
- テストファイルの配置先: tests/ ディレクトリ
## 禁止事項
- テスト対象のソースコードは変更しない
- 既存のテストファイルは上書きしない
${input:...} の部分は実行時にインタラクティブに入力できます。これを .github/prompts/ 以下に置いておけば、チャットの入力欄から / で呼び出せるようになります。
Instructions が「全般的なルール」を定義するのに対し、Prompt Files は「特定タスク向けの詳細な指示」を管理するものという整理が一番しっくりきました。テスト生成・ドキュメント作成・リファクタリング候補の洗い出しあたりをテンプレート化しておくと地味に快適です。
うまくいかないときの確認ポイント
Agent Mode を使っていてハマったとき、自分がまず確認することをまとめておきます。
- コンテキストが重くなっていないか:会話が長くなると精度が落ちやすいので、新しい Chat を開いてリセットする
- ファイルを明示的に指定しているか:
#file:xxx.pyでファイルを渡すと、Agent がコードベースをさまよう時間を減らせる - 指示が長すぎないか:情報は多ければいいわけでもなく、関係ない情報が多いと焦点がブレやすい
- 制約を書いているか:「やらないでほしいこと」を書くだけで結果がかなり安定する
Agent Mode はプレミアムリクエストを消費するので、「答えが知りたいだけ」なら Ask モード、「特定ファイルの修正」なら Edit モード、「ゼロから作成や複数ファイル変更」なら Agent モード、という使い分けが重要です。全部 Agent Mode で解決しようとすると月の上限がすぐ溶けます(経験談)。
あと、Agent Mode はモデルによっても挙動が結構変わります。Claude Sonnet 4 や GPT-4o あたりが選べますが、長めのタスクは Claude が安定してる気がしています。個人の感想なので参考程度に。
まとめ
GitHub Copilot Agent Mode で意図しない編集を防ぐポイントをまとめると:
- 指示は「目的」「対象」「制約」「出力イメージ」の4要素で構成する
- 特に「何をしないか」という制約を明示することが重要
- 大きなタスクは4ステップ(現状把握 → 方針 → 実装 → 確認)に分割して渡す
- プロジェクト共通ルールは
copilot-instructions.mdで管理する - 頻出タスクは Prompt Files でテンプレート化する
- うまくいかないときはコンテキストをリセットするか、ファイルを明示的に指定する
最初は「いちいち細かく書くのは面倒だな」と感じるかもしれませんが、これらの工夫をするのとしないのでは、Agent Mode の信頼性が全く違います。慣れると指示の粒度感も身についてくるので、試行錯誤しながら自分のワークフローを作ってみるのがいいと思います。
📚 シリーズ「GitHub Copilot Agent Mode 実践入門」(第2回 / 全4回)
← 前回の記事: 前回の記事はこちら
→ 次回の記事: 【第3回】GitHub Copilot Agent Mode 実践入門 — ファイル横断リファクタリング・テスト生成・コードレビューへの応用

