プロンプト技術

Few-shot例文でAIレビューの誤検知を激減させる設計法

Few-shot例文でAIレビューの誤検知を激減させる設計法

この記事の要点

Few-shot prompting を使ってAIコードレビューや文書チェックの誤検知を減らす方法を解説。抽象的な指示ではなく具体的な例文で判断基準を伝えることで、精度と開発者の信頼を同時に高める実践的な手法を紹介します。

結論

AIによるコードレビューや文書チェックの誤検知を減らすには、「慎重に」「確信があるものだけ」という曖昧な指示より、「この種類の問題は報告する・この種類は報告しない」という具体的な例文を2〜5個示す方がはるかに効果的です。

Few-shot例文は、判断基準を言葉で説明するのではなく行動で示します。AIは提供された例から「どのケースが報告対象で、どのケースが許容されるのか」の判断パターンを学習し、新しいコードにも同じ基準を適用します。


なぜ「慎重に」という指示が機能しないのか

AIのコードレビューで誤検知が増えると、開発者は指摘を信じなくなります。「またAIの的外れな指摘だ」という感覚が積み重なると、本当に重要な指摘も無視されるようになります。

この問題を解決しようとして、次のような指示を追加することがあります。

❌ 効果が薄い指示:
「確信があるものだけ報告してください」
「保守的に判断してください」
「高信頼度の問題のみ報告してください」

これらが機能しない理由は、AIの「確信度」の自己申告が実際の正確さとほとんど相関しないからです。AIは誤検知を引き起こすパターンについて「確信を持って」誤った判断をすることがあります。


機能する解決策:カテゴリ定義 + Few-shot例文

ステップ1: 報告するカテゴリと報告しないカテゴリを定義する

報告するカテゴリ:
✅ 認証情報のハードコード(APIキー・パスワード)
✅ SQLインジェクションの可能性
✅ 未処理の例外(catch節が空)
✅ 競合状態(Race Condition)の可能性

報告しないカテゴリ:
❌ このコードベース固有のパターン(src/legacy/以下のjQuery使用は許容)
❌ 変数名の命名スタイル(ESLintが担当)
❌ コメントの文体
❌ パフォーマンスの最適化余地(criticalでない場合)

カテゴリを明示するだけでも誤検知が減りますが、さらに効果を上げるのがFew-shot例文です。

ステップ2: 境界ケースをFew-shot例で示す

カテゴリ定義で対応しきれない「判断が難しい境界ケース」に対して例文を用意します。

# コードレビューの判断例

## 例1: 報告すべき問題(SQLインジェクション)

コード:
```python
query = f"SELECT * FROM users WHERE id = {user_input}"
cursor.execute(query)

判定: 報告する 理由: ユーザー入力を直接クエリに埋め込んでいるため、SQLインジェクションの可能性がある。 推奨修正: プレースホルダーを使用する(cursor.execute(“SELECT * FROM users WHERE id = %s”, [user_input]))


例2: 報告しない(意図的なパターン)

コード:

// legacy jQuery usage - intentional, see ARCHITECTURE.md
$.ajax({ url: '/api/data', ... });

判定: 報告しない 理由: コメントに意図的であることが明示されており、ARCHITECTURE.mdで許容されているレガシーパターン。


例3: 報告すべき問題(ハードコードされた認証情報)

コード:

API_KEY = "sk-proj-abc123xyz"

判定: 報告する 理由: APIキーがソースコードに直書きされている。環境変数またはシークレット管理サービスを使うべき。


例4: 報告しない(テスト用のモックデータ)

コード:

# test fixtures
TEST_API_KEY = "test-key-for-unit-tests-only"

判定: 報告しない 理由: テスト用のモックキーであり、コメントでその旨が明示されている。本番コードではない。


このように「同じように見えても判定が分かれるケース」の例を含めることで、AIが文脈を読んで判断できるようになります。

---

## コードレビューでの実践: 誤検知を高い分野に絞って対処する

誤検知は全ての種類で均等に起きるわけではありません。特定のカテゴリで集中して発生することが多いです。

### まず誤検知パターンを特定する

分析方法:

  1. 過去2週間のコードレビュー指摘を収集する
  2. 開発者が却下した指摘(dismissed findings)を抽出する
  3. 却下された指摘のカテゴリを集計する

結果例:

  • スタイル指摘: 却下率 89%(誤検知が多い)
  • セキュリティ指摘: 却下率 12%(精度が高い)
  • エラーハンドリング指摘: 却下率 45%(改善の余地あり)

### 誤検知が多いカテゴリを一時停止する

精度が低いカテゴリを一時的に無効化することで、開発者が残りの指摘を信頼して見るようになります。信頼を回復してから、そのカテゴリのプロンプトを改善して再導入します。

フェーズ1(現在): スタイル指摘を無効化。セキュリティ・バグ指摘のみ有効。 フェーズ2(2週間後): スタイル指摘用のFew-shot例文を作成してテスト。 フェーズ3(4週間後): 改善したスタイル指摘を再導入。


---

## Few-shot例文の効果が高い3つの状況

### 状況1: 曖昧なケースの判断

「このコードはAPIキーのように見えるが、テスト用の固定値なのか本物なのか」のような判断は、カテゴリ定義だけでは対応できません。「テスト用のモックは許容」「本番コードのハードコードは報告」という例を示すことで対応できます。

### 状況2: フォーマットの一貫性

レビュー結果の書き方が毎回変わる場合(あるときは行番号あり・ないとき・深刻度の表記が揺れるなど)、出力フォーマットの例を示すことで一貫した形式が得られます。

```markdown
## 出力フォーマットの例

```json
{
  "file": "src/payment/processor.ts",
  "line": 45,
  "severity": "critical",
  "category": "security",
  "issue": "JWTトークンの署名検証が省略されている",
  "fix": "jsonwebtoken.verify()の第2引数にsecretKeyを必ず渡す"
}

この形式で全ての問題を報告してください。


### 状況3: 文書から情報抽出する場面

書類の形式が文書ごとに異なる場合(インライン引用・参考文献リスト・本文内の数値・付録の表)、どの形式から何をどのように抽出するかの例を示すことで、空の抽出や誤フィールドへの配置が減ります。

これは[ClaudeのJSONスキーマ構造化出力](/articles/claude-structured-output-json-schema/)で解説した構造化出力と組み合わせると特に効果的です。

---

## Few-shot例文を設計する際のポイント

### 曖昧なケースを優先する

明確なケース(誰がどう見ても問題ある・ない)の例は効果が薄いです。「これは報告すべきか?」と迷うような境界的なケースの例を優先します。

**不要な例(明確すぎる):**

コード: password = “password123” 判定: 報告する(明らかなハードコード)


**有用な例(境界的):**

コード: DEFAULT_TIMEOUT = 30 # seconds 判定: 報告しない(設定値の定数は許容。認証情報ではない)


### 判断理由を必ず含める

「報告する」「報告しない」だけでなく、なぜその判断をしたかの理由を含めます。AIはこの理由から判断ロジックを学習し、新しいケースに適用します。

### 例は2〜5個が実用的

例が多すぎるとコンテキストを圧迫します。2〜5例で最も頻繁に問題になるケースをカバーします。最初は少ない例から始めて、実際に問題が発生したケースを追加していく運用が効率的です。

---

## detected_patternフィールドでフィードバックループを作る

誤検知をシステム的に改善するには、AIがどのコードパターンを見て指摘したかを記録します。

```json
{
  "file": "src/auth/token.ts",
  "line": 45,
  "issue": "ハードコードされたシークレット",
  "detected_pattern": "変数名に'key'を含む文字列への代入",
  "developer_verdict": "dismissed",
  "dismiss_reason": "テスト用のモックキーのため"
}

developer_verdictdismissedになった指摘のdetected_patternを集計すると、「変数名に’key’を含む文字列代入をシークレットと誤検知している」というパターンが見つかります。このパターンをFew-shot例の否定例として追加することで、同じ誤検知を防げます。

このフィードバックループを回すことで、AIレビューの精度が継続的に向上します。


深刻度の分類でFew-shot例を設計する

深刻度の判定が一貫しない問題も、Few-shot例で改善できます。

## 深刻度の定義例

### critical(即座に修正が必要)
例: 認証バイパスの可能性、データ漏洩のリスク
コード例: 
```python
if user.role == "admin" or True:  # バグ: or Trueで認証が常に通る

high(このPRに含めて修正すべき)

例: 未処理の例外でサービスがクラッシュする可能性 コード例:

result = fetch_data(url)
return result["data"]  # fetchが失敗したときKeyErrorが未処理

medium(次のリファクタリングで修正)

例: パフォーマンスの非効率(即座のクラッシュリスクはない) コード例:

for item in items:
    db.query(...)  # N+1クエリ

報告しない

例: コメントの文体・変数名の好みの違い


具体的なコード例を添えることで、AIが新しいコードを見たときに同じ基準で深刻度を判定できます。

---

## まとめ

Few-shot例文で誤検知を減らす実践ポイントをまとめます。

- 「慎重に」「高信頼度のみ」という指示ではなく、カテゴリの明示 + 境界ケースの例文で対応する
- 誤検知が多いカテゴリを特定して一時停止し、信頼を回復してから改善した例文で再導入する
- 例文は明確なケースより判断が難しい境界ケースを優先する
- 判断理由を例文に含めることでAIが判断ロジックを学習できる
- `detected_pattern`フィールドで誤検知のパターンを記録してフィードバックループを回す
- 深刻度の定義にもコード例を添えて一貫した分類を実現する

この設計を導入することで、開発者がAIレビューの指摘を信頼して参照するようになり、本当に重要な問題の見逃しが減ります。

よくある質問

Few-shot prompting とはどんな手法ですか?

「このようにしてほしい」という指示を言葉で説明するのではなく、具体的な例(input→output のペア)を2〜5個見せてAIに学習させる手法です。抽象的な指示より例文の方が、AIの判断精度が大幅に上がります。

「確信があるものだけ報告して」という指示は効果がありますか?

ほとんど効果がありません。AIの自己申告する確信度は、実際の正確さとの相関が低いためです。代わりに「この種類の問題は報告する、あの種類は報告しない」という具体的なカテゴリ定義が有効です。

Few-shot例文はどれくらい用意すればよいですか?

2〜5例が実用的な範囲です。曖昧なケースに対応する例を優先的に含めます。明確なケース(誰が見ても問題・問題なし)の例より、判断が難しい境界的なケースの例の方が精度向上に効果があります。