Tu Mac tiene un LLM gratis y no lo estás usando

| Última modificación: 4 de mayo de 2026 | Tiempo de Lectura: 9 minutos
Premios Blog KeepCoding 2025

Co-Fundador de KeepCoding

Estás pagando entre 20 y 200 dólares al mes por acceso a LLMs. Claude, GPT, Gemini, lo que sea. Y la mayoría de las llamadas que haces desde tus scripts y herramientas de desarrollo son variaciones de esto:

  • «Clasifícame este error en una de estas cinco categorías»
  • «Ponle nombre a esta variable»
  • «Dime si este commit es un fix, un feat o un refactor«
  • «Resume este bloque de texto en dos frases»

Mientras tanto, tu Mac con Apple Silicon tiene un modelo de lenguaje de 3.000 millones de parámetros sentado ahí, integrado en el sistema operativo, sin coste, sin red, sin API key, sin latencia de red. Y probablemente no lo estás usando para nada.

El Framework de Foundation Models

Con macOS 26 (Tahoe), Apple abrió el acceso al modelo que alimenta Apple Intelligence a través del Foundation Models framework. Es un framework Swift nativo, disponible en macOS 26, iOS 26 e iPadOS 26, en cualquier dispositivo con Apple Silicon que soporte Apple Intelligence.

Lo interesante no es que sea gratis — que lo es. Lo interesante es que genera salida tipada en Swift. No te devuelve un String que luego tienes que parsear con regex y esperanza. Te devuelve un struct.

import FoundationModels

@Generable
struct CommitClassification {
    @Guide(description: "The type of change")
    @Guide(.anyOf(["fix", "feat", "refactor", "test", "docs", "chore"]))
    let type: String

    @Guide(description: "One-line summary of the change, max 72 chars")
    let summary: String
}

El macro @Generable le dice al framework que genere un schema en tiempo de compilación. El modelo usa ese schema para producir salida estructurada. @Guide restringe los valores posibles — en román paladino, le pones las vías del tren y el modelo no puede descarrilar.

Para usarlo:

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

let diff = "..." // tu git diff aquí
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"

Eso es todo. Sin URLSession. Sin API key. Sin parsear JSON. Sin try? JSONDecoder().decode(QuienSabeQue.self, from: data). El modelo corre on-device, en el Neural Engine de tu Mac, y te devuelve un tipo de Swift que el compilador valida.

¿Para qué sirve (y para qué no)?

Aquí es donde hay que ser honesto. El modelo de Apple es un modelo de ~3B parámetros, optimizado para eficiencia energética y latencia, no para razonamiento complejo. Apple lo dice explícitamente en su documentación: está diseñado para clasificación, extracción, resumen y tareas similares. No para razonamiento avanzado ni conocimiento enciclopédico.

En benchmarks públicos, el modelo de Apple puntúa un ~44% en MMLU — por debajo de modelos como Llama 3.2 3B o Gemma 2 2B. ¿Por qué? Porque Apple priorizó que el modelo corriera eficientemente sin drenar batería, no que ganara concursos de trivial.

Pero eso no importa para lo que estamos hablando. Un porcentaje significativo de las tareas de tooling de desarrollo no necesitan razonamiento profundo. Necesitan clasificación rápida con vocabulario controlado:

Tarea ¿Necesita GPT-4? ¿Sirve el modelo de Apple?
Clasificar un commit como fix/feat/refactor No
Generar un nombre de variable a partir de contexto No
Resumir un error de compilación No
Decidir si un issue es bug o feature No
Clasificar el tono de un mensaje de PR No Sí, con cuidado
Diseñar la arquitectura de un sistema distribuido No
Explicar un bug sutil de concurrencia No
Escribir un algoritmo complejo desde cero No

La línea divisoria es clara: si la tarea tiene un conjunto finito de respuestas posibles y el contexto cabe en unas pocas frases, el modelo de Apple probablemente funciona. Si necesitas razonamiento sobre cientos de líneas de código con dependencias cruzadas, necesitas un modelo grande.

Recetas copiables

Vamos a lo práctico. Tres recetas que puedes copiar y usar hoy (bueno, cuando tengas macOS 26).

1. Triage de errores

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

    @Guide(description: "Which team should handle this")
    @Guide(.anyOf(["backend", "frontend", "infra", "ignore"]))
    let owner: String

    @Guide(description: "One sentence explaining the issue")
    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"

Esto corre en milisegundos. Sin red. En un pre-commit hook, en un script de CI local, en una barra de menú. Imagina un monitor que clasifica los errores de tu pipeline y te avisa solo de los que importan — todo corriendo en tu Mac, sin mandar nada a ningún servidor.

2. Naming assistant

@Generable
struct NamingSuggestion {
    @Guide(description: "camelCase name for the variable or function")
    let name: String

    @Guide(description: "Why this name is appropriate")
    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. Commit message generator

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

    @Guide(description: "Scope of the change, e.g. auth, ui, db")
    let scope: String

    @Guide(description: "Imperative summary, max 50 chars")
    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 y la ironía de Apple

Tengo un proyecto open-source llamado SentimentKit — un framework Swift para análisis de sentimientos especializado en texto técnico. Existe porque NLTagger de Apple, la herramienta oficial de análisis de sentimiento del SDK, es un desastre con mensajes de desarrolladores.

¿Cómo de desastre? NLTagger puntúa «delete the temp file» con un -0.8 (muy negativo). «run make test» se lleva un -0.6. «commit and push», -0.4. Según el análisis de sentimiento de Apple, programar es una actividad emocionalmente devastadora. Borrar un fichero temporal es prácticamente una amenaza de muerte.

Nadie se había dado cuenta porque nadie usa NLTagger para nada serio. No aparece en un solo paper académico sobre análisis de sentimiento en ingeniería de software. Lo probamos, documentamos el sesgo y construimos algo mejor.

SentimentKit usa diccionarios curados y reglas VADER adaptadas para 8 idiomas (en, es, pt, fr, de, ja, ko, zh). VADER (Valence Aware Dictionary and sEntiment Reasoner) es un modelo de análisis de sentimiento basado en reglas léxicas: no usa machine learning, sino un diccionario de palabras con puntuaciones de valencia y un conjunto de reglas gramaticales (negaciones, intensificadores, mayúsculas, signos de exclamación) que modulan esas puntuaciones. Es rápido, determinista y predecible — pero por definición no puede entender contexto pragmático como el sarcasmo. El pipeline de SentimentKit entiende que «elimina este fichero» es un comando neutral, no un acto de violencia. Para los casos ambiguos — sarcasmo, ironía, sutilezas — tiene un fallback opcional a CoreML (DistilBERT local) y a LLMs remotos (Anthropic, OpenAI).

Ahora bien, la parte divertida. Recientemente se filtró parte del código de Claude Code, y resulta que Anthropic — una empresa multimillonaria de inteligencia artificial — detecta la frustración del usuario con regex en inglés. Expresiones regulares. En 2026. Para detectar emociones. Cuando vi eso pensé: «Bueno, al menos yo no soy el único que ha tenido que resolver este problema, pero joder, ¿regex?».

Y aquí es donde Apple Intelligence cierra el círculo de la forma más irónica posible: el mismo Apple cuyo NLTagger me obligó a crear SentimentKit, ahora me da un modelo on-device que detecta sarcasmo mejor que sus propias herramientas de NLP.

Le pasé esto al modelo: «Great, another breaking change in the API. Just what I needed on a Friday afternoon.» Resultado: Negative. Correcto. El sarcasmo, que es exactamente donde los diccionarios y las regex fallan por definición (las palabras son «great» y «needed», ambas positivas), el modelo de 3B parámetros lo pilla.

Así que hice lo obvio: implementé un AppleIntelligenceScorer para SentimentKit. Veinte líneas de código:

@available(macOS 26, iOS 26, *)
public struct AppleIntelligenceScorer: SentimentScorer, Sendable {

    public static var isAvailable: Bool {
        SystemLanguageModel.default.isAvailable
    }

    public func meanScore(
        for messages: [String],
        baseAnalysis: SessionAnalysis
    ) async throws -> Double {
        let session = LanguageModelSession(
            instructions: LLMSentimentPrompt.systemInstructions
        )
        let input = LLMSentimentPrompt.input(
            messages: messages,
            baseAnalysis: baseAnalysis
        )
        let response = try await session.respond(
            to: input,
            generating: SentimentResponse.self
        )
        return response.content.meanScore
    }
}

@Generable
struct SentimentResponse {
    @Guide(description: "Mean sentiment, -2.0 to 2.0")
    var meanScore: Double
}

Se integra en el pipeline existente como una capa entre el CoreML local y los LLMs remotos. Sin API key, sin red, sin coste. Si el pipeline determinista (diccionarios + VADER) no está seguro de la puntuación, y Apple Intelligence está disponible, le pregunta al modelo on-device antes de escalar a Haiku o GPT-4o-mini. Para la mayoría de los casos ambiguos, eso es suficiente.

La ironía completa: Apple creó un analizador de sentimiento tan malo que tuve que crear el mío. Luego Apple creó un modelo de lenguaje que hace de fallback para el framework que tuve que crear por culpa de Apple. El círculo se cierra. Casi poético.

La arquitectura de capas

Aquí viene la tesis de fondo, y es la parte que creo que más gente se está saltando.

No deberías elegir un modelo para todo. Deberías tener una pila de modelos, como tienes una pila de caché:

┌─────────────────────────────────┐
│  Capa 3: Modelo grande (API)    │  Claude, GPT-4, etc.
│  Razonamiento, arquitectura,    │  $$$, latencia alta
│  código complejo                │
├─────────────────────────────────┤
│  Capa 2: Modelo mediano (API)   │  Sonnet, Haiku, GPT-4o-mini
│  Implementación, refactoring,   │  $$, latencia media
│  code review                    │
├─────────────────────────────────┤
│  Capa 1: Modelo on-device       │  Apple Intelligence (~3B)
│  Clasificación, naming, triage, │  Gratis, latencia ~0
│  commit messages, formateo      │
└─────────────────────────────────┘

Es exactamente la misma lógica que un sistema de caché: L1 en el chip (rápido, pequeño), L2 cerca (medio), L3 en RAM (lento, grande). No metes todo en L3 porque «total, es el que más puede». Usas L1 para lo que L1 puede resolver, y solo escalas cuando necesitas más.

El pipeline de SentimentKit lo ilustra perfectamente: diccionarios + VADER (microsegundos) → Apple Intelligence (milisegundos, gratis) → Haiku (centavos, bueno) → Opus (caro, solo si hay contradicciones). Cada capa resuelve lo que puede y solo escala lo que no sabe.

Piensa en cuántas de tus llamadas a LLMs son clasificación, formateo o resúmenes cortos. Probablemente más de las que crees. Esas llamadas deberían estar en la capa 1. Gratis. Sin red. Sin latencia. Sin que un cambio de pricing de OpenAI te arruine el mes.

El elefante en la habitación: solo Swift, solo Apple

Sí, este framework solo funciona en el ecosistema Apple. Solo Swift. Solo macOS 26+. Solo dispositivos con Apple Silicon y Apple Intelligence activado.

Si tu tooling está en Python o TypeScript, esto no te vale directamente. Podrías hacer un wrapper que exponga el modelo como un servidor HTTP local — pero en ese punto estás reinventando Ollama con pasos extra.

La apuesta de Apple es clara: si ya desarrollas en Swift, tienes un LLM gratis integrado en el sistema que puedes usar con cuatro líneas de código. Si no desarrollas en Swift… pues Apple no va a perder el sueño.

Dicho esto, la idea de la arquitectura de capas es universal. Si no tienes el modelo de Apple, Ollama con un Phi-3 o un Gemma hace el mismo trabajo en la capa 1. El punto no es qué modelo usas abajo — es que uses algo barato abajo en vez de mandar cada pregunta trivial a un modelo de 200 dólares al mes.

Lo que me habría gustado saber antes

Antes de darle leña al mono con esto, un par de cosas que no están en la documentación oficial pero que conviene saber:

  1. El modelo necesita que Apple Intelligence esté activado. Si lo has desactivado en Ajustes del Sistema, el framework no funciona. No hay forma de usar el modelo sin activar Apple Intelligence.

  2. La ventana de contexto es limitada. Es un modelo de ~3B parámetros optimizado para dispositivo. No le pases un diff de 500 líneas y esperes maravillas. Fragmenta.

  3. @Generable es tu mejor amigo. La salida libre (texto plano) del modelo es mediocre comparada con modelos grandes. Pero la salida estructurada, donde el modelo solo tiene que rellenar los huecos de un schema definido por ti, es sorprendentemente buena. Restringe siempre que puedas.

  4. No tiene conocimiento del mundo actualizado. El modelo no sabe qué versión de React salió ayer. Para tareas que requieren conocimiento factual reciente, sigue usando un modelo con acceso a internet.

El cálculo que nadie hace

Supón que haces 50 llamadas al día a un LLM desde tus scripts y herramientas. De esas, 40 son clasificación, naming, formateo y resúmenes cortos. Con el modelo de Apple en la capa 1:

  • 40 llamadas/día × 0 $ = 0 $ (on-device)
  • 10 llamadas/día a API = lo que ya pagas Esas 40 llamadas «gratis» también son más rápidas (sin latencia de red), más privadas (nada sale del dispositivo) y más fiables (sin rate limits, sin caídas de servicio).

No es que vayas a cancelar tu suscripción a Claude. Es que vas a dejar de quemarla en cosas que no la necesitan.

Y eso, al final, es lo que separa a un desarrollador que usa herramientas de uno que las entiende: saber qué pregunta merece qué modelo. No todo clavo necesita un martillo de 200 dólares. A veces el que viene gratis con el ordenador da de sobra.


Referencias

  • Apple Intelligence Foundation Language Models — tech report de Apple con la arquitectura del modelo (~3B on-device, ~30B servidor), cuantización a 4 bits con LoRA adapters, y benchmarks internos.
  • FoundationModels framework — documentación oficial del framework. Incluye @Generable, @Guide, LanguageModelSession y guided generation.
  • apfel — CLI open-source que expone Apple Intelligence como comando de terminal y servidor HTTP compatible con la API de OpenAI. MIT.
  • SentimentKit — framework Swift de análisis de sentimientos para texto técnico. Diccionarios + VADER + CoreML + LLMs, con el nuevo AppleIntelligenceScorer como capa on-device.

Read this article in English.

Noticias recientes del mundo tech


¡CONVOCATORIA ABIERTA!

Desarrollo de apps móviles ios & Android

Full Stack Bootcamp

Clases en Directo | Profesores en Activo | Temario 100% actualizado

Descárgate también el informe de tendencias en el mercado laboral 2026.

Fórmate con planes adaptados a tus objetivos y logra resultados en tiempo récord.
KeepCoding Bootcamps
Resumen de privacidad

Esta web utiliza cookies para que podamos ofrecerte la mejor experiencia de usuario posible. La información de las cookies se almacena en tu navegador y realiza funciones tales como reconocerte cuando vuelves a nuestra web o ayudar a nuestro equipo a comprender qué secciones de la web encuentras más interesantes y útiles.