Volver al blog

Novedades de Laravel 13: atributos PHP, AI SDK y passkeys

28 ago 2026 18 min de lecturaLaravel

Qué trae Laravel 13 (17 de marzo de 2026) y por qué es el upgrade más suave de la historia del framework: atributos PHP 8 para declarar modelos, jobs y comandos; el AI SDK ya de primera clase y agnóstico de proveedor; login sin contraseña con passkeys; Reverb con driver de base de datos para tiempo real sin Redis; Cache::touch(); y una guía de migración con cero cambios que rompen.

Novedades de Laravel 13: atributos PHP, AI SDK y passkeys

Laravel 13 salió el 17 de marzo de 2026 con una promesa que suena a contradicción: es a la vez el lanzamiento más aburrido y el más ambicioso en años. Aburrido porque no rompe nada —puedes subir de la 12 a la 13 casi sin tocar código—; ambicioso porque, por debajo de esa calma, mete IA de primera clase en el framework, login sin contraseñas y una forma nueva y más limpia de declarar tus clases. En este recorrido vamos por todo lo que importa, con el código a la vista, y al final te digo cuándo conviene migrar y cuándo esperar.

El requisito de entrada

Laravel 13 sube el mínimo a PHP 8.3 (la 12 pedía 8.2). Es el único requisito duro del salto: si ya corres 8.3 o más, el resto del upgrade es prácticamente cambiar un número en tu composer.json. Volvemos a ello en la sección de migración.

La arquitectura de Laravel en 30 segundos

Antes de entrar en lo nuevo, conviene recordar por dónde viaja una petición: casi todas las novedades de la 13 se enganchan en algún punto de ese recorrido. Toda petición entra por un único archivo (public/index.php), pasa por el kernel, atraviesa la pila de middleware, la resuelve el router hacia un controlador, y este apoya en los modelos de Eloquent antes de devolver una respuesta —que a veces también sale en tiempo real por WebSockets.

Diagrama animado del ciclo de vida de una petición en Laravel: una petición HTTP entra por public/index.php, pasa por el kernel HTTP y la pila de middleware, el router la enruta a un controlador que usa modelos Eloquent y el AI SDK, y devuelve una respuesta; en paralelo, los eventos de broadcasting salen por Reverb hacia el navegador por WebSocket. Se resaltan los puntos que toca Laravel 13: atributos en los modelos, el AI SDK en el controlador y el driver de base de datos de Reverb

Diagrama animado (versión vertical para móvil) del ciclo de vida de una petición en Laravel 13: los pasos se apilan de arriba abajo —Navegador, index.php, Kernel más middleware, Router, Controller y Response— y un paquete recorre el pipeline hacia abajo; debajo, las novedades de Laravel 13 en el recorrido: atributos PHP en Eloquent, el AI SDK y Reverb con driver de base de datos; una flecha de WebSocket devuelve el tiempo real al navegador

Con ese mapa en la cabeza, las novedades dejan de ser una lista suelta: los atributos ordenan tus modelos y jobs, el AI SDK vive en tus controladores y servicios, los passkeys blindan la puerta de entrada, y Reverb cambia cómo sale la respuesta en tiempo real. Vamos una por una.

Atributos PHP: menos ruido en tus clases

Es el cambio de developer experience más visible de la 13. Durante años, configurar un modelo, un job o un comando significó declarar propiedades protegidas al inicio de la clase: $table, $fillable, $hidden, y así. Laravel 13 añade una alternativa con atributos de PHP 8 en alrededor de quince lugares del framework: modelos, jobs, comandos, listeners, notificaciones, mailables, form requests, resources y factories, entre otros.

Lo importante: es opcional y retrocompatible. Las propiedades de toda la vida siguen funcionando exactamente igual; los atributos son azúcar sintáctico para quien quiera declarar la intención arriba, sobre la clase, en lugar de dentro.

La configuración del modelo sube a la cabecera de la clase, y el cuerpo queda para la lógica de negocio.

php
use Illuminate\Database\Eloquent\Attributes\{Table, Fillable, Hidden};
use Illuminate\Database\Eloquent\Model;

#[Table('invoices')]
#[Fillable('amount', 'status', 'user_id')]
#[Hidden('internal_notes')]
class Invoice extends Model
{
    // La lógica de negocio se ve de inmediato, sin propiedades de configuración arriba.
}

El equivalente clásico —que sigue siendo válido— era declarar protected $table, protected $fillable y protected $hidden. Hay atributos para casi todo lo habitual: #[Guarded], #[Appends], #[Connection], #[Touches] y #[Visible], entre otros.

Diagrama de clases comparando dos formas de declarar un modelo en Laravel 13: a la izquierda, el estilo clásico con propiedades protegidas table, fillable y hidden; a la derecha, el estilo con atributos PHP 8 Table, Fillable y Hidden sobre la clase. Ambos producen el mismo modelo; los atributos solo cambian dónde y cómo se declara la configuración

No es una migración obligatoria

No tienes que reescribir tus modelos. Los atributos brillan en clases nuevas o cuando quieres que la configuración salte a la vista; en un proyecto grande puedes adoptarlos poco a poco, o no adoptarlos. Conviven sin fricción con el estilo de propiedades.

El AI SDK ya es de primera clase

La novedad estrella. El Laravel AI SDK, que venía como paquete en beta, ahora es un componente estable y de primera clase del framework, y —clave— es agnóstico de proveedor: hablas con Anthropic, OpenAI, Gemini y otros con la misma API, y cambiar de uno a otro es cambiar un valor de configuración, no reescribir código.

Primero configuras tus proveedores. Las claves viven en el .env y el SDK trae config/ai.php:

php
// config/ai.php
'providers' => [
    'anthropic' => [
        'driver' => 'anthropic',
        'key'    => env('ANTHROPIC_API_KEY'),
    ],
    'openai' => [
        'driver' => 'openai',
        'key'    => env('OPENAI_API_KEY'),
    ],
],

El SDK organiza el trabajo en agentes. Generas uno con Artisan y describes su comportamiento en instructions():

bash
php artisan make:agent SalesCoach
php
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Promptable;

class SalesCoach implements Agent
{
    use Promptable;

    public function instructions(): string
    {
        return 'Eres un coach de ventas experto. Respondes breve y accionable.';
    }
}

Y lo usas donde lo necesites —un controlador, un job, un comando— con prompt():

php
$respuesta = (new SalesCoach)->prompt('Dame tres ideas para reactivar clientes dormidos.');

return (string) $respuesta;

Para algo rápido, ni siquiera necesitas una clase

Si solo quieres una respuesta puntual, el helper agent() evita crear un agente completo:

php
use function Laravel\Ai\agent;

$respuesta = agent(
    instructions: 'Eres experto en desarrollo de software.',
)->prompt('Explica en dos frases qué es una cola de trabajos.');

Failover entre proveedores

Aquí es donde el diseño agnóstico paga. Con un atributo declaras un orden de respaldo: si el proveedor principal falla —cae, te limita por rate limit o da error—, el SDK reintenta con el siguiente, sin que tu código se entere.

php
use Laravel\Ai\Attributes\{Provider, Model};
use Laravel\Ai\Enums\Lab;

#[Provider([Lab::Anthropic, Lab::OpenAI])] // primero Anthropic; si falla, OpenAI
#[Model('claude-sonnet-4-6')]
class SalesCoach implements Agent
{
    use Promptable;

    public function instructions(): string
    {
        return 'Eres un coach de ventas experto.';
    }
}

Diagrama de secuencia del failover del AI SDK de Laravel 13: la aplicación llama al método prompt del agente; el agente intenta primero con el proveedor Anthropic; si Anthropic responde con error o rate limit, el agente reintenta automáticamente con OpenAI usando el mismo mensaje; el proveedor que responda devuelve el texto al agente y este a la aplicación, ilustrando que el cambio de proveedor es transparente para el código

Salida estructurada y RAG

Cuando no quieres texto libre sino un objeto con forma fija, tu agente implementa HasStructuredOutput y declara un esquema. El SDK te devuelve datos validados, con acceso tipo arreglo:

php
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Laravel\Ai\Contracts\{Agent, HasStructuredOutput};
use Laravel\Ai\Promptable;

class LeadScorer implements Agent, HasStructuredOutput
{
    use Promptable;

    public function instructions(): string
    {
        return 'Evalúas la calidad de un lead comercial.';
    }

    public function schema(JsonSchema $schema): array
    {
        return [
            'score'    => $schema->integer()->min(1)->max(10)->required(),
            'feedback' => $schema->string()->required(),
        ];
    }
}

$resultado = (new LeadScorer)->prompt('Empresa mediana, presupuesto claro, decisor identificado.');

return $resultado['score']; // acceso como arreglo

Y para retrieval-augmented generation tienes embeddings de primera clase, con un ayudante muy a la mano sobre Str:

php
use Illuminate\Support\Str;
use Laravel\Ai\Embeddings;

// Un texto suelto
$vector = Str::of('Napa Valley produce excelente vino.')->toEmbeddings();

// Varios de una vez
$respuesta = Embeddings::for([
    'Napa Valley produce excelente vino.',
    'Laravel es un framework de PHP.',
])->generate();

Un SDK, no solo un cliente

El AI SDK no es un simple envoltorio de la API de un proveedor: trae agentes con herramientas (tools), sub-agentes, búsqueda por similitud para RAG (SimilaritySearch), streaming de respuestas, memoria de conversación y aprobación humana de acciones sensibles. Aquí vimos lo esencial; la documentación oficial cubre el resto.

Passkeys: adiós a las contraseñas

Una de las funciones más pedidas por la comunidad. Laravel 13 integra autenticación con passkeys (WebAuthn) directamente en Fortify y en los starter kits: tus usuarios pueden entrar sin contraseña usando Touch ID, Face ID, Windows Hello o una llave física de seguridad.

La idea de fondo es criptografía de clave pública. Al registrarse, el dispositivo del usuario genera un par de claves: la privada nunca sale del dispositivo (protegida por su biometría o PIN), y la pública se guarda en tu base de datos. Para iniciar sesión, tu servidor lanza un reto aleatorio, el dispositivo lo firma con la clave privada, y tu servidor verifica esa firma con la clave pública que ya tenía. Nunca viaja un secreto reutilizable, así que el phishing y las filtraciones de contraseñas dejan de aplicar.

Diagrama de secuencia de la autenticación con passkeys (WebAuthn) en Laravel 13, en dos fases. Registro: el navegador pide un reto a Fortify, el dispositivo genera un par de claves, guarda la privada de forma segura y envía la pública, que Fortify almacena en la base de datos. Autenticación: Fortify envía un reto aleatorio, el dispositivo lo firma con la clave privada tras la verificación biométrica, y Fortify valida la firma con la clave pública almacenada y concede la sesión. La clave privada nunca sale del dispositivo

Qué cubre lo integrado

El soporte que viene en los starter kits resuelve el caso estándar: registrar un passkey y usarlo para entrar, sin instalar nada extra. Para escenarios avanzados —gestión de varios dispositivos por usuario, políticas finas— sigue habiendo paquetes especializados de WebAuthn en el ecosistema, pero para la mayoría de las apps lo de serie basta.

Reverb con driver de base de datos

Reverb es el servidor WebSocket propio de Laravel para tiempo real (notificaciones en vivo, presencia, chats). Hasta ahora, escalarlo a varios procesos exigía Redis como capa de coordinación. Laravel 13 añade un driver de base de datos: puedes usar tu MySQL o PostgreSQL de siempre para ese escalado horizontal, sin sumar Redis a tu infraestructura.

php
// config/reverb.php
'scaling' => [
    'driver' => 'database', // usa tu MySQL/PostgreSQL en lugar de Redis
],

Diagrama de componentes del driver de base de datos de Reverb en Laravel 13: varios navegadores mantienen conexiones WebSocket con dos nodos de Reverb; ambos nodos se coordinan a través de la base de datos MySQL o PostgreSQL existente en lugar de Redis, permitiendo escalado horizontal del broadcasting en tiempo real sin añadir Redis a la infraestructura

Hasta dónde llega

El driver de base de datos está pensado para apps que quieren tiempo real sin la complejidad de Redis, típicamente por debajo de unos mil conexiones concurrentes. Si tu carga es alta y sostenida, Redis sigue siendo la opción de mayor rendimiento para la coordinación entre nodos. Es una puerta de entrada más barata, no un reemplazo universal.

Un extra pequeño y muy útil: Cache::touch()

A veces solo quieres renovar el tiempo de vida de una entrada en caché sin volver a leer ni reescribir su valor —piensa en una sesión que quieres mantener viva mientras el usuario está activo. Antes, eso implicaba un ciclo de leer y volver a guardar:

php
// Antes: dos operaciones y transferir todo el valor de ida y vuelta
$valor = Cache::get('user_session:123');
Cache::put('user_session:123', $valor, now()->addHour());

Laravel 13 lo resuelve con Cache::touch(), que extiende el TTL en una sola operaciónEXPIRE en Redis, TOUCH en Memcached, un UPDATE en base de datos—, sin mover el valor:

php
// Ahora: una sola operación, sin transferir el valor
Cache::touch('user_session:123', 3600); // 3600 s de nuevo TTL

Devuelve true si la clave existía y false si no. Un detalle pequeño, pero que en rutas calientes ahorra ancho de banda y viajes de ida y vuelta.

Migrar a Laravel 13

La gran noticia operativa: cero cambios que rompen. El salto de la 12 a la 13 es, para la mayoría de proyectos, cuestión de minutos.

Sube a PHP 8.3 o superior

Es el único requisito duro. Verifica tu versión con php -v y actualiza el entorno (local, CI y producción) si aún corres 8.2.

Apunta a la versión 13 en composer.json

Ajusta la restricción del framework y actualiza dependencias.

json
"require": {
    "php": "^8.3",
    "laravel/framework": "^13.0"
}
bash
composer update

Corre tu suite de pruebas

Al no haber cambios que rompan, tus tests deberían pasar sin tocarse. Si algo falla, casi siempre será por un paquete de terceros que todavía no declara compatibilidad con la 13, no por el framework.

Adóptalo ya si…

Ya corres PHP 8.3, tus dependencias principales están al día y quieres empezar limpio: proyectos nuevos, o apps con buena cobertura de tests donde el upgrade es de bajo riesgo. Si además vas a tocar IA, tiempo real o autenticación, la 13 te da esas piezas de serie.

Espera un poco si…

Dependes de paquetes de terceros que aún no publican compatibilidad con la 13, o sigues atado a PHP 8.2 por tu infraestructura. No hay prisa: la 12 tiene soporte por buen tiempo, y el upgrade seguirá siendo suave cuando tus dependencias se pongan al día.

La ventana de soporte

Laravel 13 recibirá corrección de errores hasta el tercer trimestre de 2027 y parches de seguridad hasta el primer trimestre de 2028. Tiempo de sobra para planear el salto con calma.

Cierre

Laravel 13 acierta en el equilibrio difícil: avanza sin castigarte. Te da IA de primera clase, autenticación sin contraseñas y tiempo real más barato, y a la vez te deja subir de versión casi sin abrir el código. Esa es la marca de un framework maduro —el que entiende que la mejor característica nueva es la que no te obliga a reescribir lo que ya funciona. Si estabas posponiendo el salto por miedo a la factura de un major, esta vez la excusa se quedó sin fundamento.

¿Planeando tu salto a Laravel 13 o una app con IA?

Si estás evaluando cómo integrar el AI SDK, mover tu tiempo real a Reverb o migrar un proyecto grande sin sobresaltos, hablemos. Puedes ver cómo trabajo en la página de servicios.


Fuentes

Foto de Marco Torres

Escrito por

Marco Torres

Desarrollador Full-Stack senior con DevOps y arquitectura cloud, y Bachiller en Ingeniería de Sistemas. Escribo sobre arquitectura escalable y las lecciones de llevar sistemas a producción — desde la trinchera.