This content originally appeared on DEV Community and was authored by Antonio Manuel Pérez López
Más allá de la aplicación web tradicional
Como desarrollador con décadas de experiencia, he sido testigo y protagonista de la evolución de la web: desde los monolitos renderizados en servidor, pasando por la revolución de las SPAs (Single-Page Applications) con AJAX, hasta el auge de los frameworks de componentes como React. Cada etapa trajo consigo nuevos patrones de diseño, desafíos de rendimiento y abstracciones. Hoy, nos encontramos en el umbral de una transformación de similar magnitud: la era de las aplicaciones de IA nativas.
Este capítulo no pretende enseñarte a programar (seguramente no sería un buen ejemplo a seguir). Su objetivo es investigar un nuevo modelo mental arquitectónico. Las aplicaciones que integraremos con Inteligencia Artificial Generativa no son simplemente aplicaciones tradicionales con una API de LLM atornillada. Requieren un enfoque fundamentalmente diferente en cuanto a la renderización, el manejo del estado, la validación de datos y la comunicación entre cliente y servidor. Las herramientas que hemos elegido —Next.js con App Router, TypeScript en su máxima expresión y el Vercel AI SDK— no son meras preferencias, sino decisiones arquitectónicas deliberadas que responden a los desafíos únicos de este nuevo paradigma.
Abordaremos tres pilares fundamentales:
- La arquitectura de renderizado de Next.js: Cómo los React Server Components (RSC) nos permiten crear interfaces más rápidas y seguras, un requisito indispensable para las costosas y, a menudo, lentas inferencias de los modelos de IA.
- TypeScript como contrato de sistema: Cómo usamos tipos avanzados y validación con Zod no solo para la seguridad, sino para definir un "contrato" estricto con una entidad no determinista como es un LLM.
- Vercel AI SDK como capa de comunicación: Cómo una capa de abstracción bien diseñada nos permite mantener la agilidad y evitar el acoplamiento a un único proveedor de IA en un ecosistema que evoluciona a una velocidad vertiginosa.
Prepárate para reevaluar algunos patrones establecidos y adoptar un nuevo conjunto de herramientas mentales. Empecemos.
Arquitectura avanzada en Next.js: El paradigma de los React Server Components (RSC)
El App Router de Next.js no es una simple mejora sobre el Pages Router; es un cambio de paradigma completo que devuelve gran parte de la lógica de renderizado al servidor, donde siempre debió estar para ciertas tareas. Para nosotros, como arquitectos de aplicaciones de IA, esto tiene implicaciones profundas.
El dúo dinámico: Server Components vs. Client Components
El modelo mental clave a interiorizar es que, por defecto, todo es un Server Component. Un RSC es un fragmento de UI que se ejecuta exclusivamente en el servidor, una única vez durante el ciclo de vida de la petición. Su resultado es una descripción de la UI (un formato intermedio similar a HTML) que se envía al cliente.
Características clave de los Server Components (RSC):
- Javascript de cliente cero: No envían ni una sola línea de su propio código JavaScript al navegador. Esto resulta en un TTI (Time to Interactive) drásticamente reducido.
- Acceso directo al backend: Pueden acceder directamente a recursos del servidor (bases de datos, sistemas de archivos, APIs internas, variables de entorno secretas) sin necesidad de una capa de API intermedia. Esto es revolucionario para la IA, ya que nos permite obtener contexto o ejecutar lógica de backend directamente desde el componente que lo necesita.
- Renderizado asíncrono: Pueden ser funciones
async
. Esto permite realizar operaciones de datos (ej.fetch
, consultas a BBDD) y esperar su resolución antes de completar el renderizado.
Por otro lado, cuando necesitamos interactividad (manejar eventos, estado, hooks de ciclo de vida), marcamos un componente con la directiva "use client"
. Esto no convierte solo a ese componente en un Client Component, sino que establece una frontera: ese componente y todos los que importe (que no sean a su vez RSC) formarán parte del bundle de JavaScript que se envía al cliente para su hidratación.
Patrones de composición para aplicaciones de IA
La maestría no reside en saber qué es un RSC o un Client Component, sino en saber cómo combinarlos. Para las aplicaciones de IA, estos patrones son cruciales:
- Patrón de "Cáscara Estática, Contenido Dinámico" (Static Shell, Dynamic Content): La estructura principal de la aplicación (layout, navegación, cabeceras) se define como RSCs. Son estáticos, se cargan instantáneamente y no cambian. Dentro de esta cáscara, las áreas interactivas (como una ventana de chat o un formulario de prompt) se definen como Client Components. Esto nos da lo mejor de ambos mundos: una carga inicial ultrarrápida y una interactividad rica donde se necesita.
- Streaming de UI con Suspense: Las respuestas de los LLMs pueden tardar varios segundos en empezar a generarse (Time To First Token). Hacer que el usuario espere a que toda la página cargue es inaceptable. Los RSC se integran nativamente con
Suspense
. Podemos envolver un componente RSC que realiza una llamada a un LLM en unSuspense
con unfallback
(p. ej., un spinner). Next.js enviará inmediatamente el HTML de la página con el spinner, y cuando la llamada al LLM resuelva, streameará la UI resultante para reemplazar el spinner, sin necesidad de una recarga de página. - Server Actions: Mutaciones sin API boilerplate: Son funciones asíncronas que se definen en el servidor (en un RSC o en un archivo con
"use server"
) pero que se pueden invocar directamente desde un Client Component. Simplifican radicalmente las mutaciones de datos. En nuestro contexto, una Server Action es la forma perfecta de manejar el envío de un prompt desde un formulario en un Client Component a nuestra lógica de backend que llamará a la IA, sin tener que escribir manualmente unfetch
a un endpoint de API.
Diagrama arquitectónico conceptual:
Dominar esta arquitectura es el primer paso para construir aplicaciones de IA que sean robustas y ofrezcan una experiencia de usuario excepcional.
TypeScript para expertos: Blindando la interfaz con la IA
Si tienes experiencia en javascript seguro que has visto cómo los sistemas de tipos han pasado de ser una curiosidad académica a una herramienta indispensable en sistemas a gran escala. En el desarrollo de IA, TypeScript trasciende la mera seguridad de tipos para convertirse en una herramienta de diseño de contratos. Nuestra interacción con un LLM es, por naturaleza, una comunicación con un sistema no determinista. Nuestro trabajo como ingenieros es imponer determinismo y estructura sobre esa interacción.
Inferencia y genéricos para abstracciones reutilizables
No nos detendremos en la sintaxis básica. En cambio, nos centraremos en cómo los genéricos avanzados nos permiten construir abstracciones robustas. Por ejemplo, podemos crear una función de envoltura para las llamadas a la IA que maneje la validación, el logging y los errores de forma genérica, sin importar la forma (schema) de la respuesta esperada:
async function safeAICall<T extends z.ZodType>(
prompt: string,
schema: T
): Promise<{ success: true, data: z.infer<T> } | { success: false, error: string }> {
// ... lógica de llamada a la IA ...
// ... validación de la respuesta contra el schema ...
// Devolvemos un tipo discriminado seguro
}
Este patrón nos permite manejar diferentes "formas" de respuesta de la IA de una manera completamente type-safe.
Zod: El contrato inmutable entre humano y máquina
zod
es la pieza central de nuestra estrategia de validación. Lo tratamos como la única fuente de verdad para la estructura de los datos que fluyen hacia y desde el LLM.
- Definición del Schema: Un schema de Zod es más que una validación; es una declaración de intenciones. Define la estructura exacta que esperamos.
- Inferencia de tipos (
z.infer
): La magia de Zod reside enz.infer<typeof miSchema>
. Esto nos permite derivar automáticamente un tipo de TypeScript estático a partir de un validador de runtime. Se acabaron las definiciones de tipos duplicadas y la desincronización entre la validación y el tipado estático. - El Método
.describe()
: A menudo subestimado, el método.describe()
es crucial en el desarrollo con IA. Cuando en capítulos posteriores pidamos al LLM que genere JSON estructurado, las descripciones que proporcionamos en el schema de Zod actúan como "hints" o instrucciones para el modelo, mejorando drásticamente la calidad y fiabilidad de su salida.
Flujo de datos validado:
Este doble filtro, en la entrada y en la salida, es nuestra principal línea de defensa contra respuestas inesperadas o malformadas del LLM, garantizando que el resto de nuestra aplicación siempre opere sobre datos predecibles y seguros.
Vercel AI SDK Core: La capa de comunicación unificada
El ecosistema de la IA generativa está en un estado de cambio constante. Los modelos se actualizan, nuevos proveedores emergen y los precios fluctúan. Acoplar nuestra lógica de negocio directamente a la API de un proveedor específico (sea OpenAI, Google, Anthropic, etc.) es una receta para la obsolescencia técnica y la rigidez.
El Vercel AI SDK nos proporciona una capa de abstracción esencial que nos aísla de esta complejidad.
El principio "proveedor agnóstico"
La belleza del AI SDK radica en su simplicidad. Cambiar de un modelo de Google a uno de Anthropic (suponiendo capacidades similares) es, idealmente, un cambio de una sola línea:
// De:
const model = google('gemini-2.5-pro');
// A:
const model = anthropic('claude-3-opus-20240229');
Esta abstracción nos permite experimentar, comparar y pivotar entre proveedores con un coste de ingeniería mínimo, una capacidad estratégica en este campo.
Anatomía de generateText
generateText
es nuestra herramienta de trabajo fundamental para interacciones simples y no conversacionales. Su firma encapsula los elementos esenciales de una llamada a un LLM:
const { text, usage, finishReason } = await generateText({
model: google('gemini-2.5-pro'),
system: 'Eres un asistente experto en literatura del Siglo de Oro.',
prompt: 'Analiza la métrica del primer soneto de Garcilaso.',
});
-
model
: La instancia del modelo que hemos elegido, abstraída por el SDK. -
system
: El "system prompt" es nuestra oportunidad para dar al modelo una personalidad, un contexto y unas reglas de comportamiento generales que aplicarán a toda la interacción. Es una de las herramientas más potentes del prompt engineering. -
prompt
: La instrucción específica para esta llamada.
El objeto devuelto nos da no solo el text
generado, sino también metadatos valiosos como usage
(el recuento de tokens, crucial para el control de costes) y finishReason
(por qué el modelo dejó de generar texto).
El poder del streaming con streamText
Para cualquier aplicación interactiva, el streaming no es una opción, es una necesidad. streamText
es la contraparte asíncrona de generateText
. En lugar de esperar a que la respuesta completa esté disponible, nos devuelve un AsyncIterable
que podemos consumir a medida que los "tokens" llegan desde el servidor.
Esto se integra perfectamente con la arquitectura de RSC y Suspense que discutimos. En el backend, un Route Handler puede usar streamText
y devolver el stream directamente. En el frontend, el hook useChat
(que veremos en el próximo capítulo) consumirá este stream para renderizar la respuesta de forma progresiva, mejorando drásticamente la experiencia de usuario percibida.
Conclusiones de la parte teórica
Hemos sentado las bases. No hemos escrito una aplicación de IA completa todavía, pero hemos hecho algo más importante: hemos establecido una arquitectura robusta y un modelo mental preparado para los desafíos que nos esperan.
Hemos entendido que la combinación de renderizado en servidor (RSC) para la estructura, validación estricta de contratos (TypeScript/Zod) para los datos y una capa de comunicación agnóstica (Vercel AI SDK) para la lógica de IA, nos proporciona la flexibilidad, seguridad y rendimiento necesarios para construir aplicaciones de IA de nivel profesional.
Con estos cimientos en su sitio, estamos listos para construir nuestra primera aplicación interactiva. En los próximos capítulos, tomaremos estos conceptos y los aplicaremos para crear un chatbot en tiempo real, manejando el streaming de principio a fin.
This content originally appeared on DEV Community and was authored by Antonio Manuel Pérez López

Antonio Manuel Pérez López | Sciencx (2025-08-26T21:28:01+00:00) Fundamentos modernos y primera interacción con IA. Parte 1. Retrieved from https://www.scien.cx/2025/08/26/fundamentos-modernos-y-primera-interaccion-con-ia-parte-1/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.