Apple Foundation ModelsでClaudeを使い分ける — iOS/macOSアプリ実装ガイド
Apple純正のFoundation ModelsフレームワークにClaudeを組み込むSwiftパッケージの使い方。認証方式の選び方とオンデバイスモデルとの使い分けを扱います。
Apple Foundation ModelsでClaudeを使うとはどういうことか
Claude for Foundation Modelsは、ClaudeをApple純正のFoundation Modelsフレームワークにサーバーサイド言語モデルとして組み込むSwiftパッケージです。ClaudeはフレームワークのLanguageModelプロトコルに準拠するため、Appleのオンデバイスモデルを動かすのと同じLanguageModelSession APIでrespond(to:)、ストリーミング、ガイド付き生成、ツール呼び出しをそのまま扱えます。
リクエストはアプリからClaude APIへ直接送られ、Appleはリクエスト経路に入りません。プロンプトも応答もAppleは見ません。利用料金はAnthropicアカウントに標準のAPI料金で課金されるため、ワークスペースにクレジット残高か有効な支払い方法が必要です。どちらのモデルを使うかはセッションごとに選べます。
このパッケージが提供しているのは、Foundation Modelsが規定するLanguageModelプロトコルへのClaudeの適合であって、汎用のMessages APIクライアントではありません。公開されている範囲は、プロバイダー適合部分と、そこに到達するための設定型(ClaudeLanguageModel・ClaudeModel・AuthMode・ClaudeServerTool)に限られます。Messages APIへ直接アクセスしたい場合は、別言語のクライアントSDKを使います。
導入の前提条件とインストール
必要な環境は次のとおりです。
- iOS 27 / macOS 27 / visionOS 27 / watchOS 27(いずれもベータ)
- Xcode 27(ベータ)
- 開発用のClaude APIキー(本番の認証方式は後述)
Package.swiftに依存を追加します。
dependencies: [
.package(url: "https://github.com/anthropics/ClaudeForFoundationModels.git", from: "0.1.0")
]Xcodeから追加する場合は「File」→「Add Package Dependencies…」でリポジトリURLを入力します。ターゲットの依存関係にClaudeForFoundationModelsを加え、FoundationModelsと並べてimportします。
最小構成でClaudeを呼び出す
エントリーポイントはClaudeLanguageModelです。LanguageModelSessionに渡せば、あとはAppleの標準的なセッションAPIと同じ書き方で呼び出せます。
import FoundationModels
import ClaudeForFoundationModels
let model = ClaudeLanguageModel(
name: .sonnet5,
auth: .apiKey(ProcessInfo.processInfo.environment["ANTHROPIC_API_KEY"] ?? "")
)
let session = LanguageModelSession(model: model)
let response = try await session.respond(to: "Plan a 4-day trip to Buenos Aires.")
print(response.content)モデル名はClaudeModelの値で指定します。.opus5のようにコンパイル済みの定数を使うのが基本で、各定数はサンプリングパラメータや思考の可否、構造化出力対応、画像入力対応といったモデルの能力(capabilities)を内蔵しています。パッケージがまだ定数を持たない新しいモデルIDを使う場合は、能力を自分で宣言します。
let model = ClaudeModel(
id: "claude-experimental-x",
capabilities: .init(samplingParams: false, effortLevels: [.low, .high])
)自動推測のショートカットは意図的に用意されていません。モデルが受け付けないフィールドを送るとハードエラーになるため、能力の宣言はここで正確に行う必要があります。
初期化子はserverToolsのほかにbaseURL(既定はhttps://api.anthropic.com)とtimeoutも受け付けます。動く例を通しで見たい場合は、リポジトリ同梱のExamples/ClaudeExampleが使えます。会話をターミナルへストリーミングするコマンドラインターゲットで、--searchフラグを付けるとその会話でサーバーサイドWeb検索が有効になります。実行にはmacOS 27のホストが必要です。
effortはfixedEffort:でリクエストごとに固定できます。フレームワーク側の推論ヒントより優先され、フレームワークが持つ推論レベルの名前はhighまでしか表現できないため、xhighやmaxを指定したい場合は.custom("xhigh")のようにカスタム値を渡します。effortを何も送らなければAPIはhighを既定値として扱います。
認証方式の使い分け — App Attest・プロキシ・APIキー
auth:パラメータに渡す認証情報は3種類あり、開発段階と本番運用で使い分けます。
| 方式 | 適した段階 | バックエンドの要否 | 制約 |
|---|---|---|---|
.apiKey | 適した段階開発中の検証 | バックエンドの要否不要 | 制約バイナリからキーが抽出可能。本番では使わない |
.appAttest | 適した段階本番(バックエンドを持たない場合) | バックエンドの要否不要 | 制約実機必須。ClaudeのAPIを直接呼ぶ構成のみ対応(Bedrock/Google Cloud/Microsoft Foundry経由では不可) |
.proxied | 適した段階本番(自前バックエンドを持つ場合) | バックエンドの要否必要 | 制約自前プロキシがヘッダーで呼び出し元を認可する設計が前提 |
App Attestは、AppleのApp Attestサービスでアプリの正当性を証明し、Anthropicがワークスペースに課金される短命アクセストークンを発行する仕組みです。アプリにAPIキーを同梱せず、プロキシの運用も不要になります。ただしシミュレーターやSecure Enclaveのないハードウェアでは動作しないため、開発中は.apiKey、実機での本番検証は.appAttestと使い分けます。
導入にはApple Developer Team IDと、組織のadmin・owner・primary owner権限が必要です。Xcodeで「Signing & Capabilities」に「App Attest」を追加し、Claude Consoleのワークスペース設定にある「App integrations」でアプリを登録してクライアントID(clid_...)を取得します。発行されたトークンはワークスペースにスコープされ、1時間で失効し、Messages APIの呼び出しのみを認可します。エンドユーザーの識別情報は含まれません — App Attestが証明するのはアプリの身元であってユーザーの身元ではないため、ユーザー単位の制御はアプリ側で実装します。侵害されたアプリや廃止したアプリはConsoleからintegrationを失効させます。失効は取り消せないため、復旧には新しいintegrationの作成が必要です。
ClaudeLanguageModel(
name: .sonnet5,
auth: .appAttest(clientID: "clid_...")
)プロキシ構成では、baseURLで指定した自前のリレーがサーバー側でClaude API資格情報を付与するため、アプリはキーを持ちません。
ClaudeLanguageModel(
name: .sonnet5,
auth: .proxied(headers: ["X-App-Token": "..."]),
baseURL: URL(string: "https://api.yourapp.com/claude")!
)オンデバイスモデルとClaudeの使い分け判断
Appleのオンデバイスモデルは高速でプライバシー面も強く、オフラインでも動きます。ただし軽量なタスク向けにサイズが絞られています。大きなコンテキスト、高度な推論、Web検索やコード実行のようなサーバーサイドツールが要る場面ではClaudeへエスカレーションするという切り分けが、公式ドキュメントが示す判断軸です。同じLanguageModelSession APIを使うため、切り替えはmodel:引数を差し替えるだけで済みます。
サーバーサイドツールと構造化出力の設定
サーバーサイドツール(Web検索・Web Fetch・コード実行)はAnthropicのインフラ上で1往復のリクエスト内に完結し、デバイス側で呼び出すものがありません。serverTools:はLanguageModelSessionではなくClaudeLanguageModel側で設定します。会話ごとに異なるツール構成を使いたい場合は、ClaudeLanguageModelのインスタンスを会話ごとに分けます。
let model = ClaudeLanguageModel(
name: .sonnet5,
auth: auth,
serverTools: [
.webSearch(maxUses: 5),
.codeExecution,
]
).webSearchと.webFetchはallowedDomains・blockedDomains・maxUsesを任意で受け付けるため、検索範囲をドメイン単位で絞り込めます。サーバーサイドツールの呼び出し履歴はClaudeServerToolSegmentというカスタムセグメントとしてトランスクリプトに残るため、tools:で登録したクライアントサイドツールの呼び出しと区別して追跡できます。
一方、フレームワーク標準のクライアントサイドツール(tools:配列)は変更なく動きます。デバイス上で実行したい処理はこちらに寄せ、Anthropic側の実行力が要る処理だけをサーバーサイドツールに回す構成が、レイテンシとコストの両面で素直です。
構造化出力は@Generableで型を注釈し、generating:で要求します。
@Generable
struct Trip {
@Guide(description: "Destination city") var destination: String
@Guide(description: "Length in days") var days: Int
}
let response = try await session.respond(to: "Plan a trip to Tokyo.", generating: Trip.self)選んだモデルが構造化出力に非対応の場合、パッケージは黙って劣化させずLanguageModelError.unsupportedGenerationGuideを投げます。Agent SDKの構造化出力と同じく、型安全な出力を前提に設計を組めます。
画像入力とエラーハンドリング
画像入力に対応したモデルは、フレームワークの標準的なvision機能をそのまま宣言します。画像コンテンツはフレームワークの通常のセッションAPIで渡せば、パッケージ側がClaude APIの画像フォーマットに変換します。渡し方を変える必要はありません。
エラーは、フレームワークの型に対応するものがあればそこへマップされ、対応が無いものはClaudeErrorとして表面化します。
do {
let response = try await session.respond(to: prompt)
print(response.content)
} catch ClaudeError.missingCredential {
// APIキーの入力を促す
} catch let error as LanguageModelError {
// レート制限・ガードレール・コンテキスト長・デコードなど、フレームワーク側の想定内エラー
} catch {
// 通信エラー
}.rateLimitedを捕まえてそのターンだけSystemLanguageModel(Appleのオンデバイスモデル)にフォールバックする、リクエストをキューに積む、リトライを促すUIを出す、といった対応が実用的です。ネットワーク層のエラーとフレームワーク層のエラーを分けてハンドリングできる設計なので、Claude固有の資格情報エラーと、汎用的な通信断とを混同せずに済みます。
よくあるつまずき
- ストリーミングの各要素を差分だと思って処理する。
streamResponse(to:)が返す各要素は、その時点までの累積スナップショットです。差分だと仮定して結合すると内容が重複します。 - プロンプトキャッシュのTTLやブレークポイント位置を調整しようとする。このパッケージはプロンプトキャッシュを自動適用しますが、TTLやブレークポイントの位置は設定できません。細かい制御が要る場合はネイティブのMessages APIを直接使う設計に切り替えます。
まとめ
Claude for Foundation Modelsは、Appleの標準的なセッションAPIを崩さずにClaudeを呼べる橋渡し役です。導入自体はClaudeLanguageModelを渡すだけで動きますが、認証方式の選択(開発は.apiKey、本番は.appAttestか.proxied)と、オンデバイスモデルとの使い分け判断が実装の質を左右します。ストップシーケンスやバッチ処理、Files API、トークンカウント、ベータヘッダーのようにフレームワークのプロトコルで表現できない機能は、このパッケージ経由では使えません。そうした機能が要る場面は、Anthropic APIをネイティブに呼ぶ構成に切り替えます。