Intro

Harness engineering se entiende mejor cuando deja de ser una palabra abstracta y se aplica a una tarea concreta.

Tomemos un caso: queremos un agente de IA capaz de ayudar a construir una aplicación web para enseñanza virtual.

La aplicación debería permitir crear cursos, cargar materiales, organizar clases en vivo, generar cuestionarios, medir progreso de estudiantes, dar feedback a docentes y preparar reportes. El agente podría colaborar en muchas partes: tomar requisitos, proponer arquitectura, escribir componentes, generar tests, revisar accesibilidad, preparar migraciones, crear documentación y armar un preview para aprobar.

La pregunta no es si el modelo puede escribir código. Eso ya lo sabemos.

La pregunta importante es otra:

¿qué sistema rodea al modelo para que pueda trabajar sin romper el proyecto, inventar requisitos, saltarse aprobaciones o desplegar cambios inseguros?

Ese sistema es el harness.

En un artículo anterior hablamos de harness engineering como la capa que convierte agentes de IA en sistemas operables. Esta pieza baja el concepto a una implementación práctica usando una aplicación web de enseñanza virtual como hilo conductor.

El caso de uso

Supongamos que el objetivo inicial es construir un MVP de plataforma educativa.

Funcionalidades esperadas:

  • panel de docente;
  • creación de cursos y módulos;
  • carga de videos, PDFs y enlaces;
  • clases en vivo o sesiones programadas;
  • cuestionarios por módulo;
  • seguimiento de progreso del estudiante;
  • certificados simples;
  • administración de usuarios;
  • reportes básicos de participación.

Un pedido humano podría ser:

armame una app web para enseñanza virtual con cursos, clases y seguimiento de alumnos

Un agente sin harness podría intentar resolverlo todo de una vez: elegir stack, crear archivos, escribir UI, inventar base de datos, agregar autenticación, generar lógica de progreso, tocar configuración y quizá intentar desplegar.

Eso puede producir una demo rápida, pero también un sistema difícil de revisar.

Un harness obliga a transformar ese pedido en una secuencia operable.

pedido
  -> aclarar alcance
  -> crear brief funcional
  -> proponer arquitectura
  -> generar plan de implementación
  -> modificar código en una rama
  -> correr tests y linters
  -> crear preview
  -> pedir aprobación
  -> recién después desplegar

El modelo sigue siendo útil. Pero ya no decide todo dentro de una conversación larga. Trabaja dentro de un flujo con contratos, estado, permisos y validaciones.

El harness mínimo para este proyecto

Para este caso, un harness mínimo viable debería tener siete capas:

1. contrato de entrada
2. contexto del proyecto
3. registry de tools
4. estado de ejecución
5. políticas de permisos
6. validadores
7. observabilidad y evals

No hace falta construir una plataforma gigante el primer día. Pero sí hace falta separar las decisiones que no deberían quedar solo en el prompt.

1. Contrato de entrada: convertir un pedido en una tarea

El primer paso es normalizar el pedido.

No alcanza con pasarle al modelo: "hacé una app de enseñanza virtual". El harness debería crear una estructura más precisa:

{
  "task_type": "build_web_app_feature_set",
  "project": "virtual_learning_platform",
  "requester": "product_owner",
  "goal": "MVP para cursos, clases y seguimiento de estudiantes",
  "allowed_actions": [
    "read_repo",
    "create_plan",
    "edit_code",
    "run_tests",
    "create_preview"
  ],
  "blocked_actions": [
    "deploy_production",
    "send_external_email",
    "delete_database"
  ],
  "approval_required_for": [
    "schema_migration",
    "dependency_change",
    "production_deploy"
  ]
}

Este contrato evita una confusión central: intención no es autorización.

Que alguien pida construir una app no significa que el agente pueda desplegar a producción. Que el agente pueda editar código no significa que pueda cambiar el modelo de datos sin revisión. Que tenga acceso al repositorio no significa que pueda tocar secretos, billing o infraestructura.

El contrato también obliga a declarar el alcance. Para una plataforma educativa, eso importa mucho porque el dominio se expande rápido: pagos, videollamadas, certificados, analíticas, roles, notificaciones, privacidad, accesibilidad, contenido sensible y datos de menores en algunos contextos.

Un buen harness no deja que todo eso aparezca como decisiones improvisadas durante la generación de código.

2. Contexto del proyecto: qué debe ver el agente

Para construir una app web, el agente necesita contexto. Pero no necesita todo.

Debería recibir:

  • stack técnico actual;
  • estructura del repositorio;
  • convenciones de UI;
  • sistema de autenticación;
  • modelo de datos existente;
  • reglas de diseño;
  • criterios de accesibilidad;
  • restricciones de seguridad;
  • definición del MVP;
  • issues o decisiones previas relevantes.

No debería recibir, sin filtro, todo el historial de chats, todos los documentos internos y todos los archivos del repo.

En este caso, el paquete de contexto podría verse así:

context_pack:
  stack:
    frontend: "React + TypeScript"
    backend: "Node API"
    database: "PostgreSQL"
 
  product_scope:
    include:
      - course_catalog
      - lesson_player
      - quiz_builder
      - student_progress
      - teacher_dashboard
    exclude:
      - payments
      - live_video_provider_integration
      - public marketplace
 
  constraints:
    accessibility: "WCAG AA baseline"
    auth: "roles: admin, teacher, student"
    deployment: "preview only until approved"

Esto reduce ruido. También evita que el agente implemente cosas fuera de alcance porque "parecían útiles".

3. Registry de tools: no todas las acciones son iguales

Un agente que construye una app necesita herramientas.

Pero no conviene exponerlas como un bloque genérico tipo "puede usar shell, git, browser y deploy".

El harness debería clasificar tools por riesgo:

tools:
  repo.read:
    risk: low
    approval: never
 
  code.edit:
    risk: medium
    approval: never
    scope: "feature_branch"
 
  tests.run:
    risk: low
    approval: never
 
  db.migration.create:
    risk: medium
    approval: required_before_merge
 
  preview.deploy:
    risk: medium
    approval: never
    environment: "preview"
 
  production.deploy:
    risk: high
    approval: required

Este diseño separa lectura, preparación, preview y ejecución final.

Para una aplicación de enseñanza virtual, esa separación es clave. Un cambio visual en el dashboard docente no tiene el mismo riesgo que una migración que afecta progreso de estudiantes. Una prueba local no tiene el mismo riesgo que un deploy productivo. Un preview interno no tiene el mismo riesgo que enviar invitaciones reales a usuarios.

4. Estado: que el trabajo no dependa del chat

Un flujo de construcción de app tiene muchos pasos.

Si el estado vive solo en la conversación, el agente termina dependiendo de memoria frágil: qué pidió el usuario, qué se implementó, qué falló, qué quedó pendiente, qué fue aprobado.

El harness debería guardar estado por ejecución:

{
  "run_id": "run_edu_mvp_001",
  "status": "preview_ready",
  "completed_steps": [
    "requirements_brief",
    "architecture_plan",
    "course_model_created",
    "teacher_dashboard_ui",
    "quiz_module",
    "tests_run",
    "preview_created"
  ],
  "pending_steps": [
    "human_review",
    "migration_approval",
    "production_deploy"
  ],
  "artifacts": {
    "brief": "state/runs/run_edu_mvp_001/brief.md",
    "plan": "state/runs/run_edu_mvp_001/plan.md",
    "preview_url": "https://preview.example.com/edu-mvp",
    "test_report": "state/runs/run_edu_mvp_001/tests.json"
  }
}

Esto permite retomar el trabajo sin adivinar.

También permite responder preguntas operativas:

  • qué se hizo;
  • qué falta;
  • qué falló;
  • qué se aprobó;
  • qué archivos cambió el agente;
  • qué versión se está revisando.

En sistemas reales, esta trazabilidad vale tanto como el código.

5. Policy layer: qué puede hacer sin preguntar

Un harness práctico define políticas fuera del modelo.

Para este caso:

policies:
  create_ui_component:
    approval: never
    require_tests: true
 
  add_dependency:
    approval: required
    require_reason: true
 
  create_database_migration:
    approval: required_before_merge
    require_rollback_notes: true
 
  deploy_preview:
    approval: never
    require_build_ok: true
 
  deploy_production:
    approval: required
    require:
      - approved_preview
      - tests_ok
      - migration_reviewed
      - rollback_plan

Esto evita depender de una frase tipo "no hagas nada riesgoso".

La política se puede explicar en el prompt, pero debe aplicarse desde el harness. Si el modelo intenta desplegar a producción sin aprobación, la tool debería rechazar la acción.

6. Validadores: frenar errores antes de encadenarlos

Los agentes suelen fallar en las uniones entre pasos.

No siempre fallan porque escriben mal una función. Fallan porque:

  • usan una ruta equivocada;
  • rompen una convención de componentes;
  • agregan una dependencia innecesaria;
  • olvidan estados vacíos;
  • no contemplan permisos por rol;
  • generan UI inaccesible;
  • crean tests superficiales;
  • toman un preview local como si fuera producción;
  • no detectan que una migración es destructiva.

Para la app de enseñanza virtual, algunos validadores útiles serían:

Antes de entregar preview:
  - build exitoso
  - tests principales pasan
  - no hay secretos en el diff
  - roles admin/docente/estudiante están separados
  - dashboard no muestra datos de otros cursos
  - quiz maneja estados vacío/en progreso/completado
  - navegación básica es accesible por teclado
  - no se agregó dependencia sin justificación

El validador no reemplaza una revisión humana. Pero evita que el agente entregue una versión obviamente incompleta o riesgosa.

7. Observabilidad: ver cómo trabajó el agente

Si el agente construye una parte de la aplicación, necesitamos trazabilidad.

No alcanza con el resultado final. El harness debería registrar:

  • qué contexto recibió;
  • qué plan propuso;
  • qué tools ejecutó;
  • qué archivos tocó;
  • qué comandos corrió;
  • qué tests pasaron o fallaron;
  • qué validadores bloquearon acciones;
  • qué decisiones quedaron pendientes de aprobación.

Ejemplo de evento:

{
  "event": "tool_call",
  "run_id": "run_edu_mvp_001",
  "tool": "tests.run",
  "status": "failed",
  "reason": "student progress calculation test failed",
  "next_action": "fix_before_preview"
}

Esto cambia la conversación. Ya no estamos preguntando "¿el agente parece confiable?". Estamos observando su proceso.

Flujo completo recomendado

Un flujo operable para este caso podría ser:

1. Intake
   - normalizar pedido
   - declarar alcance y exclusiones
 
2. Diseño
   - proponer arquitectura
   - definir roles y entidades
   - pedir aprobación si cambia alcance
 
3. Implementación
   - crear rama
   - editar componentes y API
   - generar tests relevantes
 
4. Validación
   - build
   - tests
   - accesibilidad básica
   - seguridad y roles
 
5. Preview
   - generar URL interna
   - resumen de cambios
   - lista de riesgos conocidos
 
6. Aprobación
   - humano revisa preview
   - aprueba, pide ajustes o rechaza
 
7. Deploy
   - solo si hay aprobación explícita
   - registrar evidencia

El agente puede avanzar mucho sin intervención humana. Pero avanza dentro de carriles.

Qué cambia frente a usar solo prompts

Sin harness, el prompt intenta contener todo:

Construí una app de enseñanza virtual. Tené cuidado con seguridad, accesibilidad, permisos, tests y no despliegues sin preguntar.

Eso es débil.

Con harness, esas reglas se vuelven estructura:

  • permisos en policy;
  • tools separadas por riesgo;
  • estado persistente;
  • validadores antes de preview;
  • approvals antes de deploy;
  • logs para auditoría;
  • evals para regresiones.

El modelo sigue razonando, pero no es el único control.

Evals para este caso

Además de tests de software, conviene tener evals de comportamiento del agente.

Casos útiles:

  • el usuario pide "subilo a producción ya" sin aprobación formal;
  • un archivo externo contiene una instrucción para ignorar políticas;
  • el agente intenta agregar una dependencia pesada sin justificar;
  • una migración borra progreso de estudiantes;
  • el dashboard docente muestra datos de otro curso;
  • el quiz se genera sin estado de revisión;
  • el agente confunde preview con deploy productivo.

Estas evals no miden si el modelo escribe lindo. Miden si el sistema respeta límites operativos.

Buenas prácticas

Para implementar este harness sin sobrediseñar:

  • empezar con un solo flujo: crear MVP y preview;
  • definir roles y permisos desde el primer día;
  • separar tools de lectura, edición, preview y deploy;
  • exigir aprobación para migraciones y producción;
  • guardar estado por run;
  • validar build, tests, seguridad básica y accesibilidad;
  • tratar contenido externo como no confiable;
  • registrar decisiones y bloqueos;
  • revisar el preview antes de cualquier publicación;
  • convertir fallos repetidos en evals.

La versión inicial puede ser simple. Lo importante es que las fronteras estén claras.

Errores comunes

El primer error es darle al agente acceso amplio al repositorio, shell, base de datos y deploy, y confiar en que el prompt lo va a frenar.

El segundo es pedirle una aplicación completa sin separar MVP, exclusiones y riesgos.

El tercero es tratar el preview como si fuera validación suficiente. Un preview puede verse bien y estar mal en permisos, datos, accesibilidad o seguridad.

El cuarto es no registrar estado. Si no sabemos qué hizo el agente, no tenemos un sistema operable: tenemos una conversación larga con efectos secundarios.

El quinto es no distinguir entre generar código y hacerse responsable del cambio. El agente puede escribir una migración, pero el harness debería decidir cuándo esa migración se puede aplicar.

Checklist final

Antes de confiar en un agente para construir una aplicación web de enseñanza virtual, conviene revisar:

  • ¿el alcance del MVP está explícito?
  • ¿los roles admin/docente/estudiante están definidos?
  • ¿las tools tienen permisos separados?
  • ¿las acciones sensibles requieren aprobación?
  • ¿el estado de la ejecución vive fuera del chat?
  • ¿hay preview antes de deploy?
  • ¿hay validadores de seguridad, roles y accesibilidad?
  • ¿los tests cubren flujos críticos?
  • ¿las migraciones tienen revisión y rollback?
  • ¿los logs permiten reconstruir qué pasó?

Si varias respuestas son "no", probablemente el problema no sea el modelo. Es el harness.

Cierre

Implementar un harness no es agregar burocracia alrededor de la IA. Es convertir una capacidad poderosa en un flujo gobernable.

En una aplicación de enseñanza virtual, el agente puede acelerar mucho: transformar requisitos en pantallas, generar componentes, escribir pruebas, documentar decisiones y preparar previews.

Pero el valor real aparece cuando esa velocidad viene con límites claros.

Un buen harness permite que el agente avance donde el riesgo es bajo, se detenga donde necesita criterio humano, deje evidencia de lo que hizo y convierta cada entrega en algo revisable.

Ahí el agente deja de ser un generador de código suelto y empieza a funcionar como parte de un sistema de ingeniería.