View in English

  • メニューを開く メニューを閉じる
  • Apple Developer
検索
検索を終了
  • Apple Developer
  • ニュース
  • 見つける
  • デザイン
  • 開発
  • 配信
  • サポート
  • アカウント
次の内容に検索結果を絞り込む

クイックリンク

5 クイックリンク

ビデオ

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

WWDC25に戻る

  • 概要
  • トランスクリプト
  • コード
  • Foundation Modelフレームワークの紹介

    Apple Intelligenceを支えるオンデバイスの大規模言語モデルを活用する方法を学びましょう。この概要セッションでは、Swiftのデータ構造のガイド付き生成、応答性の高い体験を実現するストリーミング、コンテキスト管理のためのデータソースとセッションの統合を可能にするツール呼び出しなど、このフレームワークの機能を幅広く網羅しています。このセッションには、参加のための前提条件はありません。

    関連する章

    • 0:00 - イントロダクション
    • 2:05 - モデル
    • 5:20 - ガイド付き生成
    • 7:45 - スナップショットのストリーミング
    • 11:28 - ツール呼び出し
    • 16:11 - ステートフルなセッション
    • 21:02 - デベロッパの体験

    リソース

    • Human Interface Guidelines: Generative AI
      • HDビデオ
      • SDビデオ

    関連ビデオ

    WWDC25

    • オンデバイス基盤モデルのためのプロンプトの設計と安全性の詳細
    • Appleプラットフォームでの機械学習/AIフレームワーク
    • Code Along:Foundation Modelフレームワークによる、アプリへのオンデバイスAIの組み込み
    • Foundation Modelフレームワークの詳細
  • このビデオを検索

    こんにちは Erikです Yifeiです このセッションで 新しいFoundation Modelフレームワークを ご紹介できるのを嬉しく思います Foundation Modelフレームワークでは Apple Intelligenceの基盤となる オンデバイスの大規模言語モデルを 便利で強力なSwift APIにより利用できます このフレームワークはmacOS、 iOS、iPadOS、visionOSで利用できます パーソナライズされた検索候補を 表示するなど アプリの既存の機能を強化できます または 旅行アプリでの旅程の生成を すべてオンデバイスで実行するなど まったく新しい機能を 作成することもできます さらには ゲームキャラクターの会話を リアルタイムで生成することさえ可能です

    このフレームワークは コンテンツの生成、テキストの要約、 ユーザー入力の分析などに 最適化されています これらはすべてデバイス上で実行されるので モデルに入力され モデルから出力される 全データのプライバシーが確保されます これは オフライン実行も可能ということです また OSに組み込まれているため アプリのサイズが大きくなりません 今年の進化は かなり大幅なので 皆さんが最大限に Foundation Modelフレームワークを 活用できるよう 一連のビデオを用意しました この最初のビデオでは フレームワーク全体の 概要を説明します まず モデルの詳細について解説し 次に ガイド付き生成を紹介します この機能はSwiftに 構造化された出力と 遅延を解消し快適さをもたらす 強力なストリーミングのAPIを提供します また ツール呼び出しについても説明します これは アプリで定義したコードをモデルが 自律的に実行できるようにする機能です 最後に 締めくくりとして ステートフルなセッションで マルチターンをサポートする方法と このフレームワークを Appleデベロッパのエコシステムに シームレスに統合する方法を説明します フレームワークの最も重要な部分は 当然ながら その基盤となるモデルです そして モデルへのプロンプティングを 開始する最良の方法は Xcodeを導入することです 様々なプロンプトをテストして 最適なプロンプトを特定することは 大規模言語モデル構築の重要な部分であり そして Xcodeの新しいPlayground機能は その作業に最適です わずか数行のコードで オンデバイスモデルの プロンプティングをすぐに開始できます ここでは 日本への旅行のタイトルを 生成するように指示します するとモデルの出力が 右側のキャンバスに表示されます このプロンプトが他の目的地の場合でも うまく機能するかどうかを確認します #Playgroundでは アプリで定義された 型にアクセスできるので アプリで紹介している観光名所を対象とする forループを作成します Xcodeは すべての観光名所に対する モデルの応答を表示します

    ここで使用したオンデバイスのモデルは 30億個のパラメータを持つ 大規模言語モデルで 各パラメータは 2ビットに量子化されます このモデルは OS内の他のどのモデルよりも 数桁大規模です

    しかしそれでも オンデバイスのモデルは デバイススケールの モデルであることを 肝に銘じておくことが重要です このモデルが最適化されているのは 要約、抽出、 分類などに対してです その設計は 世界に関する知識の収集や 高度な推論を目的としていません それらのタスクには通常 サーバスケールのLLMを使用します

    デバイススケールのモデルでは タスクを細かく分割する必要があります このモデルを扱っているうちに その長所と短所が 直感的にわかってくるでしょう

    コンテンツのタグ付けなど 特定の一般的なユースケースでは Appleは専用のアダプタも提供し その特定の分野で モデルの機能が最大化されるようにします

    さらに モデルの改良は 今後も継続していきます このビデオでは後ほど モデル使用に関する フィードバックの提供方法も紹介します これは 皆さんにとって意義のある形で Appleがモデルを改良していく上で有益です

    以上 モデルについて説明しましたが このセッションの最初のハイライトは ガイド付き生成です ガイド付き生成は 先ほど説明したような機能の 構築を可能にする技術であり Foundation Modelフレームワークの 核となるものです では ガイド付き生成によって 解決できる一般的な問題と その方法を見てみましょう 言語モデルがデフォルトで生成する出力は 構造化されていない自然言語です 人間には読みやすいですが アプリのビューへのマッピングは困難です

    一般的な解決策は JSONやCSVなど 解析しやすいファイルを生成するよう モデルに指示することです

    しかし この方法ではすぐに イタチごっこになってしまいます 何をすべきか またしないべきか 具体的な指示を 次から次へと追加することになり 大抵はうまくいきません コンテンツを抽出してパッチ適用するための 凝ったコードを書く羽目になります これは モデルが確率的な性質であるため 信頼できません しかも 構造上のミスが生じる 危険性はゼロではありません ガイド付き生成は この問題に対する 根本的な解決策を提供します

    Foundation Modelを導入すると 2つの新しいマクロである @Generableと@Guideを利用できます @Generableでは モデルにインスタンスを生成させる 型を指定できます そして@Guideでは 自然言語でプロパティの説明を提供して それらのプロパティに対し生成できる値を プログラムで制御できます

    Generable型を定義したら モデルがプロンプトへの応答として その型の インスタンスを生成するようにできます これは非常に強力です プロンプトでの出力形式の指定が 不要になったことにご注目ください フレームワークが代わりに処理してくれます

    もちろん 最も重要な部分は 魅力的なビューへと簡単にマッピングできる 豊富なSwiftオブジェクトを 利用できるようになることです

    Generable型の構成には Strings、 Integer、Double、Float、Decimal、 Booleanなどのプリミティブを使用できます 配列も生成可能です また Generable型を構成することもできます Generableは再帰型もサポートしています この型は生成UIなどの分野の 強力な用途に利用できます ガイド付き生成について理解しておくべき 最も重要なことは この機能が 制限付きデコードと呼ばれる手法により 根本において 構造上の適切さを保証してくれる点です ガイド付き生成を使用すると プロンプトがよりシンプルになり 形式ではなく 目的の動作に重点を置くことができます さらに ガイド付き生成では通常 モデルの精度が向上します また 最適化を推進できるようになり 推論の高速化にもつながります これらすべてを実現できたのは 入念な調整を行いながら Appleの各種OS、 デベロッパツール、基盤モデルの トレーニングを統合した結果です ガイド付き生成については 実行時に動的なスキーマを 作成する方法など 説明すべき内容がまだ多数あります 詳細を解説する これ以外のビデオもぜひご覧ください ガイド付き生成の説明は以上です 自然言語プロンプトを強化して 構造化された信頼性の高い出力を提供する Swiftの強力な型システムを紹介しました 次のトピックはストリーミングです これは 皆さんもすでにご存じの @Generableマクロを基盤としています 大規模言語モデルの 使用経験があればご存じでしょうが このモデルでは 短い文字のグループである トークンという形式でテキストを生成します 出力のストリーミングでは通常 トークンは デルタという形式で配信されますが Foundation Modelフレームワークの アプローチは それとは異なります その理由を説明します

    デルタが生成されると それらを蓄積しておく責任は 通常はデベロッパにあります デベロッパが デルタが生成されるたびに 追加していくと 応答は成長していきます しかし 生成結果が構造化されている場合 問題が生じます 各デルタの後にあいさつの文字列を 表示したい場合 蓄積した デルタを解析して取得する必要があります これはそう簡単な作業ではありません 特に 構造が複雑な場合は困難です デルタストリーミングは 構造化された出力を扱う場合 適切な方法とは言えません 先ほど確認したように 構造化された出力は まさに Foundation Modelフレームワークの 核心であるため 私たちは異なるアプローチを開発しました 生のデルタの代わりに スナップショットをストリーミングします

    モデルがデルタを生成すると フレーム ワークがスナップショットに変換します スナップショットは 部分的に生成された応答に相当します そのプロパティはすべて任意であり モデルが生成する応答が増えるにつれて 入力されていきます スナップショットは 構造化された 出力をストリーミングする上で 強力かつ便利な表現方法です

    @Generableマクロについては先にも 説明しましたが 今お話ししたように PartiallyGenerated型の定義も そこから提供されます マクロを展開するとわかるように 「PartiallyGenerated」という型が 生成されています それは事実上 外部構造のコピーですが プロパティがすべて任意である点が違います

    PartiallyGenerated型が機能するのは セッションで'streamResponse'メソッドを 呼び出す時です

    streamResponseは 非同期シーケンスを返します そのシーケンスの要素は PartiallyGenerated型のインスタンスです シーケンス内の各要素には 更新されたスナップショットが含まれます

    このスナップショットは SwiftUIのような 宣言型のフレームワークに最適です まず PartiallyGenerated型を保持する Stateを作成します 次に 応答のストリームを反復処理し その要素を格納して UIに反映されるのを確認します

    最後に ストリーミングに関する ベストプラクティスを確認しましょう

    まず SwiftUIのアニメーションと遷移で 創造性を発揮して 遅延が気にならないようにしましょう 単に待つだけの時間も 楽しい体験に変えられるはずです 次に SwiftUIのビューの識別子は 慎重に検討しましょう 配列を生成する場合は 特に要注意です 最後に プロパティが生成される順序は Swiftの構造体で宣言された順に 従うことに注意しましょう これは アニメーションと モデルの出力品質の両方にとって重要です 例えば モデルが生成する要約の品質を 最適化するには 要約を 構造体の最後のプロパティにする 必要がある場合があります

    お伝えしたいことは他にもたくさんあるので 詳しくは Foundation Modelの SwiftUIアプリへの統合に関する 画面に示したビデオをぜひご覧ください Foundation Modelによる ストリーミングの説明は以上です 次は ツールの呼び出しについて Yifeiが説明します ありがとう Erik ツール呼び出しも重要な機能の1つです これにより アプリで定義したコードを モデルが実行できるようになります この機能は モデルを最大限に活用する上で 特に重要です ツール呼び出しによって モデルの様々な 追加機能が利用可能になるためです 対象のタスクに 追加の情報や アクションが必要かどうか モデルが判断して どのツールをいつ使うかを プログラムでは判断しにくい場合に 自律的に決定できるようになります デベロッパがモデルに提供する情報は 世界に関する知識、 最近のイベント、個人データなどです 例えば サンプルの旅行アプリでは 様々な場所に関する情報を MapKitから提供しています これは 信頼できる情報源を引用する能力を モデルに獲得させる上でも役立ち ハルシネーションの抑制や モデル出力の ファクトチェックも可能になります 最後に ツール呼び出しによりモデルは アプリ内、 システム上、実世界など どこでもアクションを 実行できるようになります アプリ内の様々な情報源との統合は 魅力的な体験を構築する上で 効果的な戦略です ツール呼び出しが非常に便利である 理由を説明しました 次は その仕組みを見てみましょう 左側には それまでに起こった すべてのことを記録する トランスクリプトがあります セッションにツールを提供した場合 セッションはそのツールを 指示とともにモデルに提示します 次に どの目的地に行きたいかを モデルに指示するプロンプトがあります ここでモデルは ツール呼び出しにより 応答を強化できると判断した場合 1つ以上のツール呼び出しを生成します この例では モデルは 2つのツール呼び出しを生成しています レストランとホテルのクエリです この段階で Foundation Modelフレームワークが これらのツール用に記述した コードを自動的に呼び出します フレームワークは次に ツールの出力を トランスクリプトに自動的に挿入します 最後に モデルにはツール出力と その他の要素を トランスクリプトに組み込み 最終的な応答を生成します

    ツール呼び出しの概要について 理解できたので ツールの定義に移りましょう

    ここでは Toolプロトコルに準拠した シンプルな天気ツールを定義します 天気ツールは いわば ツール呼び出しの 「Hello World」となっています デモを始めるには最適な例です

    Toolプロトコルでは 最初にツールの名前と 自然言語での説明を指定する必要があります

    フレームワークはこれらの情報を モデルがツールをいつ呼び出すべきか 理解できるよう モデルに自動的に提供します

    モデルがツールを呼び出すと 定義したcallメソッドが実行されます

    callメソッドの引数には 任意のGenerable型を指定できます

    引数がGenerable型である必要があるのは ツール呼び出しが ガイド付き生成を 基盤として構築されているためです それにより モデルが 無効なツール名や引数を 生成することを防げます 引数の型を定義したら メソッドの本文に 必要なものを何でも記述できます ここでは CoreLocationと WeatherKitを使用して 都市の気温を取得しています 出力は ToolOutput型を使用して 表現されます この型は 構造化データを表現するために GeneratedContentから作成できます または ツールの出力が自然言語の場合 文字列から作成できます ツールを定義できたので 次は モデルがそのツールに アクセスできるようにする必要があります そのためには ツールをセッションの イニシャライザに渡します ツールはセッションの初期化時に アタッチされており セッションの存続期間を通じて モデルがアクセスできる必要があります

    ツールとともにセッションを作成した後 必要なことは 通常通り モデルにプロンプトを提供することだけです ツール呼び出しは透過的かつ自律的に行われ モデルはツールの出力を 最終的な応答に組み込みます ここで示した例は コンパイル時に 型安全なツールを定義する方法です これは 大部分のユースケースにおいて有効ですが ツールはあらゆる点で 動的にすることもできます 例えば 動的な生成スキーマを使用すれば 実行時のツールの 引数と動作を定義できます ご興味のある方は 詳細を解説する下記のビデオをご覧ください ツール呼び出しの説明は以上です ツール呼び出しが便利である理由と ツールを実装してモデルの機能を 拡張する方法をご紹介しました 次のテーマはステートフルなセッションです このビデオでは「セッション」という言葉が 何度も登場していますね Foundation Modelフレームワークの基盤は ステートフルなセッションという概念です デフォルトでは セッションを作成すると オンデバイスの汎用モデルに プロンプトが提示されます カスタムの指示を提供することもできます 指示を提供することで モデルに自らの役割を伝え モデルがどのように応答すべきかについて ガイドを提供できます 例えば スタイルや詳細度などを指定できます なお カスタムの指示の提供は任意であり 提供しない場合は 妥当なデフォルトの指示が使用されます

    カスタムの指示を提供する場合は 指示とプロンプトの違いを 理解することが重要です 指示はデベロッパが提供するものである一方 プロンプトはユーザーから提供可能です これは プロンプトより指示を優先するよう モデルがトレーニングされているためです これはプロンプトインジェクション攻撃への 対策に役立ちますが それで万全というわけではありません 原則として 指示はほとんどの場合静的であり 信頼されていないユーザーの入力を 指示に挿入すべきではありません これは 指示とプロンプトの 最適な作成方法に関する基本事項です より詳細なベストプラクティスについては プロンプトの設計と安全性に関する ビデオをご覧ください セッションの初期化については以上で 次は マルチターンインタラクションの説明です 先ほど説明した respondまたはstreamResponseメソッドを 使用する場合 モデルとの間の 各インタラクションは トランスクリプトの コンテキストとして保持されます それにより モデルは単一のセッション内の 過去のマルチターンインタラクションを 参照し理解できます 例えば この例のモデルは 「もう1回実行」という指示の内容が 過去における俳句の生成に 言及していることを理解できます

    また sessionオブジェクトの 'transcript'プロパティによって 過去のインタラクションを調べたり それを表すUIビューを描画したりできます

    もう1つの重要な点は モデルが出力を生成する際に 'isResponding'プロパティが 'true'になることです このプロパティを監視しておき モデルの 応答が完了するまでは別のプロンプトを 送信しないようにする必要があります デフォルトのモデル以外にも アダプタによって可能になる 組み込みの特殊なユースケースにも 対応しています ニーズに合う 組み込みのユースケースがある場合 SystemLanguageModelの イニシャライザに渡すことができます どのような組み込みのユースケースがあり どうすれば有効活用できるかについては Apple Developer Webサイトの ドキュメントをお読みください ここで詳しく説明したい 専用のアダプターの1つが コンテンツタグ付けアダプタです コンテンツタグ付けアダプタはタグ生成、 エンティティ抽出、トピック検出のための 優れたサポートを提供します このアダプタはデフォルトでトピックタグを 出力するようにトレーニングされており ガイド付き生成とそのまま統合できます そのため Generableマクロを使用して 構造体を定義し ユーザーの入力を渡すだけで トピックを抽出できます

    それだけではなく カスタムの指示と カスタムのGenerable出力型を提供すれば アクションや感情などの 検出にも使用できます セッションを作成する前に モデルが利用可能かの確認も必要です モデルは Apple Intelligence対応の デバイスで サポート対象の地域でのみ 実行できるためです モデルが現在利用可能かどうかを 確認するには SystemLanguageModelの availabilityプロパティにアクセスします

    availabilityは2ケースの列挙型であり 値はavailableかunavailableのいずれかです unavailableの場合 理由も提供されるので それに応じてUIを調整できます

    最後に モデルを呼び出す時に エラーが発生する場合があります これらのエラーの内容は ガードレール違反、サポート非対象の言語、 コンテキストウインドウの超過などです 最高のユーザー体験を提供するには これらを適切に処理する必要がありますが 対処法について詳しくは 画面に示す詳細解説ビデオをご覧ください マルチターンのステートフルなセッションの 説明は以上です セッションを作成し使用する方法と モデルがコンテキストを追跡する 仕組みについて説明しました フレームワークの様々な 素晴らしい機能を紹介してきましたが 次は デベロッパツールと デベロッパの体験についてお話しします まず プロジェクト内の 任意のSwiftファイルに移動し 新しいPlaygroundマクロを使用して モデルにプロンプトを提供します

    Playgroundの優れた点は アプリ全体の 再ビルドと再実行を行うことなく プロンプトを迅速に反復処理できる点です Playgroundでは コードはプロジェクト内の すべての型にアクセスできます 例えば 既にUIで利用されている Generable型などです

    次に 大規模言語モデルを利用している アプリの体験を構築する場合 内部におけるすべての遅延を 把握することが重要です 大規模言語モデルでは 従来型のMLモデルよりも 実行に時間がかかるためです 遅延がどこで生じるかを把握できると プロンプトの冗長性を修正したり ウォームアップなどの便利なAPIを 呼び出すタイミングを判断したりできます

    新しいInstrumentsの アプリプロファイリングテンプレートは まさにそのために構築されました モデルのリクエストの遅延をプロファイルし 最適化可能な領域を監視して 改善の度合を測定できます

    アプリを開発する中で モデルとAPIの改善に役立つような フィードバックを Appleに ご提供いただけることもあると思います

    フィードバックアシスタントを通じて ぜひフィードバックをご提供ください フィードバックにファイルとして添付できる エンコード可能な フィードバック添付用の データ構造体も提供しています

    最後に 高度に専門化されたユースケースを 扱い カスタムのデータセットを使用する ML担当のデベロッパの方は アダプタトレーニングツールキットを使った カスタムアダプタのトレーニングもできます しかし これには大きな責任も伴うことを 心に留めておいてください Appleは継続的にモデルを改良するので 再トレーニングが必要になるためです 詳しくは Apple Developer Webサイトをご覧ください 本セッションでは 新しいFoundation Modelフレームワークが 提供する 優れた機能を多数紹介しました 皆さんがこのフレームワークで最高の アプリを構築されることを期待しています 生成AIをアプリに組み込む方法の詳細や ガイド付き生成などのテクノロジーの 仕組みの詳細 最高のプロンプトを作成する方法について 知りたい方のために 充実した ビデオや記事を豊富にご用意しています ご視聴ありがとうございました 学習内容をぜひご活用ください

    • 2:28 - Playground - Trip to Japan

      import FoundationModels
      import Playgrounds
      
      #Playground {
          let session = LanguageModelSession()
          let response = try await session.respond(to: "What's a good name for a trip to Japan? Respond only with a title")
      }
    • 2:43 - Playground - Loop over landmarks

      import FoundationModels
      import Playgrounds
      
      #Playground {
          let session = LanguageModelSession()
          for landmark in ModelData.shared.landmarks {
              let response = try await session.respond(to: "What's a good name for a trip to \(landmark.name)? Respond only with a title")
          }
      }
    • 5:32 - Creating a Generable struct

      // Creating a Generable struct
      
      @Generable
      struct SearchSuggestions {
          @Guide(description: "A list of suggested search terms", .count(4))
          var searchTerms: [String]
      }
    • 5:51 - Responding with a Generable type

      // Responding with a Generable type
      
      let prompt = """
          Generate a list of suggested search terms for an app about visiting famous landmarks.
          """
      
      let response = try await session.respond(
          to: prompt,
          generating: SearchSuggestions.self
      )
      
      print(response.content)
    • 6:18 - Composing Generable types

      // Composing Generable types
      
      @Generable struct Itinerary {
          var destination: String
          var days: Int
          var budget: Float
          var rating: Double
          var requiresVisa: Bool
          var activities: [String]
          var emergencyContact: Person
          var relatedItineraries: [Itinerary]
      }
    • 9:20 - PartiallyGenerated types

      // PartiallyGenerated types
      
      @Generable struct Itinerary {
          var name: String
          var days: [Day]
      }
    • 9:40 - Streaming partial generations

      // Streaming partial generations
      
      let stream = session.streamResponse(
          to: "Craft a 3-day itinerary to Mt. Fuji.",
          generating: Itinerary.self
      )
      
      for try await partial in stream {
          print(partial)
      }
    • 10:05 - Streaming itinerary view

      struct ItineraryView: View {
          let session: LanguageModelSession
          let dayCount: Int
          let landmarkName: String
        
          @State
          private var itinerary: Itinerary.PartiallyGenerated?
        
          var body: some View {
              //...
              Button("Start") {
                  Task {
                      do {
                          let prompt = """
                              Generate a \(dayCount) itinerary \
                              to \(landmarkName).
                              """
                        
                          let stream = session.streamResponse(
                              to: prompt,
                              generating: Itinerary.self
                          )
                        
                          for try await partial in stream {
                              self.itinerary = partial
                          }
                      } catch {
                          print(error)  
                      }
                  }
              }
          }
      }
    • 11:00 - Property order matters

      @Generable struct Itinerary {
        
        @Guide(description: "Plans for each day")
        var days: [DayPlan]
        
        @Guide(description: "A brief summary of plans")
        var summary: String
      }
    • 13:42 - Defining a tool

      // Defining a tool
      import WeatherKit
      import CoreLocation
      import FoundationModels
      
      struct GetWeatherTool: Tool {
          let name = "getWeather"
          let description = "Retrieve the latest weather information for a city"
      
          @Generable
          struct Arguments {
              @Guide(description: "The city to fetch the weather for")
              var city: String
          }
      
          func call(arguments: Arguments) async throws -> ToolOutput {
              let places = try await CLGeocoder().geocodeAddressString(arguments.city)
              let weather = try await WeatherService.shared.weather(for: places.first!.location!)
              let temperature = weather.currentWeather.temperature.value
      
              let content = GeneratedContent(properties: ["temperature": temperature])
              let output = ToolOutput(content)
      
              // Or if your tool’s output is natural language:
              // let output = ToolOutput("\(arguments.city)'s temperature is \(temperature) degrees.")
      
              return output
          }
      }
    • 15:03 - Attaching tools to a session

      // Attaching tools to a session
      
      let session = LanguageModelSession(
          tools: [GetWeatherTool()],
          instructions: "Help the user with weather forecasts."
      )
      
      let response = try await session.respond(
          to: "What is the temperature in Cupertino?"
      )
      
      print(response.content)
      // It’s 71˚F in Cupertino!
    • 16:30 - Supplying custom instructions

      // Supplying custom instructions
      
      let session = LanguageModelSession(
          instructions: """
              You are a helpful assistant who always \
              responds in rhyme.
              """
      )
    • 17:46 - Multi-turn interactions

      // Multi-turn interactions
      
      let session = LanguageModelSession()
      
      let firstHaiku = try await session.respond(to: "Write a haiku about fishing")
      print(firstHaiku.content)
      // Silent waters gleam,
      // Casting lines in morning mist—
      // Hope in every cast.
      
      let secondHaiku = try await session.respond(to: "Do another one about golf")
      print(secondHaiku.content)
      // Silent morning dew,
      // Caddies guide with gentle words—
      // Paths of patience tread.
      
      print(session.transcript)
// (Prompt) Write a haiku about fishing
      // (Response) Silent waters gleam...
      // (Prompt) Do another one about golf
      // (Response) Silent morning dew...
    • 18:22 - Gate on isResponding

      import SwiftUI
      import FoundationModels
      
      struct HaikuView: View {
      
          @State
          private var session = LanguageModelSession()
      
          @State
          private var haiku: String?
      
          var body: some View {
              if let haiku {
                  Text(haiku)
              }
              Button("Go!") {
                  Task {
                      haiku = try await session.respond(
                          to: "Write a haiku about something you haven't yet"
                      ).content
                  }
              }
              // Gate on `isResponding`
              .disabled(session.isResponding)
          }
      }
    • 18:39 - Using a built-in use case

      // Using a built-in use case
      
      let session = LanguageModelSession(
          model: SystemLanguageModel(useCase: .contentTagging)
      )
    • 19:19 - Content tagging use case - 1

      // Content tagging use case
      
      @Generable
      struct Result {
          let topics: [String]
      }
      
      let session = LanguageModelSession(model: SystemLanguageModel(useCase: .contentTagging))
      let response = try await session.respond(to: ..., generating: Result.self)
    • 19:35 - Content tagging use case - 2

      // Content tagging use case
      
      @Generable
      struct Top3ActionEmotionResult {
          @Guide(.maximumCount(3))
          let actions: [String]
          @Guide(.maximumCount(3))
          let emotions: [String]
      }
      
      let session = LanguageModelSession(
          model: SystemLanguageModel(useCase: .contentTagging),
          instructions: "Tag the 3 most important actions and emotions in the given input text."
      )
      let response = try await session.respond(to: ..., generating: Top3ActionEmotionResult.self)
    • 19:56 - Availability checking

      // Availability checking
      
      struct AvailabilityExample: View {
          private let model = SystemLanguageModel.default
      
          var body: some View {
              switch model.availability {
              case .available:
                  Text("Model is available").foregroundStyle(.green)
              case .unavailable(let reason):
                  Text("Model is unavailable").foregroundStyle(.red)
                  Text("Reason: \(reason)")
              }
          }
      }
    • 22:13 - Encodable feedback attachment data structure

      let feedback = LanguageModelFeedbackAttachment(
        input: [
          // ...
        ],
        output: [
          // ...
        ],
        sentiment: .negative,
        issues: [
          LanguageModelFeedbackAttachment.Issue(
            category: .incorrect,
            explanation: "..."
          )
        ],
        desiredOutputExamples: [
          [
            // ...
          ]
        ]
      )
      let data = try JSONEncoder().encode(feedback)

Developer Footer

  • ビデオ
  • WWDC25
  • Foundation Modelフレームワークの紹介
  • メニューを開く メニューを閉じる
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    メニューを開く メニューを閉じる
    • アクセシビリティ
    • アクセサリ
    • App Extension
    • App Store
    • オーディオとビデオ(英語)
    • 拡張現実
    • デザイン
    • 配信
    • 教育
    • フォント(英語)
    • ゲーム
    • ヘルスケアとフィットネス
    • アプリ内課金
    • ローカリゼーション
    • マップと位置情報
    • 機械学習
    • オープンソース(英語)
    • セキュリティ
    • 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(英語)
    • 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 © 2025 Apple Inc. All rights reserved.
    利用規約 プライバシーポリシー 契約とガイドライン