プロンプトエンジニアリング実践
はじめに
AI コーディングエージェントを活用する上で、「何をどう伝えるか」は生産性を大きく左右する。本モジュールでは、Claude Code や Cursor などのツールで実践的に使えるプロンプトエンジニアリングの手法を学ぶ。
ポイントは、プロンプトを「その場限りの指示」ではなく「持続的なシステム」として設計することだ。
タスク分解: エージェントサイズに分割する
なぜ分解が必要か
エージェントは「1 つの明確な目標」に対して最も良い結果を出す。大きすぎるタスクは、コンテキストの喪失、方向性のブレ、中途半端な成果物につながる。
分解の原則
良い粒度の目安:
- 1 つのファイルまたは密接に関連する 2-3 ファイルの変更
- 変更の意図が 1-2 文で説明できる
- 完了条件が明確に定義できる
分解の例:
悪い例: 「患者管理機能を実装して」
良い例:
1. 「Patient の domain model を定義して」(型定義)
2. 「Patient の CRUD repository を実装して」(データアクセス)
3. 「Patient 検索 API のハンドラを実装して」(API レイヤー)
4. 「Patient 検索のバリデーションを追加して」(入力検証)
5. 「Patient 検索の統合テストを書いて」(テスト)
依存関係を意識した順序付け
## 実装順序
1. 型定義(他のすべてが依存)
2. Repository interface(ハンドラとテストが依存)
3. Repository 実装
4. API ハンドラ
5. テスト(すべての実装が完了後)
制約の明示的な指定
エージェントは暗黙の制約を理解できない。すべての制約を明示的に伝える必要がある。
制約の種類と伝え方
アーキテクチャ制約
このプロジェクトは Clean Architecture に従っている。
- domain/ は外部パッケージに依存してはならない
- handler/ は domain/ の interface を通じてのみデータにアクセスする
- 既存のパターンは src/api/handlers/medication.go を参照
スタイル制約
- エラーハンドリングは fmt.Errorf で wrap し、コンテキストを含める
- ログは structured logging (slog) を使用する
- テーブル名は snake_case の複数形(例: patients, medical_records)
ビジネス制約
- 患者 ID は UUID v4 形式
- 検索結果は最大 50 件/ページ
- 削除は論理削除(deleted_at フィールドの更新)
CLAUDE.md での制約の永続化
プロジェクトルートの CLAUDE.md に共通の制約を記述しておくと、毎回のプロンプトで繰り返す必要がなくなる。
# CLAUDE.md
## プロジェクト構造
- src/domain/ - ドメインモデルとビジネスロジック
- src/api/ - HTTP ハンドラ
- src/infra/ - 外部サービスとの接続
## コーディング規約
- Go 1.22+ の機能を使用可
- エラーは必ず wrap して返す
- context.Context を第一引数に取る
## テスト
- テストファイルは対象と同じディレクトリに配置
- テーブル駆動テストを優先
- モックは interface を使って DI する
## 重要な制約
- 患者データを含む API は必ず認証ミドルウェアを通す
- 外部 API 呼び出しは必ず timeout を設定する
- docs/architecture/ の設計ドキュメントを参照すること
Progressive Disclosure: 効率的なコンテキスト提供
問題: コンテキスト過多
エージェントに大量の情報を一度に与えると、重要な情報が埋もれる。
悪い例:
「以下の 500 行のコードを読んで、この機能を追加して...
(大量のコードをペースト)」
解決策: 段階的な情報開示
Level 1: AGENTS.md / CLAUDE.md(常に読まれる)
- プロジェクトの概要
- 重要な規約へのポインタ
- ディレクトリ構造の説明
Level 2: 参照パスの提示(必要に応じて読まれる)
既存の API ハンドラのパターンは src/api/handlers/medication.go を参照。
型定義は src/domain/patient/types.go を見てください。
Level 3: 詳細ドキュメント(深い理解が必要なとき)
設計の背景は docs/design/patient-management.md を参照。
API 仕様は docs/api/patient-search.md にある。
実践パターン
## Claude Code での例
患者検索 API を実装してください。
### 参照すべきファイル
- 既存パターン: src/api/handlers/medication.go
- 型定義: src/domain/patient/types.go
- DB スキーマ: migrations/003_patients.sql
### 仕様
- GET /api/v1/patients?q=検索語&page=1&limit=20
- レスポンス形式は既存の medication list API と同じ pagination 構造
- 検索対象: 名前(部分一致)、患者 ID(完全一致)
### 制約
- 認証必須(既存の auth middleware を使用)
- 200ms 以内のレスポンス
よくあるアンチパターン
1. 曖昧すぎるプロンプト
悪い例: 「検索機能を改善して」
良い例: 「GET /api/v1/patients の検索に、名前のふりがな検索を追加してください。
既存の name フィールドの部分一致検索に加えて、name_kana フィールドでも
部分一致検索ができるようにする。OR 条件で結合する。」
2. 冗長すぎるプロンプト
悪い例:
「Go言語でHTTPハンドラを書きます。Go言語ではnet/httpパッケージを使って
HTTPサーバーを作ることができます。ハンドラは...(Go の基礎知識を延々と説明)」
良い例:
「GET /api/v1/patients のハンドラを実装してください。
既存の medication ハンドラ (src/api/handlers/medication.go) と同じパターンで。」
3. コンテキストの手動コピー
悪い例:
「以下のコードがあります:
(500 行のコードをペースト)
これを修正して...」
良い例:
「src/api/handlers/medication.go のエラーハンドリングを改善してください。
具体的には、L45-60 の validateInput 関数で、
バリデーションエラー時にフィールド名を含めるようにする。」
4. 一度に複数の無関係なタスク
悪い例:
「検索機能を追加して、あとログのフォーマットも変えて、
ついでにテストも書いて」
良い例: 3 つの別々のプロンプトに分ける
ツール別のプロンプト戦略
Claude Code
CLI ベースで、複数ファイルの変更に強い。自律的に動作できる。
効果的な使い方:
# CLAUDE.md がある状態で
claude "Patient 検索 API を実装してください。
仕様は docs/exec-plans/patient-search.md に記載。
既存パターンは src/api/handlers/medication.go を参照。"
Tips:
- CLAUDE.md を充実させることで、毎回のプロンプトを短くできる
docs/exec-plans/に実装計画を事前に書いておくと精度が上がる- 複数ファイルにまたがる変更(リファクタリング等)に特に強い
- worktree ごとにエージェントを走らせ、並列作業が可能
Cursor
IDE 統合型で、コードを見ながらの対話的な編集に強い。
効果的な使い方:
# ファイルを開いた状態で
「この関数にページネーションのサポートを追加して。
既存の ListMedications と同じパターンで。」
Tips:
.cursorrulesファイルでプロジェクト固有のルールを設定- 開いているファイルが自動的にコンテキストになる
@fileや@folderでコンテキストを明示的に指定できる- 小さな変更の繰り返し(イテレーション)に向いている
GitHub Copilot
インライン補完型で、コードを書いている流れの中で使う。
効果的な使い方:
// ListPatients は患者一覧を返す。
// ページネーション付きで、name の部分一致検索をサポートする。
// 既存の ListMedications と同じレスポンス形式。
func (h *PatientHandler) ListPatients(w http.ResponseWriter, r *http.Request) {
// ← ここで Copilot が続きを提案
}
Tips:
- コメントで意図を書くと、より良い補完が得られる
- 関数シグネチャと doc comment を先に書く
- 同じファイル内の類似コードがコンテキストとして使われる
- 単体のコード補完には最も手軽
AGENTS.md の設計パターン
AGENTS.md は「テーブルオブコンテンツ」として設計する。百科事典ではない。
良い AGENTS.md の構造
# AGENTS.md
## このリポジトリについて
raica の IDP バックエンド。Go + PostgreSQL。
## クイックスタート
- ビルド: make build
- テスト: make test
- lint: make lint
## ディレクトリ構造
src/
domain/ - ドメインモデル(外部依存なし)
api/ - HTTP ハンドラ
infra/ - DB、外部サービス
## 重要な規約
→ docs/conventions/coding-standards.md を参照
## アーキテクチャ
→ docs/architecture/overview.md を参照
## 新機能の追加手順
→ docs/guides/adding-new-feature.md を参照
ポイント
- 短く保つ: エージェントが最初に読むファイルなので、簡潔に
- ポインタを置く: 詳細は別ファイルへのリンクで
- 実行可能な情報: ビルド・テストコマンドなど、すぐ使える情報を含める
- 更新しやすく: 情報が古くなりにくい粒度で書く
Try This: プロンプト改善ワークショップ
Exercise 1: プロンプトの書き換え
以下の曖昧なプロンプトを、具体的で制約の明確なプロンプトに書き換えてみよう:
- 「このコードをリファクタリングして」
- 「テストを追加して」
- 「パフォーマンスを改善して」
- 「エラーハンドリングを直して」
各プロンプトに以下を含めること:
- 具体的なファイルパス
- 参照すべき既存パターン
- 完了条件
- 制約事項
Exercise 2: CLAUDE.md の作成
自分が担当するリポジトリに CLAUDE.md を作成する:
- プロジェクトの概要(2-3 行)
- ビルド・テスト・lint コマンド
- ディレクトリ構造の説明
- 最も重要な規約 3 つ
- 詳細ドキュメントへのポインタ
Exercise 3: タスク分解の練習
次に取り組む機能開発を、エージェントサイズのタスクに分解してみよう:
- 最終的なゴールを定義する
- 5-8 個のサブタスクに分解する
- 各サブタスクの依存関係を図示する
- 各サブタスクのプロンプトを書く
まとめ
効果的なプロンプトエンジニアリングの原則:
- 明確さ: 曖昧さを排除し、具体的に伝える
- 簡潔さ: 必要な情報だけを、構造化して伝える
- 参照性: コンテキストはコピーせず、ファイルパスで参照する
- 分解性: 大きなタスクをエージェントサイズに分割する
- 持続性: 繰り返し使う制約は CLAUDE.md に永続化する
プロンプトは「その場の指示」ではなく「システムの一部」として設計する。良いプロンプトは、良い関数設計と同じ原則に従う: 単一責任、明確なインターフェース、適切な抽象度。
次のステップ
- リポジトリ = 知識ベース - エージェントのためのドキュメント設計
- フィードバックループの構築 - エージェント出力の品質を保証する仕組み