Harness Engineering 101: cómo funcionan de verdad los agentes de programación
¿Qué es el harness de un agente?
El harness es todo el software que rodea a un modelo de lenguaje y lo convierte en un agente que funciona. Birgitta Böckeler, de Thoughtworks, lo resumió en cuatro palabras en un artículo de la web de Martin Fowler: Agente = Modelo + Harness.
El modelo es la parte que alquilas. Todo lo demás es harness: el bucle que lo mantiene trabajando, las herramientas que puede llamar, lo que entra en su ventana de contexto, lo que tiene permitido hacer y cómo se revisa su trabajo antes de que nadie lo dé por bueno.
Harness y framework no son lo mismo, aunque se confunden a menudo. LangChain, Microsoft Agent Framework y el OpenAI Agents SDK son frameworks: cajas de piezas para montar un agente. El harness es el runtime ya terminado que sale de juntar esas piezas. Claude Code es un harness, y Codex CLI también. La frontera se está difuminando, porque varios frameworks ya traen un harness propio listo para usar.
Por qué importa el harness
Hay un experimento que me gustaría que conociera más gente. Toma un modelo y dale 169 tareas reales de corrección de bugs de SWE-bench Verified. Deja exactamente iguales los pesos, las tareas y la ventana de contexto, y cambia solo el código que se ejecuta alrededor del modelo. Las tareas resueltas por completo pasan de 43 a 72.
El dato sale de un paper que se publicó en arXiv en agosto, y es la respuesta más corta que tengo si alguien me pregunta de qué va este post. El modelo era idéntico en las dos ejecuciones. El harness, no.
Hoy paso casi toda mi jornada entre agentes, construyéndolos y usándolos para escribir código, y lo primero que me sigue preguntando la gente es qué modelo elegir. Esa pregunta pesa menos cada trimestre. Los modelos punteros están tan cerca unos de otros que lo que más pesa en el resultado es el software que los envuelve: cuánto cuesta una tarea, si el agente la termina y si puedes fiarte de lo que te entrega. Ese software es el harness, el arnés del agente. Y a diseñarlo se le ha empezado a llamar harness engineering.
Prompt, contexto, harness
El sector ha llegado hasta aquí en tres pasos, y cada uno envolvió al anterior.
El prompt engineering iba de las palabras. El context engineering, de todo lo que se pone delante del modelo junto a ellas: documentos recuperados, memoria, un resumen de lo que pasó hace diez turnos. El harness engineering se queda con las dos cosas y añade lo que un modelo necesita para actuar en lugar de limitarse a hablar.
El bucle entero en treinta líneas
La forma más fácil de entender un harness es escribir uno. Aquí abajo tienes el núcleo de un agente de programación en pseudocódigo. Está simplificado, pero todos los harness reales que he leído tienen esta forma.
def run_agent(task, model, tools, limits):
context = [system_prompt(), project_memory(), task]
for step in range(limits.max_steps):
if count_tokens(context) > limits.window * 0.8:
context = compact(context) # summarize old turns
reply = model.generate(context, tools=tools.schemas())
if reply.is_done:
report = verify(reply) # run tests, linters, a reviewer
if report.passed:
return reply
context.append(report.as_feedback())
continue
for call in reply.tool_calls:
if not policy.allows(call):
result = ask_human(call) or "denied by policy"
else:
result = tools.run(call) # most of the time: a shell command
context.append(trim(result)) # keep the lines that matter
if same_command_failed(context, times=3):
context.append("That failed three times. Try a different approach.")
return stop_and_report(context)Cuenta las líneas en las que interviene el modelo. Hay una: model.generate. Todo lo demás es harness, y cada una de esas otras líneas es una decisión que alguien tuvo que tomar. ¿Cuándo compactas? ¿Cuánto de un log de tests de 4000 líneas llega a ver el modelo? ¿Qué dice policy.allows de un git push --force? Cambia cualquiera de esas respuestas y el mismo modelo se comporta como si fuera otro agente.
Las piezas, una a una
El bucle
Planificar, actuar, observar, repetir. El núcleo es así de pequeño, de verdad: el agente Pi de Mario Zechner mete su prompt de sistema completo y las definiciones de sus herramientas en menos de 1000 tokens. Lo difícil está alrededor del bucle. Cuándo parar. Cuándo preguntar a una persona. Qué hacer cuando el agente lanza por quinta vez el mismo comando que ya ha fallado cuatro veces, que es justo el caso para el que existe la línea same_command_failed de arriba.
Herramientas
Las herramientas son la única manera que tiene el agente de tocar algo. En un agente de programación, eso es leer y editar archivos, ejecutar comandos y buscar en el repo. En uno de soporte, el sistema de tickets y la base de conocimiento.
El diseño de las herramientas importa más de lo que se suele pensar. Una herramienta que vuelca 10.000 líneas de log inunda el contexto. Otra que devuelve las 20 líneas que rodean al error deja pensar al modelo. Con MCP, conectar herramientas se ha vuelto fácil, así que el trabajo ahora está en elegir menos y en cuidar lo que devuelven. En la práctica, en los agentes de programación hay una herramienta que hace casi todo, y tiene su propia sección más abajo.
Contexto
Es la capa más infravalorada. Cualquier tarea larga acaba chocando con el límite de contexto, y lo que haga el harness en ese momento decide si el agente llega al final.
El paper de agosto que mencioné antes, "Same Model, Different Harness", es la prueba más clara que he visto de todo esto. Las dos ejecuciones usaron los mismos pesos, las mismas 169 tareas de SWE-bench Verified, la misma capacidad de contexto y el mismo protocolo. El harness nuevo cambiaba dos cosas. A medida que se llenaba la ventana, iba acortando por etapas los resultados de herramientas más antiguos. Y cuando detectaba que el agente repetía comandos que ya habían fallado, le decía que probara otra cosa.
Las técnicas habituales:
| Técnica | Qué hace |
|---|---|
| Compactación | Resume los turnos antiguos cuando el recuento de tokens sube demasiado |
| Truncado | Recorta la salida antigua de las herramientas y deja entera la reciente |
| Archivos de memoria | Notas que se cargan al empezar cada sesión, como el CLAUDE.md o el AGENTS.md de un proyecto |
| Subagentes | Dan a una tarea secundaria su propio contexto limpio y devuelven solo la respuesta |
| Reinicio de contexto | Vacía la ventana por completo y arranca una sesión nueva a partir de un archivo de traspaso escrito |
Esa última fila es más reciente que las otras, y existe por un motivo que no adivinarías. El equipo de Anthropic que desarrolla aplicaciones de larga duración vio que "la compactación por sí sola no bastaba". Según se llenaba la ventana, los modelos empezaban a mostrar lo que ellos llaman ansiedad de contexto: cerraban el trabajo antes de tiempo porque notaban que el límite se acercaba. Les funcionó mejor un reinicio limpio con un traspaso estructurado que un resumen, porque con el resumen el modelo seguía sabiendo que se estaba quedando sin sitio.
Guardrails
Un agente que puede ejecutar comandos también puede borrar cosas. Cada harness se coloca en algún punto de un espectro, y cuando los puse uno al lado de otro me sorprendió lo distintos que eran:
- Preguntar antes de todo. Es lo que hace Cline por defecto: cada acción espera a que la apruebes.
- Dejar que decida un clasificador. El modo auto de Claude Code (el modo inicial en los planes Pro, Max y Team) y el Auto-review de Cursor ponen a un segundo modelo a revisar las acciones en lugar de preguntarte cada vez.
- Aislarlo. Codex CLI se ejecuta por defecto en un sandbox del sistema operativo, limitado al directorio de trabajo y sin red.
- Confiar en el usuario. Pi no tiene sandbox ni pide permiso para nada. Su autor lo llama "modo YOLO total" y recomienda ejecutarlo dentro de un contenedor.
Ninguna de estas opciones está mal. Cuál te conviene depende de lo caro que pueda salir un error, y eso tiene que ver con tu máquina y tus datos, no con la herramienta.
Verificación
Esta es la capa que te permite fiarte del agente sin leer cada línea que escribe. Böckeler distingue dos tipos de control. Las guías orientan al agente antes de que actúe: instrucciones, convenciones, ejemplos. Los sensores vigilan el resultado después y le ayudan a corregirse: tests, linters, comprobadores de tipos, agentes revisores. En el pseudocódigo, project_memory() es una guía y verify() es un sensor.
El post de OpenAI "Harness engineering: leveraging Codex in an agent-first world" lleva esto al extremo. Un equipo que empezó siendo de tres ingenieros sacó una beta interna sin una sola línea de código escrita a mano, con unas 1500 pull requests ya fusionadas. Codex escribió la aplicación, los tests, la configuración de CI y la documentación. Las personas construyeron el harness: los controles, la estructura y los bucles de feedback que mantenían al agente encarrilado.
La pega es que un agente juzga muy mal su propio trabajo. El mismo post de Anthropic lo dice sin rodeos: cuando se les pide evaluar lo que han hecho, los agentes "tienden a responder elogiando el trabajo con total seguridad", aunque una persona vea que es mediocre. Su solución fue repartir la tarea entre tres agentes. Un planificador escribe la especificación, un generador construye, y un evaluador aparte prueba la app en marcha con Playwright según unos criterios pactados antes de escribir una sola línea de código. Un agente en solitario tardó 20 minutos y costó 9 $. El harness completo tardó seis horas y costó 200 $, y el resultado era muchísimo mejor. La verificación no aparece por arte de magia. Alguien tiene que meterla en el harness, a veces en forma de un segundo agente entero cuyo único trabajo es no darse nunca por satisfecho.
Extensibilidad
Un buen harness te deja cambiar su comportamiento sin tener que hacer un fork. Claude Code expone más de 30 eventos de hook del ciclo de vida a los que puedes enganchar scripts, además de skills, plugins, subagentes y servidores MCP. Aquí es donde entran las convenciones de cada equipo.
Este es un hook real, de los que yo pondría el primer día. Después de cada edición, pasa el formateador por el archivo que ha cambiado:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
}
]
}
]
}
}Fíjate en el comando. El harness le pasa el evento como JSON por la entrada estándar, jq saca un campo y xargs se lo entrega a otro programa. Eso es un pipeline de Unix, y no es casualidad.
Por qué la shell hace casi todo el trabajo
Mi primer trabajo fue de administrador de servidores Linux, y lo que me enganchó entonces fue lo mucho que cabía en una sola línea. Encadenabas unos cuantos programas pequeños y algo que sonaba a una tarde entera de trabajo quedaba resuelto antes de que acabaras de teclear. Me conquistaron líneas como esta:
grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | headAhí tienes todas las IP que intentaron entrar por fuerza bruta en el SSH de la máquina, contadas y ordenadas de más a menos, con cinco programas que no saben nada unos de otros. Ver trabajar a un agente de programación me produce la misma sensación. Echa mano del mismo tipo de herramientas, y más o menos en el orden en que lo haría yo:
$ rg -n "InvoiceTotal" src/
$ sed -n '118,160p' src/billing/invoice.ts
$ npm test -- invoice
$ git diff --statPara mí, de aquí sale casi toda la capacidad de actuar de un agente de programación. Dale a un modelo una sola herramienta, una shell, y con ella se lleva todos los programas de la máquina. Nadie tuvo que construir una herramienta search_code ni otra run_tests. rg y npm test ya existían, con décadas de documentación detrás.
Hay cuatro cosas que, en mi opinión, hacen que la shell encaje tan bien con un modelo de lenguaje.
La primera es que habla en texto. Doug McIlroy dejó la regla por escrito en el Bell System Technical Journal en 1978: "Cuenta con que la salida de cada programa se convierta en la entrada de otro programa, todavía desconocido". En Bell Labs nadie pensaba en modelos de lenguaje, pero lo de un programa desconocido que lee tu salida describe bastante bien a uno.
La segunda, que los modelos ya la conocen. Cincuenta años de páginas man, scripts de shell, READMEs y respuestas en foros están en sus datos de entrenamiento. Zechner lo dijo bien claro al explicar por qué Pi trae solo cuatro herramientas (read, write, edit y bash): "Los modelos saben usar bash".
La tercera, que cada comando rinde cuentas. Un código de salida, 0 o distinto de 0, es un sensor gratis. El agente sabe si el test ha pasado sin que nadie le haya escrito una capa de verificación.
Y la cuarta, que los programas se combinan. Un pipe convierte dos herramientas pequeñas en una tercera sobre la marcha, así que el harness no necesita una herramienta específica para cada trabajo.
Hay otra pieza de Unix trabajando aquí en silencio, y el análisis de LangChain sobre la anatomía de un harness la llama "posiblemente la primitiva más fundamental de un harness": el sistema de archivos. Un modelo lo olvida todo en cuanto se acaba su contexto. Un archivo, no. Una nota de progreso, una lista de funcionalidades, un git log: así sobrevive una tarea larga de una sesión a la siguiente, y de eso se encargan los archivos y git, que llevan cincuenta años haciendo justo eso.
Los fabricantes han llegado a la misma conclusión por el camino contrario. Anthropic describe el principio de diseño de su Claude Agent SDK como dar "a tus agentes un ordenador, para que puedan trabajar como lo hacen las personas". Boris Cherny, el creador de Claude Code, ha contado que las primeras versiones usaban RAG con una base de datos vectorial local, y que el equipo se pasó a la búsqueda agéntica a secas (el modelo lanzando grep y compañía) porque funcionaba mejor. Él mismo reconoce que aquello se decidió más por intuición del equipo que por un benchmark, pero es lo que acabaron publicando. Vercel dejó un agente interno de datos en poco más que una única herramienta bash y, según sus datos, pasó a ir 3,5 veces más rápido con un 37% menos de tokens. Lo midieron con cinco consultas de prueba, así que tómalo como una pista, no como una medición.
La shell también tiene sus límites, y conviene conocerlos. No puede ir haciendo clic por una aplicación web, así que el trabajo con interfaces gráficas sigue necesitando herramientas de navegador o de computer use. Un producto SaaS sin CLI entra por una API o por un servidor MCP. Y la misma shell que ejecuta npm test puede ejecutar rm -rf, que es precisamente la razón de ser de la sección de guardrails.
Comparativa de agentes de programación
Estos son los harness por los que más me preguntan, tal y como están en septiembre de 2026. Los valores por defecto cambian rápido, así que revisa la documentación antes de fiarte de cualquier celda.
| Agente | Código abierto | Modelos | Seguridad por defecto | Herramientas incluidas |
|---|---|---|---|---|
| No | Solo Claude | Clasificador en Pro, Max y Team; si no, pregunta | Más de 40; las básicas son Read, Edit, Grep, Glob, Bash | |
| Apache 2.0 | OpenAI por defecto, otros por configuración | Sandbox del SO, solo el directorio de trabajo, sin red | Sobre todo shell, más apply_patch | |
| Apache 2.0 | Solo Gemini | Sin sandbox, confirma shell y escrituras | Unas 20, entre ellas shell y grep | |
| No | Muchos proveedores | Shell en sandbox, un clasificador revisa el resto | Búsqueda, lectura, edición, shell, navegador | |
| MIT | Casi cualquiera, vía LiteLLM | Sandbox Docker en la app web, pregunta antes en la CLI | Terminal, editor de archivos, gestor de tareas | |
| Apache 2.0 | Casi cualquiera, también locales | Sin sandbox, hace commit de cada edición, pregunta antes de ejecutar comandos | Sin bucle de herramientas: formatos de edición y un mapa del repo | |
| Apache 2.0 | Muchos, también locales | Pregunta antes de cada acción | 7, con ripgrep para buscar | |
| MIT | Más de 15 proveedores | Sin sandbox, sin confirmaciones | 4: read, write, edit, bash |
Lee la última columna de arriba abajo. Los harness que más se apoyan en la shell son los que menos herramientas traen, y Codex, el más centrado en la shell de los tres grandes, es también el más estricto a la hora de encerrarla en un sandbox. Esa combinación no es casual. Aider es la excepción: es anterior al tool calling y sigue funcionando con formatos de edición y un mapa del repo, lo que recuerda que el bucle de mi pseudocódigo es un diseño entre varios posibles.
Más allá del código
Nada del primer diagrama es exclusivo del software. Microsoft Agent Framework llegó a la 1.0 en abril de 2026, y en junio, en Build, estrenó un harness integrado con acceso a shell y archivos, aprobación de herramientas, memoria basada en archivos y compactación automática del contexto. LangChain Deep Agents y el OpenAI Agents SDK ofrecen piezas parecidas.
Al salir del código, lo que cambia es sobre todo una fila:
| Agente de programación | Agente general | |
|---|---|---|
| Bucle | el mismo | el mismo |
| Herramientas | shell, git, archivos | APIs, navegador, email, CRM |
| Contexto | repo, diffs | documentación, tickets, historial de chat |
| Guardrails | sandbox | aprobación para envíos, pagos y borrados |
| Verificación | tests, de serie | evals, rúbricas, revisión humana |
Un agente de investigación no tiene una batería de tests. Un agente de soporte no puede pasarle npm test a una respuesta. El código de salida que hace tan fácil comprobar a los agentes de programación aquí no existe, así que un harness general tiene que fabricarse sus propios sensores: conjuntos de evaluación sacados de casos reales, agentes revisores con rúbricas y puntos en los que una persona da el visto bueno. Si estás construyendo un agente fuera del código, aquí es donde deberías invertir el tiempo, porque es donde fallan esos agentes, y suelen hacerlo sin avisar. Tengo otro post sobre cómo son esos fallos silenciosos en producción.
Cómo juzgar un harness
Tanto si vas a elegir uno como si vas a construir el tuyo, mide el conjunto entero y no solo el modelo:
- Coste por tarea completada, no coste por token.
- Tasa de éxito en tus propias tareas, no en un ranking público.
- Tareas largas: ¿las termina o se atasca a mitad de camino?
- Modelo de seguridad: ¿qué puede romper y quién da el visto bueno?
- Encaje: ¿funciona con tus herramientas y tus convenciones?
El coste es lo que más se subestima. Cuando Artificial Analysis lanzó su Coding Agent Index en mayo de 2026, el coste por tarea de las combinaciones de modelo y harness que probó iba de 0,07 $ a 2,26 $. Casi toda esa horquilla se explica por el modelo, pero es el harness el que decide cuántos tokens gasta el modelo por el camino.
La máquina de debajo también mueve los números. El equipo de ingeniería de Anthropic pasó el mismo modelo Claude por el mismo harness, con las mismas tareas de Terminal-Bench 2.0, y encontró 6 puntos porcentuales de diferencia entre los recursos de contenedor más ajustados y los más generosos. Así que haz la comparación en la infraestructura que vayas a usar de verdad.
Hacia dónde va esto
Está empezando a aparecer una capa por encima de los harness. En junio de 2026 Databricks liberó Omnigent, que describe como un "meta-harness": se coloca por encima de Claude Code, Codex, Pi o tu propio agente y te permite combinarlos y gobernarlos desde un solo sitio. Si la idea cuaja, el harness pasará a ser un componente intercambiable, igual que hoy cambias una base de datos por otra.
Parte del harness actual también acabará dentro del modelo. La mejor frase que he leído sobre esto viene de aquel post de Anthropic: "Cada componente de un harness codifica una suposición sobre lo que el modelo no puede hacer por sí solo". La comprobación same_command_failed de mi pseudocódigo da por hecho que el modelo no se dará cuenta de que está dando vueltas sin avanzar. La compactación da por hecho que no es capaz de abarcar una tarea larga en una sola ventana. Conforme los modelos mejoren, algunas de esas suposiciones dejarán de cumplirse, y las piezas que se apoyan en ellas sobrarán.
Lo que no espero que cambie es la frontera de los permisos. Un modelo puede aprender a cazar sus propios errores. Lo que tiene permitido borrar en tu servidor de producción sigue siendo decisión tuya, y queda escrito en un harness, igual que quedaba en un fichero sudoers mucho antes de todo esto.
Si estás dándole vueltas a cómo debería ser ese harness en tu equipo, mi calendario está en la página de contacto.
Fuentes
- Birgitta Böckeler, Harness engineering for coding agent users, martinfowler.com, abril de 2026
- Sydney Lewis, Same Model, Different Harness: Different Coding-Agent Results, arXiv, agosto de 2026
- OpenAI, Harness engineering: leveraging Codex in an agent-first world
- Anthropic, Building agents with the Claude Agent SDK
- M. D. McIlroy, E. N. Pinson y B. A. Tague, UNIX Time-Sharing System: Foreword, Bell System Technical Journal, 1978
- Mario Zechner, What I learned building an opinionated and minimal coding agent, noviembre de 2025
- Boris Cherny sobre la búsqueda agéntica que sustituyó a RAG en Claude Code, febrero de 2026
- Vercel, We removed 80% of our agent's tools, diciembre de 2025
- Artificial Analysis, Coding Agent Index y su anuncio de lanzamiento de mayo de 2026
- Anthropic, Quantifying infrastructure noise in agentic coding evals
- Anthropic, Harness design for long-running application development, marzo de 2026
- LangChain, The anatomy of an agent harness, marzo de 2026
- Microsoft, Microsoft Agent Framework at BUILD 2026
- Databricks, Introducing Omnigent
- Documentación de las herramientas de la tabla comparativa: herramientas de Claude Code, modos de permisos y hooks; Codex y sus aprobaciones y seguridad; herramientas de Gemini CLI; modos de ejecución de Cursor; OpenHands; Aider; herramientas de Cline; Pi