← Back to home ← Volver al inicio

CreatedCreado UpdatedActualizado

My Grandfather’s Toolbox

My grandfather, Jorge Jackson, was a chemical engineer — the same degree I’d end up taking, decades later. He was also, in a way I have never seen matched in a private house, a man with tools. Not a shop. A hobby. Wall after wall of them, sorted, each in its place. You could take a car apart in that house and put it back together, and he did exactly that, more than once, for fun.

Pencil drawing of a home workshop: a pegboard wall hung with wrenches, screwdrivers, pliers, files and calipers in size order, a torque wrench hanging apart on the right, and a workbench below with a vise, an open socket set and a rolling tool chest.
Not his wall — but close. I have no photograph of my grandfather's workshop, so this is a drawing of what I remember. Created by Google's Gemini 3 Pro Image model (the one nicknamed "Nano Banana") from a written description only — no reference photo, no photograph of any real workshop. The file is served exactly as the model returned it, so its provenance is intact: a SynthID watermark in the pixels and a C2PA manifest signed by Google, which you can inspect at contentcredentials.org/verify. Note the torque wrench, hanging by itself on the right — it comes back at the end of this article.

The thing he told me, over and over, was simple enough that a kid could carry it: use the right tool for the right job. He wasn’t bragging about owning many tools. He was talking about knowing which one — because a tool used out of place doesn’t just work badly. It rounds off the bolt and makes the next attempt harder.

This weekend I got the clearest demonstration of that rule I’ve had in years, and it involved three frontier AI models and a twenty-seven-year-old thermodynamics library.


The setup

In 1999, Carlos and I wrote a vapor–liquid equilibrium library in Visual Basic 6 as our thesis. This year, Claude Code helped me bring it back as a Rust engine — the same math, several orders of magnitude faster. But “fast” is a claim, and I wanted it audited by something that hadn’t written it.

So I ran a small experiment: let three different frontier models each do the part of the job they’re actually built for.1

  1. Gemini 3.1 Pro wrote the prompt. I asked it to author a prompt that would extract a ruthless Rust performance audit out of a coding agent. It produced a good one — scoped strictly to the .rs files, framed as “act as an elite Rust performance engineer,” split into Part 1: flash calculation deep-dive and Part 2: global package optimization.
  2. Codex CLI (gpt-5.6-sol) wrote the audit. It read the engine and returned a fourteen-section document with real, specific, code-level recommendations. It was fast. That fact turns out to be the entire story.
  3. Claude Opus 5, through Claude Code, benchmarked it. Not reviewed it — measured it. Captured a baseline with cargo bench, evaluated every recommendation against real numbers on this codebase, implemented the ones that survived, and reverted the ones that didn’t.
  4. I arbitrated. The approvals, the scope, and the two questions that had no technically correct answer.

What the audit got right

Credit first, because the interesting failure is only interesting against a real success. Codex’s core diagnosis was correct, and it was the single most valuable thing in the document:

Rachford–Rice is not the bottleneck. Repeated state construction, redundant EOS evaluations, pointer-chasing matrices, transient vectors, scalar transcendental work, and finite-difference Jacobians dominate execution time.

For anyone who doesn’t spend weekends in phase equilibria: Rachford–Rice2 is the equation everybody optimizes in a flash calculation. It’s the obvious target. Codex told me it was worth 1–15% of the runtime and my attention belonged one layer down. It was right, and measurement confirmed it.

It also caught a stability routine evaluating the entire mixture path twice (fixing it: −36 to −46%), two invariant matrices being rebuilt on every single call (−68% on NRTL activity coefficients),3 and a milestone my own planning document claimed was finished that the code had never implemented.

That last one deserves its own line. A milestone marked complete in a plan document is a claim. The code is the fact. An auditor with no stake in the plan found the gap on its first pass.

What the audit got wrong — and why

The audit contained zero numbers. Not one measured cost, not one profile, not one estimate of what any change was worth. So every recommendation arrived carrying identical rhetorical weight, in the same confident register. Here’s what happened when we actually measured them:4

What Codex recommendedHow the audit framed itWhat the benchmark said
Share one mixture state in the min-Gibbs pathone bullet−36…−46%
Cache per (T, P) instead of per pointone of fourteen sections−15% on the flash
Cache the activity-coefficient matricesone of fourteen sections−68% on NRTL
Keep K-values in log formone section−16% on that path
Flatten the virial coefficient matrixone of fourteen sections−21%
Precompute cᵢ = Kᵢ − 1 in Rachford–Ricestated as obvious+30…+200% — slower
Probe f(0), f(1) before bracketingrecommended for the hot path+25…+200% — slower
Hand-vectorize the inner loops with SIMDa full section, with coderejected — wrong problem size
Stop inverting the Broyden Jacobiana full section, with coderejected — nothing calls it

Two of eight concrete proposals were net regressions. And here’s the part worth sitting with: neither is wrong in principle. Hoisting a loop invariant and narrowing a root-finding bracket are both things you’d teach a student to do on day one.

They fail here for reasons only a benchmark surfaces. The hoist saves a subtract and a multiply per component — cheap arithmetic that was already hiding under the latency of a division the loop is actually limited by — while the setup pass costs more than it saves for a solve that converges in a handful of iterations. And it quietly converts two contiguous arrays into an array-of-structs, striding the memory loads. (The audit warns about that exact layout problem three sections later. It didn’t connect the two.)

Then there’s the one that isn’t subtle at all. A full section, with a polished code sketch, was devoted to fixing how a Broyden solver inverts its Jacobian. Nothing in the engine calls that file. One grep for callers would have redirected the effort — but the prompt had scoped the auditor to analyzing files, and a file looks equally important whether it runs a million times a second or never.

Three lessons that outlive this repo

Speed of generation is not free. “It did it incredibly fast” and “it put the 70% last” are the same observation. Structuring a document around its own conclusion, and calibrating confidence item by item, are the parts that take time — and the parts a reader most depends on. The audit’s own summary says the highest-value work is in Part 2. It then filled in Part 1 first, as asked, and a reader going top to bottom — the natural way to consume a numbered plan — spends their first pass on the cheap layer. That almost happened here.

Prompt framing propagates all the way through. Gemini’s Part 1 / Part 2 split was a perfectly reasonable way to scope an audit. It became the document’s implied priority order, which became the execution order. A decision made before any analysis existed shaped the outcome more than the analysis did.

A reviewer that can’t run the code is a hypothesis generator, not a plan. Everything of value here came from cargo bench. Two recommendations were reverted only because a number contradicted them. A model restricted to reading — as Codex was, by its own prompt — cannot tell you what’s hot, what’s reachable, or what’s worth doing. That isn’t a knock on the model. It’s a knock on the job description it was handed.

And a smaller fourth: every rejected optimization needs its reasoning preserved in the code. The reverted items now carry a comment at the call site naming the audit section, the reason, and the measured number. Without that, the next reader — human or model — proposes them again, because they still look obviously right on paper.

So I asked Gemini directly

Mid-experiment, curiosity got the better of me. I described the pattern I was seeing — Codex noticeably faster to answer, Claude Code noticeably better at the dense mathematical work — and asked Gemini 3.1 Pro for its opinion, with web search on. It went and looked at the repo first, then said:5

Claude Code’s agentic loop is fundamentally designed for deep synthesis. Before it writes a line of code, it reads your files, cross-references context, and builds a plan. […] That requires an extended reasoning phase, which makes it feel slower but results in vastly superior architectural decisions and mathematical correctness.

When OpenAI rebooted Codex as an agentic system, they optimized it for a tight, high-velocity loop: scope the task, write the file, and ship it. It skips the deep, multi-file planning phases that Claude Code insists on. For simple-to-medium tasks or scaffolding, Codex is significantly faster and uses fewer tokens. But when thrown into a dense, multi-file thermodynamic math problem, that “act first” approach often leads to it losing the plot.

It laid the trade-off out as a table:

Claude CodeOpenAI Codex
Execution loopContext → Plan → Execute → VerifyScope → Write → Test
Reasoning depthDeep multi-file synthesisBest for well-defined or single-file tasks
SpeedSlower (spends time planning)Snappier and more responsive
Token efficiencyHeavy (reads more files per task)Leaner, cheaper at volume

And it closed with advice I’ve taken: keep Codex alongside for the smaller, isolated jobs — boilerplate, routine unit tests — where you just want raw speed.

Now, the obvious caveat, stated plainly: that is one model’s opinion about two other models, and this article was drafted by one of the models under discussion. Neither of those is evidence. The evidence is the benchmark table above. What’s worth noting is only that the opinion and the measurements landed in the same place — and that both point at fit, not at ranking.

Back to the toolbox

The conclusion is not “Claude is better than Codex.” That’s the wrong shape of sentence, and my grandfather would have said so in about four words. A torque wrench is not better than a screwdriver. It’s slower, heavier, more expensive, and completely useless on a Phillips head — and it’s the only thing in the drawer that tells you when to stop.

What the weekend actually settled:

  • Gemini was the right tool for framing the question. It wrote a sharper audit prompt in seconds than I would have written in an hour.
  • Codex was the right tool for generating hypotheses fast. Fourteen sections of informed, specific, code-level suggestions, quickly — and roughly three-quarters of them were real.
  • Claude Code was the right tool for the deep multi-file mathematical work, and for being the one that measures. The slow, load-bearing part.
  • A human was the right tool for the two decisions with no technically correct answer: whether a workspace type belongs in the public API of a published crate, and whether four substantial deferrals stood.

Three models, one engineer, four jobs. The failure mode was never any one of them being bad at its work. It was almost letting a fast tool’s confident, unmeasured output set the order of everything that followed.

My grandfather’s tool walls weren’t impressive because they were big. They were impressive because he could look at a job and walk straight to the right drawer. Twenty-some years and one Rust engine later, I don’t think the rule has changed at all. The drawers just got stranger.


References

  1. The complete chain of custody, with every verdict and number, is public: OPTIMIZATION_AUDIT_HISTORY.md in the miguelju/vle repository — alongside optimizations_audit.md, the Codex audit itself, published unmodified.

  2. The Rachford–Rice equation — the mass-balance root-find at the heart of every isothermal flash calculation, solved for the vapor fraction given a set of K-values.

  3. NRTL (Non-Random Two-Liquid) — an activity-coefficient model for the liquid phase of strongly non-ideal mixtures, and one of the most-called routines in the engine.

  4. All figures are Criterion benchmarks run on the same machine against a captured baseline, recorded per item in OPTIMIZATION_PLAN_PART1.md (the flash layer) and OPTIMIZATION_PLAN_PART2.md (the mixture core). Percentages are change in wall-clock time on the named path; negative is faster.

  5. Gemini 3.1 Pro, in response to a direct question about Codex versus Claude Code on this repository, quoted with light trimming and no reordering.

La caja de herramientas de mi abuelo

Mi abuelo, Jorge Jackson, era ingeniero químico — la misma carrera que yo terminaría estudiando, décadas después. También era, de una forma que nunca he vuelto a ver en una casa particular, un hombre con herramientas. No un taller. Un pasatiempo. Pared tras pared de ellas, ordenadas, cada una en su sitio. En esa casa podías desarmar un carro y volverlo a armar, y él lo hizo exactamente así, más de una vez, por gusto.

Dibujo a lápiz de un taller casero: una pared de tablero perforado con llaves, destornilladores, alicates, limas y calibradores ordenados por tamaño, una llave de torque colgando aparte a la derecha, y debajo un banco de trabajo con prensa, un juego de dados abierto y un gabinete de herramientas con ruedas.
No es su pared — pero se le parece. No tengo ninguna fotografía del taller de mi abuelo, así que esto es un dibujo de lo que recuerdo. Creado por el modelo Gemini 3 Pro Image de Google (el apodado «Nano Banana») a partir únicamente de una descripción escrita — sin foto de referencia, sin fotografía de ningún taller real. El archivo se sirve exactamente como lo devolvió el modelo, así que su procedencia está intacta: una marca de agua SynthID en los píxeles y un manifiesto C2PA firmado por Google, que puedes inspeccionar en contentcredentials.org/verify. Fíjate en la llave de torque, colgando sola a la derecha — vuelve al final de este artículo.

Lo que me repetía, una y otra vez, era lo bastante sencillo como para que un carajito lo cargara toda la vida: usa la herramienta correcta para el trabajo correcto. No estaba presumiendo de tener muchas herramientas. Estaba hablando de saber cuál — porque una herramienta usada fuera de lugar no solo trabaja mal. Redondea el tornillo y hace más difícil el siguiente intento.

Este fin de semana tuve la demostración más clara de esa regla que he tenido en años, y en ella participaron tres modelos de IA de frontera y una librería de termodinámica de veintisiete años.


El montaje

En 1999, Carlos y yo escribimos una librería de equilibrio líquido–vapor en Visual Basic 6 como nuestra tesis. Este año, Claude Code me ayudó a revivirla como un motor en Rust — la misma matemática, varios órdenes de magnitud más rápida. Pero «rápido» es una afirmación, y yo quería que la auditara algo que no la hubiera escrito.

Así que armé un experimento pequeño: dejar que tres modelos de frontera distintos hicieran, cada uno, la parte del trabajo para la que realmente sirven.1

  1. Gemini 3.1 Pro escribió el prompt. Le pedí que redactara un prompt capaz de sacarle una auditoría de rendimiento despiadada en Rust a un agente de código. Produjo uno bueno — limitado estrictamente a los archivos .rs, planteado como «actúa como un ingeniero de rendimiento de élite en Rust», dividido en Parte 1: análisis profundo del cálculo de flash y Parte 2: optimización global del paquete.
  2. Codex CLI (gpt-5.6-sol) escribió la auditoría. Leyó el motor y devolvió un documento de catorce secciones con recomendaciones reales, específicas, a nivel de código. Fue rápido. Ese detalle resulta ser toda la historia.
  3. Claude Opus 5, a través de Claude Code, la midió. No la revisó — la midió. Capturó una línea base con cargo bench, evaluó cada recomendación contra números reales sobre este código, implementó las que sobrevivieron y revirtió las que no.
  4. Yo arbitré. Las aprobaciones, el alcance y las dos preguntas que no tenían respuesta técnicamente correcta.

Lo que la auditoría acertó

Primero el crédito, porque la falla interesante solo es interesante contra un éxito real. El diagnóstico central de Codex fue correcto, y fue lo más valioso de todo el documento:

Rachford–Rice no es el cuello de botella. La construcción repetida de estados, las evaluaciones redundantes de la ecuación de estado, las matrices que persiguen punteros, los vectores transitorios, el trabajo transcendental escalar y los jacobianos por diferencias finitas dominan el tiempo de ejecución.

Para quien no pase los fines de semana en equilibrio de fases: Rachford–Rice2 es la ecuación que todo el mundo optimiza en un cálculo de flash. Es el blanco obvio. Codex me dijo que valía entre 1 y 15% del tiempo de ejecución y que mi atención pertenecía una capa más abajo. Tenía razón, y la medición lo confirmó.

También detectó una rutina de estabilidad que evaluaba dos veces todo el camino de la mezcla (arreglarlo: −36 a −46%), dos matrices invariantes que se reconstruían en cada llamada (−68% en los coeficientes de actividad NRTL),3 y un hito que mi propio documento de planificación declaraba terminado y que el código nunca había implementado.

Ese último merece su propia línea. Un hito marcado como completo en un documento de planificación es una afirmación. El código es el hecho. Un auditor sin nada invertido en el plan encontró el hueco en su primera pasada.

Lo que la auditoría erró — y por qué

La auditoría contenía cero números. Ni un costo medido, ni un perfilado, ni una estimación de cuánto valía cualquiera de los cambios. Así que todas las recomendaciones llegaron con idéntico peso retórico, en el mismo tono seguro. Esto fue lo que pasó cuando de verdad las medimos:4

Lo que recomendó CodexCómo lo planteó la auditoríaLo que dijo el benchmark
Compartir un solo estado de mezcla en el camino de mínima Gibbsuna viñeta−36…−46%
Cachear por (T, P) en vez de por puntouna de catorce secciones−15% en el flash
Cachear las matrices de coeficientes de actividaduna de catorce secciones−68% en NRTL
Mantener los valores K en forma logarítmicauna sección−16% en ese camino
Aplanar la matriz de coeficientes virialesuna de catorce secciones−21%
Precalcular cᵢ = Kᵢ − 1 en Rachford–Riceplanteado como obvio+30…+200% — más lento
Probar f(0), f(1) antes de acotarrecomendado para el camino caliente+25…+200% — más lento
Vectorizar los bucles internos a mano con SIMDuna sección completa, con códigorechazado — tamaño de problema equivocado
Dejar de invertir el jacobiano de Broydenuna sección completa, con códigorechazado — nada lo llama

Dos de ocho propuestas concretas fueron regresiones netas. Y aquí está la parte que vale la pena masticar: ninguna de las dos está equivocada en principio. Sacar un invariante de un bucle y estrechar el intervalo de búsqueda de una raíz son cosas que le enseñarías a un estudiante el primer día.

Fallan aquí por razones que solo un benchmark saca a la luz. El invariante ahorra una resta y una multiplicación por componente — aritmética barata que ya se escondía bajo la latencia de una división que es lo que realmente limita el bucle — mientras que la pasada de preparación cuesta más de lo que ahorra en una solución que converge en un puñado de iteraciones. Y además convierte, calladito, dos arreglos contiguos en un arreglo de estructuras, dispersando los accesos a memoria. (La auditoría advierte sobre ese mismísimo problema de disposición tres secciones más adelante. No conectó las dos cosas.)

Y luego está la que no tiene nada de sutil. Una sección completa, con su código pulido y todo, dedicada a arreglar cómo un solucionador de Broyden invierte su jacobiano. Nada en el motor llama a ese archivo. Un solo grep buscando quién lo invoca habría redirigido ese esfuerzo — pero el prompt había limitado al auditor a analizar archivos, y un archivo se ve igual de importante corra un millón de veces por segundo o nunca.

Tres lecciones que sobreviven a este repositorio

La velocidad de generación no es gratis. «Lo hizo rapidísimo» y «dejó el 70% de último» son la misma observación. Estructurar un documento alrededor de su propia conclusión, y calibrar la confianza punto por punto, son las partes que toman tiempo — y las partes de las que más depende quien lee. El resumen de la propia auditoría dice que el trabajo de mayor valor está en la Parte 2. Después llenó la Parte 1 primero, tal como se le pidió, y quien la lea de arriba abajo — la forma natural de consumir un plan numerado — gasta su primera pasada en la capa barata. Aquí casi pasa.

El encuadre del prompt se propaga hasta el final. La división Parte 1 / Parte 2 de Gemini era una forma perfectamente razonable de acotar una auditoría. Se convirtió en el orden de prioridad implícito del documento, que se convirtió en el orden de ejecución. Una decisión tomada antes de que existiera análisis alguno moldeó el resultado más que el análisis mismo.

Un revisor que no puede correr el código es un generador de hipótesis, no un plan. Todo lo valioso aquí salió de cargo bench. Dos recomendaciones se revirtieron únicamente porque un número las contradijo. Un modelo restringido a leer — como lo estaba Codex, por su propio prompt — no puede decirte qué está caliente, qué es alcanzable ni qué vale la pena. Eso no es una crítica al modelo. Es una crítica a la descripción del trabajo que le entregaron.

Y una cuarta, más pequeña: cada optimización rechazada necesita que su razonamiento quede guardado en el código. Los ítems revertidos llevan ahora un comentario en el sitio de la llamada que nombra la sección de la auditoría, el motivo y el número medido. Sin eso, el próximo que lea — humano o modelo — las vuelve a proponer, porque sobre el papel siguen viéndose obviamente correctas.

Entonces le pregunté a Gemini directamente

A mitad del experimento me pudo la curiosidad. Le describí el patrón que estaba viendo — Codex notablemente más rápido para responder, Claude Code notablemente mejor en el trabajo matemático denso — y le pedí su opinión a Gemini 3.1 Pro, con búsqueda web activada. Fue a mirar el repositorio primero, y después dijo:5

El bucle agéntico de Claude Code está fundamentalmente diseñado para la síntesis profunda. Antes de escribir una línea de código, lee tus archivos, cruza el contexto y construye un plan. […] Eso requiere una fase de razonamiento extendida, que lo hace sentir más lento pero produce decisiones arquitectónicas y corrección matemática enormemente superiores.

Cuando OpenAI relanzó Codex como sistema agéntico, lo optimizaron para un bucle apretado y de alta velocidad: acotar la tarea, escribir el archivo y despacharlo. Se salta las fases de planificación profunda y multiarchivo en las que Claude Code insiste. Para tareas simples o medianas y para andamiaje, Codex es significativamente más rápido y usa menos tokens. Pero cuando lo lanzas a un problema matemático termodinámico denso y multiarchivo, ese enfoque de «actuar primero» a menudo lo hace perder el hilo.

Y puso el compromiso en una tabla:

Claude CodeOpenAI Codex
Bucle de ejecuciónContexto → Plan → Ejecutar → VerificarAcotar → Escribir → Probar
Profundidad de razonamientoSíntesis profunda multiarchivoMejor en tareas bien definidas o de un solo archivo
VelocidadMás lento (invierte tiempo planificando)Más ágil y responsivo
Eficiencia en tokensPesado (lee más archivos por tarea)Más liviano y barato en volumen

Cerró con un consejo que sí tomé: mantén a Codex al lado para los trabajos pequeños y aislados — código de andamiaje, pruebas unitarias de rutina — donde lo único que quieres es velocidad pura.

Ahora, la advertencia obvia, dicha sin rodeos: eso es la opinión de un modelo sobre otros dos modelos, y este artículo lo redactó uno de los modelos en discusión. Ninguna de las dos cosas es evidencia. La evidencia es la tabla de benchmarks de arriba. Lo único notable es que la opinión y las mediciones aterrizaron en el mismo sitio — y que ambas apuntan al encaje, no a un ranking.

De vuelta a la caja de herramientas

La conclusión no es «Claude es mejor que Codex». Esa es la forma equivocada de la oración, y mi abuelo lo habría dicho en unas cuatro palabras. Una llave de torque no es mejor que un destornillador. Es más lenta, más pesada, más cara y completamente inútil en un tornillo de estrella — y es lo único en la gaveta que te dice cuándo parar.

Lo que el fin de semana dejó claro:

  • Gemini fue la herramienta correcta para encuadrar la pregunta. Escribió en segundos un prompt de auditoría más afilado del que yo habría escrito en una hora.
  • Codex fue la herramienta correcta para generar hipótesis rápido. Catorce secciones de sugerencias informadas, específicas y a nivel de código, en poco tiempo — y como tres cuartas partes eran reales.
  • Claude Code fue la herramienta correcta para el trabajo matemático profundo y multiarchivo, y para ser el que mide. La parte lenta, la que sostiene la estructura.
  • Un humano fue la herramienta correcta para las dos decisiones sin respuesta técnicamente correcta: si un tipo de workspace pertenece a la API pública de un crate publicado, y si cuatro aplazamientos importantes se mantenían.

Tres modelos, un ingeniero, cuatro trabajos. El modo de falla nunca fue que alguno fuera malo en lo suyo. Fue estar a punto de dejar que la salida veloz y segura de sí misma de una herramienta rápida definiera el orden de todo lo que vino después.

Las paredes de herramientas de mi abuelo no impresionaban por ser grandes. Impresionaban porque él podía mirar un trabajo e ir derechito a la gaveta correcta. Veintitantos años y un motor en Rust después, no creo que la regla haya cambiado ni un poquito. Las gavetas nada más se pusieron más raras.


Referencias

  1. La cadena de custodia completa, con cada veredicto y cada número, es pública: OPTIMIZATION_AUDIT_HISTORY.md en el repositorio miguelju/vle — junto a optimizations_audit.md, la auditoría de Codex misma, publicada sin modificar.

  2. La ecuación de Rachford–Rice — el balance de masa cuya raíz hay que encontrar en el corazón de todo cálculo de flash isotérmico, resuelto para la fracción de vapor dados unos valores K.

  3. NRTL (Non-Random Two-Liquid) — un modelo de coeficientes de actividad para la fase líquida de mezclas fuertemente no ideales, y una de las rutinas más llamadas del motor.

  4. Todas las cifras son benchmarks de Criterion corridos en la misma máquina contra una línea base capturada, registrados ítem por ítem en OPTIMIZATION_PLAN_PART1.md (la capa de flash) y OPTIMIZATION_PLAN_PART2.md (el núcleo de mezclas). Los porcentajes son cambio en tiempo de reloj sobre el camino nombrado; negativo es más rápido.

  5. Gemini 3.1 Pro, respondiendo a una pregunta directa sobre Codex frente a Claude Code en este repositorio; citado con recortes leves y sin reordenar, traducido del inglés.