WWDC26:Improve your prompts by hill-climbing with Evaluations

統計学的にモデル評価を行いながら、ヒルクライミングプロセスで性能改善する手法の紹介。カッパ係数、統計学の授業で触れた気がするがまったく覚えてなかった。

Improve your prompts by hill-climbing with Evaluations


0:00 – Introduction

  • ヒルクライミングの定義
    • 評価スコアをガイドに知能機能を反復改善するアプローチ
    • サイクル:開発 → 実行 → 分析
  • AI 機能の改善に科学的思考を持ち込む考え方

2:42 – BookTracker’s tagging problem

  • Book Tracker のタグジェネレーターが抱える問題
    • 重要なテーマを見逃す
    • 本の内容ではなく読者の感想やレビューからの引用をタグとして生成してしまう

5:27 – Analyzing the evaluation results

  • データセットにレビューを 2 件追加して評価を実行
  • Xcode の評価レポートで生成タグと期待タグを比較
  • レポートの活用
    • サンプルごとのスコアとジャッジの rationale を確認
    • 期待するタグを欠いていてもモデルは高いジャッジスコアを付けており、人間評価と乖離があることが判明

8:26 – Drift between judge and human

  • モデルジャッジの評価と人間の専門家評価の乖離:「ドリフト」
  • 複数サンプルに対しモデル・人間で評価、それぞれの平均値の乖離がドリフト
  • ドリフトが存在すると評価スコアを信頼できなくなるため、ジャッジを人間の判断に揃える必要がある
  • 評価の乖離を測定する方法:
    • 両者合致する評価の割合をパーセンテージで表記(accuracy)
      • 分布が偏るケースに不適合(e.g. データセットの品質が高く人間がすべてを高く評価しがちな場合、モデルの評価と乖離が生じない)
    • accuracy とは異なる評価方法が必要

9:37 – Measuring drift with Cohen’s kappa

  • カッパ係数(Cohen’s kappa)によるアライメント計測で一致度(alignment)を測定
    • 偶然の一致(coincidence)の確率を差し引いた上で正確度を正規化 alignment = (accuracy –  coincidence) / (1 – coincidence)
    • 単純な一致率よりも真のアライメントを反映
  • Evaluations の記述に必要な4つの要素:データセット、Evaluation の対象、Evaluation の定義、結果の集計

12:26 – Building a judge alignment evaluation

  • BookTagJudgmentCalibration:ジャッジと評者の評価を比較するための専用評価
    • 同じデータセットに対して人間の手動評価とモデルのジャッジの両方のスコアを収集
    • aggregateMetrics でカッパ係数を集計
  • ジャッジアライメントのテスト
    • カッパ係数に加えて、平均値と各 dimension ごとの標準偏差も取っておくと、ジャッジスコアの増減を把握するのに役立つ
    • 閾値の目安:0.6 以上が望ましい(統計学的に意義のある一致水準を表すため)
      • #expect(result.aggregateValue(.custom(label: "Relevance: Judge vs Expert")) > 0.6)

15:16 – Analyzing alignment failures

  • Evaluate を再実行するとテストに失敗:Assistant Editorでレポートを深掘りするとジャッジが過剰に特定的なタグや的外れなタグを高く評価していると判明
  • 原因:良いタグ/悪いタグを分別するためのアプリに関するコンテキストがプロンプトに不足している

17:16 – Comparative evaluation: control vs experimental

  • Xcode 27 の比較評価機能
    • 2 つの評価を対照実験として比較し、変更の効果を客観的に検証
    • Control group:ベースとなるプロンプト vs Experimental group:実験的に変更を加えたプロンプト

19:12 – Refining the scoring dimensions

  • ScoreDimension の説明文を精緻化
    • Relevance:読者の反応・メタコメンタリー・著者情報をタグにしてはいけないことを明示
    • Usefulness:標準的なジャンル・テーマタグが機能する一方で、造語・キャラクター名・過度に一般的な語は不適と明示
  • 説明の改善で両次元のスコアが向上

21:23 – Adding few-shot examples to the judge

  • ModelJudgePrompt でジャッジに文脈と worked examples を提供
    • アプリの目的(Shelf:個人書籍管理アプリのタグ生成)を説明
    • Worked examples でレーティングの基準を示す
      • 例 A(Pride and Prejudice):タグが適切
      • 例 E(Frankenstein):ジャンル矛盾あり
  • Few-shot examples でジャッジの評価を専門家の感覚に近づける

23:38 – Going beyond prompts: adding a tool

  • ヒルクライミングの対象はプロンプトだけではない
  • BookLookupTool の追加し機能の品質を段階的に高める試み
    • レビューから本のタイトルと著者を検索するツール
    • 登場人物名・舞台設定・引用フレーズなどの手がかりからサンプルブックを特定
  • タグ生成サービスにツールを渡すだけで追加文脈を提供
    • BookTaggingService.generateTags(for:tools:) でツールを注入
  • 評価スイートでツールなし vs ツールありを同時に比較

27:17 – Next steps

  • 科学者のように考える:仮説を立て、変数を制御し、結果を測定する
  • 投資する価値のあるプロセス
  • 変数の創造性を持つ(プロンプトだけでなくツール・モデル・指示の構造なども対象)
  • ドリフトに注意し続ける(ジャッジのアライメントを定期的に確認)

WWDC26:Create robust evaluations for agentic apps

非決定的出力を評価するためのデータセットを大量生成する方法。とにかく数打ちながら期待値を満たすデータをふるいにかけながら集めると言う泥臭い方法だが、Evaluation フレームワークの機能として提供されているのがありがたい。

中でも、データセットにとどまらずツール呼び出しの検証が含まれているのは興味深かった。Foundation Models を使って開発する中でも、特に tool calling には泣かされた。以下の記事のようにツール呼び出しがされているかをログベースで検証したりしていたが、バージョンがあがると期待通りに呼び出されなくなり、プロンプトをどう工夫してもこの問題はついに解決されなかった。

今年こそは検証に足る挙動が実現していると期待しつつ、こうした評価のしがいがある高度な実装に挑戦してみたい。

Create robust evaluations for agentic apps


0:00 – Introduction

  • Evaluations フレームワーク(Xcode 27 新機能)の高度な機能を紹介
    • 合成データでデータセットを拡張する
    • ツールコーリングを伴うエージェンティックなワークフローの堅牢な評価構築
  • Hill-climbing プロセスにおける、”Develop” と “Evaluate” ステップに着目

2:21 – The dataset problem in BookTracker

  • Book Tracker のタグ自動生成機能が抱えるデータセット問題
    • 実際のレビューは書籍・ジャンル・長さ・文体で無限に多様
    • 手作業で書いた 13 サンプルではすべてを捉えられない

3:46 – Generating synthetic data with makeSamples

  • makeSamples API でデータセットを合成拡張
    • プロンプト・データセット(ModelSample の配列)・targetCount(シード含む合計サイズ、e.g. 100)を渡す
    • 合成データの生成は反復的なプロセスの中で行われる(データが代表的か確証が得られるまで検証される)
    • 妥当なサンプル数はケースバイケース:量より網羅性

6:27 – Customizing generation with SampleGenerator

  • SampleGenerator で、prompt, dataset, targetCount を超えたより細かい設定
    • sessionProvider クロージャでモデルを選択(例:Private Cloud Compute)
    • sessionProvider は実行開始時1度実行され、バッチ間で再利用されるが、コンテキストウィンドウを使い切ると再度呼び出される
      • コンテクストは共有されないので、サンプル生成の期待を指示する sessionProvider へのカスタムインストラクションは、自己完結型にする(前のバッチの状態に依存させない)

8:38 – Sampling strategies

  • samplingStrategy でシードサンプルの提示方法を制御
    • .random(デフォルト):ランダムなサブセット。多様性重視のデータセットに適する
    • .slidingWindow:連続したシードを提示。順序に意味があるデータセットに適する

10:11 – Validating synthetic samples

  • validator クロージャで各サンプルを個別に検証
    • レビュー長 ≥ 100 文字
    • タグ数 3〜8 個
    • タグはすべて小文字
  • 有効なサンプルは samples、不合格は invalidSamples に分類

13:04 – Comparing evaluation results

  • Xcode 27 の Evaluations Report で 2 つの実行結果を比較
    • 13 サンプルと 100 サンプルの結果を比較
    • サンプルが増えたことで、品質スコアが低下し、小さなデータセットではよく見えていた機能の限界が露呈
      • プロンプトやインストラクションによって改善しうる
      • 評価を調整し、実際に何が評価されているかを理解できる
      • データセットがまだ代表的でないかもしれない(増やしたり、エッジケースを網羅)

15:09 – Tool calling and tool evaluations

  • ツール評価は「何が返ってきたか」ではなく「どうやって取得したか」を検証
    • 正しいツールを、正しい引数で、正しい順序で呼んでいるか
    • 想定外のツール呼び出しがないか
  • デモアプリのツール例
    • searchBooks・getBookDetails・findSimilarBooks

18:54 – Trajectory expectations

  • TrajectoryExpectation でセッションのトランスクリプト上のツール呼び出しの種類と順序を検証
  • 引数マッチャーの種類
    • .exact:厳密な値の一致
    • .naturalLanguage:意図ベースのファジーマッチング(基準を自然言語で記述)
    • .contains.hasPrefix.hasSuffix:部分文字列マッチング
    • .oneOf.pattern:列挙値・正規表現マッチング
    • .range:数値の範囲チェック
    • .keyOnly:キー名だけ確認(値は問わない)
  • 順序付き期待(ordered)と順不同期待(unordered)を組み合わせ可能
  • disallowed で呼び出してはいけないツールを指定

21:26 – Building a tool call evaluation

  • データセットをそれぞれに対するプロンプト、インストラクション、TrajectoryExpectation  をもって、ToolCallEvaluator でスコア付けをする
    • LanguageModelSession にツールを渡し、構造化されたトランスクリプトをキャプチャ
    • allPasspercentagePass の 2 つのメトリクスを自動計算

22:02 – Synthetic data for tool evaluations

  • ModelSampleTrajectoryExpectation はいずれも @Generable のため SampleGenerator を用いて合成生成が可能
  • 合成プロンプトの設計ポイント
    • 利用可能なツールの説明(名前・引数)
    • 順序要件(ordered vs unordered の使い分け)
    • 使用すべき引数マッチャーの説明
  • バリデーターで品質を担保
    • expectations が定義されているか
    • 少なくとも 1 つのツール期待が含まれているか
    • すべてのツール名が有効なセットに含まれているか

WWDC26:Meet the Evaluations framework

ユニットテストが行えない非決定的な Foundation Models の出力を統計的に評価できる Evaluations フレームワークの紹介。評価軸を試行錯誤することでプロンプトのブラッシュアップサイクルにつながる、まさに「evaluation-driven development」。

Meet the Evaluations framework


0:00 – Introduction

  • 生成 AI 機能は「同じ入力に同じ出力」というユニットテストの前提を壊す
    • 非決定的な出力をどれだけの頻度で正しく生成できるか測定する新しいテスト手法が必要
  • Evaluations フレームワークで、予期しない出力や安全でない結果の発生率を計測可能

3:10 – Demo app Book Tacker: a manual evaluation

  • デモアプリ Book Trackerの紹介
  • #Playground で試した結果、いくつかの問題を発見
    • タグが多すぎる
    • 本のタイトルがタグになっている
    • 複数単語のタグが生成される
  • モデルの性能を評価薄る人手評価(human judgement)を作成したが、これはスケーラブルではない:そこで自動化できスケーラブルな評価手法を作った

4:31 – Building your first evaluation

  1. Evaluation プロトコルの実装手順(5 ステップ)
    1. Subject:ModelSubject による subject の定義(テスト対象のコード)
    2. Dataset:ModelSample を使ったデータセットの作成(プロンプトと期待値のペア)
    3. Evaluators & Metrics:MetricEvaluators による評価指標とタグ数の合否判定ロジックの定義
    4. Analysis:aggregateMetrics でサンプル全体の集計を定義
    5. Tests:次

8:06 – Running the evaluation and reading the report

  • Swift Testing の .evaluates トレイトで評価を実行
  • 最適化ターゲットの設定
    • #expect(result.aggregateValue(.mean(of: rangeMetric)) >= 0.8) のように合格基準を数値で表現
  • 評価レポートの確認
    • サンプルごとの結果・プロンプト・測定値・モデルレスポンスの全文を確認可能
    • 例:@Guide でタグ数を 3〜8 に制約した BookTags@Generable 定義
    • 評価を再実行し、修正が正しかったかを検証:「ヒルクライム」プロセス

10:57 – Building robust datasets

  • さきほどは 2 サンプルで検証したが、これでは不十分。優れたデータセットの条件は:
    • 数千件規模
    • ジャンル・レビューの長さ・フィクション/ノンフィクション・文体・個人的な感想など多様性が重要
    • 自分のような出力(タグ付け)をして欲しい場合、まずは個人的なスタイルを期待値としたより多くのサンプルを提供することから始める
  • 手作業では限界があるため、Evaluations フレームワークの SampleGenerator で大量合成が可能
    • シードセットからプロンプトを与えて合成サンプルを生成
    • targetCount で目標サンプル数(シードを含む合計)を指定

14:20 – Refining metrics and evaluators

  • 複数のメトリクスを追加してより深い洞察を得る。タグ付けを例とすると:
    • TagTotal:タグ数の分布(スコアリング型、合否ではなく数値)
    • wordCount:タグが単一単語かのチェック(スペース含みを除外)
    • hasGenreTag:既知ジャンル(knownGenres)との一致確認
  • aggregateMetrics での集計
    • computeMeancomputeStandardDeviationcomputeVariance を組み合わせて分布を把握

15:41 – Evaluation-driven development and hill-climbing

  1. ヒルクライミングのループ
    1. 最適化ターゲットの失敗を検出
    2. 原因を分析して変更を加える(例:@Guide にカウント範囲を追加)
    3. 再実行して結果を確認
  2. このループを中心に開発を進めるのが evaluation-driven development(評価駆動開発)

16:12 – Model judges: qualitative metrics

  • 定量的なメトリクスが合格でも、タグの内容が間違っている場合がある
    • 読者の感想がタグになっている、ジャンルの誤推論など
  • Model Judge:人間の評価を模倣する第2のモデルで出力を採点
    • ジャッジモデルは評価対象と同等以上の能力が必要(ここでは Private Cloud Compute を使用)
    • データセット全体にわたって一貫したスコアリングが可能

18:42 – Building a model judge

  • ModelJudgeEvaluator は通常の Evaluator と同じ Metric 型を返す
  • 設定のポイント
    • スコアスケールは偶数レベルにする(中立デフォルトを避けるため)
      • 例:1〜4 の 4 段階スケール
    • judge パラメータにジャッジモデルを指定
  • レポートでジャッジの根拠(rationale)も確認可能

21:19 – Refining with score dimensions

  • ジャッジモデルによるスコアが人間が評価したスコアと異なる場合がある
    • 評価の問いが広すぎることが多い(e.g. “relevant”, “”useful for browsing)
  • 二つの評価軸を ScoreDimension で分割、description で詳解し、scale も評価軸ごとに分ける
    • e.g. relevant → Relevance(関連性):タグが本自体を表しているか
    • e.g. useful for browsing → Usefulness(有用性):ブラウジングに役立つ粒度か
  • 評価軸を分けるだけ、何を評価するかを伝えているだけで不十分:アプリのコンテクスト(使われ方)が抜けているため
    • ModelJudgePrompt でどんなアプリかというコンテキストをジャッジに伝え、評価精度を高める

23:45 – Reviewing dimension results

  • 次元ごとに分かれた rationale で診断が明確化
    • Relevance のスコアでどの種類のタグが間違っているかがわかる
    • Usefulness のスコアでブラウジングの失敗の原因がわかる
  • 次のヒルクライミングの反復に向けた明確な方向性が得られる

24:20 – Best practices

  • 小さく始める(20〜30 の焦点を絞ったサンプルから)
  • 定量的な特性にはヒューリスティック(コードで計測できるもの)を使う
  • 定性的な特性には ModelJudgeEvaluator を使う
  • ジャッジはシンプルな設定から始める
  • 評価の根拠を次の変更に活かす
    • スコアがすべて同じなら問いかけが広すぎるサイン
    • 問題を切り分けられないなら次元を分割
    • ジャッジがアプリを理解していないならコンテキストを追加すること。