Passa al contenuto principale

Apple Foundation Models 3 e lo stack LLM on-device per chi usa Claude

Intermedio

Al WWDC 2026 (annunciato l'8 giugno 2026) Apple ha rilasciato la terza generazione dei suoi modelli Foundation — AFM 3 — ed esteso il Foundation Models framework in un modo che conta anche se non scrivi mai Swift: il framework ora accetta provider LLM di terze parti (Anthropic Claude e Google Gemini vengono distribuiti come pacchetti Swift), e il percorso on-device smette di essere un giocattolo da 3B e aggiunge un MoE sparso da 20 miliardi di parametri che gira su Apple Silicon tenendo la maggior parte degli esperti in NAND e caricando in RAM solo quelli che servono per un prompt. Se costruisci app Claude e hai finora trattato "on-device" come un universo separato dai tuoi workflow API, quest'anno quel divario si chiude. Questa pagina scompone cosa è stato effettivamente rilasciato, i meccanismi non ovvi, e le scelte concrete di migrazione e compatibilità che ora hai a disposizione.

What you'll learn
  • Nominare i quattro modelli AFM 3 — Core (3B), Core Advanced (20B sparso), Cloud, Cloud Pro — e sapere quale gira dove
  • Capire il trucco flash-più-DRAM del routing degli esperti che permette a un modello da 20B di stare su un iPhone
  • Usare le macro @Generable / @Guide del Foundation Models framework per il decoding vincolato — il modello letteralmente non può emettere JSON non valido
  • Sapere cosa è cambiato al WWDC26: i protocolli LanguageModel / LanguageModelExecutor che permettono di collegare Claude o qualunque altro LLM alla stessa API di sessione Swift
  • Decidere quando usare il 3B on-device, quando saltare a Private Cloud Compute, e quando tenere il carico sull'API Claude

La versione in una frase

AFM 3 è il secondo tentativo serio di Apple sugli LLM on-device: un modello denso da 3B (Core) ricostruito, un nuovo MoE sparso da 20B (Core Advanced) che gira su iPhone tenendo la maggior parte degli esperti in memoria flash, una coppia Cloud e Cloud Pro su Apple Silicon più GPU NVIDIA in Google Cloud, e un framework che ora tratta Anthropic Claude e Google Gemini come provider di prima classe intercambiabili dietro lo stesso protocollo LanguageModel. Gratuito per gli sviluppatori per le chiamate on-device; gratuito su Private Cloud Compute per i membri dell'App Store Small Business Program sotto i 2M di primi download.

Tre cose non ovvie su AFM 3

Tutti scrivono il titolo "Apple ha un modello 3B on-device". Ecco i meccanismi che la maggior parte degli articoli salta.

1. Il modello da 20B sta su iPhone perché la maggior parte vive in NAND, non in RAM

La lettura ingenua di "modello da 20 miliardi di parametri su iPhone" è impossibile: anche a 4-bit, 20B di pesi sono ~10 GB, ben oltre ciò che un iPhone può tenere in RAM. Il trucco di Apple, secondo l'annuncio del WWDC 2026, è memorizzare l'intero modello AFM 3 Core Advanced in memoria flash (NAND) e caricare solo gli esperti routed dipendenti dall'input in DRAM al momento dell'inferenza. L'architettura ha esperti condivisi che restano residenti ed esperti routed che un router seleziona per prompt (attivando 1–4B parametri per volta, non l'intero 20B). Combinato con il Quantization Aware Training, è questo che permette ad Apple di distribuire un modello di classe 20B su un dispositivo con ~8 GB di RAM utilizzabile. La conseguenza per te: la latenza lato iPhone ora è dominata meno dalla moltiplicazione di matrici e più dalla banda di lettura NAND e dalle scelte del router — un profilo di prestazioni molto diverso da un modello denso da 3B.

2. Il decoding vincolato è cotto nel compilatore Swift, non nel runtime

La macro @Generable del framework viene spesso descritta come "output strutturato", ma questa definizione sottovaluta cosa fa. @Generable gira in compile time: genera uno schema JSON e un parser per il tuo tipo Swift, e il framework poi usa quello schema per il decoding vincolato — il modello on-device è forzato, a livello di token, a produrre output che si riparsa nel tuo struct Swift. Non c'è "spera che sia JSON valido, poi riprova". Un'annotazione @Guide ti permette di aggiungere vincoli (.anyOf(["PG", "PG-13", "R", "G"]), range, descrizioni) che vengono anch'essi imposti in fase di decode. Se hai speso tempo a scrivere fallback JSON-repair attorno a un loop di tool-use di Claude, il lato modello 3B on-device della tua app può eliminare tutto quel livello di retry.

3. Il framework ora accetta qualsiasi LLM — Claude e Gemini inclusi — dietro un'unica API Swift

La sessione WWDC 2026 "Bring an LLM provider to the Foundation Models framework" ha rilasciato due nuovi protocolli: LanguageModel (dichiara capacità e configurazione dell'executor) e LanguageModelExecutor (gestisce la generazione vera e propria, la KV cache, e lo streaming). Chiunque può distribuire un pacchetto Swift che li implementa — Apple ha esplicitamente nominato Anthropic Claude e Google Gemini come provider al lancio. La conseguenza: dal punto di vista dell'app, la stessa LanguageModelSession, gli stessi tipi @Generable, lo stesso contratto di tool-calling, e lo stesso modello di transcript si applicano che il modello sottostante sia il 3B on-device, Private Cloud Compute, Claude sull'API di Anthropic, Gemini su Google Cloud, o un file di pesi MLX da Hugging Face. La scelta del modello diventa una dipendenza di pacchetto Swift invece di una riscrittura dell'SDK.

AFM 3 a colpo d'occhio

Premi Invio o Spazio per girare la carta. Usa le frecce sinistra e destra per spostarti tra le carte.Termine mostrato.
1 / 6

Cosa gira dove, in pratica

Guided walkthrough1 of 4
  1. Gira su qualsiasi dispositivo Apple Intelligence. Gratuito da chiamare da Swift via Foundation Models framework — nessuna API key, nessuna rete, nessuna bolletta per token. Qui metti classificazione, estrazione, sommarizzazione, riscritture on-device, e qualsiasi cosa che debba funzionare in modalità aereo.

Una chiamata minima on-device

La feature di punta del framework è che puoi ottenere output tipizzati e validati da schema dal 3B on-device con quasi nessuna cerimonia.

Chiamata on-device 3B con output strutturato @Generable (Swift)

import FoundationModels

@Generable
struct TripIdea {
  @Guide(description: "Short, evocative title")
  let title: String

  @Guide(description: "One-paragraph pitch, 40–80 words")
  let summary: String

  @Guide(.range(1...14))
  let estimatedDays: Int

  @Guide(.anyOf(["easy", "moderate", "hard"]))
  let difficulty: String
}

let session = LanguageModelSession()   // defaults to on-device Core
let idea = try await session.respond(
  to: "Suggest a shoulder-season trip in Puglia for a family with a 6-year-old.",
  generating: TripIdea.self          // constrained decoding
)

print(idea.title, idea.difficulty, idea.estimatedDays)

A runtime il modello è forzato, a livello di token, a emettere token che mantengono il testo corrente parsabile come TripIdea. Non vedi mai una stringa JSON; ricevi un valore TripIdea. Questo è lo stesso contratto che la sessione stia parlando con il 3B on-device, PCC, o un provider di terze parti che hai collegato come pacchetto Swift.

Portare Claude nella stessa sessione Swift

La sessione WWDC 2026 "Bring an LLM provider" ha reso questo concreto: implementa LanguageModel e LanguageModelExecutor, pubblicalo come pacchetto Swift con git tag, e il codice dell'app che già usava il 3B on-device può chiamare il tuo provider cambiando un initializer.

Schizzo di un provider di terze parti conforme a LanguageModel

import FoundationModels

public struct ClaudeSonnet5: LanguageModel {
  public let capabilities = LanguageModelCapabilities(capabilities: [
      .toolCalling, .guidedGeneration, .reasoning
  ])
  public var executorConfiguration: ClaudeExecutor.Configuration
}

public final class ClaudeExecutor: LanguageModelExecutor {
  public struct Configuration: Hashable {   // hashable = KV-cache key
      public var modelID: String
      public var tokenProvider: TokenProvider   // NOT a plain API key string
  }

  public required init(configuration: Configuration) throws { /* … */ }

  public func respond(
      to request: LanguageModelExecutorGenerationRequest,
      model: Model,
      streamingInto channel: LanguageModelExecutorGenerationChannel
  ) async throws {
      // 1. Map Foundation Models transcript → Anthropic /messages payload
      // 2. Stream deltas back via channel.send(.response(action: .appendText(...)))
      // 3. Surface tool calls / reasoning via the same transcript entry types
  }
}

Due sottigliezze verso cui l'API ti spinge deliberatamente. Primo, Configuration è Hashable di proposito: il framework mette in cache gli executor per configurazione, quindi stessa config = stesso executor = KV cache preservata tra i turni. Secondo, la guida sconsiglia esplicitamente stringhe API-key in chiaro negli initializer — preferisci un TokenProvider o un flusso di sign-in, persisti i token nel keychain, e usa App Attest per le chiamate cloud per verificare che il dispositivo non sia una build manomessa che colpisce il tuo endpoint dall'esterno.

Quando usare cosa — una tabella decisionale per chi costruisce con Claude

Pro tip
  • Punta su AFM 3 Core on-device (3B): sommarizzazione, classificazione, estrazione di entità, riscritture on-device, suggerimenti da tastiera — qualsiasi cosa in cui un prompt limitato e un output tipizzato battono un roundtrip di rete. Gratis.
  • Punta su AFM 3 Core Advanced (20B): ragionamento privato che non può lasciare il dispositivo (salute, finanza, documenti non pubblici) e su cui il 3B inciampa. Aspettati latenza variabile per lo swap degli esperti da NAND.
  • Punta su Private Cloud Compute (Cloud / Cloud Pro): contesto più grande, ragionamento più lungo, o multimodale dove il 20B on-device non regge ma la privacy esclude comunque le API di terze parti.
  • Resta su Claude via API di Anthropic (o il nuovo provider Swift-package): run di agenti lunghi, extended thinking, lavoro su codebase con contesto grande, e app cross-platform che vogliono lo stesso modello su Android e web. Vedi la pagina Claude vs altri foundation.
  • NON avvolgere il 3B on-device in un loop di JSON-repair: ha il decoding vincolato. Se il tuo output non si parsa, lo schema è sbagliato o hai saltato @Generable.

Collegamenti

Verifica rapida

Check yourself

0/5
  1. Come fa AFM 3 Core Advanced a far entrare un modello da 20B parametri in un iPhone?
  2. Cosa ti dà la macro @Generable che il prompting JSON scritto a mano non dà?
  3. Vuoi chiamare Claude Sonnet 5 da un'app iOS che già usa il Foundation Models framework per la sommarizzazione on-device. Qual è il percorso nativo WWDC26?
  4. Quale gruppo di sviluppatori ottiene chiamate Private Cloud Compute gratuite dal framework?
  5. Perché il tipo `Configuration` dell'executor deve essere `Hashable`?

Fonti e approfondimenti