← Todos os Posts

Apple Foundation Models: o framework de LLM on-device, explicado

O framework Foundation Models dá a um app acesso direto, gratuito e offline ao mesmo modelo de linguagem grande on-device que move o Apple Intelligence1. Sem chave de API, sem cobrança por token, sem ida e volta pela rede, sem dados saindo do dispositivo. Para uma classe de recursos que antes significava um LLM na nuvem e uma revisão de privacidade, o custo agora arredonda para zero. A troca está na capacidade: o modelo on-device é pequeno, a janela de contexto é finita e o framework traça linhas rígidas em torno do que ele faz e do que não faz. Conhecer essas linhas é o jogo inteiro.

Esta é a referência para o framework em si: os tipos que você de fato chama, o único recurso que faz valer a pena usá-lo e o ponto em que você deve parar e buscar algo maior.

TL;DR

  • LanguageModelSession é o ponto de entrada. Crie uma, chame respond(to:), receba texto de volta. O contexto de múltiplos turnos vive na sessão; trabalho de turno único recebe uma sessão nova a cada vez2.
  • A geração guiada é a razão para usar este framework. Anote um tipo Swift com @Generable e o modelo retorna esse tipo, preenchido e validado pelo compilador, em vez de uma string que você precisa parsear3.
  • O protocolo Tool permite que o modelo chame seu código durante a geração para buscar dados ou executar uma ação, e então incorpore o resultado de volta à resposta4.
  • Verifique SystemLanguageModel.default.availability antes de fazer qualquer coisa. O modelo está ausente em dispositivos não elegíveis, com o Apple Intelligence desligado ou enquanto ele é baixado5.
  • A janela de contexto é real e pequena. SystemLanguageModel.default.contextSize informa o orçamento de tokens compartilhado entre prompt e resposta6. Planeje para isso, ou a sessão lança um erro.
  • Requer iOS 26 e um dispositivo compatível com Apple Intelligence. Abaixo desse piso, o framework não existe.

O que o framework é, e o que ele não é

Foundation Models não é um wrapper em torno de um endpoint na nuvem. O modelo vive no dispositivo, vem com o sistema operacional e roda sobre o Neural Engine. Esse único fato move cada decisão de design na API e cada decisão que você toma ao usá-la.

O que você ganha: geração de texto, sumarização, classificação, extração, reescrita de textos curtos e saída estruturada, tudo on-device e tudo gratuito. O que você não ganha: um modelo de fronteira. A Apple construiu o modelo on-device para tarefas de linguagem focadas dentro de um app, não para raciocínio aberto, não para análise de documentos longos, não para conhecimento de mundo que você possa testar com perguntas. A Apple diz exatamente isso, e o enquadramento importa porque estabelece expectativas que, de outra forma, a API deixaria você violar1.

O modelo mental que mantém você longe de problemas: trate o modelo on-device como um estagiário rápido, privado e gratuito, que é excelente em moldar texto e péssimo em saber fatos. Entregue a ele material e uma tarefa clara. Não faça perguntas que ele não tem como responder.

LanguageModelSession: o ponto de entrada

Toda interação começa com uma sessão.

import FoundationModels

let session = LanguageModelSession()
let response = try await session.respond(to: "Summarize this review in one sentence: \(reviewText)")
print(response.content)

A sessão guarda o estado da conversa. Cada chamada a respond(to:) é anexada ao transcript em andamento, então uma sessão que você mantém por perto lembra o que veio antes. Para um recurso de chat, é exatamente isso que você quer. Para tarefas independentes de uma só vez (resumir isto, classificar aquilo), crie uma sessão nova por chamada, para que contexto velho não vaze para dentro e consuma seu orçamento de tokens2.

respond(to:) é async throws. Ele suspende enquanto o modelo trabalha e lança um erro quando a requisição excede a janela de contexto, quando o modelo está indisponível ou quando as proteções rejeitam o conteúdo. Cada um desses casos é um ramo real que você trata, não uma exceção marginal que você ignora.

Para uma UI responsiva, transmita em fluxo em vez de esperar. streamResponse(to:) produz saída parcial à medida que o modelo a gera, o que transforma uma pausa de três segundos em texto que aparece conforme se forma7.

Geração guiada: o recurso que justifica o framework

Aqui está a parte que vale o preço da entrada. A maioria das integrações de LLM gasta um terço do código convencendo o modelo a cuspir JSON válido e os outros dois terços se defendendo das vezes em que ele falha mesmo assim. Foundation Models apaga esse trabalho.

Anote um tipo Swift com @Generable, peça à sessão para gerá-lo, e o modelo retorna uma instância desse tipo, preenchida e type-safe3:

@Generable
struct Recipe {
    @Guide(description: "The dish name")
    let title: String

    @Guide(description: "Ingredients, each as 'quantity item'")
    let ingredients: [String]

    @Guide(description: "Total minutes, start to finish", .range(5...240))
    let minutes: Int
}

let session = LanguageModelSession()
let response = try await session.respond(
    to: "A weeknight pasta for two.",
    generating: Recipe.self
)
let recipe = response.content   // a Recipe, not a String

Sem parsing. Sem JSONDecoder. Sem loop de retentativa para saída malformada. A macro @Guide restringe campos individuais: uma descrição que o modelo lê como instrução, e limites opcionais como uma faixa numérica ou uma expressão regular que a saída precisa satisfazer8. O framework não pede gentilmente ao modelo um número entre 5 e 240; ele restringe a decodificação para que o campo não possa voltar de outro jeito.

A disciplina que isso impõe é o valor de verdade. Você projeta o tipo de saída primeiro, em Swift, com o compilador verificando-o. O modelo preenche um contrato que você definiu, em vez de retornar uma prosa que você precisa fazer engenharia reversa. Para extração, preenchimento de formulários e qualquer recurso que transforma linguagem em dados, a geração guiada é a diferença entre um demo e código que vai para produção.

Um controle que vale conhecer: respond(to:generating:) define includeSchemaInPrompt como true por padrão, o que injeta a forma do seu tipo no prompt para inclinar o modelo em direção a ela. Deixe ligado, a menos que o modelo já conheça o formato pelo treinamento ou por turnos anteriores na sessão; desligar para economizar tokens em um formato que o modelo nunca viu é a receita para receber lixo de volta9.

Tool calling: deixando o modelo alcançar seu código

A geração guiada molda o que sai. O tool calling muda o que entra. Uma tool é um trecho do seu código que o modelo pode invocar durante a geração para buscar informação que não tem ou executar uma ação, e então continuar a resposta usando o resultado4.

Uma tool está em conformidade com o protocolo Tool: um name, uma description que o modelo lê para decidir quando chamá-la, um tipo Arguments marcado com @Generable e um método call(arguments:) que faz o trabalho4:

struct FindContacts: Tool {
    let name = "findContacts"
    let description = "Find a specific number of contacts from the address book"

    @Generable
    struct Arguments {
        @Guide(description: "How many contacts to return", .range(1...10))
        let count: Int
    }

    func call(arguments: Arguments) async throws -> [String] {
        // Fetch contacts, return formatted names.
    }
}

let session = LanguageModelSession(tools: [FindContacts()])
let response = try await session.respond(to: "Draft a dinner invite to three of my contacts.")

O fluxo: o modelo decide que precisa de contatos, chama sua tool com um count validado, você retorna os dados, e o modelo escreve o convite usando nomes reais. Os argumentos chegam validados pela mesma maquinaria de geração guiada, então você nunca precisa extrair a intenção do modelo a partir de texto livre. A descrição da tool é sua única alavanca sobre quando o modelo recorre a ela, então escreva-a como a documentação de uma função que outro engenheiro (sem nenhum outro contexto) precisa ler e usar corretamente.

Esta é também a costura onde o Foundation Models encontra o resto da história dos agentes. Uma tool que o modelo on-device chama e um App Intent que o Apple Intelligence chama são superfícies diferentes com a mesma forma: uma capacidade nomeada, descrita e tipada. Projete a capacidade uma vez e você pode expô-la pelas duas.

Disponibilidade: a verificação que você não pode pular

O modelo nem sempre está lá. Ele está ausente em dispositivos que não suportam Apple Intelligence, quando o usuário o desligou e durante a janela em que o sistema operacional ainda está baixando os recursos do modelo. Publique código que assume que o modelo existe e ele vai travar, degradar silenciosamente ou pendurar para uma parcela dos seus usuários em que você nunca testou.

Verifique SystemLanguageModel.default.availability e ramifique conforme o motivo5:

switch SystemLanguageModel.default.availability {
case .available:
    // Show the intelligence feature.
case .unavailable(.deviceNotEligible):
    // Hide it. This device will never have the model.
case .unavailable(.appleIntelligenceNotEnabled):
    // Prompt the user to turn on Apple Intelligence.
case .unavailable(.modelNotReady):
    // Downloading or otherwise not ready yet. Try again later.
case .unavailable(let other):
    // Unknown reason. Fail closed.
}

Os três motivos exigem três respostas de produto diferentes, e confundi-los é a forma mais comum de fazer esses recursos parecerem quebrados. deviceNotEligible é permanente: esconda o recurso, não fique insistindo. appleIntelligenceNotEnabled é uma configuração que o usuário controla: um aviso único é justo. modelNotReady é temporário: tente de novo, não mostre um erro. Construa o caminho de indisponibilidade com o mesmo cuidado do caminho feliz, porque, para uma fatia real de dispositivos, ele é o único caminho.

Quando o modelo está disponível e você sabe que uma requisição está chegando, prewarm() na sessão aquece o modelo para que a primeira resposta real chegue mais rápido10. Vale a pena numa tela em que o usuário está prestes a agir, e é desperdício se você o chama de forma especulativa.

A janela de contexto, e onde ela deixa de ser suficiente

SystemLanguageModel.default.contextSize informa o orçamento de tokens dentro do qual o modelo trabalha, e esse orçamento é compartilhado: prompt mais resposta, juntos, precisam caber6. O número é pequeno em comparação com um modelo na nuvem, e você sente isso rápido em entradas reais. Um documento longo, um histórico de chat completo, um resultado de tool gordo: qualquer um deles pode estourar o orçamento e fazer respond lançar um erro.

Daí decorrem dois modos de falha, e ambos cabe a você prevenir. Primeiro, o acúmulo lento: uma sessão de múltiplos turnos acumula transcript até que mais um turno transborde. Gerencie isso iniciando sessões novas para trabalhos não relacionados e mantendo a entrada de cada turno enxuta. Segundo, a requisição isolada grande demais: um PDF de 20 páginas não cabe, ponto final. Fragmente-o, resuma os fragmentos e então raciocine sobre os resumos (o map-reduce que engenheiros de LLM conhecem bem), ou aceite que a tarefa tem o formato errado para um modelo on-device.

A janela de contexto é o sinal mais limpo para a decisão que de fato importa com este framework: quando ficar on-device e quando partir.

Quando não usar o Foundation Models

O framework é gratuito, privado e offline, o que torna tentador recorrer a ele em todo lugar. Resista. Vá além dele quando:

  • Você precisa de raciocínio de verdade ou amplitude de conhecimento de mundo. O modelo on-device é pequeno por design. Raciocínio aberto, geração de código e análise profunda pertencem a um modelo de fronteira na nuvem. Pedir isso ao modelo on-device produz respostas confiantes e erradas.
  • A entrada não cabe na janela de contexto e fragmentar destruiria o sentido. Algumas tarefas precisam ver tudo de uma vez.
  • Você precisa de um modelo que controla: um checkpoint específico, um fine-tune, pesos customizados, versionamento determinístico ao longo das atualizações do SO. A Apple publica e atualiza o modelo no cronograma dela, não no seu.
  • Você está abaixo do iOS 26 ou em um dispositivo não elegível. O framework simplesmente não está lá, e a verificação de disponibilidade vai dizer isso a você em toda execução.

Para os casos on-device que o framework não cobre (um modelo customizado, seus próprios pesos, treinamento no dispositivo), a camada abaixo é o Core ML e o MLX da Apple. Para os casos que genuinamente precisam de escala, um LLM na nuvem por trás de uma fronteira de privacidade ainda é a resposta honesta. Foundation Models não é um substituto para nenhum dos dois. É a primeira escolha certa para trabalho de linguagem focado sobre texto que você já tem em mãos, e a escolha errada para todo o resto.

A habilidade que este framework recompensa não é a arte do prompt. É bom gosto quanto ao escopo: alimentar o modelo com tarefas em que ele é bom, projetar tipos @Generable que capturam exatamente o que você precisa e reconhecer o momento em que o trabalho cresce além do dispositivo. Construa com esses instintos e o modelo on-device faz uma quantidade surpreendente de trabalho real de graça. Ignore-os e você publica um recurso que quebra para todo usuário cuja entrada passou um token do limite.

FAQ

O framework Foundation Models da Apple é gratuito para usar?

Sim. O framework dá a um app acesso direto, gratuito e offline ao mesmo modelo on-device que move o Apple Intelligence. Não há chave de API, não há cobrança por token e não há ida e volta pela rede1.

Quais dispositivos e qual versão do iOS o Foundation Models exige?

Ele exige iOS 26 e um dispositivo compatível com Apple Intelligence. Abaixo desse piso o framework não existe, e mesmo em um SO suportado o modelo está ausente em dispositivos não elegíveis, com o Apple Intelligence desligado ou enquanto o modelo é baixado. Sempre verifique SystemLanguageModel.default.availability antes de usá-lo5.

Como obtenho saída estruturada e type-safe em vez de uma string?

Anote um tipo Swift com @Generable e o modelo retorna esse tipo, preenchido e validado pelo compilador, em vez de uma string que você precisa parsear. Essa geração guiada é o único recurso que faz o framework valer a pena3.

Qual é a janela de contexto do modelo on-device da Apple?

SystemLanguageModel.default.contextSize informa o orçamento de tokens, que é compartilhado entre o prompt e a resposta gerada6. Ele é pequeno por design, então documentos longos e históricos longos de múltiplos turnos vão excedê-lo. Planeje para o limite ou a sessão lança um erro.

O Foundation Models funciona offline, e ele envia dados para a Apple?

Ele roda inteiramente on-device sobre o Neural Engine. Nenhum dado sai do dispositivo e nenhuma ida e volta pela rede é necessária, o que é exatamente o que o torna adequado a recursos que antes precisavam de um LLM na nuvem e de uma revisão de privacidade1.

O modelo on-device pode chamar meu próprio código durante a geração?

Sim. O protocolo Tool permite que o modelo invoque seu código para buscar dados ou executar uma ação durante a geração, e então incorpore o resultado de volta à resposta4.

Quando eu não deveria usar o Foundation Models?

Vá além dele quando precisar de um modelo de fronteira: raciocínio aberto, geração de código, análise de documentos longos ou conhecimento de mundo. A Apple construiu o modelo on-device para tarefas de linguagem focadas dentro de um app, então pedir inteligência geral a ele produz respostas confiantes e erradas1.



  1. Apple Developer, visão geral do framework “Foundation Models”. A Apple descreve o framework como acesso ao modelo on-device que move o Apple Intelligence, adequado a tarefas de linguagem focadas como geração de texto, sumarização, classificação e saída estruturada, em vez de raciocínio aberto ou conhecimento de mundo. 

  2. Apple Developer, “LanguageModelSession” e “Generating content and performing tasks with Foundation Models”. Uma sessão guarda o contexto de múltiplos turnos; a orientação da Apple é criar uma nova sessão para cada interação distinta de turno único. 

  3. Apple Developer, “Generable” e “Prompting an on-device foundation model”. A macro @Generable permite que o framework retorne um valor Swift preenchido e validado pelo compilador, em vez de uma string. 

  4. Apple Developer, protocolo “Tool”. Define protocol Tool<Arguments, Output>: Sendable com name, description e parameters: GenerationSchema obrigatórios, além de call(arguments:) async throws -> Output. O tipo Arguments está em conformidade com ConvertibleFromGeneratedContent e normalmente é declarado @Generable

  5. Apple Developer, “SystemLanguageModel.Availability” e seu UnavailableReason. Casos: .available e .unavailable(...) com os motivos deviceNotEligible, appleIntelligenceNotEnabled e modelNotReady. SystemLanguageModel.default.isAvailable é o booleano de conveniência. 

  6. Apple Developer, “SystemLanguageModel.contextSize”. Uma propriedade de instância (alcançada por SystemLanguageModel.default) documentada como o tamanho máximo de contexto, representando o total de tokens entre o prompt de entrada e a resposta gerada. 

  7. Apple Developer, “LanguageModelSession.streamResponse(to:)”. Transmite a saída parcial gerada à medida que o modelo a produz, para atualizações incrementais de UI. 

  8. Apple Developer, “Guide(description:_:)”. Uma macro peer que anexa uma descrição em linguagem natural e restrições opcionais (faixas numéricas, guides de expressão regular) a uma propriedade @Generable. Requer iOS 26.0+. 

  9. Apple Developer, “respond(to:schema:includeSchemaInPrompt:options:)”. includeSchemaInPrompt tem true como padrão; a discussão da Apple recomenda manter o padrão a menos que o modelo já conheça o formato esperado. 

  10. Apple Developer, “LanguageModelSession.prewarm()”. Pede ao framework para carregar os recursos do modelo antes de uma requisição conhecida que está por vir, reduzindo a latência da primeira resposta. 

  11. Análise relacionada do autor: LLMs on-device com o Foundation Models da Apple, Adapters customizados para o Foundation Models, Casos de uso do Foundation Models e Workflows agênticos no Foundation Models. O argumento sobre App Intents e a superfície de tools é desenvolvido em App Intents são a nova API da Apple para o seu app

Artigos relacionados

Casos de uso do Foundation Models: General vs Content Tagging

O Foundation Models do iOS 26 tem os casos de uso .general e .contentTagging. Use as regras da Apple para decidir quando…

8 min de leitura

Adaptadores customizados do Foundation Models: quando treinar um

Adaptadores customizados do Foundation Models no iOS 26 treinam pesos LoRA, exportam pacotes .fmadapter, são entregues v…

12 min de leitura

The Robots Are Taking Exams in My Search Console

First-party GSC data: 91% of 3.8M impressions fail a human-query filter. Exam questions, pasted errors, and agent sweeps…

10 min de leitura