【iOS27】FoundationModels入門④(外部モデルの切り替え)

【iOS27】FoundationModels入門④(外部モデルの切り替え)

FoundationModelsから外部モデルへの切り替えができることをご存知ですか?この記事では、Claudeを例に、APIキーの設定から実装、会話途中でのモデル切り替えまでの一連の検証結果をお伝えします。
2026.11.09

はじめに

こんにちは。リテールアプリ共創部のYahiroです。

iPhone Duoでましたね。同僚はすでに予約したらしいです。
先日、実機を初めて触りましたが、触ったら欲しくなるので予約するか悩み中です。

さて、今回はFoundationModelsの機能の一つである、オンデバイスのみならず外部モデルへの切り替えができる機能について検証していきたいと思います。
本来でしたらここで、Private Cloud Computeについて検証する予定でしたが、AppleにSmall Business Programの申請を出しているもののまだ申請が通っていないため、他のモデルへの切り替えとして検証記事を書くことにしました。

この記事でわかること

  • ClaudeをFoundationModelsから呼ぶために必要なもの(パッケージとAPIキー)
  • model:に渡すものを替えるだけでClaudeになること
  • Dynamic Profileで、会話の途中からClaudeに切り替えられること
  • 外部モデルにすると、認証・課金・データの行き先が変わること

検証環境

この記事では、以下の環境で検証しています。

・MacBook Pro(M3, 2023)
・Apple M3
・メモリ 16GB
・macOS GoldenGate 27.2
・Xcode 27.0

FoundationModelsのすごいところ

AFM3に入り、FoundationModelsでは一見するとAppleのエコシステムの中でのAIのみが対象のように見えますが、そうではありません。
今回から、FoundationModelsにモデルを差し替えるための受け口が用意され、AnthropicとGoogleがそれぞれ、FoundationModelsから自社のモデル(Claude、Gemini)を呼べるSwiftパッケージを公開しています。

Claudeの場合は、Anthropicが公開しているパッケージ(ClaudeForFoundationModels)を追加すると、以下のような書き方で手軽に呼べるようになります。

import ClaudeForFoundationModels
import FoundationModels
import Playgrounds

#Playground{
    let claude = ClaudeLanguageModel(name: .haiku5_5, auth: .apiKey(anthropicAPIKey))
}

上記はClaudeの例ですが、nameからサジェストで.haiku5_5などが出てくるのは便利ですね。

ClaudeのAPIキーを取得しておく

検証するにあたり、パッケージからClaudeを呼ぶにはAnthropicのAPIキーが必要です。
ClaudeのPro / Maxのサブスクリプションを契約していても、APIの利用枠は含まれていないため、別途APIキーの発行とクレジットの購入が必要になります。

platform.claude.com/settings/keys

上記より、APIキーを作成してください。
また、クレジット残高がある状態にしておいてください。

Claudeを呼び出してみる

実際に呼び出してみましょう。
以下のようにPlaygroundから呼び出してみます。

import ClaudeForFoundationModels
import FoundationModels
import Playgrounds

#Playground {
  let claude = ClaudeLanguageModel(name: .haiku5_5, auth: .apiKey(anthropicAPIKey))
  let session = LanguageModelSession(model: claude)
  let response = try await session.respond(to: "あなたは誰ですか?モデル名を答えて")

  print(response.content)

  // 使ったトークン数。Claude はこの数で従量課金される
  print("入力", session.usage.input.totalTokenCount, "/ 出力", session.usage.output.totalTokenCount, "トークン")
}

すると以下のような回答が得られました。

呼び出しは無事できているようです。

オンデバイスのモデルとの違いは、LanguageModelSessionに渡すmodel:だけです。
一方で、呼び出しはAnthropicのサーバーに送られ、使ったトークン数に応じて課金されます。session.usageで、1回の呼び出しで使ったトークン数を確認できます。

Private Cloud Computeは認証が不要で、条件を満たせば追加費用もかかりません。同じ「外部のモデル」でも、Claudeは認証と課金を自分で用意する必要がある点が大きな違いです。

Dynamic Profileを使用して、セッション中にモデルを切り替える

前回の記事でも触れましたが、Dynamic Profileを用いて、動的にモデルを切り替えることができます。

https://dev.classmethod.jp/articles/afm3-introduction3/

一回目はオンデバイス、二回目は内容を引き継いで別のモデルと会話をするといったことができます。

セッションで紹介されているのはPrivate Cloud Computeとオンデバイスの切り替えですが、同じ書き方でClaudeも渡せるか試してみます。

前回の記事と同様にまずは、Profileを用意しましょう。

import ClaudeForFoundationModels
import FoundationModels
import Playgrounds

final class Route: @unchecked Sendable {
    var useClaude = false
}

struct SwitchingProfile: LanguageModelSession.DynamicProfile {
    let route: Route
    let claude: ClaudeLanguageModel

    var body: some LanguageModelSession.DynamicProfile {
        if route.useClaude {
            LanguageModelSession.Profile {
            }
            .model(claude)
        } else {
            LanguageModelSession.Profile {
            }
        }
    }
}

上記のコードでは、useClaudeがtrueのときは、Claudeをモデルとして渡すようになっています。
2つの分岐の違いは.model(claude)の1行だけです。

続いて、上記のProfileを用いて、一回目はオンデバイス、二回目はClaudeにそれぞれあなたは誰か?と問うセッションを作ってみます。
モデルの自己紹介は正確とは限らないため、最後に実際にどのモデルが応答したかも出力します。

#Playground("Dynamic Profile:端末の中 → Claude") {
    let route = Route()
    let claude = ClaudeLanguageModel(name: .haiku5_5, auth: .apiKey(anthropicAPIKey))
    let session = LanguageModelSession(profile: SwitchingProfile(route: route, claude: claude))

    let first = try await session.respond(to: "あなたは誰ですか?モデル名を答えてください。")
    print("1回目:", first.content)

    // 状態を書き換えるだけで、次の呼び出しから Claude に切り替わる
    route.useClaude = true
    let second = try await session.respond(
        to: "さっきの回答から、モデル名が変わっているなら名乗ってください。"
    )
    print("2回目:", second.content)

    // 実際にどのモデルが応答したか(Claude のときだけ ID が記録される)
    for case .response(let entry) in session.transcript {
        print("応答したモデル:", entry.claudeModelID ?? "端末の中のモデル")
    }
}

結果は以下のように出力されました。

良いですね。無事切り替わっているようです。

切り替えるときの注意

ここで注意したいのが、Claudeに切り替えた時点で、1回目のオンデバイスでの会話もAnthropicのサーバーに送られることです。
内容を引き継げるということは、それまでの会話をまるごと渡しているということです。オンデバイスで扱っていた情報も、切り替えた後は端末の外に出ます。

Appleもセッションの中で、プライバシーの低いモデルへ移るときは、個人情報を伏せるよう勧めています。

また、どちらのモデルを呼ぶかは自動では切り替わりません。今回のuseClaudeのように、アプリのコードで決める必要があります。

まとめ

  • ClaudeはAnthropicのパッケージを追加すれば、同じLanguageModelSessionから呼べる
  • サブスクリプションでは呼べない。APIキーとクレジットが必要
  • Dynamic Profileの.model(...)に渡せば、履歴を引き継いだまま切り替わる
  • 切り替えた時点で、それまでの会話もAnthropicに送られる。課金も自分持ちになる
  • 本番では鍵をアプリに入れず、App Attestを使う

さいごに

FoundationModelsが対応してくれるおかげで、モデルを柔軟に切り替えることができました。
これにより、モデルをアプリ内に組み込んで使用する場面において、柔軟な選択が取れるようになったと思います。

同時に、モデルごとのスペックの差やコストなどで細やかな実装ができるようになるため、より設計、ビジネス的戦略設計が重要になってもくると思いました。

次回はEvaluationsについて調べていきたいと思います。

ではまた。


AI白書2026 配布中

クラスメソッドが独自に行なったAI診断調査をもとに、企業のAI活用の現在地を調査レポートとしてまとめました。企業規模別の活用度傾向に加え、規模を超えてAI活用を進める企業に共通する取り組みまで、自社の現在地を捉えるためのヒントにぜひ。

AI白書2026

無料でダウンロードする

この記事をシェアする

関連記事