Foundation Models On-Device LLM: el protocolo Tool
El contrato del LLM on-device que Apple presentó en la WWDC 2025 plantea una pregunta inmediata de enrutamiento: ¿cuándo es LanguageModelSession la respuesta correcta, cuándo es AppIntent, cuándo es MCP, cuándo no es ninguno de los anteriores?
iOS 26 incluye un modelo de lenguaje de 3 mil millones de parámetros en cada dispositivo compatible con Apple Intelligence.1 Apple llama al framework Foundation Models. El framework es local. La inferencia está optimizada para Apple silicon y se ejecuta on-device; la red no está en la ruta de la llamada. El modelo vive en SystemLanguageModel.default, tu app obtiene un LanguageModelSession, y la superficie tipada para permitirle a esa sesión hacer trabajo útil es el protocolo Tool.
El protocolo Tool es la parte que importa para los desarrolladores de apps. Sin él, el LLM on-device es un endpoint de chat completion sin conexión a los datos de tu app, los datos del usuario o el resto del sistema. Con él, el modelo puede llamar a funciones tipadas de Swift, recibir resultados tipados, y razonar sobre la respuesta en su siguiente turno. La generación on-device aumentada con tools es la capacidad real del framework. La superficie de chat es la demo.
TL;DR
- Foundation Models le da a cada dispositivo elegible para Apple Intelligence un LLM de 3B parámetros en
SystemLanguageModel.default. El modelo es local; la inferencia está optimizada para Apple silicon y se ejecuta on-device; la red queda fuera de la ruta de la llamada. - El protocolo Tool es el contrato entre el modelo y tu app. Una tool declara
Argumentstipados, devuelve unOutputtipado, y se vincula a unLanguageModelSessionen el momento de la construcción. - Las anotaciones
GenerableyGuidepermiten que el modelo produzca valores Swift tipados directamente, no solo strings. El decodificador es parte del framework, no de tu código. - La regla de enrutamiento entre Foundation Models, App Intents y MCP es quién ejecuta el modelo y dónde. Foundation Models = tu app ejecuta el modelo on-device. App Intents = Apple Intelligence ejecuta el modelo on-device y enruta a tu app. MCP = un host externo ejecuta el modelo donde quiera y se comunica con tu app a través de un servidor de tools.
Lo que el framework realmente proporciona
Tres primitivas sostienen el framework: el modelo, la sesión y la tool.2
SystemLanguageModel. Una referencia al modelo fundacional on-device. La instancia por defecto está vinculada al dispositivo del usuario, disponible en hardware elegible para Apple Intelligence, y expone verificaciones de capacidad que la app lee en runtime para decidir si el modelo está disponible. El framework admite configuración a través de SystemLanguageModel(useCase:guardrails:), adaptadores personalizados y GenerationOptions, pero no eliges IDs de modelos en la nube de forma arbitraria como lo harías con OpenAI o Anthropic; Apple distribuye y actualiza el modelo on-device por cada release del SO, y el framework te entrega la versión que esté instalada actualmente.
LanguageModelSession. Un objeto con estado que mantiene el estado de la conversación entre llamadas. La sesión toma un system prompt en la construcción, acumula turnos de usuario/asistente con el tiempo, y expone métodos async para generar respuestas. Las sesiones son ligeras de crear y desechables; creas una por tarea, no una por app. Una app de meditación crea una sesión para “resume mis últimos 7 días de práctica”; una app de recetas crea una sesión diferente para “convierte esto para dos personas en lugar de cuatro”.
Tool (el protocolo). Un protocolo de Swift que declara un name, una description, un tipo Arguments, un tipo Output, y una función async call(arguments:). Las tools se vinculan a una sesión en el momento de la construcción (LanguageModelSession(tools: [...], instructions: ...)). Cuando el modelo decide que necesita una tool, emite una llamada estructurada; el framework decodifica los argumentos, ejecuta la tool, codifica el resultado, y lo realimenta a la sesión para el siguiente turno. El modelo no ve Swift; el framework hace el marshalling.
Los requisitos completos del protocolo: name: String, description: String, un tipo asociado Arguments que se conforma a ConvertibleFromGeneratedContent, un tipo asociado Output que se conforma a PromptRepresentable, y un método async call(arguments:). La macro @Generable sobre la struct Arguments genera la conformidad con ConvertibleFromGeneratedContent de forma gratuita; para Output, String y GeneratedContent ya se conforman. Los ejemplos documentados de Apple devuelven String o [String].
La forma del protocolo Tool, condensada:
import FoundationModels
struct WaterEntryLookup: Tool {
let name = "lookup_water_entries"
let description = "Look up water intake entries for a given date range."
@Generable
struct Arguments {
@Guide(description: "Start date in ISO-8601 format")
let startDate: String
@Guide(description: "End date in ISO-8601 format")
let endDate: String
}
func call(arguments: Arguments) async throws -> String {
let entries = try store.entries(
from: ISO8601DateFormatter().date(from: arguments.startDate) ?? .now,
to: ISO8601DateFormatter().date(from: arguments.endDate) ?? .now
)
let totalMl = entries.reduce(0) { $0 + $1.amountMl }
return "Found \(entries.count) entries totalling \(totalMl)ml."
}
}
El modelo ve una descripción de tool y una forma de argumentos en esquema de generación. El código Swift ve entrada tipada y salida tipada. La frontera de decodificación/codificación es la parte que Apple posee. La salida de la tool puede ser un String o un objeto GeneratedContent; el ejemplo anterior devuelve String ya que el razonamiento del siguiente turno del modelo es el consumidor.
Generable y Guide: salida tipada sin parser
El mismo sistema de anotaciones que hace que los argumentos de las tools sean tipados también permite que el modelo produzca valores Swift tipados directamente.3 Una struct @Generable declara su forma; el framework restringe la salida del modelo para que coincida.
@Generable
struct PracticeSummary {
@Guide(description: "Single-sentence headline summarizing the user's week")
let headline: String
@Guide(description: "Total practice duration this week in minutes")
let totalMinutes: Int
@Guide(description: "Three short observations as bullet points")
let observations: [String]
}
let session = LanguageModelSession(instructions: "You are a meditation coach.")
let summary = try await session.respond(
to: "Summarize this week of practice given the entries.",
generating: PracticeSummary.self
)
La llamada devuelve un Response<PracticeSummary> cuyo content es un PracticeSummary tipado. Sin parsing de JSON en tu código, sin matching de strings para “headline:”, sin fallback para cuando el modelo devolvió un objeto malformado. El framework usa muestreo restringido para mantener la salida token a token del modelo estructuralmente alineada con el esquema, de modo que la salida estructuralmente inválida no se cuela más allá de la frontera. La sesión anterior no toma tools porque la salida tipada y la llamada a tools son capacidades independientes; una sesión puede usar @Generable para la forma de la respuesta, tools para grounding, ambos, o ninguno.
La superficie tipada en Swift es lo que distingue al framework de los SDKs de LLM en la nube. Los SDKs en la nube (OpenAI Structured Outputs, Anthropic tool use, otros) también admiten muestreo restringido, pero el valor tipado que recibe el desarrollador es un objeto JSON validado contra un esquema, luego decodificado a un tipo Swift Codable como un paso separado. Foundation Models colapsa esos pasos: la macro @Generable y el decodificador del framework producen un valor Swift tipado como retorno directo, con las anotaciones @Guide por campo llevando la intención a la restricción de generación. La salida es tipada porque la generación fue tipada contra el esquema Swift, no contra una especificación JSON que el desarrollador reconstruyó en Swift.
Las anotaciones @Guide son la forma en que comunicas la intención por campo al modelo sin escribirla en el prompt. La descripción generada se vuelve parte de la restricción de generación. Las guías a nivel de campo mantienen el prompt limpio y el esquema cerca de los datos.
La pregunta de enrutamiento, de tres maneras
Apple ahora ofrece tres superficies de protocolo que una app puede usar para exponer su dominio a un modelo de lenguaje. Se enrutan a runners diferentes.
Foundation Models (LanguageModelSession). Tu app carga el modelo on-device y ejecuta la inferencia. Las tools que la sesión puede llamar son tools que el código de tu app define. El modelo nunca abandona el dispositivo. El usuario no invoca esto a través de Siri; el código de tu app lo hace. El caso de uso es dentro de tu app: una app de meditación que usa el LLM para resumir una semana, una app de recetas que adapta una receta para menos porciones, un rastreador de agua que convierte “tomé un vaso con el almuerzo” en una entrada estructurada.
App Intents. Apple Intelligence ejecuta un LLM en nombre del usuario (el agente de primera parte de Apple) y enruta llamadas de capacidad a los tipos AppIntent de tu app. Tu app no ejecuta el modelo. Declaras acciones tipadas a través del framework App Intents, y el stack del sistema de Apple decide cuándo invocarlas según la solicitud del usuario, la consulta de Spotlight, la entrada de Siri o la orquestación de Shortcuts. Cubierto en detalle en App Intents Are Apple’s New API to Your App.4
MCP. Un host externo (Claude Desktop, Claude Code, Cursor, ChatGPT) ejecuta el modelo que el desarrollador eligió. Tu app expone un servidor que el modelo del host puede llamar. El modelo se ejecuta donde sea que el host lo ejecute; las llamadas a tools cruzan un transporte JSON-RPC. Cubierto en Two Agent Ecosystems, One Shopping List y la síntesis sobre la pregunta de enrutamiento en App Intents vs MCP.5
La decisión de enrutamiento se reduce a quién es el agente.
┌──────────────────────────────────┐
│ Who is the language model? │
└────┬─────────────┬─────────────┬──┘
│ │ │
┌────────┴────┐ ┌──────┴──────┐ ┌────┴──────┐
│ Your app's │ │ Apple │ │ External │
│ own use of │ │ Intelligence│ │ host's │
│ LLM │ │ agent │ │ agent │
└──────┬──────┘ └──────┬──────┘ └────┬──────┘
│ │ │
▼ ▼ ▼
Foundation Models App Intents MCP
+ Tool protocol + AppEntity + tools/list
(on-device, your (system runs (host runs
app runs model) the model) the model)
Una app de meditación que resume la semana del usuario usa Foundation Models porque la app misma quiere llamar al modelo y presentar un resultado dentro de la app. La capacidad de “registrar una sesión de 5 minutos” de la misma app usa App Intents para que Siri pueda invocarla. La capacidad de “muéstrame mis últimas entradas del registro de meditación” de la misma app usada por una sesión de Claude Code usa MCP. Tres runners diferentes, tres obligaciones diferentes, una capa de dominio compartida debajo.
Presupuestos de inferencia: lo que el framework te exige
Ejecutar un LLM on-device no es gratis. Apple silicon maneja la inferencia, pero el modelo aún tiene una ventana de contexto, un presupuesto de tokens y una latencia de wall-clock que depende del dispositivo. Tres restricciones dan forma a cómo diseñas con el framework:6
La disponibilidad es por dispositivo. No todos los dispositivos con iOS 26 tienen Apple Intelligence. Los iPhones más antiguos, los dispositivos bloqueados y los dispositivos donde el usuario ha desactivado Apple Intelligence devuelven un estado no disponible desde SystemLanguageModel.default.availability. El código que llama a LanguageModelSession sin verificar la disponibilidad expone un error de generación en runtime; el patrón correcto es ramificar la UI según el estado de disponibilidad de antemano y presentar una ruta sin LLM cuando el estado no está disponible. Trata el modelo como un feature flag, no como una garantía.
La latencia no es trivial. La latencia del primer token en hardware iPhone 16 Pro es usable para interacciones dentro de la app en nuestras pruebas con Return; las generaciones más largas y las cadenas de tool-calling no son instantáneas. Los patrones de UI que funcionan para streaming de LLM en la nube también funcionan aquí; no bloquees el hilo principal, sí muestra salida progresiva, y sí diseña para el caso en que el usuario navega fuera a mitad de la generación.
Las ventanas de contexto son más pequeñas que en la nube. El modelo on-device tiene una ventana de contexto más pequeña que los modelos en la nube de la clase GPT-4. Los documentos largos necesitan resumen o chunking. El historial de conversación largo necesita recortes. Las salidas de tools que devuelven payloads estructurados grandes deberían devolver una referencia (un ID, una clave) que el siguiente turno pueda recuperar bajo demanda, no el payload completo en línea.
El conjunto de restricciones es similar a diseñar para un runtime edge de gama baja, no para un modelo frontera en la nube. Las facilidades del framework lo hacen más agradable; los límites físicos subyacentes no se mueven.
Cuándo recurrir a Foundation Models
Las mejores adecuaciones del framework están donde la generación on-device de baja fricción es el producto:
Reformatear y reescribir. Convertir una nota libre del usuario en una entrada estructurada, pulir un borrador de mensaje, resumir una transcripción capturada. La tolerancia a la latencia es moderada; la sensibilidad de los datos es alta; la inferencia en la nube es excesiva.
Síntesis local sobre datos privados. Una app de entrenamiento que convierte el historial de entrenamiento del usuario en un resumen de “esta semana”. Una app de finanzas que explica el patrón de gasto de un usuario. Una app de diario que hace emerger temas a lo largo de un trimestre de entradas. Los datos no deberían salir del dispositivo; la respuesta debería aparecer dentro de la app; el prompt está acotado.
Tool-calling ligero para automatización interna de la app. Una app que permite al usuario decir “muéstrame el registro de meditación del martes” y usa una tool para obtener los registros subyacentes, luego formatea la respuesta. El agente es la app, la tool es la propia capa de datos de la app, el modelo es local.
Generación con conformidad de tipo. En cualquier lugar donde la app de otra forma escribiría a mano un parser JSON o una plantilla de string, @Generable más @Guide es una superficie más duradera.
Cuándo NO recurrir a Foundation Models
El framework es la respuesta equivocada para varios casos comunes:
Cualquier cosa que el usuario podría preguntarle a Siri. “Registra 250 ml de agua”, “Inicia una meditación de 5 minutos”, “Agrega bananas a mi lista” son App Intents. Apple Intelligence es el runner; tu app es el destino. Foundation Models es para generación dentro de la app, no para acciones enrutadas por Siri. Si construyes la misma capacidad dos veces (App Intent + LanguageModelSession con una tool), gana el App Intent porque el usuario invoca a Siri, no a tu pantalla dentro de la app.
Cualquier cosa que un agente LLM externo deba conducir. Una sesión de Claude Code que se conecta al dominio de tu app pertenece a MCP. La app no ejecuta el LLM; el host lo hace; el modelo vive donde sea que el host lo haya puesto. Foundation Models no puede servir a agentes externos.
Razonamiento pesado sobre documentos grandes. El modelo on-device es pequeño. Un contrato de 200 páginas, un contexto largo de codebase, o razonamiento multi-imagen sobre muchas fotos pertenece a la inferencia en la nube (tuya o de un proveedor), donde la ventana de contexto y el conteo de parámetros coinciden con la carga de trabajo. Las tareas que exceden la envoltura del framework producen errores concretos: ventana de contexto excedida, violaciones de guardrails, locales no soportados. Expón esos errores deliberadamente en lugar de diseñar flujos que dependan de que el modelo maneje trabajo fuera de envoltura.
Flujos cross-device y cross-user. El modelo on-device tiene acceso solo a lo que la app pasa a la sesión. La sincronización cross-device (estado del temporizador desde Watch a iPhone), la colaboración cross-user (listas compartidas, documentos compartidos) y cualquier flujo que se beneficie de la coordinación del lado del servidor necesitan un servidor. El modelo no es una primitiva de red.
Lo que construiría diferente en mi stack
El framework recompensa una elección arquitectónica específica que es fácil equivocar en la primera pasada. Las capacidades que el usuario invoca a través de la UI de la app y el LLM deberían consumirse como tools, no como rutas de prosa duplicadas.
Una app de meditación podría agregar un panel de “revisión semanal” resumido por LLM. La construcción ingenua es un solo prompt: “Aquí están las entradas del usuario de esta semana, escribe un párrafo”. La construcción mejor define una tool WeeklyEntries que el modelo puede llamar cuando necesita saber qué hubo en la semana, más una salida estructurada WeeklySummary vía @Generable. La primera construcción es frágil (el modelo tiene que ingerir una lista larga de entradas en cada llamada), cara en tokens, y produce prosa no estructurada. La segunda es duradera (la tool-call separa “qué pasó” de “cómo hablar de ello”), barata (el modelo solo obtiene lo que necesita) y estructurada (el resultado es un valor Swift tipado).
El patrón compone limpiamente con App Intents y MCP. La misma consulta WeeklyEntries es también el cuerpo de un resolvedor de parámetros de AppIntent y un manejador de tool de MCP. Una función Swift; tres superficies. El modelo llama a la misma función que llama el usuario.
La otra decisión de arquitectura: las descripciones de las tools son parte del prompt. El modelo lee Tool.description para decidir si y cuándo llamar. Trata la descripción como un docstring que esperas que un futuro contribuidor lea; el modelo es el futuro contribuidor.
Lo que el patrón significa para el stack de Apple en iOS 26+
Tres conclusiones.
-
El LLM on-device es una función de runtime, no un backend. Trátalo como un framework del sistema con una ventana de contexto y un presupuesto de inferencia on-device, no como un servicio remoto. Las decisiones de arquitectura son disponibilidad, latencia, disciplina de la ventana de contexto, y salida estructurada.
-
El protocolo Tool es la superficie. Sin tools, el modelo es un endpoint de chat completion sin conexión a tu dominio. Con tools, el modelo se convierte en una capa de consulta estructurada sobre los datos de tu app.
-
La regla de enrutamiento entre Foundation Models, App Intents y MCP es “quién ejecuta el modelo”. La generación dentro de la app va a Foundation Models. Las capacidades enrutadas por Apple Intelligence van a App Intents. Las capacidades de agentes externos van a MCP. La misma función de dominio Swift puede ser llamada por las tres superficies.
Tres posts hermanos profundizan dentro del framework Foundation Models: casos de uso de Foundation Models para las decisiones de adecuación a la carga de trabajo, adaptadores personalizados para hacer fine-tuning del modelo on-device sobre datos de la app, y el flujo de trabajo agéntico para la división LLM dentro-de-app vs tooling.
El cluster completo del Apple Ecosystem: App Intents tipados para Apple Intelligence; servidores MCP para agentes cross-LLM; la pregunta de enrutamiento entre los dos; Live Activities para la máquina de estados de la Lock Screen; patrones de Liquid Glass para la capa visual; shipping multiplataforma para alcance cross-device. El hub está en la Apple Ecosystem Series. Para un contexto más amplio de iOS-con-agentes-de-AI, consulta la iOS Agent Development guide.
FAQ
¿Qué es el framework Foundation Models en iOS 26?
Foundation Models es el framework de Apple para acceder al modelo de lenguaje on-device que viene con los dispositivos elegibles para Apple Intelligence en iOS 26 (y iPadOS 26, macOS 26, visionOS 26). El framework expone SystemLanguageModel, LanguageModelSession y el protocolo Tool para que las apps puedan ejecutar llamadas tipadas al LLM on-device sin acceso a la red.
¿Cómo funciona el protocolo Tool?
Un Tool es un tipo Swift que declara una struct Arguments (anotada con @Generable y @Guide), un método async call(arguments:), y un nombre + descripción que el modelo usa para decidir cuándo llamar. Las tools se vinculan a un LanguageModelSession en el momento de la construcción. Cuando el modelo decide que necesita una tool, el framework decodifica los argumentos, ejecuta la llamada, y realimenta la salida tipada a la sesión.
¿Cuál es la diferencia entre Foundation Models, App Intents y MCP?
Foundation Models es para que tu app ejecute el LLM on-device para generación dentro de la app. App Intents es para que Apple Intelligence (el agente del sistema) llame a las capacidades tipadas de tu app. MCP es para que hosts LLM externos (Claude, ChatGPT, etc.) llamen a las tools tipadas de tu app a través de un transporte JSON-RPC. Los tres protocolos difieren en quién ejecuta el modelo. La misma función de dominio Swift puede servir a las tres.
¿Puede Foundation Models llamar a tools de MCP?
No. LanguageModelSession.tools acepta conformantes al protocolo Tool de Apple, no servidores de tools de MCP. Para tender un puente entre los dos, escribirías un Tool de Foundation Models cuyo método call invoque un cliente MCP. Apple no ha lanzado un adaptador integrado; el puente sería código del lado de la app.
¿Es el modelo on-device lo suficientemente bueno para producción?
Para los casos de uso para los que el framework está diseñado (reformateo, resumen, generación estructurada sobre datos locales, tool-calling ligero), sí. Para razonamiento de frontera sobre contextos grandes, comprensión multimodal a escala, o razonamiento cross-document, no. El modelo on-device es un modelo de 3 mil millones de parámetros con una ventana de contexto más pequeña que los LLMs en la nube; elige cargas de trabajo que encajen en la envoltura.
Referencias
-
Apple Developer, “Apple Intelligence and machine learning” y la sesión de WWDC 2025 “Meet the Foundation Models framework”. El número titular del framework (un modelo de lenguaje on-device de 3 mil millones de parámetros) proviene del anuncio de Apple en la WWDC 2025. ↩
-
Apple Developer, “FoundationModels framework”.
SystemLanguageModel,LanguageModelSession,Tool,GeneratedContenty tipos de soporte. ↩ -
Apple Developer, “Generating Swift data structures with guided generation” y la referencia de las macros
@Generable/@Guide. Generación restringida por tipo como capacidad de primera clase vía muestreo restringido. ↩ -
Análisis del autor en App Intents Are Apple’s New API to Your App, 28 de abril de 2026. ↩
-
Análisis del autor en Two Agent Ecosystems, One Shopping List, 29 de abril de 2026, y App Intents vs MCP: The Routing Question, 30 de abril de 2026. ↩
-
Apple Developer, “Adopting Apple Intelligence in your app” y “SystemLanguageModel” para los patrones de
availability. Las sesiones de WWDC 2025 de Apple cubren la ruta de inferencia on-device en Apple silicon y las restricciones de disponibilidad por dispositivo. ↩