Tres superficies: humano, Apple Intelligence, agente
Cada capacidad significativa de una app de iOS en iOS 26+ ahora enfrenta hasta tres superficies desde las cuales puede ser invocada. La misma función de Swift que registra un vaso de agua puede ser activada por un humano que toca un botón, por Apple Intelligence enrutando una solicitud de Siri, o por un agente externo (Claude Code, Cursor, ChatGPT) llamando a una herramienta MCP. Tres llamadores distintos, tres obligaciones distintas, tres superficies de renderizado distintas. La capacidad es la misma; las superficies no.
Muchos errores de arquitectura en iOS provienen de diseñar para una superficie y luego forzar la capacidad para que encaje en las otras. Los flujos de UI se filtran en las respuestas de Siri; las herramientas de agente que son correctas para un desarrollador se vuelven peligrosas para usuarios finales; las funciones de LLM en el dispositivo asumen contexto de calidad en la nube. El cluster ha estado mapeando estas superficies en publicaciones individuales. Esta publicación es la síntesis: las tres superficies, sus diferencias, la regla de enrutamiento y cómo debe verse la capa de dominio de una app para servir a las tres sin comprometer ninguna.
El modelo mental: elige una capacidad de dominio. Pregunta cuál de las tres superficies debería poder invocarla. Pregunta cuáles pueden. Pregunta qué necesita cada superficie de la capacidad y qué le debe la capacidad a cambio. Las respuestas dan forma a la arquitectura.
TL;DR
- Tres superficies: humano (vistas SwiftUI, toques, gestos, pantalla), Apple Intelligence (App Intents, Siri, Shortcuts, Spotlight), agente (servidores MCP, hosts LLM externos).
- Cada superficie tiene obligaciones distintas: postura de confianza, presupuesto de latencia, ubicación de renderizado, semántica de persistencia, manejo de errores, requisitos de accesibilidad.
- La arquitectura correcta es una capa de dominio debajo de las superficies. Cada superficie es un adaptador delgado sobre las mismas funciones de Swift; la función toma un argumento
Callertipado para que pueda ramificar según reglas transversales (límites de tasa, auditoría, confirmaciones) sin conocer los detalles del protocolo de cada superficie. - No toda capacidad sirve a las tres. La decisión sobre qué superficie es una decisión de diseño. Ocultar capacidades de las superficies que no deberían tenerlas es tanto una decisión de producto como exponerlas a las superficies que sí deberían.
Superficie uno: humano
La superficie humana es la pantalla. El usuario mira la app, toca, hace scroll, arrastra, desliza, escribe. El framework es SwiftUI (o UIKit, o para algunas cargas RealityKit en visionOS). El renderizado ocurre en el dispositivo del usuario, dentro del proceso de la app, contra el esquema de color elegido por el usuario, su tamaño de tipografía dinámica y su configuración de accesibilidad.1
Lo que la superficie humana necesita de una capacidad:
- Una expresión visual. Un botón, una fila de lista, un gesto de deslizamiento, un menú contextual. La capacidad tiene que ser descubrible a través de la navegación de la app y estilizada de forma consistente con el resto de la UI.
- Retroalimentación en tiempo real. Cada interacción necesita una respuesta visible inmediata. Un botón que dispara una operación de larga duración tiene que mostrar un indicador de progreso, un estado habilitado/deshabilitado, una animación.
- Accesibilidad. Etiquetas de VoiceOver, soporte para Dynamic Type, contraste de color, alternativas para control motriz. La superficie humana es la que tiene los requisitos de accesibilidad más exigentes porque el usuario está interactuando directamente con el renderizado.
- Visibilidad de errores. Los errores aterrizan en la vista del usuario. Un guardado fallido muestra una alerta; un timeout de red muestra un reintento; una denegación de permiso muestra un enlace a configuración.
Lo que la superficie humana le debe a la capacidad a cambio:
- Intención del usuario inequívoca. El usuario tocó un botón específico; la capacidad sabe exactamente lo que se solicitó. No hay capa de inferencia.
- Presupuesto de latencia ajustado. Un toque que tarda más de unos cientos de milisegundos en responder visiblemente se siente roto. La capacidad tiene que ser rápida o estar diseñada para mostrar progreso de inmediato.
- Sin autoridad externa. El usuario está en la app; el usuario es el agente en el sentido más amplio (el humano es quien impulsa la acción). Sin LLM de terceros, sin agente del sistema, solo las manos del usuario.
La superficie humana es la más antigua de las tres. Cada framework de iOS, patrón de diseño y regla de accesibilidad que la plataforma ha acumulado desde iOS 7 está al servicio de esta superficie. Las otras dos superficies son lo bastante recientes como para que los patrones todavía se estén asentando.
Superficie dos: Apple Intelligence
La superficie de Apple Intelligence es el agente del sistema. Siri, Shortcuts, Spotlight, el stack de sugerencias del sistema. El usuario habla, escribe en Spotlight, o encadena una acción en Shortcuts; el sistema enruta la solicitud a través del framework App Intents, encuentra un AppIntent que coincide, resuelve los parámetros y ejecuta el cuerpo perform() del intent. El framework es App Intents.2
Lo que la superficie de Apple Intelligence necesita de una capacidad:
- Un esquema tipado. Los tipos
AppIntentdeclaran propiedades@Parameter; los tiposAppEntityproveen identidad persistente para cosas de las que el sistema puede hablar; los tiposAppEnumnombran conjuntos cerrados de opciones. El sistema lee el esquema en tiempo de instalación. - Identidad que sobrevive al proceso de la app. Una entrada de agua que el usuario registró ayer a través de Siri debería poder ser referenciada hoy a través de Siri. El modelo
AppEntityle da al sistema una forma estable de hablar de objetos a lo largo de las sesiones. - Manejo de errores silencioso. Los errores no aterrizan en la vista de un usuario; aterrizan en una respuesta de Siri, una salida de Shortcuts o un resultado de Spotlight. El formato de error que el sistema espera es estructurado (el
AppIntentErrorde Apple más lanzamientos que conformenLocalizedError), no visual. - Idempotencia bajo reintento. El sistema puede reinvocar un intent durante una cadena de Shortcut o tras un fallo parcial. Las capacidades que mutan estado tienen que ser seguras bajo llamadas repetidas o exponer una semántica clara de “ya hecho”.
Lo que la superficie de Apple Intelligence le debe a la capacidad a cambio:
- La identidad real del usuario. El sistema sabe quién es el usuario, lo ha autenticado a través del SO y ejecuta el intent en su contexto. La capacidad no necesita verificar la identidad más allá de lo que el SO provee.
- Renderizado a nivel de sistema. El resultado que devuelve el intent es formateado por el sistema en el chrome apropiado (banner de Lock Screen, tarjeta de respuesta de Siri, salida de Shortcuts). La app no controla cómo se presenta la respuesta.
- Descubribilidad sin que tu código se ejecute. Los App Intents pueden ser invocados cuando tu app no está en ejecución. El sistema lee el esquema y expone la capacidad de forma proactiva.
La postura de confianza: Apple Intelligence es el agente de primera parte de Apple. El usuario no lo configuró; lo hizo el sistema. El usuario confía en el SO; el SO confía en el esquema de App Intents que tu app envió a través de revisión. La cadena de confianza es SO → app. Los App Intents sí soportan requestConfirmation(...) y confirmaciones en modo foreground, así que las capacidades que necesitan un “¿estás seguro?” pueden técnicamente vivir ahí; el juicio de producto, no la restricción de plataforma, es si las confirmaciones de alto riesgo pertenecen dentro de un turno de Siri o en la propia pantalla de la app. Cualquier cosa irreversible (eliminación de cuenta, ediciones masivas destructivas, pago) suele ser más segura en la superficie humana aunque los App Intents puedan solicitar confirmación.3
Superficie tres: agente
La superficie de agente es cualquier otro sistema con LLM que quiera operar el dominio de la app. Claude Desktop, Claude Code, Cursor, la app de escritorio de ChatGPT, Codex CLI, harnesses de agente personalizados. El framework es el Model Context Protocol: un servidor MCP expone el dominio de la app a través de métodos tools/call JSON-RPC; el host LLM descubre las herramientas al inicio de la sesión y las llama por nombre con un payload JSON.4
Lo que la superficie de agente necesita de una capacidad:
- Un contrato JSON-RPC. Nombre de la herramienta, descripción,
inputSchema,outputSchemaopcional. El agente lee la descripción para decidir si llamar; sigue el esquema para formatear los argumentos. - Una descripción útil. El modelo decide cuándo usar la herramienta basándose en su descripción. Trata la descripción como un docstring que esperas que otro desarrollador (el modelo) lea. Las descripciones vagas producen una mala selección de herramienta.
- Errores con dos formas. Los errores de ejecución de la herramienta se devuelven como un bloque de contenido más
isError: trueen el resultado de la herramienta que el modelo lee. Los errores a nivel de protocolo (solicitud malformada, herramienta faltante, fallo de transporte) se devuelven como respuestaserrorJSON-RPC estándar que maneja el host. El autor de la herramienta es dueño del primero; el protocolo es dueño del segundo. - Semántica sin estado o con estado explícito. MCP tiene estado a nivel de protocolo (ciclo de vida de sesión, IDs de sesión en Streamable HTTP), pero la identidad de dominio durable es responsabilidad del lado del servidor, no una garantía a nivel de protocolo. Si el mismo identificador debe significar lo mismo a lo largo de las sesiones, el servidor tiene que hacerlo cumplir.
Lo que la superficie de agente le debe a la capacidad a cambio:
- La autenticación del host, no la del usuario. La confianza viene de quien sea que haya desplegado el servidor MCP. Stdio local del desarrollador: los permisos del sistema de archivos del propio desarrollador. HTTP accesible desde Internet: cualquier autenticación que el servidor imponga. La capacidad tiene que asumir que la afirmación de identidad es la que sea que el servidor le dio.
- Tolerancia a latencia variable. El host puede esperar más que la superficie humana o la superficie de Apple Intelligence. Una llamada de herramienta que tarda treinta segundos es aceptable en la superficie de agente e inaceptable en las otras.
- Sin superficie de renderizado. El resultado es texto o datos estructurados que el modelo interpreta. Sin chrome, sin UI, sin formato del sistema.
La postura de confianza: el servidor MCP es el contrato del desarrollador sobre quién puede llamarlo. Dos despliegues del mismo servidor (stdio local para desarrollo, HTTP en Internet para usuarios finales) tienen posturas de confianza muy distintas y necesitan barreras de protección muy distintas. El protocolo es el mismo; el despliegue es la arquitectura. Cubierto en detalle en App Intents vs MCP: la cuestión del enrutamiento y Cuándo el LLM vive en tu app vs en tus herramientas.5
Los seis ejes en los que las superficies discrepan
Llevar las tres superficies a una tabla comparativa hace concretas las decisiones de arquitectura:
| Eje | Humano | Apple Intelligence | Agente |
|---|---|---|---|
| Identidad del llamador | El usuario (en la app, autenticado por el SO) | El usuario (resuelto por el sistema a través del SO) | La afirmación de identidad del host (impuesta por el servidor) |
| Presupuesto de latencia | Cientos de milisegundos | Segundos (turnos de Siri) | Segundos a decenas de segundos |
| Renderizado | Vistas SwiftUI de la app | Chrome del sistema (banner, tarjeta de Siri, Shortcuts) | Bloques de contenido que el modelo interpreta |
| Descubrimiento | Navegación de la app | Esquema de App Intent leído al instalar | Lista de herramientas devuelta al inicio de la sesión |
| Semántica de persistencia | Estado gestionado por la app | Identidad AppEntity a lo largo de las sesiones |
Gestionada por el servidor; no a nivel de protocolo |
| Formato de error | Alertas, banners, estado de la vista | Lanzamientos AppIntentError + LocalizedError |
Ejec. de herramienta: contenido + isError; protocolo: error JSON-RPC |
Las discrepancias se componen. Una capacidad diseñada para la superficie humana asume latencia ajustada, renderizado rico, errores gestionados por la app. Forzarla a través de Apple Intelligence pierde el control del renderizado y agrega identidad mediada por el SO. Forzarla a través de la superficie de agente pierde el renderizado por completo y desplaza el límite de confianza a quien haya desplegado el servidor. La capacidad tiene que ser remodelada, no solo re-envuelta.
La regla de arquitectura: capa de dominio debajo de las superficies
El patrón que sobrevive a través de las tres superficies es una capa de dominio debajo de ellas. La capa de dominio son funciones simples de Swift: entradas tipadas, salidas tipadas, sin asunciones de protocolo. Cada superficie es un adaptador delgado sobre el dominio. La misma función logWater(amount:caller:) respalda el botón de SwiftUI, el perform() del App Intent y el manejador de la herramienta MCP.
El esbozo (la producción real haría que WaterEntry conformara AppEntity para el retorno del App Intent, inyectaría domain como dependencia en lugar de una referencia de nivel superior, y agregaría el static var title requerido en el intent):
// Domain layer (the actual capability)
func logWater(amount: Measurement<UnitVolume>, at: Date, caller: Caller) throws -> WaterEntry {
try guards.requireWritePermission(caller)
let entry = WaterEntry(amount: amount, timestamp: at)
try store.insert(entry)
return entry
}
// Adapter A: human surface (SwiftUI button)
Button("Log 250ml") {
Task {
let entry = try await domain.logWater(
amount: .init(value: 250, unit: .milliliters),
at: .now,
caller: .human
)
// Update view state, show confirmation animation, etc.
}
}
// Adapter B: Apple Intelligence surface (AppIntent)
struct LogWaterIntent: AppIntent {
static var title: LocalizedStringResource = "Log Water"
@Parameter(title: "Amount") var amount: Measurement<UnitVolume>
func perform() async throws -> some IntentResult & ReturnsValue<WaterEntry> {
let entry = try domain.logWater(amount: amount, at: .now, caller: .siri)
return .result(value: entry) // WaterEntry conforms to AppEntity
}
}
// Adapter C: agent surface (MCP tool handler)
let entry = try domain.logWater(
amount: .init(value: ml, unit: .milliliters),
at: .now,
caller: .mcp(host: hostName)
)
return .text("Logged \(entry.amount) at \(entry.timestamp)")
Tres llamadores. Una función de dominio. La función de dominio toma un parámetro Caller para que pueda hacer cumplir reglas distintas por superficie (límites de tasa, registro de auditoría, requisitos de confirmación) sin que cada superficie tenga que reimplementarlas. Los adaptadores son tontos; el dominio es inteligente.
La forma generaliza el patrón de doble adaptador de App Intents vs MCP; agregar la superficie humana como una tercera clase de llamador es la extensión natural. El LLM en el dispositivo de Foundation Models, cuando se usa dentro de la app, se sitúa en la superficie humana (el usuario invocó una función dentro de la app que resulta llamar al modelo); el LLM en tiempo de ejecución no es una cuarta superficie, es una forma de ejecutar capacidades que ya pertenecen a la superficie humana.6
No toda capacidad sirve a las tres superficies
La exposición equitativa no es el objetivo. Capacidades distintas pertenecen a superficies distintas.
Capacidades que normalmente deberían requerir presencia humana en primer plano. Captura de fotos, autenticación biométrica, ingreso sensible de PII, confirmación de pago, eliminación de cuenta. El humano tiene que estar mirando la pantalla, tiene que dar consentimiento, tiene que autenticarse. Apple Intelligence puede técnicamente traer la app al primer plano y solicitar confirmación; la superficie de agente no tiene una garantía equivalente de presencia. El juicio de producto es que estas capacidades deben ejecutarse como UI en primer plano con una acción explícita y deliberada, no como una llamada silenciosa de Siri o de herramienta en segundo plano.
Capacidades que deberían vivir en las superficies humana + Apple Intelligence. La mayoría de las acciones orientadas al usuario. Registrar agua, iniciar una meditación, agregar un elemento a la lista, muéstrame las entradas del martes. El usuario podría tocar un botón o podría decir “Hey Siri.” Ambas superficies son válidas; ambas deberían alcanzar la misma función de dominio.
Capacidades que deberían vivir en las tres superficies. Integraciones entre procesos. Una lista de compras compartida entre el iPhone del usuario y una sesión de Claude Code que importa recetas. La superficie humana es dueña del uso diario; la superficie de Apple Intelligence es dueña del alcance Siri/Spotlight; la superficie de agente es dueña del flujo de trabajo externo impulsado por desarrollador o por usuario.
Capacidades que deberían vivir solo en la superficie de agente. Importaciones masivas de desarrollador o admin sin un flujo de revisión del usuario final, integraciones con sistemas externos, flujos orquestados por agentes que no tienen expresión en Siri ni dentro de la app. Importar masivamente 500 entradas históricas desde un CSV de un desarrollador durante un backfill puntual. Las importaciones de archivos del usuario final suelen tener un flujo en la superficie humana (Shortcuts puede pasar archivos; un importador dentro de la app puede fragmentar el progreso); el caso solo de agente es el flujo que genuinamente no tiene lugar en ninguna de las otras dos superficies.
La decisión es el diseño. Listar las superficies a las que una capacidad no sirve es tan importante como listar a las que sí.
Lo que construiría diferente
Dos patrones que las apps del cluster o bien envían o bien desearían haber enviado.
Hacer de Caller un tipo de primera clase en la capa de dominio. Cada función pública de dominio toma un argumento Caller. El tipo codifica qué superficie invocó la llamada (.human, .siri, .mcp(host:)). La lógica de dominio se ramifica según él para los prompts de confirmación, los límites de tasa, el registro de auditoría y las puertas de acción sensible. La alternativa (cada superficie reimplementando las reglas) deriva; la versión centralizada se mantiene consistente.
Tratar la cobertura de superficies como una lista de verificación explícita. Al agregar una capacidad, el documento de diseño lista cuáles de las tres superficies deberían exponerla y cuáles deberían rechazarla. La lista de rechazo no es un valor por defecto; es una elección deliberada. Rechazada: superficie de Apple Intelligence, porque la capacidad requiere prueba de atención del usuario que Siri no puede proporcionar. El razonamiento queda registrado; la auditoría detecta la deriva más adelante.
Lo que el patrón significa para apps que se envían en iOS 26+
Tres conclusiones.
-
Tres superficies, tres posturas de confianza. Humano, Apple Intelligence, agente. Cada una tiene obligaciones que las otras no. Diseñar para una y forzarla a las otras produce mala arquitectura en cada superficie.
-
Dominio debajo; adaptadores arriba. Una función de Swift por capacidad; adaptadores delgados por superficie; la función toma un parámetro
Callerpara que pueda hacer cumplir las reglas específicas de cada superficie en un solo lugar. -
No toda capacidad sirve a las tres. Ocultar una capacidad de las superficies que no deberían tenerla es tanto una decisión de diseño como exponerla. La lista de rechazo se gana su lugar.
El cluster completo del Ecosistema Apple: App Intents tipados para la superficie de Apple Intelligence; servidores MCP para la superficie de agente; la cuestión del enrutamiento entre ellos; Foundation Models para funciones de LLM en el dispositivo dentro de la superficie humana; la distinción entre LLM en tiempo de ejecución vs en herramientas; Live Activities para la máquina de estados del Lock Screen de iOS; el contrato del runtime de watchOS en Apple Watch; los internos de SwiftUI para el sustrato de la superficie humana; el modelo mental espacial de RealityKit para escenas de visionOS; la disciplina de esquema de SwiftData para persistencia entre superficies; los patrones de Liquid Glass para la capa visual humana; el envío multi-plataforma para alcance entre dispositivos. El hub está en la Serie del Ecosistema Apple. Para un contexto más amplio de iOS con agentes de LLM, consulta la guía de Desarrollo de Agentes en iOS.
Preguntas frecuentes
¿Cuáles son las tres superficies de una app de iOS?
La superficie humana (vistas SwiftUI, toques, gestos, pantalla), la superficie de Apple Intelligence (App Intents, Siri, Shortcuts, Spotlight) y la superficie de agente (servidores MCP expuestos a hosts LLM externos como Claude Code, Cursor, ChatGPT). Cada una tiene su propia identidad de llamador, presupuesto de latencia, ubicación de renderizado, semántica de persistencia y postura de confianza. Una capacidad que quiere servir a más de una superficie debería ubicarse en una capa de dominio debajo de adaptadores delgados por superficie.
¿Debe exponerse cada capacidad a las tres superficies?
No. Algunas capacidades están correctamente limitadas a una o dos superficies. La captura de fotos, la autenticación biométrica y las confirmaciones de acciones sensibles suelen quedar mejor como flujos en la superficie humana en primer plano, porque las señales de confianza (atención del usuario, acción deliberada) están allí presentes de la forma más fiable. Las operaciones masivas impulsadas por desarrollador pertenecen únicamente a la superficie de agente cuando no existe un flujo de revisión del usuario final. La decisión de diseño es a qué superficies sirve una capacidad y cuáles rechaza.
¿Cuál es la diferencia entre las superficies de Apple Intelligence y de agente?
Apple Intelligence es el agente de primera parte de Apple: el usuario invoca Siri, Shortcuts o Spotlight; el sistema enruta a través de App Intents. La confianza viene del SO. La superficie de agente es cualquier otro host LLM: los desarrolladores ejecutan Claude Code o Cursor, los usuarios finales ejecutan Claude Desktop o ChatGPT. La confianza viene de quien sea que haya desplegado el servidor MCP. Los App Intents son la superficie de protocolo para la primera; MCP es la superficie de protocolo para la segunda.
¿Dónde encaja el LLM en el dispositivo de Foundation Models?
Dentro de la superficie humana. Cuando el usuario invoca una función dentro de la app que llama a Foundation Models, el LLM en tiempo de ejecución es la implementación de una capacidad de la superficie humana, no una cuarta superficie. El LLM en tiempo de ejecución no tiene un llamador propio de Siri ni de host externo. Las herramientas de Foundation Models son la forma en que el modelo en el dispositivo lee/escribe el estado del dominio de la app; el usuario es quien impulsa la llamada.
¿Cómo simplifica el patrón de capa de dominio el código multi-superficie?
Centralizando las reglas. Una función de Swift toma un argumento Caller y hace cumplir el comportamiento específico de cada superficie (prompts de confirmación, límites de tasa, registro de auditoría) en un solo lugar. Cada superficie es un adaptador delgado (binding de SwiftUI, AppIntent.perform, manejador MCP) que traduce el protocolo de la superficie a la función de dominio. La deriva entre superficies se vuelve imposible porque hay una sola fuente de verdad.
Referencias
-
Análisis del autor en De qué está hecho SwiftUI, 30 de abril de 2026, que cubre el árbol de vistas con tipos por valor, el DSL de result-builder y el sustrato debajo de la superficie humana. ↩
-
Análisis del autor en Los App Intents son la nueva API de Apple a tu app, 28 de abril de 2026, que cubre
AppIntent,AppEntity,AppEnumy el modelo de esquema tipado que permite a Apple Intelligence operar la app. ↩ -
Apple Developer, “Framework de App Intents”. Superficie para declarar intents, entidades, parámetros y queries que Apple Intelligence, Siri, Shortcuts y Spotlight pueden enrutar. El descubrimiento es en tiempo de instalación más actualización; la donación e indexación llevan los intents a búsquedas de Spotlight y sugerencias de Siri. ↩
-
Anthropic, “Model Context Protocol” y “Especificación MCP: Tools (2025-06-18)”. Exposición de herramientas JSON-RPC, arquitectura host/servidor, los transportes stdio + Streamable HTTP, e
inputSchema/outputSchemaopcional. ↩ -
Análisis del autor en App Intents vs MCP: la cuestión del enrutamiento, 30 de abril de 2026, y Cuándo el LLM vive en tu app vs en tus herramientas, 1 de mayo de 2026. El encuadre de “despliegue, no protocolo” para la postura de confianza y la distinción entre LLM en tiempo de ejecución y en herramientas. ↩
-
Análisis del autor en LLM en el dispositivo de Foundation Models: el protocolo de Tool, 30 de abril de 2026. El LLM en el dispositivo como una función en tiempo de ejecución que respalda capacidades de la superficie humana; el protocolo
Toolcomo puente entre el modelo dentro de la app y el dominio de la app. ↩