Agent-First Development

プロンプトエンジニアリング実践

はじめに

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: プロンプトの書き換え

以下の曖昧なプロンプトを、具体的で制約の明確なプロンプトに書き換えてみよう:

  1. 「このコードをリファクタリングして」
  2. 「テストを追加して」
  3. 「パフォーマンスを改善して」
  4. 「エラーハンドリングを直して」

各プロンプトに以下を含めること:

  • 具体的なファイルパス
  • 参照すべき既存パターン
  • 完了条件
  • 制約事項

Exercise 2: CLAUDE.md の作成

自分が担当するリポジトリに CLAUDE.md を作成する:

  1. プロジェクトの概要(2-3 行)
  2. ビルド・テスト・lint コマンド
  3. ディレクトリ構造の説明
  4. 最も重要な規約 3 つ
  5. 詳細ドキュメントへのポインタ

Exercise 3: タスク分解の練習

次に取り組む機能開発を、エージェントサイズのタスクに分解してみよう:

  1. 最終的なゴールを定義する
  2. 5-8 個のサブタスクに分解する
  3. 各サブタスクの依存関係を図示する
  4. 各サブタスクのプロンプトを書く

まとめ

効果的なプロンプトエンジニアリングの原則:

  1. 明確さ: 曖昧さを排除し、具体的に伝える
  2. 簡潔さ: 必要な情報だけを、構造化して伝える
  3. 参照性: コンテキストはコピーせず、ファイルパスで参照する
  4. 分解性: 大きなタスクをエージェントサイズに分割する
  5. 持続性: 繰り返し使う制約は CLAUDE.md に永続化する

プロンプトは「その場の指示」ではなく「システムの一部」として設計する。良いプロンプトは、良い関数設計と同じ原則に従う: 単一責任、明確なインターフェース、適切な抽象度。

次のステップ