Apple Foundation Models:オンデバイスのLLMフレームワークを解説
Foundation Modelsフレームワークを使うと、アプリからApple Intelligenceを支えるのと同じオンデバイス大規模言語モデルへ、直接かつ無料で、オフラインのままアクセスできます1。APIキーも、トークン単位の課金も、ネットワークの往復も不要で、データが端末の外へ出ることもありません。かつてはクラウドLLMとプライバシーレビューを意味していた種類の機能が、いまやコストはほぼゼロに丸め込まれます。その引き換えになるのが能力です。オンデバイスモデルは小さく、コンテキストウィンドウは有限で、フレームワーク自体が「何をして、何をしないか」に明確な線を引いています。その線を知ることこそが、すべてなのです。
本稿はフレームワークそのもののリファレンスです。実際に呼び出す型、このフレームワークを使う価値を生む唯一の機能、そして手を止めてより大きなものに頼るべき分岐点を扱います。
TL;DR
LanguageModelSessionが入り口です。生成してrespond(to:)を呼べば、テキストが返ってきます。複数ターンの文脈はセッションが保持し、単発の処理には毎回新しいセッションを使います2。- ガイド付き生成こそが、このフレームワークを使う理由です。 Swiftの型に
@Generableを付ければ、自分でパースする文字列ではなく、値が埋まり型チェックも済んだその型そのものがモデルから返ってきます3。 Toolプロトコルを使えば、モデルは生成の途中であなたのコードを呼び出してデータを取得したりアクションを実行したりし、その結果を答えに織り込めます4。- 何をするにも、まず
SystemLanguageModel.default.availabilityを確認してください。対象外の端末や、Apple Intelligenceがオフのとき、あるいはモデルのダウンロード中には、モデルは存在しません5。 - コンテキストウィンドウは現実に存在し、しかも小さいものです。
SystemLanguageModel.default.contextSizeは、プロンプトと応答で共有されるトークン予算を示します6。これを織り込んで設計しないと、セッションは例外を投げます。 - iOS 26とApple Intelligence対応端末が必要です。その下限を下回ると、フレームワークは存在すらしません。
このフレームワークは何で、何でないのか
Foundation Modelsはクラウドのエンドポイントをラップしたものではありません。モデルは端末上に存在し、OSとともに出荷され、Neural Engine上で動きます。この一点が、APIのあらゆる設計判断と、それを使うあなたのあらゆる判断を方向づけます。
得られるもの——テキスト生成、要約、分類、抽出、短文のリライト、そして構造化出力。いずれもオンデバイスで、すべて無料です。得られないもの——フロンティアモデルです。Appleがこのオンデバイスモデルを作ったのは、アプリ内の的を絞った言語タスクのためであって、際限のない推論や、長文の分析や、クイズのように問える世界知識のためではありません。Apple自身がそう述べていますし、この位置づけは重要です。なぜなら、放っておけばAPIはその期待を裏切らせてしまうからです1。
トラブルを避けるための心構えはこうです。オンデバイスモデルを、文章を整えるのは抜群にうまいが、事実を知るのはからきしダメな、速くて私的で無料のインターンだと思ってください。素材と明確なタスクを手渡しましょう。答えようのない問いを投げてはいけません。
LanguageModelSession——入り口
あらゆるやり取りはセッションから始まります。
import FoundationModels
let session = LanguageModelSession()
let response = try await session.respond(to: "Summarize this review in one sentence: \(reviewText)")
print(response.content)
セッションは会話の状態を保持します。respond(to:)を呼ぶたびに、進行中のトランスクリプトへ追記されるので、保持し続けたセッションはそれまでの流れを覚えています。チャット機能ならこれが望ましい挙動です。一方、独立した単発のタスク(これを要約せよ、これを分類せよ)では、呼び出しごとに新しいセッションを作りましょう。そうすれば古い文脈が紛れ込んでトークン予算を食いつぶすことがありません2。
respond(to:)はasync throwsです。モデルが処理する間は中断し、リクエストがコンテキストウィンドウを超えたとき、モデルが利用できないとき、ガードレールがコンテンツを拒否したときには例外を投げます。これらはどれも無視してよい例外ケースではなく、あなたが処理すべき現実の分岐です。
応答性の高いUIのためには、待つのではなくストリーミングしましょう。streamResponse(to:)はモデルが生成するそばから部分的な出力を返すので、3秒間の沈黙が、形になりながら現れていくテキストへと変わります7。
ガイド付き生成——フレームワークの元を取る機能
ここが入場料に見合う部分です。たいていのLLM連携は、コードの3分の1をモデルから妥当なJSONを引き出すことに費やし、残りの3分の2をそれでも失敗したときの防御に費やします。Foundation Modelsはその作業をまるごと消し去ります。
Swiftの型に@Generableを付け、それを生成するようセッションに頼めば、値が埋まり型安全なその型のインスタンスがモデルから返ってきます3。
@Generable
struct Recipe {
@Guide(description: "The dish name")
let title: String
@Guide(description: "Ingredients, each as 'quantity item'")
let ingredients: [String]
@Guide(description: "Total minutes, start to finish", .range(5...240))
let minutes: Int
}
let session = LanguageModelSession()
let response = try await session.respond(
to: "A weeknight pasta for two.",
generating: Recipe.self
)
let recipe = response.content // a Recipe, not a String
パース処理は不要です。JSONDecoderも、不正な出力に備えたリトライループも要りません。@Guideマクロは個々のフィールドに制約をかけます——モデルが指示として読む説明文と、数値範囲や出力が一致すべき正規表現といった任意の制限です8。フレームワークはモデルに「5から240までの数字をどうかお願いします」と頼むのではありません。そうとしか返せないようにデコードを制約するのです。
これが課す規律こそ、本当の価値です。出力の型を、まずSwiftで、コンパイラのチェックを受けながら設計します。モデルは、あなたが読み解いて整形する散文を返すのではなく、あなたが定義した契約を満たすのです。抽出やフォーム入力、そして言語をデータへ変えるあらゆる機能において、ガイド付き生成はデモと出荷できるコードとを分ける違いになります。
知っておく価値のある制御がひとつあります。respond(to:generating:)はincludeSchemaInPromptが既定でtrueになっており、これがあなたの型の形をプロンプトに注入してモデルをそちらへ寄せます。モデルが学習済みか、セッションの先行ターンですでにその形式を知っている場合を除き、有効のままにしておきましょう。モデルが見たことのない形式でトークン節約のためにこれを切ると、ゴミが返ってくることになります9。
ツール呼び出し——モデルにあなたのコードを届かせる
ガイド付き生成は「何が出てくるか」を形づくります。ツール呼び出しは「何が入っていくか」を変えます。ツールとは、モデルが持っていない情報を取得したりアクションを実行したりするために、生成の途中で呼び出せるあなたのコードの一片であり、その結果を使ってモデルは答えを続けます4。
ツールはToolプロトコルに準拠します——name、モデルがいつ呼ぶか判断するために読むdescription、@GenerableなArguments型、そして実際の処理を行うcall(arguments:)メソッドです4。
struct FindContacts: Tool {
let name = "findContacts"
let description = "Find a specific number of contacts from the address book"
@Generable
struct Arguments {
@Guide(description: "How many contacts to return", .range(1...10))
let count: Int
}
func call(arguments: Arguments) async throws -> [String] {
// Fetch contacts, return formatted names.
}
}
let session = LanguageModelSession(tools: [FindContacts()])
let response = try await session.respond(to: "Draft a dinner invite to three of my contacts.")
流れはこうです。モデルが連絡先を必要だと判断し、検証済みのcountを渡してあなたのツールを呼び、あなたがデータを返し、モデルが実在の名前を使って招待文を書きます。引数は同じガイド付き生成の仕組みを通って型チェック済みで届くので、自由なテキストからモデルの意図をパースし出す必要は一切ありません。ツールの説明文は、モデルがそれに手を伸ばすタイミングを左右する唯一のレバーです。だからこそ、他のエンジニアが(前提知識なしに)読んで正しく使えるよう、関数のドキュメントを書くように書きましょう。
ここはまた、Foundation Modelsがエージェントの物語の残りと出会う継ぎ目でもあります。オンデバイスモデルが呼ぶツールと、Apple Intelligenceが呼ぶApp Intentは、表面こそ違えど同じ形——名前があり、説明があり、型付けされた能力です。能力を一度設計すれば、その両方を通して公開できます。
可用性——飛ばせない確認
モデルは常にそこにあるわけではありません。Apple Intelligenceに対応しない端末、ユーザーがオフにしているとき、OSがまだモデルのアセットをダウンロードしている間には、存在しません。モデルが存在する前提でコードを出荷すれば、テストしたことのないユーザー層に対して、クラッシュするか、静かに劣化するか、ハングします。
SystemLanguageModel.default.availabilityを確認し、その理由で分岐しましょう5。
switch SystemLanguageModel.default.availability {
case .available:
// Show the intelligence feature.
case .unavailable(.deviceNotEligible):
// Hide it. This device will never have the model.
case .unavailable(.appleIntelligenceNotEnabled):
// Prompt the user to turn on Apple Intelligence.
case .unavailable(.modelNotReady):
// Downloading or otherwise not ready yet. Try again later.
case .unavailable(let other):
// Unknown reason. Fail closed.
}
3つの理由は、それぞれ異なる3つのプロダクト対応を求めます。これらを混同することが、こうした機能が「壊れている」と感じられる最も多い原因です。deviceNotEligibleは恒久的です——機能を隠し、しつこく促さないこと。appleIntelligenceNotEnabledはユーザーが制御する設定です——一度きりの案内なら妥当でしょう。modelNotReadyは一時的です——再試行し、エラーを表示しないこと。利用不可の経路も、うまくいく経路と同じ丁寧さで作りましょう。一定数の端末にとっては、それが唯一の経路なのですから。
モデルが利用可能で、リクエストが来ると分かっているなら、セッションのprewarm()がモデルを温め、最初の本番応答が速く着地します10。ユーザーがこれから操作しようとしている画面では価値がありますが、当て推量で呼ぶなら無駄になります。
コンテキストウィンドウと、それが足りなくなる地点
SystemLanguageModel.default.contextSizeは、モデルが内側で扱うトークン予算を示します。そしてこの予算は共有されます——プロンプトと応答が合わせて収まらなければなりません6。この数値はクラウドモデルに比べて小さく、実際の入力ではすぐに体感します。長い文書、丸ごとのチャット履歴、肥大なツール結果——どれもが予算を吹き飛ばし、respondに例外を投げさせかねません。
ここから2つの失敗モードが続き、どちらもあなたが防ぐべきものです。第一に、じわじわと忍び寄るもの。複数ターンのセッションは、もう1ターンであふれるまでトランスクリプトを溜め込みます。無関係な作業では新しいセッションから始め、1ターンあたりの入力を絞り込んで管理しましょう。第二に、単発の特大リクエスト。20ページのPDFは収まりません、それだけのことです。分割し、各断片を要約し、その要約の上で推論する(LLMエンジニアにはお馴染みのmap-reduceです)か、あるいはそのタスクがオンデバイスモデルには形が合っていないと受け入れるかです。
コンテキストウィンドウは、このフレームワークで本当に重要な判断——オンデバイスに留まるか、それとも離れるか——にとって、最もきれいなシグナルです。
Foundation Modelsを使うべきでないとき
このフレームワークは無料で、私的で、オフラインです。だからこそ、どこにでも持ち出したくなります。こらえてください。次の場合は、これを通り越して手を伸ばしましょう。
- 本物の推論や、世界知識の広さが必要なとき。 オンデバイスモデルは設計上小さいものです。際限のない推論、コード生成、深い分析は、フロンティアのクラウドモデルの領分です。それらをオンデバイスモデルに求めると、自信に満ちた誤答が返ってきます。
- 入力がコンテキストウィンドウに収まらず、分割すると意味が壊れてしまうとき。すべてを一度に見る必要があるタスクもあります。
- 自分で制御できるモデルが必要なとき。 特定のチェックポイント、ファインチューン、カスタムの重み、OSアップデートをまたいだ決定論的なバージョン管理など。Appleはモデルを、あなたではなく自分のスケジュールで出荷し更新します。
- iOS 26より下か、対象外の端末にいるとき。 フレームワークはそもそも存在せず、可用性の確認が実行のたびにそう告げます。
このフレームワークがカバーしないオンデバイスのケース(カスタムモデル、独自の重み、端末上での学習)には、その下の層であるCore MLとAppleのMLXがあります。本当にスケールが必要なケースには、プライバシー境界の背後に置いたクラウドLLMが、いまも誠実な答えです。Foundation Modelsはそのどちらの代わりにもなりません。すでに手元にあるテキストへの的を絞った言語処理に最初に手を伸ばすべき正しい選択であり、それ以外のすべてには間違った選択なのです。
このフレームワークが報いてくれる技能は、プロンプトの巧みさではありません。スコープに対するセンス——モデルが得意とするタスクを与え、必要なものを過不足なく捉える@Generable型を設計し、作業が端末の手に余る瞬間を見抜くこと——です。そうした勘どころで作れば、オンデバイスモデルは驚くほどの量の実作業を無料でこなします。それを無視すれば、入力がたった1トークン長すぎたすべてのユーザーで壊れる機能を出荷することになります。
FAQ
AppleのFoundation Modelsフレームワークは無料で使えますか?
はい。このフレームワークを使うと、アプリからApple Intelligenceを支えるのと同じオンデバイスモデルへ、直接かつ無料で、オフラインのままアクセスできます。APIキーも、トークン単位の課金も、ネットワークの往復もありません1。
Foundation Modelsにはどの端末とiOSバージョンが必要ですか?
iOS 26とApple Intelligence対応端末が必要です。その下限を下回るとフレームワークは存在しませんし、対応OS上であっても、対象外の端末や、Apple Intelligenceがオフのとき、モデルのダウンロード中にはモデルは存在しません。使う前に必ずSystemLanguageModel.default.availabilityを確認してください5。
文字列ではなく、構造化された型安全な出力を得るには?
Swiftの型に@Generableを付ければ、自分でパースする文字列ではなく、値が埋まり型チェックも済んだその型がモデルから返ってきます。このガイド付き生成こそ、フレームワークを使う価値を生む唯一の機能です3。
Appleのオンデバイスモデルのコンテキストウィンドウはどれくらいですか?
SystemLanguageModel.default.contextSizeがトークン予算を示し、それはプロンプトと生成される応答で共有されます6。設計上小さいので、長い文書や長い複数ターンの履歴はこれを超えてしまいます。この上限を織り込んで設計しないと、セッションは例外を投げます。
Foundation Modelsはオフラインで動きますか?データはAppleに送られますか?
完全にオンデバイスで、Neural Engineに対して動きます。データは端末の外へ出ず、ネットワークの往復も不要です。だからこそ、かつてはクラウドLLMとプライバシーレビューを必要とした機能に適しているのです1。
オンデバイスモデルは生成の途中で自分のコードを呼び出せますか?
はい。Toolプロトコルを使えば、生成中にモデルがあなたのコードを呼び出してデータを取得したりアクションを実行したりし、その結果を答えに織り込めます4。
Foundation Modelsを使うべきでないのはいつですか?
フロンティアモデルが必要なとき——際限のない推論、コード生成、長文の分析、世界知識——には、これを通り越して手を伸ばしてください。Appleはこのオンデバイスモデルをアプリ内の的を絞った言語タスクのために作ったので、汎用的な知性を求めると自信に満ちた誤答が返ってきます1。
-
Apple Developer, 「Foundation Models」フレームワーク概要. Appleはこのフレームワークを、Apple Intelligenceを支えるオンデバイスモデルへのアクセスとして説明しており、際限のない推論や世界知識ではなく、テキスト生成・要約・分類・構造化出力といった的を絞った言語タスクに適するとしています。 ↩↩↩↩↩
-
Apple Developer, 「LanguageModelSession」 および 「Generating content and performing tasks with Foundation Models」. セッションは複数ターンの文脈を保持します。Appleの指針は、個別の単発のやり取りごとに新しいセッションを作ることです。 ↩↩
-
Apple Developer, 「Generable」 および 「Prompting an on-device foundation model」.
@Generableマクロにより、フレームワークは文字列ではなく、値が埋まり型チェックも済んだSwiftの値を返せます。 ↩↩↩ -
Apple Developer, 「Tool」プロトコル.
protocol Tool<Arguments, Output>: Sendableを定義し、必須のname・description・parameters: GenerationSchemaに加えてcall(arguments:) async throws -> Outputを備えます。Arguments型はConvertibleFromGeneratedContentに準拠し、通常は@Generableとして宣言されます。 ↩↩↩↩ -
Apple Developer, 「SystemLanguageModel.Availability」 および その
UnavailableReason. ケースは.availableと.unavailable(...)で、理由はdeviceNotEligible・appleIntelligenceNotEnabled・modelNotReadyです。SystemLanguageModel.default.isAvailableが便宜的な真偽値です。 ↩↩↩ -
Apple Developer, 「SystemLanguageModel.contextSize」. (
SystemLanguageModel.defaultを通してアクセスする)インスタンスプロパティで、最大コンテキストサイズとして文書化されており、入力プロンプトと生成される応答を合わせた総トークン数を表します。 ↩↩↩ -
Apple Developer, 「LanguageModelSession.streamResponse(to:)」. モデルが生成するそばから部分的な出力をストリーミングし、UIの逐次更新に使えます。 ↩
-
Apple Developer, 「Guide(description:_:)」.
@Generableプロパティに自然言語の説明と任意の制約(数値範囲、正規表現によるガイド)を付与するピアマクロです。iOS 26.0以降が必要です。 ↩ -
Apple Developer, 「respond(to:schema:includeSchemaInPrompt:options:)」.
includeSchemaInPromptは既定でtrueです。Appleの解説は、モデルがすでに期待する形式を知っている場合を除き、既定のままにすることを推奨しています。 ↩ -
Apple Developer, 「LanguageModelSession.prewarm()」. 来ると分かっているリクエストに先立ってモデルのリソースを読み込むようフレームワークに求め、初回応答のレイテンシを減らします。 ↩
-
著者による関連分析:AppleのオンデバイスLLM——Foundation Models、Foundation Models向けのカスタムアダプタ、Foundation Modelsのユースケース、Foundation Models上のエージェント型ワークフロー。App Intentsとツール表面の議論はApp IntentsはAppleが用意したあなたのアプリへの新しいAPIで展開しています。 ↩