TL;DR
- iPhoneの端末内で完結するLLM。インターネットに接続不要 なため、どんな環境でも使用可能
- たった 3 行の Swift で、iPhone 15 Pro 以降(A17 Pro/M シリーズ)のみで 3B パラメータの言語モデルをオフライン推論
- 3行なので、とにかく簡単!!!
- ハマりポイントは 対応端末制限 と 初回ロードのキャッシュ。Tool Calling を絡めると簡易 RAG も可能
Foundation Models 解説
用語 | 説明 |
---|---|
Foundation Models framework | Apple Intelligence の オンデバイス LLM(約 3 B パラメータ) をアプリから直接呼び出せる新 API。端末内での推論が基本で、処理が重い場合だけクラウドへ自動フェイルオーバー。Swift のわずか数行で要約・リライト・抽出といった生成系タスクを実装できる。Xcode 26 β に「Foundation Models App」テンプレートも追加。 |
FMTextModel | Foundation Models の代表クラス。内部で A17 Pro/M1 以上の Neural Engine を使って推論してくれる。 |
Tool Calling | モデルが 外部ツールや API を自律的に呼び出す 仕組み。RAG 的用途もできる。 |
Private Cloud Compute | 端末性能を超えるタスクを処理する Apple 独自のセキュア推論クラウド。Apple Silicon サーバ上で大型モデルを動かし、エンドツーエンド暗号化+コード署名でプライバシーを担保。 ログは残さず、第三者によるバイナリ検証を前提に設計されている。 |
https://developer.apple.com/documentation/foundationmodels
https://developer.apple.com/videos/play/wwdc2025/301/
環境セットアップ
※正直ここが時間かかります
以下リンクより、Xcode 26β版をインストールしてください。
https://developer.apple.com/news/releases/
iPhoneは設定>一般>ソフトウェアアップデート>ベータアップデート をオンにしてください。
実際にコード書いてみた
import FoundationModels
/// (略) ///
// 3行でモデルを呼び出し
let model = SystemLanguageModel.default
let result = try await model.generate("Qiitaの記事の書くコツについて教えて")
output = result.string
これだけでモデルを呼び出すことができる。
SystemLanguageModelは、Apple Intelligence(約 3 B param のオンデバイス LLM)をアプリ側から触るためのシングルトンで、端末で 使えるか/使えないか を即判定し、LanguageModelSession へ橋渡ししてくれるものです。
動くチャットアプリのようなを作ってみた
文字入力をして、実行を押せばApple Intelligence を使い推論し、結果を返してくれるだけのアプリです。
import SwiftUI
import FoundationModels
struct ContentView: View {
@State private var userInput = "" // ① ユーザー入力
@State private var output = "" // ② モデルからの返答
@State private var isLoading = false // ③ 送信中フラグ
private let session = LanguageModelSession() // ④ セッションを一度だけ生成
var body: some View {
VStack(spacing: 12) {
// 入力欄
TextEditor(text: $userInput)
.frame(height: 100)
.overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.gray.opacity(0.5)))
.padding(.horizontal)
// 送信ボタン
Button(action: sendPrompt) {
if isLoading {
ProgressView()
} else {
Text("送信")
.bold()
}
}
.disabled(isLoading || userInput.isEmpty)
.padding()
Divider()
// 出力欄
ScrollView {
Text(output)
.padding()
}
}
.padding(.top)
}
// MARK: - プロンプト送信処理
private func sendPrompt() {
Task {
guard SystemLanguageModel.default.availability == .available else {
output = "モデルが利用できません"
return
}
isLoading = true
do {
let response = try await session.respond(to: userInput)
output = response.content // ← .content で文字列を取得
} catch {
output = "エラー:\(error.localizedDescription)"
}
isLoading = false
}
}
}
上記のように比較的容易な形で書くことができます。
今後の展開
RAGを実現したいので、Tool Callingも少し触る予定。
iPhone内部でネットワークなしの環境で完結できるので、使い道が多くあると考えられる。
特に社用携帯など社外に漏らせない情報などなどで、可能性がある。