Harness Engineering con Codex de OpenAI: el arte de que tu agente de IA funcione de verdad
Llevaba una hora con GPT-4o intentando refactorizar un servicio de autenticación en NestJS. El modelo era bueno. La tarea era sencilla. Y aun así el agente leyó los archivos equivocados, modificó código que nadie le pidió tocar y entró en un bucle explicando por qué había hecho algo que nunca debió hacer.
Ese día entendí qué es harness engineering — y por qué importa más que el modelo.
Si tu agente de IA hace cosas raras, borra lo que no debe, o simplemente no termina la tarea, casi nunca es el modelo el problema. Es el sistema que rodea al modelo. Ese sistema tiene nombre: harness. Y diseñarlo bien es la diferencia entre un agente que funciona y uno que frustra.
En este post vas a ver cómo funciona el harness, qué elementos lo componen y cómo configurarlo con Codex de OpenAI como caso concreto. He aplicado estos principios en proyectos reales de Dominicode — en el curso Angular Moderno, en el repositorio ShopFlow y en varios workflows de automatización — y estos son los patrones que funcionan.
Qué es harness engineering: definición y concepto clave
El modelo de lenguaje es solo el cerebro. Un cerebro sin ojos, sin manos y sin memoria no hace gran cosa.
El harness es todo lo demás: las instrucciones que recibe al arrancar, las herramientas que puede usar, qué archivos puede leer y escribir, qué comandos puede ejecutar, qué recordará la próxima sesión y qué no, cómo escala la complejidad cuando la tarea crece.
Harness engineering es la disciplina de diseñar, configurar y optimizar ese sistema — no el modelo — para obtener resultados predecibles y de calidad de un agente de IA.
Piensa en ello como la diferencia entre contratar a un developer senior excelente y meterlo en una empresa sin onboarding, sin acceso a los repositorios correctos, sin saber cuál es el stack ni los estándares del proyecto. Ese developer se va a equivocar. No porque sea malo — sino porque no tiene el contexto para operar.
Un harness bien diseñado responde estas preguntas antes de que el agente empiece a trabajar:
- ¿Qué sabe el agente sobre este proyecto?
- ¿Qué herramientas tiene disponibles?
- ¿Qué puede hacer sin pedir permiso y qué no?
- ¿Cómo gestiona situaciones de ambigüedad?
- ¿Qué pasa cuando algo falla?
Cada agente de IA moderno — Claude Code, Cursor, Codex — tiene su propio mecanismo para configurar el harness. En Codex de OpenAI, ese mecanismo se llama AGENTS.md.
Harness vs system prompt: la diferencia que importa
Mucha gente confunde el harness con un system prompt. No son lo mismo.
Un system prompt clásico es estático, vive fuera del repositorio y generalmente lo escribe el equipo que construye la herramienta de IA. Es el contexto base del modelo, pero no sabe nada de tu proyecto específico.
El harness es específico a tu proyecto y tu contexto. Vive dentro del repositorio, se versiona con git, puede tener múltiples capas (uno en la raíz, otros en subdirectorios para módulos específicos), y está diseñado para agentes que operan sobre código concreto. Es la capa que tú controlas — y la que determina si el agente opera en tu proyecto o en uno imaginario.
Cómo instalar y configurar Codex CLI de OpenAI
OpenAI lanzó Codex CLI como su apuesta para el desarrollo asistido por agentes directamente desde el terminal. Usa el modelo codex-1, optimizado específicamente para tareas de código, y puede ejecutar comandos, leer y escribir archivos, y razonar sobre tu codebase de forma autónoma.
Instalación
npm install -g @openai/codex
Necesitas una API key de OpenAI exportada como variable de entorno:
export OPENAI_API_KEY=sk-...
Modos de operación
Codex tiene dos modos principales que controlan cuánta autonomía le das al agente:
# Modo sugerencia — el agente propone, tú apruebas cada acción
codex --approval-mode suggest "refactoriza el servicio de autenticación"
# Modo automático — el agente ejecuta sin pedir confirmación
codex --approval-mode auto "añade tests unitarios al módulo de usuarios"
La diferencia no es trivial. En modo suggest puedes revisar cada paso antes de que ocurra. En modo auto el agente opera con autonomía total — lo que significa que un harness mal configurado puede hacer daño real antes de que te des cuenta.
Regla básica: empieza siempre con suggest. Mueve a auto solo cuando el harness esté probado y el alcance de la tarea esté bien definido.
Codex vs otros agentes: comparativa de harness
| Codex CLI | Claude Code | Cursor Agent |
| Archivo de harness | AGENTS.md |
CLAUDE.md |
.cursorrules |
| Soporte MCP | Sí | Sí (amplio) | Limitado |
| Modos de aprobación | suggest / auto |
Por herramienta | Por acción |
| Sandboxing de red | Estricto por defecto | Configurable | No aplica |
| AGENTS.md en subdirectorios | Sí (monorepo) | Sí | No |
| Modelo base | codex-1 (o3) |
Claude Sonnet/Opus | GPT-4o / Claude |
El concepto de harness engineering aplica a los tres. Lo que cambia es el nombre del archivo y algunos detalles de configuración.
Qué es AGENTS.md y cómo configurarlo en Codex
Cuando Codex arranca en un directorio, busca AGENTS.md en la raíz del proyecto. En proyectos monorepo también puede leer AGENTS.md en subdirectorios — el más específico tiene precedencia sobre el de la raíz.
Si no existe, el agente opera sin contexto. Si existe pero está mal escrito, opera con contexto equivocado. Las dos situaciones producen resultados impredecibles.
Un AGENTS.md bien estructurado tiene estas secciones:
# AGENTS.md
Contexto del proyecto
[Qué hace este proyecto, stack tecnológico, arquitectura general]
Reglas de operación
[Qué puede y no puede hacer el agente sin preguntar]
Convenciones del código
[Estilo, nomenclatura, patrones usados en el proyecto]
Herramientas disponibles
[Comandos de build, test, lint que el agente puede ejecutar]
Flujo de trabajo esperado
[Cómo debe abordar las tareas: leer primero, preguntar si hay ambigüedad, etc.]
Ejemplo concreto para un proyecto NestJS:
# AGENTS.md — ShopFlow API
Contexto del proyecto
API REST en NestJS 10 + TypeScript. Base de datos PostgreSQL con TypeORM.
Autenticación con JWT. Testing con Jest. Endpoints bajo /src/modules/.
Stack
- Runtime: Node.js 20 + Bun para scripts
- Framework: NestJS 10
- ORM: TypeORM
- Tests: Jest + Supertest
- Lint: ESLint + Prettier
Reglas de operación
- NUNCA modificar archivos en
src/migrations/ sin instrucción explícita
- NUNCA eliminar archivos. Si algo ya no se necesita, comentarlo y avisar
- Si hay ambigüedad sobre el alcance de la tarea, preguntar antes de ejecutar
- Ejecutar
npm run lint y npm run test después de cualquier cambio
Convenciones
- Nombres de archivos: kebab-case
- Servicios: sufijo
.service.ts
- DTOs: sufijo
.dto.ts, ubicados en dto/ dentro de cada módulo
- Interfaces: prefijo
I (IUser, IProduct)
Comandos disponibles
npm run build — compilar
npm run test — tests unitarios
npm run test:e2e — tests end-to-end
npm run lint — verificar estilo
Flujo esperado
- Leer los archivos relevantes antes de modificar cualquier cosa
- Si la tarea afecta a más de un módulo, listar los archivos involucrados antes de empezar
- Al terminar, ejecutar lint y tests y reportar el resultado
Este AGENTS.md elimina la mayoría de los errores típicos: el agente sabe qué tocar, qué no tocar, cómo llamar a las cosas y cómo verificar que su trabajo está bien hecho.
Los 5 elementos de un harness de agente IA bien diseñado
El AGENTS.md es el núcleo, pero un harness completo tiene más capas. Estos son los cinco elementos que marcan la diferencia.
1. Contexto del proyecto con suficiente densidad
El error más común: escribir un AGENTS.md de tres líneas.
El agente necesita saber lo suficiente para razonar bien. No todo — pero sí el stack, la estructura de directorios, las decisiones de arquitectura más importantes y las restricciones no negociables.
Si el proyecto tiene una convención no obvia (por ejemplo, “todos los handlers de errores van en src/shared/errors/“), escríbelo explícitamente. El agente no puede adivinar convenciones que no están en ningún archivo.
2. Límites claros de autonomía
Define explícitamente qué puede hacer el agente sin preguntar y qué requiere confirmación.
## Autonomía permitida
- Crear archivos nuevos en
src/modules/
- Ejecutar
npm run test y npm run lint
- Instalar dependencias de desarrollo con
npm install --save-dev
Requiere confirmación explícita
- Modificar
package.json en sección scripts
- Tocar cualquier archivo de configuración de base de datos
- Eliminar o renombrar archivos existentes
Sin estos límites, el agente toma decisiones basándose en lo que parece razonable. A veces acierta. Muchas veces no.
3. Herramientas y comandos verificables
El agente necesita poder verificar su propio trabajo. Si no tiene acceso a los comandos de test y lint, no puede saber si lo que hizo funciona.
## Verificación
Después de cualquier cambio de código:
npm run lint — debe pasar sin errores
npm run test -- --passWithNoTests — los tests existentes deben pasar
- Si hay tests fallando que NO estaban fallando antes, reportarlo antes de continuar
Este punto es especialmente importante en modo auto. Un agente con capacidad de verificación autónoma puede detectar que rompió algo y corregirlo antes de que tú lo veas.
4. Gestión explícita de la ambigüedad
Los agentes tienden a asumir en vez de preguntar. Eso produce trabajo que hay que deshacer.
## Manejo de ambigüedad
- Si una tarea puede interpretarse de más de una manera, listar las interpretaciones y preguntar
- Si no encuentras el archivo mencionado en la tarea, preguntar en vez de crearlo desde cero
- Si la tarea requiere modificar lógica crítica (pagos, auth, permisos), confirmar antes de ejecutar
5. Instrucciones de salida y reporte
El agente necesita saber qué se espera de él al terminar.
## Al finalizar cada tarea
Proporciona:
- Lista de archivos modificados o creados
- Resumen en 2-3 líneas de lo que hiciste
- Resultado de lint y tests
- Si hay algo que no pudiste completar, explicarlo con el motivo
Sin esta instrucción, algunos agentes terminan con un párrafo de texto que no dice nada concreto. Con ella, tienes un log estructurado que revisas en segundos.
Harness débil vs harness fuerte: la misma tarea, dos mundos distintos
Tarea concreta: “Añade validación de email al endpoint de registro de usuarios.”
| Sin harness | Con harness |
| Archivos leídos | Varios al azar | register.dto.ts y auth.controller.ts |
| Dependencias | Instala class-validator (ya estaba) |
Detecta que ya existe en package.json |
| Cambios realizados | DTO + guard de auth “por si acaso” | Solo @IsEmail() en el DTO |
| Verificación | No ejecuta tests (no sabe el script) | npm run lint y npm run test — pasan |
| Reporte final | Dos páginas explicando cada decisión | “Un archivo. Lint y tests pasan.” |
| Tiempo de revisión | 20 minutos | 30 segundos |
La diferencia no está en el modelo. Está en el harness.
Errores comunes al configurar el harness de Codex CLI
Error 1: AGENTS.md demasiado vago
# Proyecto web en TypeScript. Usa buenas prácticas.
Esto no es un harness. Es un deseo. El agente no sabe qué son “buenas prácticas” en tu proyecto.
Error 2: No definir qué NO debe tocar
Si no dices “no toques las migraciones”, el agente podría modificarlas si cree que tiene sentido. Los límites negativos son tan importantes como los positivos.
Error 3: Empezar en modo auto sin probar primero
Úsalo en modo suggest en varias tareas distintas. Observa dónde el agente malinterpreta las instrucciones. Ajusta el AGENTS.md. Luego sube a auto.
Error 4: Un AGENTS.md genérico para todos los proyectos
El harness es específico al proyecto. Un AGENTS.md copiado de Angular en un proyecto NestJS produce confusión. Uno por proyecto, aunque sea corto.
Error 5: No actualizar el harness cuando cambia el proyecto
El stack cambia. Las convenciones evolucionan. Si el AGENTS.md describe el proyecto de hace seis meses, el agente opera con un mapa desactualizado.
Cómo crear tu primer harness con Codex: guía paso a paso
Paso 1: Instala Codex CLI
npm install -g @openai/codex
export OPENAI_API_KEY=tu-api-key
Paso 2: Crea un AGENTS.md mínimo pero útil
Con estos cinco bloques ya tienes algo funcional:
# AGENTS.md
Proyecto
[Descripción en 2-3 líneas. Stack principal.]
Estructura relevante
[Dónde vive el código importante. Directorios a conocer.]
Convenciones
[Nomenclatura. Patrones. Lo que hace raro a este proyecto.]
Comandos
[Build, test, lint — los scripts exactos de package.json]
Restricciones
[Qué no debe tocar nunca. Qué requiere confirmación.]
Paso 3: Prueba con una tarea pequeña en modo suggest
codex --approval-mode suggest "lista los archivos del módulo de usuarios"
Observa cómo razona. Dónde se pierde. Qué asume incorrectamente. Ajusta el AGENTS.md.
Paso 4: Itera subiendo la complejidad
Del “lista archivos” al “añade un campo al DTO” al “crea un nuevo módulo completo con tests”. Cada tarea te dice algo sobre qué falta en el harness.
Paso 5: Documenta los patrones que funcionan
Cuando encuentres una instrucción que produce resultados consistentemente buenos, guárdala. El AGENTS.md es un documento vivo.
El agente que fallaba en NestJS al principio de este post no era el problema. Era yo — operando sin harness, esperando que el modelo adivinara el contexto de un proyecto que nunca le había explicado. Con un AGENTS.md bien escrito, esa misma tarea tarda tres minutos y no requiere revisión manual.
Si quieres profundizar en cómo diseñar sistemas con IA que funcionen en proyectos reales, tengo el curso Construye con IA: de la idea al producto con Claude Code donde aplicamos estos principios desde cero. Y si buscas el marco para especificar antes de soltar al agente, el Libro de Spec-Driven Development te da el sistema completo — que encaja perfectamente con harness engineering.
También publico sobre esto regularmente en el canal de YouTube.
FAQ — Preguntas frecuentes sobre harness engineering y Codex
¿El concepto de harness aplica solo a Codex o también a otros agentes?
Es completamente agnóstico al modelo. Claude Code usa CLAUDE.md con el mismo rol que AGENTS.md en Codex. Cursor usa .cursorrules. La disciplina de harness engineering aplica a cualquier agente porque el problema que resuelve — dar contexto estructurado al sistema que rodea al modelo — es universal. Lo que cambia entre herramientas es el nombre del archivo y algunos detalles de configuración.
¿Qué diferencia hay entre harness engineering e ingeniería de prompts?
La ingeniería de prompts optimiza la instrucción puntual que le das al modelo en una conversación. El harness engineering diseña el sistema persistente que define cómo el agente opera en tu proyecto de forma continua. Un buen prompt en un harness malo produce resultados inconsistentes. Un prompt mediocre en un harness bien diseñado produce resultados predecibles. El harness tiene más impacto a largo plazo.
¿Es seguro usar el modo --approval-mode auto?
Depende del harness. En modo auto el agente ejecuta acciones sin confirmación — comandos de terminal incluidos. Si el harness define bien qué puede y no puede hacer, y el agente tiene acceso a verificación (lint, tests), es razonablemente seguro para tareas bien acotadas. Para operaciones destructivas o sobre sistemas en producción, siempre modo suggest. Y siempre con el repositorio en un estado limpio de git antes de empezar.
¿Cuánto tiempo lleva escribir un buen AGENTS.md?
Para un proyecto nuevo, entre 20 y 45 minutos la primera vez. La clave es empezar con la versión mínima (5 secciones) y enriquecerla después de las primeras sesiones con el agente. En proyectos que ya tienen documentación, muchas veces es adaptar lo que existe al formato del harness.
¿Codex de OpenAI puede conectarse a MCP servers como Claude Code?
Sí, Codex soporta MCP (Model Context Protocol) para conectar herramientas externas — bases de datos, APIs, sistemas de ficheros remotos. La configuración es similar a Claude Code, aunque el ecosistema de servidores MCP disponibles sigue siendo más amplio para Claude. Para la mayoría de casos de uso de desarrollo, las herramientas nativas de Codex son suficientes.
¿Necesito saber usar la API de OpenAI para usar Codex CLI?
Solo necesitas una API key de OpenAI y tener créditos disponibles. No necesitas saber programar contra la API — Codex CLI abstrae todo eso. La curva de entrada es baja: instalar el paquete npm, exportar la API key y escribir el AGENTS.md. El coste por uso depende de cuánto contexto maneja el agente en cada sesión.
Por Bezael Pérez — Developer senior con más de 15 años de experiencia y fundador de Dominicode.
