Claude Media
Apple Foundation ModelsでClaudeを使い分ける — iOS/macOSアプリ実装ガイド

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クライアントではありません。公開されている範囲は、プロバイダー適合部分と、そこに到達するための設定型(ClaudeLanguageModelClaudeModelAuthModeClaudeServerTool)に限られます。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のホストが必要です。

effortfixedEffort:でリクエストごとに固定できます。フレームワーク側の推論ヒントより優先され、フレームワークが持つ推論レベルの名前は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.webFetchallowedDomainsblockedDomainsmaxUsesを任意で受け付けるため、検索範囲をドメイン単位で絞り込めます。サーバーサイドツールの呼び出し履歴は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をネイティブに呼ぶ構成に切り替えます。

この記事を共有:XはてブLinkedIn