メインコンテンツまでスキップ

指示のポイント

GitHub Copilotから質の高いコードを引き出すためには、的確な指示(プロンプト)が不可欠です。AIを優秀な開発パートナーとして活かすには、人が「適切なコンテキスト」と「明確なゴール」を与えることが重要です。

本ページでは、AIへ指示を出す際の基本的なポイントを解説します。まずはここで紹介する基本的な考え方を押さえ、具体的なプロンプトの例は後続のコンテンツで学んでいきましょう。

また、ここで紹介するポイントは1度の指示で完結させることだけを目指すものではありません。AIとの対話を通じて段階的に適用していくことで、より良い成果物が得られます。
AIを優秀なパートナーと捉え、対話を重ねながら共同で成果物を育てていく意識が重要です。

GitHub CopilotおよびVisual Studio Codeの以下のドキュメントも参考にするとよいでしょう。

実装要件を明確に伝える

AIにコード生成を依頼する上でもっとも重要なのは、「何を作って欲しいのか」を具体的かつ明確に伝えることです。曖昧な指示は、意図しない結果を招く最大の原因となります。
実装したいクラスやメソッドの目的、満たすべき仕様などを具体的に記述することが、精度の高いコード生成への第一歩です。

良くない例:

ユーザー登録機能を作成して。

良い例:

`User`オブジェクト(名前、メールアドレスを持つ)を引数に取り、DBに保存する`createUser`メソッドを作成してください。その際、同じメールアドレスがすでに存在する場合は例外をスローしてください。

テストコードの生成を依頼する場合も同様です。正常系・異常系シナリオ、モックの振る舞い、期待するアサーションなど、テストの観点や仕様を具体的に伝えることで、網羅的で質の高いテストコードを得られます。

関連するコードや文脈(コンテキスト)を提供する

AIはプロジェクトの全体像、たとえばプロジェクトの背景やコーディング規約やディレクトリ構造などを把握していません。そのため、生成を依頼するコードがプロジェクト内でどのような役割を担い、他のどの部分と連携するのか、といった「文脈(コンテキスト)」を提供することが極めて重要になります。関連する既存のインターフェースやデータモデルのコードを提示し、それらを利用して実装するよう具体的に指示しましょう。

たとえば、実装指示をする時は合わせて参考にするコードも渡すようにします。

以下の`User`クラスと`UserMapper`インターフェースを使って、ユーザーをIDで検索する`UserService`クラスの`findUserById`メソッドを実装してください。

```java
// User.java
public class User {
private Long id;
private String name;
// ... getter/setter
}

// UserMapper.java
public interface UserMapper {
User selectById(Long id);
}
```

一方で関連性の低い情報を大量に与えすぎると、AIが混乱して精度が落ちる原因になります。また関連はあっても情報が多すぎると、本当に重要な指示が埋もれてしまう可能性もあります。
これは、人間に対して一度に大量の資料を渡したり、本筋と関係のない話を延々と聞かせたりすると、かえって要点が伝わりにくくなるのと同じです。
コンテキストは「量より質」を意識し、今まさに行おうとしているタスクに直接関係する情報へ、的を絞って提供することが重要です。

トークン数について

AIが扱えるトークンの数(コンテキストウィンドウ)には上限があります。どのくらいの数のトークンを扱えるのかはモデルごとに異なりますが、多くのトークンを扱えるモデルであってもこのセクションで書いたようにAIに与える情報は取捨選択するようにしましょう。

また、AIは一連の会話の内容を覚えています。現在会話しているテーマとはまったく異なるテーマの話をするのであれば、新しくチャットを始めましょう。
新しいテーマに関する文脈から見るとその直前の会話も「関連性の低い情報」となるため、いろいろなテーマを混ぜてしまうとこれもAIの精度が落ちる原因となります。

役割(ロール)を指定する

AIに特定の専門家としての「役割(ロール)」を与えることで、出力されるコードのスタイルや品質をコントロールできます。求める専門性(例:セキュリティ専門家、パフォーマンスチューニングの達人など)を明確に指定することで、AIはその役割に沿った視点からコードを生成しようとします。
これは、役割を与えることで、AIが膨大な学習データの中からその役割に特化した知識やコーディングスタイルを優先的に参照するようになるためです。

たとえば、以下のような役割を与えることで、より質の高いコード生成が期待できます。

あなたは経験豊富なSpring Boot開発者です。フレームワークのベストプラクティスに従い、堅牢で保守性の高いREST APIのエンドポイントを実装してください。

実装例を示す

プロジェクトに固有のコーディング規約や特徴的な設計パターンが存在する場合、そのルールに沿った短いコード片を「お手本」として示すことが非常に有効です。AIは提示された例を模倣し、プロジェクト全体で一貫性のあるコードを生成しようとします。

たとえば、以下のような実装例を提示し、「このコーディングスタイルにしたがって、ユーザ(User)を管理するUserControllerを実装してください」と指示します。

@RestController
@RequestMapping("/api/products")
public class ProductController {

private final ProductService productService;

public ProductController(ProductService productService) {
this.productService = productService;
}

@GetMapping("/{id}")
public Product getProduct(@PathVariable Long id) {
return productService.findById(id);
}
}

制約条件や非機能要件を伝える

「何をするか(機能要件)」だけでなく、「何をすべきでないか」や「どのような品質を担保すべきか(非機能要件)」といった制約を明確に伝えることも、手戻りを減らす上で重要です。

- パフォーマンスを優先し、ループ内でのデータベースアクセスは避けてください
- ○○ライブラリは使用せず、△△に関する機能はJava標準APIのみで実装してください

対話を通じてアウトプットを洗練させる

一度の指示で完璧なコードが得られることは稀です。もし意図しないコードが生成されたとしても、それは失敗ではありません。「自分の指示のどこが曖昧だったか?」を振り返り、改善する良い機会と捉えましょう。
生成されたコードを土台として、具体的かつ建設的なフィードバックを与えることで、コードの品質を段階的に高めていくことができます。

**ユーザー:** (必要な仕様は提示したうえで)`createUser`メソッドを作成して。

**AI:**`createUser`メソッドを生成)

**ユーザー:** では、このメソッドにJakarta Bean Validationを使った入力チェック処理を追加してください。

**AI:** (入力チェック処理を追加したコードを生成)

**ユーザー:** 最後にこのクラスのJavadocを記述してください。

また、内容によってはプロンプトにフィードバックすることも検討しましょう。