🤯 Apple ha puesto en tus manos el mismo modelo de lenguaje que usa Apple Intelligence. Sin servidores externos. Sin APIs de pago. Sin depender de OpenAI. Todo ejecutándose en tu dispositivo. Y hoy te voy a enseñar, paso a paso, cómo crear un generador de recetas que funciona con IA 100% on-device.
¿Qué es Foundation Model Framework?
Foundation Model Framework es la nueva librería de Apple, disponible a partir de iOS 26, macOS 26 y visionOS 26, que te da acceso directo al modelo de lenguaje que está detrás de Apple Intelligence. Esto significa que puedes integrar capacidades de IA generativa en tus apps sin necesidad de conexión a internet y sin enviar los datos de tus usuarios a servidores de terceros.
La privacidad no es un eslogan aquí: es una realidad técnica. El modelo corre íntegramente en el dispositivo del usuario.
El proyecto: un generador de recetas inteligente
Vamos a crear un pequeño sistema que, dado un prompt, nos devuelva una receta completa con nombre, ingredientes, pasos a seguir y tiempo de preparación. Todo estructurado, tipado y listo para usar en tu UI. Nada de parsear JSONs a mano ni de rezar para que el modelo te devuelva algo coherente.
Lo primero: necesitas importar las librerías necesarias.
import Playgrounds
import FoundationModels
FoundationModels es el framework que nos da acceso al modelo de lenguaje. Playgrounds lo usamos porque vamos a ejecutar esto en un Swift Playground, la forma más rápida de prototipar cualquier idea. Sí, puedes hacer esto en Xcode con un proyecto completo, pero para probar y aprender, Playgrounds es tu mejor amigo.
Definiendo la estructura de datos: @Generable
Aquí viene lo interesante. En vez de pedirle al modelo que nos devuelva un texto libre que luego tenemos que parsear (con todos los errores que eso implica), vamos a definir exactamente qué estructura queremos que nos devuelva. Apple lo llama «Guided Generation» o generación guiada.
@Generable
struct Recipe {
let name: String
let ingredients: [String]
let instructions: [String]
let steps: [String]
let preparationTime: Int
}
¿Qué hace @Generable? Esta macro le dice al framework que esta estructura es un tipo válido para que el modelo de lenguaje la genere. El framework convierte automáticamente tu estructura Swift a un esquema JSON que el modelo entiende, y cuando el modelo responde, ese JSON se convierte de vuelta a tu estructura Swift.
Fíjate en los tipos que hemos usado:
Stringpara el nombre de la receta[String](arrays de strings) para ingredientes, instrucciones y pasosIntpara el tiempo de preparación en minutos
El framework soporta tipos básicos como Bool, Int, Float, Double, Decimal y Array. También puedes anidar estructuras @Generable dentro de otras, pero eso ya es para nota.
Comprobando la disponibilidad del modelo
⚠️ Antes de hacer cualquier llamada al modelo, SIEMPRE debes comprobar que está disponible. No todos los dispositivos soportan Apple Intelligence, y aunque lo soporten, el usuario puede tenerlo desactivado. Nunca asumas nada.
guard SystemLanguageModel.default.isAvailable else {
print("Foundation Models no disponible en este dispositivo")
return
}
SystemLanguageModel.default es la referencia al modelo de lenguaje del sistema. La propiedad isAvailable te dice si puedes usarlo o no. Si no está disponible, tu app debe tener un plan B. Siempre.
Creando la sesión con instrucciones
Ahora viene la parte donde configuramos el comportamiento del modelo. En Foundation Models, trabajamos con sesiones (LanguageModelSession). Una sesión mantiene el contexto entre llamadas, como una conversación.
let instructions = "Eres un chef experto en comida italiana, que responde todo en español con un toque maestro"
let session = LanguageModelSession(instructions: instructions)
Las instructions son fundamentales. Le dicen al modelo quién es y cómo debe comportarse. En este caso:
- Rol: un chef experto en comida italiana
- Idioma: español
- Tono: con un toque maestro (esto influye en cómo redacta las respuestas)
Apple entrena el modelo para que obedezca las instrucciones por encima de los prompts del usuario. Esto es importante: las instrucciones son tu forma de controlar el comportamiento del modelo de manera consistente.
Haciendo la petición al modelo
🚀 Aquí es donde ocurre la magia. Llamamos al método respond de la sesión, pasándole el prompt y el tipo de dato que queremos que genere.
let response = try await session.respond(
to: "Genera una receta de pasta carbonara",
generating: Recipe.self
)
Analicemos esto:
try await: la llamada es asíncrona y puede lanzar errores. El modelo necesita tiempo para generar la respuesta.to:: el prompt, la pregunta o petición que hacemos al modelo.generating: Recipe.self: aquí le decimos que queremos que nos devuelva una instancia de nuestra estructuraRecipe.
Esto es Guided Generation en acción. En lugar de recibir un texto libre que tienes que parsear, recibes directamente tu estructura Swift rellenada con los datos generados. El framework se encarga de todo el trabajo sucio.
Accediendo a los datos generados
Una vez tenemos la respuesta, acceder a los datos es trivial:
let recipe = response.content
print("Receta: \(recipe.name)")
print("Ingredientes: \n\(recipe.ingredients.joined(separator: "\n"))")
print("Pasos a seguir: \n\(recipe.steps.joined(separator: "\n"))")
print("Tiempo: \(recipe.preparationTime) min")
response.content contiene nuestra estructura Recipe completamente inicializada. No hay parsing. No hay opcionales que desenvolver. No hay errores de formato. Es Swift puro y duro.
El código completo
Aquí tienes todo el código junto, listo para copiar y probar:
import Playgrounds
import FoundationModels
@Generable
struct Recipe {
let name: String
let ingredients: [String]
let instructions: [String]
let steps: [String]
let preparationTime: Int
}
#Playground {
guard SystemLanguageModel.default.isAvailable else {
print("Foundation Models no disponible en este dispositivo")
return
}
let instructions = "Eres un chef experto en comida italiana, que responde todo en español con un toque maestro"
let session = LanguageModelSession(instructions: instructions)
let response = try await session.respond(
to: "Genera una receta de pasta carbonara",
generating: Recipe.self
)
let recipe = response.content
print("Receta: \(recipe.name)")
print("Ingredientes: \n\(recipe.ingredients.joined(separator: "\n"))")
print("Pasos a seguir: \n\(recipe.steps.joined(separator: "\n"))")
print("Tiempo: \(recipe.preparationTime) min")
}
Cosas que debes saber
Context Window: el modelo tiene un límite de 4.096 tokens por sesión. Un token son aproximadamente 3-4 caracteres en español. Si tu sesión supera este límite, recibirás un error exceededContextWindowSize. En ese caso, crea una nueva sesión o simplifica tus prompts.
Rendimiento: el modelo corre en el dispositivo, así que el tiempo de respuesta depende del hardware. En un iPhone reciente, las respuestas son bastante rápidas. Usa GenerationOptions si necesitas ajustar parámetros como la temperatura(creatividad) del modelo.
Guías adicionales: puedes usar la macro @Guide en las propiedades para dar más contexto al modelo:
@Generable
struct Recipe {
@Guide(description: "Nombre creativo de la receta")
let name: String
@Guide(description: "Lista de ingredientes con cantidades")
let ingredients: [String]
@Guide(description: "Tiempo en minutos", .range(5...180))
let preparationTime: Int
}
Idiomas: el modelo es multilingüe. Soporta los mismos idiomas que Apple Intelligence. Si quieres respuestas en un idioma específico, indícalo en las instrucciones.
¿Por qué esto importa?
Porque estamos ante un cambio de paradigma. Ya no necesitas depender de servicios externos para añadir capacidades de IA a tus apps. No tienes que preocuparte por costes de API, latencia de red, o privacidad de datos.
Piensa en las posibilidades: asistentes personales que funcionan sin conexión, apps de productividad que procesan datos sensibles sin enviarlos a ningún servidor, juegos con NPCs que generan diálogos dinámicos…
Foundation Model Framework no es el futuro. Es el presente. Y está disponible ahora mismo para que empieces a experimentar.




