Você está pagando entre 20 e 200 dólares por mês para acessar LLMs. Claude, GPT, Gemini, o que seja. E a maioria das consultas feitas a partir de seus scripts e ferramentas de desenvolvimento é uma variação disto:

  • “Classifique este erro em uma dessas cinco categorias.”
  • “Dê um nome para essa variável.”
  • “Diga se este commit é um fix, feat ou refactor.”
  • “Resuma este bloco de texto em duas frases.”

Enquanto isso, seu Mac com Apple Silicon tem um modelo de linguagem com 3 bilhões de parâmetros, integrado ao sistema operacional, sem custo, sem necessidade de conexão à internet, sem chave de API e sem latência de rede. E provavelmente você não está aproveitando isso.

O framework Foundation Models

Com o macOS 26 (Tahoe), a Apple disponibilizou o acesso ao modelo que alimenta o Apple Intelligence através do framework Foundation Models. É um framework nativo em Swift, disponível no macOS 26, iOS 26 e iPadOS 26, em qualquer dispositivo com Apple Silicon que suporte o Apple Intelligence.

O interessante não é que seja gratuito — o que, de fato, é. O mais incrível é que ele gera saída com tipos em Swift. Não retorna uma String que você terá que interpretar com regex e sorte. Ele retorna uma estrutura com tipo (struct).

import FoundationModels

@Generable
struct CommitClassification {
    @Guide(description: "O tipo da alteração")
    @Guide(.anyOf(["fix", "feat", "refactor", "test", "docs", "chore"]))
    let type: String

    @Guide(description: "Resumo em uma linha da alteração, máx. 72 caracteres")
    let summary: String
}
---

A macro `@Generable` informa ao framework que ele deve gerar um esquema em tempo de compilação. O modelo utiliza este esquema para produzir saídas estruturadas. Com `@Guide`, você restringe os valores possíveis — em linguagem simples, você define as regras e o modelo segue.

Para utilizá-lo:

```swift
let session = LanguageModelSession(instructions: """
    You are a commit message classifier. Given a git diff,
    classify the change and write a summary.
    """)

let diff = "..." // seu git diff aqui
let result = try await session.respond(
    to: "Classify this diff:\n\(diff)",
    generating: CommitClassification.self
)

print("\(result.type): \(result.summary)")
// "fix: handle nil response in auth flow"

É basicamente isso. Sem URLSession. Sem chave de API. Sem análise de JSON. Sem try? JSONDecoder().decode(OQueFor.self, from: data). O modelo roda no dispositivo, no Neural Engine do seu Mac, e retorna um tipo do Swift validado pelo compilador.

Para que serve (e para que não)?

Aqui é onde precisamos ser honestos. O modelo da Apple é um modelo de ~3 bilhões de parâmetros, otimizado para eficiência energética e baixa latência, não para raciocínio complexo. A Apple diz explicitamente em sua documentação: ele foi projetado para classificação, extração e resumo, entre outras tarefas similares. Não para raciocínios avançados ou conhecimento enciclopédico.

Em benchmarks públicos, o modelo da Apple alcança pontuação de ~44% no MMLU — abaixo de modelos como Llama 3.2 3B ou Gemma 2 2B. Por quê? Porque a Apple priorizou que o modelo funcionasse eficientemente sem drenar a bateria, ao invés de buscar vencer competições de questões complexas.

Mas isso não importa para o que estamos falando aqui. Uma parte significativa das tarefas relacionadas à criação de ferramentas de desenvolvimento não precisa de raciocínio profundo. Precisa de classificação rápida com vocabulário controlado:

TarefaPrecisa do GPT-4?O modelo da Apple funciona?
Classificar um commit como fix/feat/refactorNãoSim
Gerar um nome de variável a partir do contextoNãoSim
Resumir um erro de compilaçãoNãoSim
Determinar se um issue é bug ou featureNãoSim
Classificar o tom de uma mensagem de PRNãoSim, com cautela
Projetar a arquitetura de um sistema distribuídoSimNão
Explicar um bug sutil de concorrênciaSimNão
Escrever um algoritmo complexo do zeroSimNão

A linha divisória é clara: se a tarefa tem um conjunto finito de respostas possíveis e o contexto cabe em algumas frases, o modelo da Apple provavelmente funcionará. Se você precisa de análise sobre centenas de linhas de código com dependências cruzadas, vai necessitar de um modelo grande.

Receitas copiáveis

Vamos ao lado prático. Três receitas que você pode copiar e usar hoje (bom, quando tiver macOS 26).

1. Triagem de erros

@Generable
struct ErrorTriage {
    @Guide(.anyOf(["critical", "warning", "info", "noise"]))
    let severity: String

    @Guide(description: "Qual equipe deve lidar com isso")
    @Guide(.anyOf(["backend", "frontend", "infra", "ignore"]))
    let owner: String

    @Guide(description: "Uma frase explicando o problema")
    let summary: String
}

let session = LanguageModelSession(instructions: """
    You triage error messages from a CI pipeline.
    Classify severity and assign to the right team.
    """)

let error = "FATAL: column 'user_id' does not exist"
let triage = try await session.respond(
    to: "Triage: \(error)",
    generating: ErrorTriage.self
)
// severity: "critical", owner: "backend",
// summary: "Missing column in database schema"

Isso roda em milissegundos. Sem conexão. Em um pre-commit hook, em um script de CI local, ou em uma barra de menu. Imagine monitorar a pipeline para classificar erros e alertar apenas os importantes — tudo rodando no seu Mac, sem enviar nada para servidores externos.

2. Assistente de nomenclatura

@Generable
struct NamingSuggestion {
    @Guide(description: "Nome em camelCase para a variável ou função")
    let name: String

    @Guide(description: "Por que esse nome é apropriado")
    let reasoning: String
}

let session = LanguageModelSession(instructions: """
    You suggest variable and function names following
    Swift naming conventions (camelCase, descriptive,
    no abbreviations except standard ones like URL, ID).
    """)

let context = "A function that takes a list of timestamps and returns the average interval between consecutive entries"
let suggestion = try await session.respond(
    to: "Suggest a name for: \(context)",
    generating: NamingSuggestion.self
)
// name: "averageIntervalBetweenTimestamps"

3. Gerador de mensagens de commit

@Generable
struct CommitMessage {
    @Guide(.anyOf(["fix", "feat", "refactor", "test", "docs", "chore"]))
    let type: String

    @Guide(description: "Escopo da alteração, exemplo: auth, ui, db")
    let scope: String

    @Guide(description: "Resumo imperativo, máx. 50 caracteres")
    let subject: String
}

let session = LanguageModelSession(instructions: """
    Generate a conventional commit message from a git diff.
    Use imperative mood. Be concise.
    """)

let diff = try String(contentsOfFile: "/tmp/current.diff")
let msg = try await session.respond(
    to: "Generate commit message:\n\(diff)",
    generating: CommitMessage.self
)
print("\(msg.type)(\(msg.scope)): \(msg.subject)")
// "fix(auth): handle expired token in refresh flow"

Caso real: SentimentKit e uma ironia da Apple

Eu tenho um projeto de código aberto chamado SentimentKit — um framework Swift para análise de sentimento especializado em texto técnico. Ele existe porque o NLTagger da Apple, a ferramenta oficial de análise de sentimento do SDK, é terrível com mensagens de desenvolvedores.

Quão ruim? O NLTagger classifica “delete the temp file” com um -0.8 (muito negativo). “run make test” recebe -0.6. “commit and push”, -0.4. Se você seguir o sistema de análise de sentimentos da Apple, programar é aparentemente devastador. Apagar um arquivo temporário é quase uma ameaça.

Isso nunca foi percebido porque ninguém usa o NLTagger para propósitos sérios. Ele não aparece em nenhum artigo acadêmico de análise de sentimento aplicado em desenvolvimento de software. Nós testamos, documentamos os erros e construímos algo melhor.

SentimentKit utiliza dicionários curados e regras do VADER, adaptadas para 8 idiomas (en, es, pt, fr, de, ja, ko, zh). O pipeline interpretativo reconhece que “delete the temp file” é neutro e não agressivo. E para casos ambíguos — sarcasmo, ironia — há fallback via CoreML e APIs de LLM.

Curiosamente agora, o Apple Intelligence detecta sarcasmo que NLTagger não. Exemplar? Sim! Resultado? Muito mais estável.

Arquitetura de camadas

Assim como memórias “cache layers” organizam respostas dos diferentes subsistemas. Conclusão: melhores reusos baratos sem depender 1 grande topo $$$ API. Evita queries redundantes e custos elevados.