Saltar al contenido

Soy usuario de Claude Max. Lo uso a diario en Zed Editor mientras programo y casi nunca había sentido la necesidad de probar otra cosa. Me cuadra el plan Max de 90€, me cuadra el flujo, me cuadran los resultados.

Pero el 23 de abril salió GPT-5.5 y el ruido fue importante. Que si lidera Terminal-Bench 2.0 con un 82.7%. Que si SWE-Bench Pro. Que si el modelo más capaz de OpenAI hasta la fecha. Lo normal cuando lanzan algo nuevo. Pagué los 23€ del plan Plus, lo conecté a Zed, y me lancé a usarlo en serio durante una semana en un proyecto Laravel mediano.

Esto es lo que ha pasado. Lo bueno, lo malo, y lo que me llevó a montar un experimento controlado para zanjar la cuestión, que puedes ver entero aquí: github.com/cursosdesarrolloweb/distributed-rate-limiter-llm-comparison.

Por qué quise probar GPT-5.5

No fue capricho. Cuando alguien lanza un modelo y dice que es state-of-the-art, la pregunta es si lo es para tu trabajo concreto. No para benchmarks publicados, no para tareas que el modelo ha visto en entrenamiento. Para mi día a día con Laravel, PHPStan, PHPUnit, Sail, refactors largos y decisiones de arquitectura.

Los benchmarks oficiales no responden a eso. Los reviews tipo "10 cosas que GPT-5.5 hace genial" tampoco. Necesitaba probarlo yo mismo en mi día a día.

Tampoco es la primera vez que hago este ejercicio. Cuando salió GPT-5 Codex ya monté una comparativa contra Claude Sonnet 4.5 refactorizando un controlador Laravel y los resultados ya apuntaron por dónde iban los tiros. Pero GPT-5.5 es modelo nuevo, y todo modelo nuevo merece una nueva revisión.

Una semana de uso real

Lo más útil que puedo contar es lo que no aparece en los anuncios. Las cosas pequeñas que solo descubres cuando llevas días seguidos pidiéndole tareas y midiendo qué tal lo hace.

El plan Plus se queda corto

Esto fue lo primero que me molestó, aunque hoy en día ya nada me sorprende. El plan Plus cuesta 23€ al mes, es el equivalente al plan Pro de Claude, el cual cuesta 18€ al mes. Suena razonable hasta que descubres que te dura una hora y media de uso intenso, como mucho. Después, ventana de espera. Si estás en mitad de un refactor o de una sesión de pair programming, te toca cerrar y volver al cabo de horas o arremangarte y darlo todo.

Y si subes el modelo a Xhigh, ahí ya no llegas ni a 30 minutos. Es imposible mantener un ritmo de trabajo serio.

Dicho esto, el plan Pro de Claude está igual o peor que el plan Plus de OpenAI. Utilizar el modelo Opus 4.7 con el plan Pro de Claude apenas te da para 40 minutos en un proyecto sencillito... Me parece sinceramente ridículo y abusivo por ambas partes, OpenAI y Claude.

Yo actualmente uso Claude Max (x5) 90€, donde el margen para trabajar de seguido es muy amplio. Que con GPT-5.5 Plus me topara con el límite a media tarde fue una sorpresa desagradable. Pero aquí no veo distinciones con Opus 4.7.

Es lento razonando

GPT-5.5 normalmente piensa mucho antes de responder. Cuando le mandas una tarea no trivial, se queda dándole vueltas un buen rato antes de empezar a escribir. En tareas complejas, la espera se alarga.

Pensar antes de actuar está bien. Pero la lentitud es real y se nota cuando vienes de un modelo más fluido. En sesiones cortas no importa. En sesiones largas, te roba ritmo.

Zed Editor: te lo crea todo sin preguntar (¡el modo Read Only sí funciona!)

Esta fue la sorpresa más grande, y la peor. Cuando uso Claude en Zed, antes de crear o modificar archivos me pregunta si quiero aceptar el cambio. Lo veo, lo apruebo o lo rechazo. Es un workflow seguro.

Con GPT-5.5 en Zed, no pregunta. Lo crea directamente. Genera archivos, modifica los existentes, reemplaza código sin pedir confirmación. La primera vez que me pasó pensé que era cosa mía. La segunda, que era un bug. La tercera, entendí que era el comportamiento por defecto.

No sé si es problema del modelo, de la integración de Zed con OpenAI, o de cómo OpenAI expone su API agéntica. Pero el efecto práctico es que pierdes control sobre tu repositorio. Si el modelo se equivoca, ya está en disco. A revisar con git diff, esperando que no haya tocado lo que no querías.

Dicho esto, por fin descubrí qué sucedía. En Zed Editor, tienes 3 modos con GPT, Read Only, Default y Full Access. El modo Default pensaba yo que era para trabajar "normalmente", iluso de mi... Parece ser que para que no lo haga todo en piloto automático sin preguntar, debes trabajar en modo Read Only, donde sí escribe archivos y lo hace todo, pero siempre preguntando. Es raro utilizar el término "Read Only" cuando sí puede escribir, pero en fin, aprendí algo que me sirvió mucho...

El entorno de sandbox de GPT

Otro detalle que me costó entender. Como ya he dicho, Zed con GPT ofrece tres modos de permisos: Read Only, Default y Full Access. En el modo Default, la primera vez que le pides ejecutar un comando con Sail, GPT-5.5 te responde que no tiene Sail disponible, que está en un entorno sandbox, que no puede garantizar que el comando funcione.

Si le dices que sí existe, entonces lo usa. Pero eso hay que repetirlo en cada sesión. Es engorroso. La única manera de evitar esto, por lo menos la que yo he encontrado, ha sido utilizando el modo Full Access, donde entonces no te pregunta, pero ese modo permite al agente salir de tu proyecto y poder ejecutar cualquier acción, así que mucho ojo con esto...

Claude nunca me ha hecho pasar por ese paso. Asume el entorno y sigue. GPT-5.5 te obliga a luchar contra su prudencia o ponerlo en modo Full Access., obviamente, prefiero la primera opción, prudencia ante todo con la IA.

Lo que sí hace bien

No todo es malo. Hay cosas concretas donde GPT-5.5 brilla:

  • Razonamiento de sistemas: cuando le planteas una arquitectura compleja, da respuestas con detalles que otros modelos pasan por alto.

  • Sintaxis moderna: usa property promotion, readonly, named arguments, match expressions de PHP 8.3 sin necesidad de recordárselo.

  • Detalles operacionales: variables de entorno bien pensadas, defensa en profundidad en validaciones, atención a la observabilidad.

Cuando funciona, funciona bien. El problema es cuándo funciona, los límites del plan, la lentitud y la fricción del workflow.

De la anécdota al método

Una semana de uso es valioso pero subjetivo. Para zanjar la cuestión necesitaba algo más sólido: un experimento controlado, mismo prompt, mismo problema, comparando los dos modelos a igualdad de condiciones. Y de paso metí un tercero, GLM-5.1, porque es open-weight y tenía curiosidad por ver dónde queda.

El reto que elegí: implementar un rate limiter distribuido en Laravel. No el throttle de toda la vida que cualquier modelo te escribe en 30 segundos. Uno serio, con scripts Lua atómicos en Redis, dos algoritmos (token bucket y sliding window), tests de concurrencia con pcntl_fork reales, y decisiones explícitas de fail-open vs fail-closed.

Es exactamente el tipo de tarea donde un modelo competente y un modelo con cicatriz se separan.

Por qué este reto y no otro

El throttle de Laravel hace dos operaciones separadas: lee el contador y, si está por debajo del límite, lo incrementa. Entre el paso 1 y el paso 2 hay un hueco de microsegundos donde otra request puede colarse. Bajo concurrencia real, el límite se sobrepasa. Para casos triviales no importa. Para endpoints donde cada llamada cuesta dinero (APIs de IA, pasarelas de pago) o donde el límite es contractual, importa mucho.

La solución correcta es meter la lógica dentro de un script Lua que Redis ejecuta atómicamente, sin dejar que nadie se cuele en medio. Pero esto abre una caja de complejidades:

  • Clock skew entre servidores distribuidos

  • Dos algoritmos distintos con trade-offs reales

  • Decisión de qué hacer si Redis se cae (¿dejar pasar todo? ¿rechazar todo?)

  • Tests de concurrencia que de verdad detecten race conditions

  • Detalles de producción como el reset de la conexión Redis tras pcntl_fork, hash tags para Redis Cluster, fallback EVALSHA cuando Redis se reinicia, SIGKILL en hijos PHPUnit para que no reentren los shutdown handlers

Cada uno de estos detalles separa a un modelo que ha visto producción de uno que solo ha leído tutoriales.

El prompt

Mismo prompt para los tres, en sesión limpia, sin contexto previo. La instrucción clave: antes de escribir código, listar asunciones y qué le preguntarías a un staff engineer. Es el filtro de disciplina que separa al que se lanza a teclear del que para a pensar.

Lo demás del prompt: dos algoritmos configurables, Lua atómico, redis.call('TIME') para evitar clock skew, middleware HTTP y uso programático, tests PHPUnit con paralelismo real, y documentación de fail-open vs fail-closed con justificación.

Tienes el prompt completo en el README del repositorio por si quieres replicarlo cuando salga el siguiente modelo.

Lo que entregó cada modelo

Claude Opus 4.7

Antes de escribir una línea de código, paró. Listó diez preguntas afiladas, clasificadas explícitamente entre "voy a asumir" y "necesito respuesta". Topología Redis. Granularidad de claves. Cabeceras IETF draft o legacy. Cost variable o siempre 1. Observabilidad. Tests en CI con extensión pcntl. Y cerró con propuesta concreta:

Si confirmas que tira por fail-open por defecto + override fail-closed por instancia, cost configurable (default 1), cabeceras IETF draft, y single-node Redis, procedo a implementar.

Esto es comportamiento de senior real. No bloquea con preguntas, identifica las dos críticas, asume el resto con defaults razonables, propone un plan para desbloquear. Cuando le confirmé, entregó la implementación completa con un detalle que ningún otro modelo mostró: un test que se valida a sí mismo.

El planteamiento merece la pena explicarlo. El test atómico afirma que un limiter correcto nunca pasa más requests de las permitidas. Bien. Pero ¿cómo sabes que el test detecta race conditions de verdad y no es teatro? Opus añadió una segunda pieza: un BrokenTokenBucketLimiter deliberadamente roto (operaciones no atómicas, con un usleep aleatorio para agrandar la ventana TOCTOU) y un meta-test que afirma que ese sí debe sobrepasar la capacidad. Si algún día deja de sobrepasarla, salta la alarma: el harness ha perdido sensibilidad, los otros tests han dejado de probar concurrencia real, alguien tiene que investigar.

Esto no son tests. Es mutation testing automatizado y permanente dentro de la suite. No documentación de "cómo deberías verificar el test si te apetece". Verificación ejecutable que vive en el repositorio y se ejecuta en cada CI run.

Otros detalles que mostraron cicatriz:

  • SIGKILL en los hijos forkeados, con un comentario explicando que sin eso, los shutdown handlers de PHPUnit se ejecutan en cada hijo y el output del test queda destrozado. Solo lo escribe alguien que ha sufrido el bug.

  • Doble Redis::purge, antes y después del fork, para que padre e hijos no compartan el mismo socket TCP.

  • Cálculo correcto del retry-after en sliding window: cuando hay deuda mayor que uno, mira el N-ésimo evento más antiguo, no el primero. Matemáticamente correcto.

  • EVALSHA con fallback a NOSCRIPT, agnóstico de driver phpredis y Predis, implementado de verdad, no solo mencionado.

Implementación completa, alineada con la documentación, sin gaps entre lo que dice y lo que hace.

GPT-5.5

Cumplió la instrucción de listar asunciones, pero al mínimo:

Asunciones iniciales: es una app Laravel estándar con Redis disponible en entorno de test, PHP tiene pcntl habilitado, y la política por defecto debe proteger disponibilidad (fail-open) salvo endpoints críticos. A un staff engineer le preguntaría: qué SLO se prioriza cuando Redis falla, si los límites se aplican por usuario/IP/tenant o por una clave de negocio concreta, qué precisión temporal y coste de memoria aceptamos para sliding window, y si necesitamos compatibilidad cluster Redis con hash tags. rg no está instalado, así que sigo con herramientas estándar.

Tres asunciones obvias y cuatro preguntas en una frase corrida. Comparado con las diez clasificadas de Opus, esto es flojo. Cumple el formato. No cumple el espíritu. Y ese detalle del "rg no está instalado" delata que está pensando en su propio entorno de ejecución, no en el problema.

Pero entonces empezó a codear, y entregó cosas que Opus no implementa.

Hash tags para Redis Cluster, de verdad implementados, generando claves con la sintaxis con llaves que garantiza que múltiples claves caigan en el mismo slot del cluster. Opus lo menciona en doc pero no lo implementa. GPT-5.5 sí.

La barrera de sincronización en el test la resolvió con stream_socket_pair y fread bloqueante. Es objetivamente la mejor barrera de los tres modelos: cero polling, cero usleep, los hijos se desbloquean en una ventana de microsegundos. Más limpio que la versión de Opus.

Y un detalle que solo GPT-5.5 expuso: marcar el resultado con un flag backendFailure cuando Redis falla y vamos fail-open, para que sistemas downstream puedan reaccionar diferente a "denegado por límite" vs "permitido porque Redis se cayó". Útil para métricas y observabilidad.

Pero falla en cosas importantes. El test solo cubre sliding window, no token bucket. La verificación inversa es solo documentación, no meta-test ejecutable. Las cabeceras son X-RateLimit-* legacy, no las del draft IETF. El retry-after del sliding window mira siempre el primer evento, dando una respuesta optimista incorrecta cuando hay deuda mayor que uno. Y el config mezcla campos de los dos algoritmos en un único objeto, donde la mitad son irrelevantes según el caso.

Es una implementación competente y profesional, pero requiere revisión cuidadosa antes de poner en producción. Te ahorra el 70% del trabajo, pero el 30% restante necesita ojo de senior.

El veredicto

Los tres modelos entienden el problema. Los tres saben qué es una race condition, qué es atomicidad, qué hace Lua dentro de Redis. Donde se separan es en cuatro ejes:

Disciplina al leer el prompt. Opus lee "lista asunciones" como una invitación a pensar en profundidad. GPT-5.5 cumple pero sin excesos. Si tu workflow castiga la falta de disciplina y premia el criterio, esto importa.

Calidad de tests. Solo Opus construye un meta-test ejecutable. Los demás documentan cómo deberías verificar el test, pero la verificación queda en manual y se pudre con el tiempo.

Cicatriz operacional. SIGKILL en hijos PHPUnit, doble Redis::purge, fail-open sin escribir cabeceras misleading. Detalles que solo conoce alguien que los ha sufrido. Solo Opus los muestra.

Cálculos matemáticamente correctos. El retry-after del sliding window es el ejemplo más claro. Dos modelos lo calculan optimista (mira el primer evento), Opus lo calcula correcto (mira el N-ésimo).

Tom's Guide reportó que GPT-5.5 perdió las 7 categorías en una comparación cualitativa contra Opus 4.7, a pesar de liderar Terminal-Bench 2.0 con 82.7% vs 69.4%. Mi experimento, con un solo prompt, replica el mismo patrón: los benchmarks oficiales miden capacidad técnica estrecha; las pruebas cualitativas miden disciplina, criterio y calidad de entrega. Son ejes distintos, y para trabajo profesional el segundo grupo es el que importa.

Quién gana

Para mi workflow, Opus 4.7 sigue siendo la elección. Por capacidad, por disciplina, por cicatriz. GPT-5.5 tiene capacidad técnica real y en algunos detalles es objetivamente mejor (los hash tags de Cluster son una victoria clara).

Si vienes de OpenAI y GPT-5.5 te funciona, no hay motivo para cambiar, aunque siempre puedes probar Opus 4.7 si no lo has hecho antes igual que yo. Pero si estás eligiendo herramienta nueva en 2026 con expectativas serias para programar Laravel, mi recomendación es Opus 4.7.

Una nota sobre GLM-5.1

GLM-5.1 también participó en el experimento, aunque no en mi semana de uso (a GLM ya lo cubrí en otros artículos del blog). Su patrón es interesante y consistente con lo que ya conté de versiones anteriores: documentación de nivel staff y código con bugs funcionales reales.

Por ejemplo, su método para consultar el estado del rate limiter sin consumir tokens lee directamente del backend sin aplicar el refill basado en tiempo. Resultado: si pasaron cinco minutos desde la última operación, el bucket ya debería estar lleno por refill, pero GLM te dirá que está vacío. Información incorrecta al cliente, cabeceras HTTP que mienten.

Hay más detalles del estilo: cleanup roto en los tests por confusión con el prefijo, sin reset de conexión Redis tras fork, sintaxis Laravel arcaica con $app['config']->get(...) repetido cinco veces. Es código que funciona en el camino feliz y se rompe en casos límite reales. La documentación que produce es mejor que la del 80% de paquetes Laravel publicados. El código va detrás.

Si te interesa GLM como alternativa económica con modelos open-weight, ya escribí sobre eso: GLM-4.7 vs Claude Sonnet 4.5: refactorizando un controlador Laravel. El veredicto es matizado: para casos donde puedes supervisar el código línea a línea y el coste importa, tiene sentido. Para producción crítica sin revisión humana, no.

El experimento entero, con código, en GitHub

Todo lo que conté del experimento está publicado en abierto en GitHub: distributed-rate-limiter-llm-comparison. El repo tiene cuatro ramas:

  • main: el README con la comparativa, la metodología, la tabla de resultados y el ranking final

  • opus47: la implementación completa de Claude Opus 4.7 con análisis detallado

  • gpt55: la de GPT-5.5

  • glm51: la de GLM-5.1

Cada rama incluye su propio README explicando qué hizo bien el modelo, qué hizo mal, y qué se podría mejorar. El código es ejecutable, los tests están ahí, puedes correrlos tú mismo con Sail.

La intención del repo es que sirva de plantilla repetible: cuando salga el siguiente modelo (GPT-6, Claude 5, Gemini 4, lo que toque), tiras el mismo prompt y comparas. Treinta minutos y tienes señal real sobre dónde está la frontera de ese modelo, no la frontera de marketing.

Cierre

GPT-5.5 es un modelo muy capaz. No me esperaba que hubiese cosas que hace mejor que Opus, y las hay.

Una semana es poco para un veredicto absoluto, pero suficiente para un veredicto honrado. Vuelvo a Claude para mi día a día. Dicho esto, pienso mantener de momento mi cuenta Plus de OpenAI para seguir utilizándolo en mi día a día y ver qué tal me voy adaptando a él y cómo evoluciona, nunca se sabe.

Y si te ha picado la curiosidad por la parte técnica del experimento, échale un ojo al repo: github.com/cursosdesarrolloweb/distributed-rate-limiter-llm-comparison. Para entender por qué el throttle de Laravel no basta en sistemas distribuidos, por qué Lua dentro de Redis es la herramienta correcta, y cómo se testea concurrencia de verdad con pcntl_fork, ahí lo tienes. Si vas a probar el siguiente modelo que salga, tienes la metodología lista para repetirla.

school Curso completo

Curso Laravel 12
Completo 2026

El único curso 100% actualizado que incluye Laravel 12, Livewire 3, Vue 3, React 19 e Inertia 2. Aprende con proyectos reales y las últimas funcionalidades.

access_time 8 horas de contenido
layers 4 tecnologías en 1
update 100% actualizado
code Proyectos prácticos
Ver Curso Laravel 12 arrow_forward

star Incluido en cualquier suscripción

Rutas de aprendizaje