Capítulo 2 — Harness Engineering: el marco de ingeniería
Capítulo 2 — Harness Engineering: el marco de ingeniería
Basado en el artículo de Birgitta Böckeler, Distinguished Engineer en Thoughtworks, publicado en martinfowler.com (abril 2026).
Del patrón a la disciplina
El capítulo anterior mostró un harness concreto: feature list, progress file, init.sh. Funciona, es replicable, resuelve problemas reales. Pero deja preguntas abiertas:
- ¿Por qué esos componentes y no otros?
- ¿Cómo decido qué agregar al harness cuando el agente falla en algo nuevo?
- ¿Qué hace que un codebase sea fácil o difícil de “harnesear”?
- ¿Por dónde empieza un equipo que recién entra a esto?
Böckeler propone que el harness engineering no es una receta sino una práctica de ingeniería continua — equiparable a testing, observabilidad o seguridad — con su propio vocabulario y sus propias decisiones de diseño. Este capítulo presenta ese vocabulario.
La ecuación base
flowchart LR
M[Modelo] --> AB[Agent Builder Harness]
AB --> UB[User Harness]
UB --> A[Agente útil]
style M fill:#fde68a,stroke:#92400e
style UB fill:#bfdbfe,stroke:#1e40af
Agent = Model + Harness
El modelo (Claude, GPT, Gemini) es el núcleo: una caja de inferencia con capacidades generales. A su alrededor existen dos capas concéntricas de harness:
- Harness del builder del agente: lo que aporta el creador de la herramienta (Cursor, Claude Code, Cline, Aider). Loops, gestión de contexto, herramientas built-in.
- Harness del usuario: lo que aporta el equipo que usa la herramienta dentro de su codebase. Reglas, scripts, sensores, convenciones, plantillas.
El artículo se enfoca en la segunda capa — la que está bajo tu control. Es donde tu equipo gana o pierde la batalla por la calidad cuando trabaja con agentes.
Feedforward y feedback: las dos palancas
Todo control que pongas en el harness cae en una de dos categorías:
Guías (feedforward)
Anticipan el comportamiento del agente antes de que actúe. Empujan la probabilidad de éxito al primer intento.
Ejemplos:
- Documentación de arquitectura (
AGENTS.md,CLAUDE.md) - Scripts de bootstrap (
init.sh) - Skills, prompts del sistema, plantillas
- Convenciones documentadas
- “Howtos” para tareas frecuentes
Sensores (feedback)
Observan después de que el agente actúa. Le permiten autocorrección.
Ejemplos:
- Tests, linters, type checkers
- Output de un build
- Resultado de una herramienta de automatización de browser
- “LLM como juez” de un bot revisor
- Sondas de runtime
flowchart LR
F1[Feedforward\nguías] -->|prevenir| AC[Acción del agente]
AC --> F2[Feedback\nsensores]
F2 -->|corregir| AC
F2 -->|aprender| F1
style F1 fill:#dcfce7,stroke:#166534
style F2 fill:#fee2e2,stroke:#991b1b
La regla crítica
Cada palanca por separado falla:
- Solo feedforward: codificás reglas pero no validás que el agente las siga. Las reglas se ignoran silenciosamente.
- Solo feedback: el agente repite el mismo error en cada intento. Cada sesión empieza igual de ciega.
Un harness útil siempre combina ambas. Si tu agente ignora una convención, no alcanza con escribirla en un markdown — necesitás un sensor que la detecte. Si el sensor detecta, no alcanza — necesitás que la guía evite que se repita.
Inyección positiva de prompt: los sensores más potentes generan señales “optimizadas para consumo de LLM”. No solo dicen “test fallido”, sino “test fallido en X.spec.ts:42; la causa probable es Y; revisá la convención Z documentada en AGENTS.md”. El feedback se convierte en feedforward de la siguiente iteración.
Computacional vs inferencial
Los sensores y guías se pueden ejecutar de dos maneras radicalmente distintas:
| Tipo | Quién ejecuta | Velocidad | Costo | Determinismo |
|---|---|---|---|---|
| Computacional | CPU | ms a segundos | bajo | alto |
| Inferencial | GPU/NPU (otro LLM) | segundos a minutos | alto | bajo |
Computacional
Tests, linters, type checkers, análisis estructural, métricas de complejidad ciclomática, escaneos de dependencias. Resultados confiables y reproducibles.
Inferencial
Análisis semántico, detección de código duplicado conceptualmente, “LLM como juez” para revisar PRs, validación de que un test cubre el caso real y no un falso positivo. Más caro y probabilístico, pero captura cosas que el código no puede capturar.
El criterio de elección
Privilegiá computacional cuando puedas. Es más barato, más rápido, más confiable y permite poner el sensor más temprano en el ciclo. Reservá inferencial para los problemas semánticos donde no hay alternativa: ¿esta función está sobreingenierizada?, ¿este test prueba algo útil?, ¿este nombre transmite la intención correcta?
El bucle de dirección (steering loop)
El humano no desaparece — su rol cambia. En lugar de revisar cada cambio del agente, itera sobre el harness cuando aparecen problemas repetidos.
flowchart LR
O[Observar\nproblema repetido] --> D[Diseñar\nguía o sensor]
D --> I[Integrar\nen harness]
I --> A[Agente actúa]
A --> O
style O fill:#fef3c7,stroke:#92400e
Pasos típicos:
- Notás que el agente comete el mismo error varias veces.
- Decidís: ¿es un problema de feedforward (no sabe qué hacer) o de feedback (no detecta que falló)?
- Diseñás el control mínimo: un test estructural, una línea en
AGENTS.md, un linter custom, un skill nuevo. - Lo integrás. La próxima vez el agente ya no comete el error — o si lo comete, lo corrige solo.
Lo interesante: el propio agente puede construir esos controles. Le pedís “escribí un linter que detecte cuando alguien usa fetch sin manejar errores” y queda incorporado al harness para siempre.
Keep quality left
El timing del control importa tanto como el control en sí. La regla: cuanto antes se active el sensor, mejor.
flowchart LR
PRE[Pre-integración\nrápido] --> POST[Post-integración\npipeline]
POST --> RUN[Runtime / Drift\nmonitoreo continuo]
style PRE fill:#dcfce7,stroke:#166534
style POST fill:#fef3c7,stroke:#92400e
style RUN fill:#fee2e2,stroke:#991b1b
Pre-integración (rápido y barato)
- Language Server Protocol (LSP)
- Linters
- Tests rápidos unitarios
- Agente revisor básico
- Pre-push hooks
Estos sensores corren en segundos. El agente los ejecuta dentro de su propio loop, antes de declarar la tarea completa.
Post-integración (más caro, más profundo)
- Tests de mutación
- Revisiones amplias considerando contexto mayor
- Reiteración de los chequeos rápidos
- Métricas de calidad agregada
Corren en CI. Tardan más pero atrapan problemas que requieren ver el conjunto.
Runtime y drift (continuo)
- Detección de código muerto
- Cobertura agregada
- Escaneo de dependencias
- Monitoreo de SLOs
- Detección de drift arquitectónico
Corren periódicamente o continuamente. Atrapan problemas que no son visibles en un cambio individual.
Stripe es ejemplo público de esta filosofía: aplican pre-push hooks con linters relevantes, integrando blueprints que llevan los sensores de feedback al inicio del workflow del agente.
Tres categorías de regulación
Böckeler distingue tres dominios donde aplicar harness — cada uno con grados diferentes de madurez.
1. Mantenibilidad
El más maduro. Sensores computacionales atrapan confiablemente:
- Código duplicado
- Complejidad ciclomática
- Cobertura de tests faltante
- Drift arquitectónico
- Violaciones de estilo
Para los problemas semánticos (código conceptualmente duplicado, tests redundantes, soluciones de fuerza bruta) los LLMs ayudan parcialmente — pero costoso y probabilístico.
Lo que no captura ningún sensor: diagnóstico erróneo del problema, sobreingeniería, features innecesarias, instrucciones malinterpretadas. Estos requieren claridad humana inicial, antes de delegarle al agente.
2. Fitness arquitectónico
Inspirado en las fitness functions de Building Evolutionary Architectures. Define qué características arquitectónicas debe mantener el sistema y verifica que se cumplan.
Ejemplos:
- Skill que comunica requisitos de rendimiento + tests que retroalimentan al agente
- Convenciones de logging que mejoran observabilidad
- Instrucciones de debugging que piden reflexión sobre la calidad de los logs antes de cerrar el ticket
- Reglas de dependencia entre módulos verificadas con linters de arquitectura
3. Comportamiento
El “elefante en la sala”. Hoy se aborda así:
- Feedforward: especificación funcional (desde un prompt corto hasta documentación multi-archivo).
- Feedback: verificar que la suite de tests generada por IA quede en verde, con cobertura razonable, posiblemente tests de mutación, combinado con testing manual.
El problema: confiamos demasiado en tests generados por la misma IA. Si el agente escribe el código y el test, ambos pueden estar mal de la misma manera. El patrón approved fixtures (snapshots aprobados manualmente) es prometedor pero no universal.
La solución integral para harness de comportamiento sigue siendo un problema abierto. Acá el humano todavía es indispensable.
Harnessability
No todos los codebases son igualmente “harneseables”. Las propiedades favorables:
| Propiedad | Por qué ayuda |
|---|---|
| Tipado fuerte | Habilita verificación de tipos como sensor barato y temprano |
| Límites de módulo claros | Permite reglas de restricción arquitectónica |
| Frameworks que abstraen detalles | Reducen lo que el agente debe considerar |
| Affordances ambientales | Estructura legible, navegable, “tratable” para agentes |
El dilema legacy vs greenfield
Un equipo nuevo con codebase greenfield puede integrar harnessability desde el día uno. Un equipo legacy con deuda técnica enfrenta la paradoja: el harness es más necesario justamente donde es más difícil construirlo.
La consecuencia práctica: en codebases legacy, los primeros sprints de adopción de agentes deberían incluir trabajo deliberado de mejora de harnessability — agregar tipos, definir límites de módulo, eliminar singletons globales, separar capas. No es trabajo desperdiciado: es la condición previa para que el agente pueda contribuir sin romper.
Plantillas de harness
Las empresas maduras ya estandarizan topologías de servicios: el “servicio empresarial con API REST”, el “procesador de eventos”, el “dashboard de datos”. Cada topología tiene su scaffold, sus librerías estándar, su forma de hacer logging.
La predicción de Böckeler: estas topologías evolucionarán a plantillas de harness — paquetes que incluyen además las guías y sensores específicos para esa topología.
flowchart TD
T[Topología:\nAPI REST empresarial] --> S[Scaffold de código]
T --> H[Skills + sensores]
T --> R[Reglas arquitectónicas]
H --> A[Agente sabe\nqué esperar]
R --> A
S --> A
style T fill:#bfdbfe,stroke:#1e40af
Implicación profunda: la elección de stack tecnológico empezará a depender de qué harnesses están disponibles, no al revés. Si el equipo de plataforma mantiene un harness sólido para FastAPI + PostgreSQL pero no para Hono + SQLite, hay un costo invisible al elegir el segundo.
Desafíos abiertos: versioning, sincronizar mejoras upstream con downstream, gobernanza de contribuciones — peor todavía cuando los componentes son no determinísticos y difíciles de testear.
La ley de Ashby
Ley de variedad requisita de Ashby: un regulador debe poseer al menos tanta variedad como el sistema que regula.
Aplicada a agentes: un LLM puede generar casi cualquier cosa. Construir un harness que cubra ese espacio infinito es imposible. La salida es reducir la variedad del sistema.
Una topología comprometida (REST + Postgres + JWT, por decir algo) es una decisión estratégica de variety reduction. Restringe lo que el agente puede hacer, lo que vuelve realista construir un harness comprehensivo.
Esto reordena cómo se piensa la arquitectura:
- Antes: “elegimos REST porque es lo mejor para nuestro caso de uso”
- Ahora: “elegimos REST porque tenemos un harness sólido para REST y eso vale más que la diferencia marginal con otras opciones”
El rol del humano
Un desarrollador humano trae a cada codebase un harness implícito:
- Habilidades y experiencia internalizadas
- Sensibilidad cognitiva ante complejidad (“esto huele mal”)
- Responsabilidad social (“mi nombre va en el commit”)
- Alineamiento organizacional con prioridades del equipo
Un agente carece de:
- Responsabilidad social
- Disgusto estético frente a una función de 300 líneas
- Intuición contexto-específica
- Memoria organizacional
El objetivo del harness no es eliminar al humano, sino dirigir su atención hacia donde realmente vale: las decisiones que ningún sensor puede tomar.
flowchart LR
H[Atención\nhumana] -->|antes| TODO[Revisar\ntodo]
H2[Atención\nhumana] -->|con harness| CRIT[Decisiones críticas:\ndiagnóstico, scope,\ntrade-offs estratégicos]
style TODO fill:#fee2e2,stroke:#991b1b
style CRIT fill:#dcfce7,stroke:#166534
Ejemplos de la práctica actual
OpenAI
Arquitectura en capas reforzada por linters custom y tests estructurales. Recolección de basura recurrente. Su conclusión pública: “los desafíos más difíciles ahora se centran en diseñar ambientes, loops de feedback y sistemas de control” — exactamente la definición de harness engineering.
Stripe
Pre-push hooks con linters relevantes; énfasis explícito en “shift feedback left”; blueprints que integran sensores de feedback dentro de los workflows de agentes desde el inicio.
Tendencias emergentes
- Resurgimiento de tests de mutación y estructurales (que estaban olvidados)
- Integración de LSP en agentes
- Drift arquitectónico atacado con combinación de sensores computacionales e inferenciales
Preguntas abiertas
Böckeler cierra con preguntas que la disciplina todavía no resolvió:
- Coherencia a escala: ¿cómo mantener un harness coherente conforme crece, evitando que las reglas se contradigan entre sí?
- Trade-offs: ¿hasta dónde se puede confiar en que el agente haga trade-offs sensatos cuando las instrucciones y el feedback divergen?
- Silencio sospechoso: si los sensores nunca se activan, ¿es señal de calidad alta o de detección inadecuada?
- Cobertura de harness: ¿necesitamos una métrica análoga a code coverage para medir cuánto del comportamiento posible está realmente cubierto?
- Tooling unificado: ¿qué herramientas podrían sincronizar todos los controles como un sistema coherente, en lugar de archivos sueltos?
Estas no son preguntas retóricas. Son el espacio de investigación abierto para los próximos años.
Conexión con el capítulo 1
Mirando la propuesta de Anthropic con este vocabulario, los componentes encajan así:
| Componente del capítulo 1 | En términos del marco de Fowler |
|---|---|
init.sh | Feedforward / guía operacional |
AGENTS.md, system prompt | Feedforward / guía de comportamiento |
feature-list.json (con passes) | Feedback computacional + variety reduction |
claude-progress.txt | Memoria persistente — ni feedforward puro ni feedback, una tercera pieza |
| Browser automation | Sensor inferencial post-acción |
| Git como fuente de verdad | Sensor computacional + memoria |
| ”Una feature por sesión” | Variety reduction (ley de Ashby aplicada al scope) |
La regla de “no eliminar tests existentes” es un sensor estructural que se asegura de que el agente no degrade el feedback futuro. Es harness sobre el harness.
Cómo aplicarlo a tu equipo
Plan mínimo de adopción:
flowchart TD
A[1. Auditar codebase\nharnessability] --> B[2. Listar problemas\nrepetidos del agente]
B --> C[3. Para cada uno:\n¿feedforward o feedback?]
C --> D[4. Implementar\nel sensor más barato]
D --> E[5. Iterar\nsteering loop]
E --> B
- Auditar harnessability: ¿el codebase tiene tipos? ¿límites de módulo? ¿affordances claras? Anotar lo que falta.
- Listar fallas repetidas: las últimas 5–10 sesiones donde el agente metió la pata, ¿qué patrón se repite?
- Diagnosticar: cada falla, ¿es porque el agente no sabía algo (feedforward) o porque no detectó que falló (feedback)?
- Implementar el control más barato que resuelve cada falla: privilegiar computacional sobre inferencial, pre-integración sobre post-integración.
- Iterar: el harness no se diseña una vez. Es un loop continuo donde cada falla nueva es input para el siguiente sprint de mejora.
Conclusión
El harness engineering externaliza y vuelve explícito lo que la experiencia de un desarrollador humano aporta implícitamente. Pero — y esto es importante — “solo puede llegar hasta cierto punto”.
Construir un harness coherente es caro. Exige priorización. Un harness bueno dirige el input humano a donde más vale, no elimina toda supervisión.
El cierre de Böckeler:
El harness engineering emerge como una práctica continua de ingeniería, no una configuración inicial.
Es el mismo cambio mental que hubo cuando testing dejó de ser “lo que hace QA al final” y se volvió práctica continua del desarrollador. Cuando observabilidad dejó de ser “logs por las dudas” y se volvió diseño explícito de qué medir y cómo. Ahora le toca al harness.
Nota meta del artículo original: GenAI (Claude y Claude Code) fue usado para investigación, integración de ideas y pulido de lenguaje del propio artículo de Fowler — un ejemplo perfecto de cómo las herramientas de IA requieren ellas mismas un harness para producir resultados confiables.
En el próximo capítulo bajamos del marco a la práctica vivida: Mitchell Hashimoto documenta las seis fases por las que pasó hasta integrar agentes en su día a día. Es la mejor evidencia pública de que el harness no se diseña de entrada — emerge cuando la práctica encuentra problemas y los nombra.
Fuente: Harness Engineering for Users of Coding Agents — Birgitta Böckeler, martinfowler.com, abril 2026.