View in English

  • Apple Developer
    • 今すぐ始める

    「今すぐ始める」を詳しく見る

    • 概要
    • 学ぶ
    • Apple Developer Program

    最新情報

    • 最新ニュース
    • Hello Developer
    • プラットフォーム

    プラットフォームを詳しく見る

    • Appleプラットフォーム
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store

    特集

    • デザイン
    • 配信
    • ゲーム
    • アクセサリ
    • Web
    • Home
    • CarPlay
    • テクノロジー

    テクノロジーを詳しく見る

    • 概要
    • Xcode
    • Swift
    • SwiftUI

    特集

    • アクセシビリティ
    • App Intent
    • Apple Intelligence
    • ゲーム
    • 機械学習とAI
    • セキュリティ
    • Xcode Cloud
    • コミュニティ

    コミュニティを詳しく見る

    • 概要
    • 「Appleに相談」イベント
    • コミュニティによるイベント
    • デベロッパフォーラム
    • オープンソース

    特集

    • WWDC
    • Swift Student Challenge
    • デベロッパストーリー
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Center
    • ドキュメント

    ドキュメントを詳しく見る

    • ドキュメントライブラリ
    • テクノロジー概要
    • サンプルコード
    • ヒューマンインターフェイスガイドライン
    • ビデオ

    リリースノート

    • 注目のアップデート
    • iOS
    • iPadOS
    • macOS
    • watchOS
    • visionOS
    • tvOS
    • Xcode
    • ダウンロード

    ダウンロードを詳しく見る

    • すべてのダウンロード
    • オペレーティングシステム
    • アプリ
    • デザインリソース

    特集

    • Xcode
    • TestFlight
    • フォント
    • SF Symbols
    • Icon Composer
    • サポート

    サポートを詳しく見る

    • 概要
    • ヘルプガイド
    • デベロッパフォーラム
    • フィードバックアシスタント
    • お問い合わせ

    特集

    • アカウントヘルプ
    • App Reviewガイドライン
    • App Store Connectヘルプ
    • 近日導入予定の要件
    • 契約およびガイドライン
    • システムステータス
  • クイックリンク

    • イベント
    • ニュース
    • Forum
    • サンプルコード
    • ビデオ
 

ビデオ

メニューを開く メニューを閉じる
  • コレクション
  • すべてのビデオ
  • 利用方法

その他のビデオ

  • 概要
  • Summary
  • トランスクリプト
  • コード
  • エージェント型アプリに対する信頼性の高い評価プロセスの確立

    Evaluationsフレームワークの高度な機能を活用して、アプリに対する信頼性の高い評価プロセスを確立する方法を学びましょう。ツール呼び出しや動的条件によるフローの評価方法と、自身のユースケースにおいてどのような動作が正しいのかを定義する方法を紹介します。信頼性の高い結果を得る上で役立つ、合成データの生成、判定の効果的な使用、データセットの検証の方法も説明します。

    関連する章

    • 0:00 - Introduction
    • 2:21 - The dataset problem in BookTracker
    • 3:46 - Generating synthetic data with makeSamples
    • 6:27 - Customizing generation with SampleGenerator
    • 8:38 - Sampling strategies
    • 10:11 - Validating synthetic samples
    • 13:04 - Comparing evaluation results
    • 15:09 - Tool calling and tool evaluations
    • 18:54 - Trajectory expectations
    • 21:26 - Building a tool call evaluation
    • 22:02 - Synthetic data for tool evaluations
    • 23:49 - Next steps

    リソース

    • Book Tracker: Using Evaluations to evaluate an intelligent feature
    • Generating synthetic datasets
    • Evaluating tool-calling behavior
    • Scoring with model-as-judge evaluators
      • HDビデオ
      • SDビデオ
  • このビデオを検索

    こんにちは、Adaです! Kyleです! 私たちはEvaluationチームの エンジニアです! 本日は皆さんに Evaluationフレームワークの 高度な機能をご紹介します! Evaluationフレームワークは Swiftアプリのインテリジェンス機能を 評価する方法を提供します 改善を継続的に追跡し 本番環境での品質を確保します このフレームワークはXcode 27の新機能で macOS、iOS、watchOS、visionOSに対応しています まだご覧になっていない方は "Meet the Evaluations framework"をご覧ください Evaluationフレームワークの 基礎について学べます またこちらのビデオ "Improve your prompts by hill climbing with Evaluations"では インテリジェンス機能を改善するための さまざまな戦略を紹介しています

    このビデオでは複雑さへの対処法と evaluationのスケーラビリティについて 説明します まずevaluationデータセットを 拡張する方法を探ります 合成データの生成と検証によって 次にエージェントワークフロー向けの 堅牢なevaluationの構築方法を取り上げます ツールコーリングと呼ばれる 特殊なモデルの動作が含まれます

    "Meet the Evaluations framework"では ヒルクライミングプロセスを紹介しました これはインテリジェント機能の構築 テスト、リリースプロセスを表しています このビデオではDevelopとEvaluateの ステップに重点を置きます Developステップでは少数のサンプルから evaluationを始めることが多いですが 機能はデータセットがカバーできる以上に 複雑なことがほぼ常にあります 構築に時間がかかり スケールも困難で 必要な多様性を とらえることも難しく 実世界での機能の動作を 真に理解することができません evaluationの結果の品質は データの品質に依存します 良いevaluationデータの作成は 難しいものです そこで合成データの出番です EvaluationフレームワークはAPIを提供し サンプル生成をすべてコードで 定義できます 独自の生成パイプラインを構築し コマンドラインから実行したり 既存のワークフローに直接 組み込むことができます テキストベースのデータを サポートしており generable macroを活用して 構造化された合成データを生成します 同僚とともにBookTrackerに 取り組んできました これはインテリジェンス機能を使った 個人ライブラリアプリです 書かれたレビューに基づいて 本のタグを自動付けします 各本の定義方法を見ていきましょう BookというクラスにはTitleが含まれ author、review、tags、ratingも含みます カバーデザインをサポートする 変数も定義します またsampleBooksも定義します 13個のBookサンプルの配列で こちらはPride and Prejudiceです この13サンプルは 妥当な出発点に思えますが この小さなデータセットでは 限られた視点しか得られず 機能のパフォーマンスを 十分に把握できません evaluation結果が良好に見えても 完全に誤解を招く可能性があります タグ生成機能の評価に使用する データの多様性を 考えてみてください!

    本は無数にあります 何百ものジャンル

    読んだものをレビューする方法も 多様です これは実世界の話でもあります まとめが曖昧だったり 不完全だったりします 13サンプルでは そのすべてをとらえられません より広いカバレッジが必要です 手動でサンプルを書く日々を 費やさずに済む必要があります! そのような多様性をとらえるための データセット拡張方法を説明します シンプルに始めましょう makeSamples APIには 3つのコンポーネントが必要です prompt、dataset、target countです これは生成したいサンプル数で 提供するデータセットを含む 合成生成の数です ここではpromptを定義しました モデルにより多様なブックレビュー サンプルを提案させます よく定義されたpromptを書くには モデルがタスクを最もよく理解するために 必要な情報を考慮してください ユーザーが提供する可能性のある 入力の範囲も含めて datasetにはsampleBooksを 渡しています 13の初期サンプルが含まれます

    新しいModelSamples APIを活用し 本のreviewを promptとして、本のtagsを 期待される出力として含めます target countは100サンプルに 設定して始めます! targetCountは最終的なデータセット 全体のサイズです 最初のサンプルも含みます つまりモデルは実際に 87個の新しいサンプルを生成します どれくらいのデータが十分か 気になるかもしれません 答えはケースバイケースです BookTrackerアプリでは100という target countは出発点に過ぎません! 合成データ生成は 反復的なプロセスです 初期データセットの定義から始まり 合成データを生成し サンプルを検証します 次にデータが十分に 代表的かどうかを分析し 確信が持てるまで このサイクルを続けます! evaluationデータセットに適した target countは 機能によって完全に異なります 機能内容、使用者、利用方法の 多様性すべてによります 量よりもはるかに重要なのは カバレッジです!

    何サンプル必要かを問う代わりに 次のことを自問してください この機能が実際に使われる 意味ある多様性をカバーしているか? 必要な変数を定義したので makeSamplesメソッドを使います 新しく生成されたサンプルの async streamを返します イテレートしながら 新しいサンプルはそれぞれ expandedDatasetに追加されます これは最初のデータセットで 初期化されています フレームワークはデフォルトで オンデバイスモデルを使用します オンデバイスモデルは ほとんどの場合に適していますが 独自のモデルを使いたい場合や モデルへの指示を カスタマイズしたい場合もあります フレームワークは柔軟性を提供しており サンプル生成の独自設定を 定義できます その方法を説明します!

    prompt、dataset、target countを超えた より複雑な設定には フレームワークはSampleGeneratorを 提供します 生成プロセスを完全に 制御できます 設定の一部を見ていきましょう!

    sessionProviderはLanguageModelSessionを 返すクロージャです ここで生成を担当する モデルを制御します またシステムレベルの指示で タスクを定義します 合成データ生成では PrivateCloudComputeLanguageModelを 使用します コンテキストサイズが大きいためで 次のような指示を追加します 特定の本、ジャンル、ムードに 絞り込むカスタム指示です

    生成サンプルへの期待として ルールリストも指定します これについては後ほど説明します セッションの使用方法について 説明します フレームワークはバッチサイズを 自動的に処理します これは生成時に処理される サンプル数です ジェネレータは実行開始時に sessionProviderを1回呼び出します その後バッチをまたいで セッションを再利用します 生成が進むにつれて モデルがコンテキストを維持できます

    ただしセッションには 上限があります 多数のリクエストを行う場合や 大きなプロンプトを与えたり 大きな出力を得る場合 実行中にセッションのコンテキスト ウィンドウが枯渇してエラーが発生します その場合ジェネレータは sessionProviderを再度呼び出し 新しいセッションで 生成を続けます ただし前のセッションの コンテキストは引き継がれません sessionProvider内の指示が 自己完結していることを確認してください 1回だけ呼ばれると 仮定しないようにしてください コンテキストサイズ制限の 対処法については "Build agentic app experiences with Foundation Models"をご覧ください カスタムのsession providerを使えば SampleGeneratorも活用できます samplingStrategyのカスタマイズも 可能です

    これはジェネレータが例を 選択する方法を制御します 初期データセットからモデルへの in-context例を表示します 指定できるサンプリング戦略は 2種類あります 1つ目はランダムサンプリングです

    この戦略は初期サンプルから ランダムなサブセットを選択します モデルに見せる例として 重複なく使用します 出力を多様に保ちながら 初期サンプルの順序を 慎重に考える必要がありません 2つ目のサンプリング戦略は スライディングウィンドウです

    この戦略は初期サンプルを 順番に処理します 重複はスキップしながら データセットに意味のある 順序がある場合 このスライディングウィンドウ 戦略の使用を検討してください

    私たちのジェネレータでは ランダム戦略を使用します 初期サンプルには意味のある 順序がないためです これはデフォルト戦略なので 明示的に定義する必要はありません

    カスタムsessionProviderで ジェネレータを設定したので .run関数を呼び出せます 新しく合成されたサンプルの streamを返します 各サンプルをイテレートすると 先に定義したexpandeDatasetに 追加されます

    設定が完了したので 合成データが期待通りかを 確認する方法を見ていきましょう ここでvalidatorクロージャが 活躍します validatorを使えば 独自のロジックで 生成された各サンプルを 受け入れるか拒否するかを定義できます すでにルールセットを定義しました 先ほどsession providerの 指示に含めました ただし出力が実際にルールに 従うことは保証されません 確認しましょう 最初のルールは レビューが100文字以上で あることです 各レビューはジャンル、ムード トーンを幅広くカバーする必要があります レビューの長さも 変化が必要です モデルは3から8個の ブックタグを生成する必要があります タグは小文字でなければなりません サンプルの検証内容を把握するには これらのルールに基づいて 体系的に確認できる内容を考えます validationクロージャは 各サンプルを個別に検証します 他のサンプルのコンテキストは 持ちません これらのルールを見ると レビューの多様性は より多くの判断を必要とし シンプルな検証チェックを 超えています レビューの長さはすべての サンプルにわたる評価が必要です

    その他のルールは 体系的に評価できます validationクロージャを使って 最初のルールにはレビューの 長さ検証を定義できます 誰もが知るクラシックな本として Mary Shelleyの"Frankenstein"を 例にしましょう 生成されたサンプルのレビューが 100文字以上あるかを 確認できます モデルは各レビューに タグも生成します つまり3から8個のタグがあるかを 検証できます

    最後にタグがすべて 小文字かを確認できます

    SampleGeneratorでこれら3つの 検証メトリクスを定義しました サンプルが期待する構造を 満たしているかを確認します 結果はどこに格納されるのでしょうか? 生成が進むにつれて 有効なサンプルはSyntheticGeneratorの samplesプロパティに収集されます これらのvalidatorに失敗したサンプルは invalidSamplesとして 自動的に除外されます どちらも実行中にリアルタイムで 更新されます いつでもアクセスできます イテレーション中に進捗を確認したり ループ完了後に参照できます 結果をアプリで直接使用したり データセットをローカルに保存できます 13の初期サンプルでの evaluationを確認しましょう Xcode 27では新しい Evaluations Reportを導入しました 結果を可視化できます これは13の初期サンプルを使った BookTaggingEvaluationです タグ品質のスコアが 非常に高いことがわかります 関連性と有用性の両方を 評価しています 100サンプルの新しいデータセットで evaluationを実行しました ボタンを使って 2つのevaluationを比較できます スコアが下がると予想しています!

    予想通りでした! 品質スコアが低下しました タグ生成機能は以前は 良好に見えていましたが 包括的なデータセットで テストしていなかったためです より大きなデータセットで evaluationを実行することで スコアの低下は さまざまなことを示します このシグナルが示す可能性を 考えてみましょう スコアの変化はpromptや 指示の問題かもしれません どちらかまたは両方を 改善して対応できます インテリジェンス機能の ギャップも考慮できます またはevaluationを調整して 実際に何を評価しているのかを 理解することも検討できます 最後に、データセットが まだ十分に代表的でない場合 より多くの変動を とらえる必要があります データセットをさらに増やしたり エッジケースを追加できます 合成データAPIを使って これらが結果をさらに改善する 主要な方法です

    堅牢なevaluationデータセットを 構築する確かなアプローチが整いました 合成データを使って さらに一歩進めたいと思います これまでブックタグ機能を 評価してきましたが アプリがより複雑になって 検索などのタスクに複数のアクションが 必要になったらどうなるでしょうか? そこでツールコーリングの出番です Kyleにバトンタッチして 説明してもらいます! ありがとう、Ada!

    evaluation driven developmentを 続けていきましょう tool evaluationを取り上げます これまではモデルが生成するものを 評価してきました 私たちの機能では本のタグです インテリジェンス機能は 多くの裏側の処理を経て 出力を生成します アプリ内で複数のアクションを実行し それぞれが結果に貢献します ツールはモデルのワークフローに 構造を追加します アプリのユーザーが タスクを完了する際に

    日常的に使用する実際のデータに 対して操作を行います

    定義したカスタムビジネスロジックで 動作できます

    ユーザーが直接呼び出せる機能や インテリジェンス機能のための 全く新しいロジック またはその組み合わせも使えます 重要なことがあります モデルはもっともらしい 回答を返すかもしれません 正しいツールを一切呼び出さずに 最終出力が正しく見えても そこに至る過程が正しくない場合があります それらの課題について tool evaluationがどのように 対処に役立つかを説明します

    まず、指示の遵守について: 各ツールの使い方を モデルに伝える必要があります 細部への注意が重要です

    自分で指示を一言一句 実行してみてください ステップを見落とすかを 確認するために

    次にツールの複雑さがあります シンプルな指示を受け入れたり パラメータ範囲の調整が必要なものもあります

    そしてエッジケースがあります ツールは一般的な入力では 正常に動作しているように見えても まれなケースでは 予期しない動作をすることがあります

    だからtool evaluationが 必要なのです 「何を」だけでなく 「どのように」を検証できます

    モデルは正しいツールを呼び出し 正しい引数を期待する順序で 使用する必要があります またその過程で 途中に予期しないツールコールが ないことを確認します

    実際に見ていき 最初のtool evaluationを構築します BookTrackerアプリに ライブラリアシスタントを追加しました ユーザーは本を検索でき タイトルや文字列だけで フィルタリングする代わりに モデルはアプリのカスタムツールを使って 関連する本を見つけます

    searchBooksツールは 類似タグの本を検索します getBookDetailsツールは 本のメタデータを抽出します 検索結果から出版日などを取得します

    findSimilarBooksツールは 類似する本のセマンティック検索を 実行します 複数のステップをチェーンし それぞれがツールコールです SearchBooksToolです

    Toolプロトコルに準拠し モデルが見る名前があります このツールが有用なタイミングを 説明するdescriptionがあります

    argumentsはGenerableのstructです これらはすべてoptionalです モデルはユーザーの要求に基づいて 使用するフィルタを決定します

    "find gothic books"と promptすると tag引数に値が入ることを 期待します "show me something cheerful"と promptすると ムード検索が生成されることを 期待します まさにこのような決定を 評価したいのです ツールについての復習でした では最初のtool evaluationを書き パフォーマンスを確認しましょう tool evaluationの主要コンポーネントは trajectory expectationです セッションのトランスクリプトには promptとレスポンスの中にツールコールが含まれます

    trajectory expectationは順序を確認します 言語モデルセッションの 各ツールコールの種類も確認します trajectory expectationチェックは ルートを計画する際の 決定リストを確認するようなものです 車、自転車、バスはすべてツールです それぞれ移動に適した 時と場所があります 特定の旅程の各区間での 有用性を評価できます

    expectationはすべての ツールコーろを確認します それぞれについて evaluationsに書いた expectationsと照合します コードでシンプルな例を見てみましょう promptは"Find books tagged gothic"です "searchBooks"への1つのツールコールを 期待します これはTrajectoryExpectationです モデルのトランスクリプトで 期待するツールコールを記述します unorderedはこのツールコールが いつ発生するかを問わないことを意味します 発生することだけが重要です expectationに引数を追加して さらに絞り込めます "gothic"というタグを 期待する引数を追加しています 完全一致が常に必要とは 限りません promptが"Find something cheerful"の場合 uplifting、happy、cheerfulなど どれでも問題ありません

    .naturalLanguageマッチャーは 値が意図に合うかを確認します 完全一致の文字列ではなく さまざまな状況に対応する マッチャーが揃っています contains、oneOf、pattern range などがあります 詳細についてはデベロッパ ドキュメントをご確認ください マルチステップタスクでは 順序が重要です

    モデルはまず "searchBooks"を呼び出す必要があります 次に"getBookDetails"を 呼び出します エージェントが最初に詳細を取得しようとすると bookIdがまだありません これはバグです Trajectory expectationsはこれをとらえます 旅程を確認しているからです 目的地だけでなく

    エージェントがすべきでないことも 同様に重要な場合があります

    promptに類似本を検索しないといった 指示が含まれる場合 モデルは指示に従う必要があります disallowedパラメータはトランスクリプトに 表示されないツールを指定します エージェントが"findSimilarBooks"を 呼び出した場合はfailureです すべてのtrajectory expectationsが まとまります 完全なevaluationの中で サンプルのデータセットを定義します それぞれにpromptと trajectory expectationがあります ToolCallEvaluatorを使って スコアをつけます ToolCallEvaluatorはLanguageModelSessionと ツールを組み合わせます レスポンスを取得し 構造化されたトランスクリプトをキャプチャします

    tool call evaluationの結果は Xcodeアシスタントに表示されます 他の結果と並んで インテリジェンス機能の動作の 全体像が把握できます しかし待ってください! Evaluations APIも使えます tool evaluationの合成データを 生成するために!

    ぜひやりましょう! Trajectory expectationsも generableです tool evaluationのデータセット拡張は 非常に複雑になりえます Evaluationフレームワークで それがはるかに簡単になりました! Tool Call evaluationは ModelSampleを活用しています またgenerableな TrajectoryExpectationも活用しています 以前と同様にSample generatorを使って サンプルを合成生成できます promptを定義しました sessionProvider用の カスタム指示も含めて tool evaluationの合成データを 作成する際に注意すべき点があります モデルは定義したツールを 知りません またツールを呼び出す 順序も知りません 利用可能なツールとその目的を 指定しました 順序の期待値など モデルが必要とするコンテキストも 次にsampleGeneratorを定義します 既存のデータセットを 初期サンプルとして使用します targetCountは100です ここで検証メトリクスも 指定できます! 常にexpectationがあることを 確認しました 合成サンプルに少なくとも 1つのツールが含まれることも確認しました 最後に呼び出されたツールが 定義済みのツールであることを確認します これがtool evaluationの 合成サンプルを生成・検証する 方法です! 合成データAPIは強力な方法で 既存のデータセットを 大幅に拡張できます! データが代表的であるほど スコアが実態を反映します Kyleさん、お願いします! すべてがまとまります 先ほどbook tagging evaluationを構築し モデルの生成内容を確認しました タグ数、ジャンルカバレッジ 品質スコアです tool evaluationでは モデルがそこに至る方法を確認します 正しいツール、正しい引数 そして正しい順序です 同じevaluationスイートで 両方を実行すれば 機能のエンドツーエンドの 信頼性が確保されます evaluationをより堅牢にする 方法をいくつかご紹介しました ご自身のアプリと evaluationデータセットに適用できます まず独自の合成データを 作成してみてください アプリのカスタムツールを評価し デベロッパドキュメントのサンプルアプリと 記事もご確認ください

    Ada、今日はたくさんカバーしましたね! そうですね、確かに! でも本当の見どころは 皆さんが構築するものです ネタバレはなしで! Evaluationフレームワークについて 楽しく学んでいただければ幸いです!

    • 5:16 - Generate synthetic data with makeSamples

      // Synthetic data
        let prompt = Prompt("""
            Generate diverse range of book reviews and corresponding tags.
            Cover a wide range of genres, time periods, cultures, and
            reader personas. Do not repeat books already in the dataset.
            """)
        
        let dataset = Book.sampleBooks.map { book in
            ModelSample(prompt: book.review, expected: BookTags(tags: book.tags))
        }
        
        let targetCount = 100
        var expandedDataset = dataset
      
        for try await sample in dataset.makeSamples(prompt, targetCount: targetCount) {
            expandedDataset.append(sample)
            print("Generated \(expandedDataset.count) samples so far.")
        }
      
        2. Configure a custom SampleGenerator — slides 30–43
        
        // Define your own configuration
        let generator = SampleGenerator<ModelSample<BookTags>>(
            prompt,
            samples: dataset,
            targetCount: targetCount,
            sessionProvider: {
                LanguageModelSession( 
                    model: PrivateCloudComputeLanguageModel(),
                    instructions: """
                        You are a synthetic data generator for a book-tracking app's evaluation suite.
                        Your job is to produce realistic, diverse book entries that will stress-test
                        a tagging system.
      
                        Rules:
                        - Review must be at least 100 characters long.
                        - Review should cover a mix of genre, mood/tone, and themes.
                        - Reviews should vary in length.
                        - Create between 3 and 8 tags.
                        - Tags must be lowercase.
                        """ 
                )
            }
        )
    • 5:53 - Configure a custom SampleGenerator

      // Define your own configuration
        let generator = SampleGenerator<ModelSample<BookTags>>(
            prompt,
            samples: dataset,
            targetCount: targetCount,
            sessionProvider: {
                LanguageModelSession( 
                    model: PrivateCloudComputeLanguageModel(),
                    instructions: """
                        You are a synthetic data generator for a book-tracking app's evaluation suite.
                        Your job is to produce realistic, diverse book entries that will stress-test
                        a tagging system.
      
                        Rules:
                        - Review must be at least 100 characters long.
                        - Review should cover a mix of genre, mood/tone, and themes.
                        - Reviews should vary in length.
                        - Create between 3 and 8 tags.
                        - Tags must be lowercase.
                        """ 
                )
            }
        )
    • 10:37 - Validate generated samples

      // Define validation metrics
        validator: { sample in
            guard let book = sample.expected else { return false }
      
            // Review must be at least 100 characters
            guard sample.promptDescription.count >= 100 else { return false }
      
            // Must have between 3 and 8 tags
            guard (3...8).contains(book.tags.count) else { return false }
      
            // All tags must be lowercase
            guard book.tags.allSatisfy({ $0 == $0.lowercased() }) else { return false }
      
            return true
        }
    • 10:58 - Access valid and invalid results

      // Accessing results
        for try await sample in generator.run() {
            // During iteration
            expandedDataset.append(sample)
        }
      
        // After iteration
        let allSamples = await generator.samples
        let invalidSamples = await generator.invalidSamples
        
        print("Generated \(allSamples.count) new samples. Total: \(expandedDataset.count)")
    • 15:30 - Define a tool's Generable argument

      @Generable
        struct SearchBooksArguments {
            @Guide(description: "A freeform search term to match against titles, reviews, or tags")
            var query: String?
        
            @Guide(description: "Filter results to books with this specific tag")
            var tag: String?
      
            @Guide(description: "Filter results by mood")
            var mood: String?
      
            @Guide(description: "Filter results by genre")
            var genre: String?
      
            @Guide(description: "Maximum number of results to return. Defaults to 5.")
            var limit: Int? 
        }
    • 16:37 - A basic trajectory expectation

      // "Find books tagged gothic"
        TrajectoryExpectation(
            unordered: [
                ToolExpectation(
                    "searchBooks",
                    arguments: [
                        .exact(argumentName: "tag", value: .string("gothic"))
                    ]
                )
            ]
        )
    • 17:07 - Match arguments by intent (naturalLanguage)

      // "Find something cheerful"
        TrajectoryExpectation(
            "searchBooks",
            arguments: [
                .naturalLanguage(
                    argumentName: "mood",
                    criteria: "Should relate to uplifting, hopeful, or positive feelings"
                )
            ]
        )
        Other matchers available: .contains, .oneOf, .pattern, .range, and more.
    • 17:34 - Expect tool calls in order

      // "Find gothic books and show details on the first"
        TrajectoryExpectation(
            ordered: [
                ToolExpectation(
                    "searchBooks",
                    arguments: [
                        .exact(argumentName: "tag", value: .string("gothic"))
                    ]
                ),
                ToolExpectation(
                    "getBookDetails",
                    arguments: [
                        .keyOnly(argumentName: "bookId")
                    ]
                )
            ]
        )
    • 17:55 - Disallow specific tool calls

      // "Show only sci-fi books. Don't look for similar ones."
        TrajectoryExpectation(
            unordered: [
                ToolExpectation(
                    "searchBooks",
                    arguments: [
                        .naturalLanguage(
                            argumentName: "genre",
                            criteria: "Should refer to science fiction")
                    ]
                )
            ],
            disallowed: [
                ToolExpectation("findSimilarBooks")
            ]
        )
    • 18:14 - Build a tool call evaluation

      // Tool call evaluations
        let samples = SampleArrayLoader(samples: [
            ModelSample(
                prompt: "Find all the books tagged with 'gothic'.",
                instructions: "Help the user explore their book collection.",
                expectations: TrajectoryExpectation(  )
            )
        ])
      
        struct BookLibraryToolCallEval: Evaluation {
            var dataset = samples
      
            let pass = Metric("All Passed")
            let percent = Metric("Percentage Passed")
      
            var evaluators: Evaluators { 
                ToolCallEvaluator(allPass: pass, percentagePass: percent)
            }
        }
    • 19:20 - Synthesize tool-evaluation samples

      // Tool call evaluations
        let prompt = Prompt("""
            Generate diverse user queries for a personal book library assistant.
            Each sample needs a prompt (what the user says), and a trajectory
            expectation describing which tools should be called and in what order.
            """)
      
        let instructions = """
            AVAILABLE TOOLS:
            - searchBooks(query?, tag?, mood?, genre?, limit?): search the library
            - getBookDetails(bookId): full details for one book
            - findSimilarBooks(bookId, maxResults?): find books sharing tags
            ORDER REQUIREMENTS:
            - searchBooks must comes before getBookDetails or findSimilarBooks
            - Use TrajectoryExpectation(ordered:) when sequence matters, else (unordered:)
            USE THESE ARGUMENT MATCHERS:
            - .exact for precise values, .naturalLanguage for fuzzy matching
            - .keyOnly when any value is acceptable, .range for numeric constraints
            - .contains/.hasPrefix/.hasSuffix for partial string matching
            """
    • 19:51 - Validate tool-evaluation samples

      // Tool call evaluations
        validator: { sample in
            // Must have expectations defined
            guard sample.output.expectations != nil else { return false }
      
            let expectations = sample.output.expectations!
      
            // Must reference at least one tool
            let totalExpectations = expectations.ordered.count + expectations.unordered.count
            guard totalExpectations > 0 else { return false }
      
            // All tool names must be from the valid set
            let validTools: Set<String> = ["searchBooks", "getBookDetails", "findSimilarBooks"]
            let allExpectations = expectations.ordered + expectations.unordered + expectations.disallowed
            for expectation in allExpectations {
                guard validTools.contains(expectation.name) else { return false }
            }
        
            return true
        }
      
        ---
    • 0:00 - Introduction
    • Ada Wong and Kyle Murray introduce advanced features of the Evaluations framework (new in Xcode 27). Outlines the agenda: growing your dataset with synthetic data, then building robust evaluations for agentic, tool-calling workflows, focused on the develop-and-evaluate step of hill-climbing.

    • 2:21 - The dataset problem in BookTracker
    • The BookTracker app auto-tags books from reviews, but its 13 hand-written sampleBooks give only a narrow view. Real-world reviews span countless books, genres, lengths, and styles, too much variety to capture by hand.

    • 3:46 - Generating synthetic data with makeSamples
    • The makeSamples API takes a prompt, a dataset (ModelSample with review to tags), and a target count (the full resulting size, including your seeds). It returns an async stream of new samples; coverage of real usage matters more than raw quantity.

    • 6:27 - Customizing generation with SampleGenerator
    • For more control, SampleGenerator exposes a sessionProvider closure to pick the model (such as Private Cloud Compute) and instructions. The session is reused across batches but can exhaust its context window mid-run, so make instructions self-contained since the provider may be called again.

    • 8:38 - Sampling strategies
    • The samplingStrategy controls which seed samples are shown to the model as in-context examples: random (a varied subset, the default) or slidingWindow (sequential, for datasets with meaningful order).

    • 10:11 - Validating synthetic samples
    • A validator closure accepts or rejects each generated sample in isolation against systematic rules: review length at least 100 characters, 3 to 8 tags, lowercase tags. Valid samples collect in samples, rejects in invalidSamples, both updated in real time.

    • 13:04 - Comparing evaluation results
    • Using the Xcode 27 Evaluations Report, compare the 13-sample run against the 100-sample run. The quality scores drop, the feature only looked good on the small dataset, and a drop can signal issues in the prompt, the feature, the evaluation, or the dataset.

    • 15:09 - Tool calling and tool evaluations
    • Tool evaluations: features often take multiple behind-the-scenes tool calls, and a plausible answer can come from the wrong path. Tool evaluations verify the how: correct tools, correct arguments, correct order, no surprises, illustrated with searchBooks, getBookDetails, and findSimilarBooks.

    • 18:54 - Trajectory expectations
    • A TrajectoryExpectation checks the kind and order of tool calls in a session transcript. Refine with argument matchers (exact, naturalLanguage, contains, oneOf, pattern, range), plus ordered expectations and a disallowed set for tools that must not be called.

    • 21:26 - Building a tool call evaluation
    • Bring the trajectory expectations together: a dataset of samples (each a prompt plus expectation) scored by ToolCallEvaluator, which combines a LanguageModelSession with the tools, captures the structured transcript, and reports alongside your other results in Xcode.

    • 22:02 - Synthetic data for tool evaluations
    • Because ModelSample and TrajectoryExpectation are Generable, you can synthesize tool-evaluation samples too, describing the available tools, order expectations, and context in the prompt, then validating that each sample has an expectation, at least one tool, and only real tools.

    • 23:49 - Next steps
    • Run BookTaggingEvaluation (what the model produces) and tool evaluations (how it gets there) in one suite for end-to-end confidence. Next steps: create your own synthetic data, evaluate your app's custom tools, and explore the sample app and documentation.

Developer Footer

  • ビデオ
  • WWDC26
  • エージェント型アプリに対する信頼性の高い評価プロセスの確立
  • メニューを開く メニューを閉じる
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    メニューを開く メニューを閉じる
    • アクセシビリティ
    • アクセサリ
    • Apple Intelligence
    • App Extension
    • App Store
    • オーディオとビデオ(英語)
    • 拡張現実
    • デザイン
    • 配信
    • 教育
    • フォント(英語)
    • ゲーム
    • ヘルスケアとフィットネス
    • アプリ内課金
    • ローカリゼーション
    • マップと位置情報
    • 機械学習とAI
    • オープンソース(英語)
    • セキュリティ
    • SafariとWeb(英語)
    メニューを開く メニューを閉じる
    • 英語ドキュメント(完全版)
    • 日本語ドキュメント(一部トピック)
    • チュートリアル
    • ダウンロード
    • フォーラム(英語)
    • ビデオ
    Open Menu Close Menu
    • サポートドキュメント
    • お問い合わせ
    • バグ報告
    • システム状況(英語)
    メニューを開く メニューを閉じる
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles(英語)
    • フィードバックアシスタント
    メニューを開く メニューを閉じる
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program(英語)
    • Mini Apps Partner Program
    • News Partner Program(英語)
    • Video Partner Program(英語)
    • セキュリティ報奨金プログラム(英語)
    • Security Research Device Program(英語)
    Open Menu Close Menu
    • Appleに相談
    • Apple Developer Center
    • App Store Awards(英語)
    • Apple Design Awards
    • Apple Developer Academy(英語)
    • WWDC
    最新ニュースを読む。
    Apple Developerアプリを入手する。
    Copyright © 2026 Apple Inc. All rights reserved.
    利用規約 プライバシーポリシー 契約とガイドライン