Reflection パターンの本質は自己評価と反復改善。出力して終わりじゃなくて、「これで良いのか?」と振り返り、品質を高めていく。ただし万能じゃない。すでに良い回答に過剰な振り返りは無駄。


5 分で掴む核心

  1. Reflection = 出力を評価 + 弱点を特定 + 改善を生成
  2. 二つのモード:自己批評(同じ LLM)と外部評価(別のモデルや人間)
  3. 停止条件が重要:品質閾値を満たすか、最大反復回数に達したら止める
  4. 過剰反復は禁物:良い答えをいじりすぎると逆に悪化することも
  5. 評価基準は明確に:曖昧な「良い」「悪い」ではなく、具体的な指標で評価

10 分コース:11.1-11.3 → 11.5 → Shannon Lab


11.1 なぜ振り返りが必要なのか?

LLM は一発で完璧な答えを出せるわけじゃない。よくある問題:

  1. 不完全:重要なポイントが抜けている
  2. 曖昧:もっと具体的にできる
  3. 構造が乱雑:整理すれば読みやすくなる
  4. 事実誤り:ハルシネーションが含まれることも

人間だって、レポートを書いたら見直すでしょ?それと同じことを Agent にやらせる。

Reflection パターンの価値

問題Reflection での改善
不完全な回答「何が足りないか」を評価して追加
曖昧な表現「もっと具体的に」と指摘して改善
構造の乱雑さ「読みやすい構造に」と再構成
事実誤り「これは正しいか」とチェックして修正

11.2 Reflection の基本フロー

Shannon での Reflection は 3 ステップのループ:

Reflection フロー

func ReflectionLoop(ctx context.Context, query string, agent *Agent, config ReflectionConfig) (*Result, error) {
    // 1. 初期回答を生成
    response, err := agent.Generate(ctx, query)
    if err != nil {
        return nil, err
    }

    for i := 0; i < config.MaxIterations; i++ {
        // 2. 回答を評価
        evaluation, err := evaluate(ctx, query, response, config.Criteria)
        if err != nil {
            return nil, err
        }

        // 3. 品質閾値を満たしたら終了
        if evaluation.Score >= config.QualityThreshold {
            return &Result{
                Response:   response,
                Iterations: i + 1,
                FinalScore: evaluation.Score,
            }, nil
        }

        // 4. 改善を生成
        response, err = improve(ctx, query, response, evaluation.Feedback)
        if err != nil {
            return nil, err
        }
    }

    // 最大反復回数に達した
    return &Result{
        Response:   response,
        Iterations: config.MaxIterations,
        Warning:    "max iterations reached without meeting quality threshold",
    }, nil
}

11.3 評価(Evaluation)の設計

評価は Reflection の核心。曖昧な「良い」「悪い」じゃなく、具体的な指標で評価する。

評価基準の例

type EvaluationCriteria struct {
    Completeness  bool    // すべての質問に答えているか
    Accuracy      bool    // 事実として正しいか
    Clarity       bool    // 明確で理解しやすいか
    Structure     bool    // 論理的に構成されているか
    Relevance     bool    // 質問に関連しているか
    Specificity   bool    // 具体的で詳細か
}

type Evaluation struct {
    Score    float64           // 総合スコア 0-1
    Criteria map[string]bool   // 各基準の結果
    Feedback string            // 改善のためのフィードバック
    Weaknesses []string        // 特定された弱点
}

評価プロンプトの設計

func buildEvaluationPrompt(query, response string, criteria EvaluationCriteria) string {
    return fmt.Sprintf(`## Task
Evaluate the following response to the user's question.

## User's Question
%s

## Response to Evaluate
%s

## Evaluation Criteria
1. Completeness: Does it address all aspects of the question?
2. Accuracy: Are the facts correct?
3. Clarity: Is it easy to understand?
4. Structure: Is it well-organized?
5. Relevance: Does it stay on topic?
6. Specificity: Is it concrete and detailed?

## Output Format
{
    "score": 0.0-1.0,
    "criteria": {
        "completeness": true/false,
        "accuracy": true/false,
        "clarity": true/false,
        "structure": true/false,
        "relevance": true/false,
        "specificity": true/false
    },
    "feedback": "Specific areas for improvement",
    "weaknesses": ["weakness 1", "weakness 2"]
}
`, query, response)
}

評価のバリエーション

方法説明メリットデメリット
自己批評同じ LLM が評価シンプル、速い自分の誤りに気づきにくい
別モデル評価別の LLM が評価客観的コストが上がる
人間評価Human-in-the-loop最も正確遅い、スケールしない
ルールベース事前定義のチェック一貫性がある柔軟性に欠ける

11.4 改善(Improvement)の生成

評価結果を元に、具体的な改善を生成する。

func buildImprovementPrompt(query, response, feedback string, weaknesses []string) string {
    return fmt.Sprintf(`## Task
Improve the following response based on the feedback.

## Original Question
%s

## Current Response
%s

## Feedback
%s

## Identified Weaknesses
%s

## Instructions
1. Address all identified weaknesses
2. Keep the good parts unchanged
3. Be specific and concrete in improvements
4. Maintain the same overall structure unless it was a weakness

## Improved Response
`, query, response, feedback, strings.Join(weaknesses, "\n- "))
}

改善のベストプラクティス

  1. 具体的なフィードバック:「もっと良くして」ではなく「例を追加して」
  2. 良い部分は保持:全部書き直す必要はない
  3. 優先順位をつける:すべての弱点を一度に直そうとしない
  4. 変更を追跡可能に:何を変えたか分かるように

11.5 停止条件の設計

いつ反復を止めるか?これが重要。

停止条件の種類

type StopConditions struct {
    MaxIterations     int     // 最大反復回数(安全網)
    QualityThreshold  float64 // 品質スコア閾値
    NoImprovement     int     // N 回連続で改善なしなら停止
    TimeBudget        time.Duration // 時間制限
    TokenBudget       int     // トークン制限
}

func shouldStop(iteration int, scores []float64, config StopConditions) (bool, string) {
    // 1. 最大反復回数
    if iteration >= config.MaxIterations {
        return true, "max iterations reached"
    }

    // 2. 品質閾値を満たした
    if len(scores) > 0 && scores[len(scores)-1] >= config.QualityThreshold {
        return true, "quality threshold met"
    }

    // 3. 改善が停滞
    if len(scores) >= config.NoImprovement {
        recent := scores[len(scores)-config.NoImprovement:]
        if !hasImprovement(recent) {
            return true, "no improvement detected"
        }
    }

    return false, ""
}

func hasImprovement(scores []float64) bool {
    if len(scores) < 2 {
        return true
    }
    // 最近のスコアが上昇傾向にあるか
    for i := 1; i < len(scores); i++ {
        if scores[i] > scores[i-1]+0.01 { // 1%以上の改善
            return true
        }
    }
    return false
}

推奨設定

パラメータ推奨値理由
MaxIterations3-5これ以上は収穫逓減
QualityThreshold0.8-0.85完璧を求めすぎない
NoImprovement22 回改善なしなら停滞

11.6 実践例:レポート品質改善

func improveReport(ctx context.Context, query string, agent *Agent) (*Result, error) {
    config := ReflectionConfig{
        MaxIterations:    3,
        QualityThreshold: 0.85,
        Criteria: EvaluationCriteria{
            Completeness: true,
            Accuracy:     true,
            Clarity:      true,
            Structure:    true,
        },
    }

    return ReflectionLoop(ctx, query, agent, config)
}

実行例

=== 初期回答 ===
テスラの2024年業績について...(簡潔だが詳細が不足)

=== 評価 1 ===
Score: 0.6
Weaknesses:
- 具体的な数字がない
- 競合との比較がない
- 将来の展望が不足

=== 改善 1 ===
テスラの2024年業績は...売上高は前年比15%...(数字を追加)

=== 評価 2 ===
Score: 0.75
Weaknesses:
- 競合との比較がまだない
- ソースの明記がない

=== 改善 2 ===
テスラの2024年業績は...BYDと比較すると...(比較を追加)

=== 評価 3 ===
Score: 0.88 >= 0.85(閾値)

=== 最終出力 ===
反復回数: 3
最終スコア: 0.88

11.7 よくある落とし穴

落とし穴 1:過剰反復

// 悪い例:すでに良い回答をいじりすぎる
config := ReflectionConfig{
    MaxIterations:    10,  // 多すぎ
    QualityThreshold: 0.99, // 高すぎ
}
// 結果:良い答えを「改悪」する可能性

// 良い例:適度に止める
config := ReflectionConfig{
    MaxIterations:    3,
    QualityThreshold: 0.85,
    NoImprovement:    2,  // 改善が止まったら終了
}

落とし穴 2:曖昧な評価基準

// 悪い例:曖昧なフィードバック
feedback := "もっと良くして"

// 良い例:具体的なフィードバック
feedback := "以下を改善してください:\n" +
    "1. 売上の具体的な数字を追加\n" +
    "2. 前年比較を含める\n" +
    "3. データソースを明記"

落とし穴 3:評価と改善の不整合

// 悪い例:評価で指摘した点が改善されない
evaluation.Weaknesses = ["具体例がない"]
// 改善時にこのフィードバックを無視

// 良い例:評価結果を明示的に改善プロンプトに含める
improvementPrompt := buildImprovementPrompt(query, response,
    evaluation.Feedback, evaluation.Weaknesses)

11.8 高度なトピック:マルチアスペクト評価

複数の側面を独立に評価し、それぞれを改善する:

type MultiAspectEvaluation struct {
    Aspects map[string]AspectScore
}

type AspectScore struct {
    Score    float64
    Feedback string
}

func multiAspectReflection(ctx context.Context, query, response string) (*Result, error) {
    aspects := []string{"accuracy", "completeness", "clarity", "usefulness"}

    for iteration := 0; iteration < maxIterations; iteration++ {
        // 各側面を独立に評価
        evaluation := evaluateAllAspects(ctx, query, response, aspects)

        // 最も弱い側面を特定
        weakestAspect := findWeakestAspect(evaluation)

        // その側面を重点的に改善
        response = improveAspect(ctx, query, response, weakestAspect)
    }

    return &Result{Response: response}, nil
}

11.9 他のパターンとの組み合わせ

Planning + Reflection

計画の各ステップの出力を Reflection で改善:

for _, step := range plan.Steps {
    result := executeStep(step)
    // 各ステップの出力を評価・改善
    result = reflectionLoop(result, stepConfig)
    stepResults = append(stepResults, result)
}

Reflection + RAG

検索結果を使って評価の精度を上げる:

func evaluateWithRAG(ctx context.Context, query, response string) (*Evaluation, error) {
    // 関連する事実を検索
    facts := search(query)

    // 事実に基づいて正確性を評価
    evaluation := evaluateAgainstFacts(response, facts)

    return evaluation, nil
}

この章のまとめ

核心は一言で:Reflection パターンは「出力 → 評価 → 改善」のループで品質を高める。自己批評や外部評価で弱点を特定し、具体的なフィードバックで改善する。

要点

  1. 3 ステップループ:生成 → 評価 → 改善
  2. 明確な評価基準:曖昧な「良い」「悪い」ではなく具体的な指標
  3. 適切な停止条件:品質閾値、最大反復回数、改善停滞の検出
  4. 過剰反復を避ける:良い答えをいじりすぎない
  5. 具体的なフィードバック:「もっと良く」ではなく「何をどう直すか」

Shannon Lab(10 分で始める)

このセクションで、本章の概念を Shannon のソースコードにマッピングする。

必読(1 ファイル)

  • patterns/reflection.goReflectionLoop 関数を見て、評価と改善がどうループするか理解する。停止条件の実装を確認する

選読で深掘り(興味に応じて 2 つ)


演習

演習 1:評価基準の設計

「技術ブログ記事」の評価基準を 6 つ設計せよ。各基準について:

  • 名前
  • 説明(何をチェックするか)
  • どうすれば「良い」と判断するか

演習 2:停止条件の分析

以下のスコア推移を見て、いつ反復を止めるべきか判断せよ:

反復 1: 0.55
反復 2: 0.68
反復 3: 0.72
反復 4: 0.73
反復 5: 0.72

理由も説明せよ。

演習 3(上級):マルチアスペクト改善

「AIエージェントとは何か」という質問への回答を改善するシナリオを考えよ:

  1. 評価する側面を 4 つ決める
  2. 各側面の評価基準を定義
  3. 改善の優先順位付けロジックを設計

もっと深く学びたい?


次章の予告

Planning は「先に考える」、Reflection は「後で振り返る」。どちらも推論を分割するパターンだった。

次章では Chain-of-Thought (CoT) を説明する。「一歩一歩考える」ことで、複雑な推論を分解し、最終的な答えの精度を上げる。

これは単一エージェントパターンの最後の章。CoT を理解すれば、Part 5 のマルチエージェント編成に進む準備ができる。

次へ進もう。

この記事を引用する / Cite
Zhang, W. (2026). 第 11 章:Reflection パターン. In AI Agent アーキテクチャ:単体からエンタープライズ級マルチエージェントへ. https://waylandz.com/ai-agent-book-ja/第11章-Reflectionパターン
@incollection{zhang2026aiagent_ja_第11章_Reflectionパターン,
  author = {Zhang, Wayland},
  title = {第 11 章:Reflection パターン},
  booktitle = {AI Agent アーキテクチャ:単体からエンタープライズ級マルチエージェントへ},
  year = {2026},
  url = {https://waylandz.com/ai-agent-book-ja/第11章-Reflectionパターン}
}