Intro
Cuando se habla de agentes de IA, la discusión suele empezar por el modelo.
Qué modelo razona mejor. Qué modelo llama herramientas con menos errores. Qué modelo escribe código más limpio. Qué modelo cuesta menos. Qué modelo tiene más contexto.
Todo eso importa, pero no alcanza.
En producción, la diferencia entre un agente que impresiona en una demo y uno que se puede operar con confianza rara vez está solo en el modelo. Está en la capa que lo rodea: cómo recibe contexto, qué herramientas puede usar, cómo se validan sus acciones, qué memoria conserva, cuándo pide aprobación, cómo se miden sus resultados, cómo se recupera de errores y qué trazabilidad deja.
A esa capa se la empieza a nombrar cada vez más como harness engineering.
El término puede sonar nuevo, pero el problema que describe es muy concreto: si un modelo es el motor, el harness es el chasis, los frenos, el tablero, los sensores, las reglas de conducción y el sistema de seguridad. Sin eso, tener más potencia no necesariamente te lleva más lejos. A veces solo te hace chocar más rápido.
Qué es harness engineering
Harness engineering es la disciplina de diseñar, construir y operar la estructura que envuelve a un modelo o agente para que pueda trabajar de forma confiable en un entorno real.
No es solamente prompt engineering. No es solamente evals. No es solamente observabilidad. No es solamente tool calling.
Es la combinación de todo eso en una arquitectura operativa.
Un harness define:
- qué información ve el agente;
- qué instrucciones son estables y cuáles son dinámicas;
- qué herramientas puede usar;
- con qué permisos;
- bajo qué condiciones puede actuar;
- cómo se validan entradas y salidas;
- qué pasa si falla una tool;
- cuándo debe pedir aprobación humana;
- cómo se registra cada decisión;
- cómo se evalúa si el resultado fue bueno;
- cómo se detectan regresiones;
- cómo se limita el daño cuando algo sale mal.
Dicho de otra forma: el harness es la diferencia entre un modelo conversando y un sistema ejecutando trabajo.
Un chatbot puede responder. Un agente puede actuar. Un agente con buen harness puede actuar dentro de límites, con evidencia, con trazabilidad y con controles proporcionales al riesgo.
La diferencia con prompt engineering, context engineering y evals
Conviene separar conceptos porque se suelen mezclar.
Prompt engineering trabaja sobre cómo se instruye al modelo: rol, tono, reglas, formato, ejemplos, restricciones y criterios de respuesta. Es importante, pero vive principalmente dentro del intercambio con el modelo.
Context engineering diseña qué información se le entrega al modelo y en qué forma: documentos, memoria, resultados de búsqueda, historial, metadata, prioridades, recortes, resúmenes y etiquetas de confianza.
Evals miden comportamiento contra casos repetibles: si responde bien, si usa herramientas correctamente, si respeta políticas, si evita riesgos, si empeora después de un cambio.
Harness engineering contiene a todo eso y agrega la dimensión operativa: tools, permisos, estado, ejecución, observabilidad, validadores, retries, approvals, límites, rollback y gobierno.
Una forma simple de verlo:
Prompt engineering -> cómo se le pide trabajar
Context engineering -> con qué información trabaja
Evals -> cómo medimos si trabaja bien
Harness engineering -> en qué sistema opera, con qué controles y consecuenciasEl harness no reemplaza esas disciplinas. Las ordena dentro de un flujo ejecutable.
Un ejemplo muy simple
Supongamos que queremos un agente que revise facturas recibidas por email.
Sin harness, el flujo puede ser:
Email -> LLM -> "esta factura parece válida"Con harness, el flujo empieza a parecerse a un sistema:
Email recibido
-> clasificar adjuntos
-> extraer datos de factura
-> validar CUIT/RUT, fecha, moneda y proveedor
-> comparar contra orden de compra
-> detectar duplicados
-> asignar riesgo
-> generar recomendación
-> pedir aprobación si supera cierto monto
-> registrar evidencia
-> enviar a contabilidad o bloquearEl LLM sigue siendo útil, pero ya no está solo. El sistema alrededor reduce ambigüedad y separa interpretación, verificación y acción.
Por qué aparece ahora
Durante mucho tiempo, la capa principal de trabajo con LLM fue el prompt.
Si la respuesta salía mal, se ajustaba el prompt. Si el tono no gustaba, se ajustaba el prompt. Si el modelo inventaba algo, se agregaba una instrucción para no inventar. Si se necesitaba un formato, se pedía ese formato con más fuerza.
Ese enfoque funciona hasta cierto punto.
Pero cuando el sistema empieza a usar herramientas, leer datos privados, modificar archivos, consultar APIs, abrir tickets, ejecutar código, escribir documentación, operar infraestructura o coordinar flujos largos, el prompt deja de ser el centro suficiente del diseño.
Ahí aparecen problemas que no se arreglan solo con una frase más en las instrucciones:
- el agente tiene demasiado contexto y no sabe qué priorizar;
- una tool devuelve una respuesta ambigua;
- una acción válida se ejecuta sobre el recurso equivocado;
- el agente repite una operación porque no entiende el estado;
- una salida externa contiene prompt injection;
- el modelo confunde recomendación con autorización;
- una regresión aparece después de cambiar de modelo;
- no hay forma clara de auditar por qué tomó una decisión.
En ese punto, el trabajo deja de ser “escribir mejores prompts” y pasa a ser diseñar mejores sistemas alrededor del modelo.
Eso es harness engineering.
Qué incluye un harness real
Un harness puede ser simple o complejo, pero en agentes útiles suele tener varias capas.
1. Capa de contexto
El agente no debería recibir “todo por si acaso”. Debería recibir el contexto correcto para la tarea correcta.
Esta capa decide:
- qué documentos se recuperan;
- qué memoria se incluye;
- qué datos se excluyen;
- qué partes del historial importan;
- qué instrucciones se inyectan según el tipo de tarea;
- cómo se separa contexto confiable de contenido no confiable.
Ejemplo práctico: un agente de soporte técnico no necesita toda la wiki interna en cada conversación. Necesita el runbook correspondiente al producto, el historial del ticket, el estado del cliente y las restricciones de acción aplicables a ese caso.
Un mal harness mete todo en el prompt y espera que el modelo ordene el caos. Un buen harness prepara un paquete de contexto pequeño, relevante y etiquetado.
2. Capa de herramientas
Las tools son una de las zonas donde más se rompe un agente.
Un harness sano no expone herramientas como funciones sueltas sin criterio. Define contratos claros:
- schemas estrictos;
- campos obligatorios;
- tipos cerrados;
- errores explícitos;
- permisos por acción;
- límites de alcance;
- idempotencia cuando corresponde;
- dry-run para operaciones sensibles.
Esto conecta directamente con el problema de tool calling en agentes: la dificultad no está solo en llamar una tool, sino en operarla sin ambigüedad.
Ejemplo de contrato débil:
{
"tool": "update_user",
"params": {
"user": "cliente mencionado",
"plan": "mejor"
}
}Ejemplo de contrato más sano:
{
"tool": "billing.plan_change.preview",
"params": {
"account_id": "acc_12345",
"target_plan_id": "pro_monthly",
"effective_date": "2026-05-14",
"requested_by": "support_agent",
"reason_code": "customer_requested_upgrade"
}
}La diferencia no es estética. La segunda versión permite validar, auditar, simular y pedir aprobación antes de ejecutar.
3. Capa de permisos y approvals
No todas las acciones tienen el mismo riesgo.
Leer documentación no es lo mismo que borrar datos. Resumir un ticket no es lo mismo que enviar una respuesta al cliente. Generar un plan no es lo mismo que aplicarlo sobre infraestructura.
Un harness bien diseñado clasifica acciones por nivel de riesgo:
- bajo riesgo: leer, resumir, clasificar, proponer;
- riesgo medio: editar borradores, preparar cambios, crear previews;
- alto riesgo: publicar, enviar mensajes externos, borrar, modificar producción, mover dinero, cambiar permisos.
Cada nivel puede tener controles distintos.
Por ejemplo:
policies:
read_docs:
approval: never
log: true
create_ticket_draft:
approval: never
log: true
send_customer_reply:
approval: required
approver: human_operator
require_preview: true
delete_resource:
approval: required
approver: admin
require_rollback_plan: trueEsta capa evita una confusión muy común: que el modelo interprete “podés ayudar con esto” como “podés ejecutarlo”. En producción, autorización y capacidad técnica tienen que ser cosas separadas.
Para profundizar en este punto, vale mirar cómo diseñar approvals en agentes sin frenar la operación.
4. Capa de estado
Un agente que hace trabajo real necesita entender estado.
No alcanza con saber qué dijo el usuario. También importa:
- qué pasos ya se completaron;
- qué acciones quedaron pendientes;
- qué outputs fueron generados;
- qué aprobaciones faltan;
- qué intentos fallaron;
- qué cambios están en draft;
- qué versión de datos se usó.
Sin una capa de estado, el agente depende demasiado del historial conversacional. Eso es frágil: el historial puede ser largo, incompleto, ambiguo o estar mezclado con mensajes irrelevantes.
Un harness más sólido separa el estado operativo en estructuras explícitas.
Ejemplo:
{
"workflow_id": "incident-summary-2026-05-14-001",
"status": "waiting_for_approval",
"inputs": {
"ticket_id": "INC-9381",
"source_logs_hash": "sha256:..."
},
"completed_steps": [
"fetch_ticket",
"fetch_logs",
"draft_summary",
"risk_check"
],
"pending_steps": [
"human_approval",
"send_summary"
],
"risk_level": "medium",
"last_agent_output": "draft_v2.md"
}Esto permite retomar, auditar y evitar duplicaciones.
5. Capa de validación
El modelo puede proponer. El harness debe verificar.
Algunas validaciones son simples:
- el JSON parsea;
- el campo requerido existe;
- el email tiene formato válido;
- el ID pertenece al tenant correcto;
- la URL no apunta a localhost;
- el archivo existe.
Otras son semánticas:
- la respuesta cita fuentes reales;
- el resumen no contradice el ticket;
- el cambio propuesto toca solo archivos permitidos;
- la acción coincide con la intención del usuario;
- el output no contiene secretos;
- el plan incluye rollback si modifica producción.
Un patrón útil es separar generación y verificación.
Primero el agente produce. Después otra capa valida.
def run_agent(task):
context = build_context(task)
draft = model.generate(context)
checks = [
validate_schema(draft),
check_sources(draft, context.sources),
detect_secrets(draft),
classify_risk(draft),
]
if any(check.failed for check in checks):
return block_with_report(draft, checks)
if requires_approval(draft):
return request_human_approval(draft, checks)
return execute_or_publish(draft)Esta estructura cambia la conversación. El agente ya no es una caja negra que “parece haber entendido”; es un componente dentro de un circuito de control.
6. Capa de observabilidad
Si no podés reconstruir qué pasó, no tenés un sistema operable. Tenés una conversación con efectos secundarios.
Un harness debería registrar:
- input recibido;
- contexto recuperado;
- versión del prompt;
- modelo usado;
- tools disponibles;
- tool calls ejecutadas;
- parámetros enviados;
- resultados de tools;
- decisiones de aprobación;
- errores y retries;
- costo y latencia;
- resultado final.
No todo tiene que exponerse al usuario, y hay que cuidar secretos y datos sensibles. Pero internamente, la trazabilidad es lo que permite depurar, mejorar y gobernar.
Esta capa se cruza con el rol de un AI gateway: centralizar uso, políticas, modelos, logs, límites y observabilidad.
7. Capa de evaluación
Un harness no está completo si no se puede medir.
Las evals permiten saber si el agente mejora o empeora cuando cambiás:
- modelo;
- prompt;
- contexto;
- tools;
- memoria;
- permisos;
- criterios de validación;
- estrategia de recuperación.
La clave es evaluar tareas reales, no solo ejemplos cómodos. Esto ya lo desarrollamos en por qué sin evaluaciones no hay agentes confiables, pero en harness engineering la idea se vuelve todavía más importante: no se evalúa solo la respuesta final, sino también la trayectoria.
Un agente puede acertar por casualidad después de usar una tool incorrecta. Otro puede fallar con seguridad pero dejar trazabilidad impecable. Otro puede producir una respuesta correcta pero saltarse una aprobación obligatoria.
Si solo medís “la respuesta suena bien”, no estás midiendo el harness.
Cómo funciona en la práctica
Un flujo típico con harness puede verse así:
- entra una tarea;
- se clasifica intención y riesgo;
- se arma contexto mínimo;
- se seleccionan tools permitidas;
- el agente propone un plan;
- el harness valida el plan;
- se ejecutan pasos seguros o se pide aprobación;
- se verifican outputs;
- se registra todo;
- se actualiza el estado;
- se evalúa el resultado.
En pseudocódigo:
def handle_task(user_request):
task = classify(user_request)
risk = classify_risk(task)
context = retrieve_context(
task=task,
max_documents=5,
include_memory=risk != "high",
mark_untrusted_sources=True,
)
tools = select_tools(
task=task,
risk=risk,
user_permissions=current_user.permissions,
)
plan = agent.plan(
request=user_request,
context=context,
tools=tools,
policies=load_policies(risk),
)
plan_check = validate_plan(plan, policies=load_policies(risk))
if not plan_check.ok:
return ask_for_clarification_or_block(plan_check)
result = execute_plan_with_guards(plan, tools)
output_check = validate_output(result)
log_trace(task, context, tools, plan, result, output_check)
if output_check.requires_human_review:
return send_for_approval(result)
return result.final_outputLo importante no es copiar esta estructura literal. Lo importante es la idea: el modelo no decide en el vacío. Decide dentro de un sistema que prepara, limita, observa y verifica.
Ejemplo práctico 1: agente de soporte técnico
Supongamos un agente que ayuda a responder tickets.
Versión demo
El usuario pega un ticket. El agente responde con una solución probable.
Funciona bien en una demo, pero tiene problemas:
- puede inventar políticas;
- puede responder sin conocer el plan del cliente;
- puede usar documentación vieja;
- puede prometer acciones que soporte no puede hacer;
- puede enviar una respuesta incorrecta al cliente.
Versión con harness
El harness cambia el flujo.
Entrada: ticket del cliente.
Contexto controlado:
- producto afectado;
- plan contratado;
- documentación vigente;
- incidentes recientes;
- historial relevante;
- límites de soporte.
Tools disponibles:
search_docsget_customer_planget_service_statusdraft_ticket_replyrequest_human_approval
Políticas:
- puede leer documentación sin aprobación;
- puede redactar borrador sin aprobación;
- no puede enviar al cliente sin aprobación humana;
- debe citar fuente interna si recomienda pasos técnicos;
- debe marcar incertidumbre si falta información.
Salida esperada: borrador de respuesta + evidencia + nivel de confianza.
Ejemplo de salida estructurada:
{
"ticket_id": "SUP-2048",
"classification": "configuration_issue",
"confidence": "medium",
"draft_reply": "...",
"sources": [
"docs/networking/dns-troubleshooting.md#ttl-cache",
"status/2026-05-14.md"
],
"requires_human_approval": true,
"missing_information": [
"confirmar proveedor DNS externo usado por el cliente"
]
}Este agente no solo escribe mejor. Trabaja mejor porque el sistema le exige evidencia, límites y revisión.
Ejemplo práctico 2: agente para repositorios de código
Ahora pensemos en un agente que modifica código.
Riesgo
Un agente de código puede:
- tocar archivos fuera de alcance;
- romper tests;
- introducir dependencias innecesarias;
- filtrar secretos en logs;
- hacer cambios demasiado amplios;
- arreglar un bug y romper otro;
- dejar el repo en estado inconsistente.
Harness mínimo razonable
Un harness para código debería incluir:
- sandbox o workspace aislado;
- diff obligatorio;
- allowlist de rutas;
- tests antes de declarar éxito;
- lint/typecheck si existen;
- prohibición de modificar secretos;
- resumen de cambios;
- rollback simple;
- aprobación antes de merge/push si corresponde.
Ejemplo de política:
code_agent:
allowed_paths:
- "src/"
- "tests/"
- "docs/"
blocked_paths:
- ".env"
- "secrets/"
- "infra/prod/"
required_checks:
- "npm test"
- "npm run lint"
require_diff_summary: true
require_human_approval_for:
- "dependency_changes"
- "database_migrations"
- "production_config"Ejemplo de loop operativo:
# 1. crear rama temporal
# 2. aplicar cambios
# 3. correr tests
# 4. generar diff
# 5. bloquear si tocó rutas prohibidas
# 6. pedir aprobación si cambia dependenciasEl punto central: el agente no “tiene acceso al repo” de forma genérica. Tiene acceso a un entorno, rutas, checks y reglas.
Esto se conecta con el problema de sandboxing en agentes con shell, browser y código: cuando el agente puede actuar sobre sistemas reales, aislar y limitar no es un extra, es parte del diseño.
Ejemplo práctico 3: agente operativo con shell o APIs
Un agente que opera infraestructura o sistemas internos necesita todavía más cuidado.
Supongamos que puede revisar un servicio, diagnosticar errores y proponer acciones.
Acciones posibles
- leer logs;
- consultar métricas;
- revisar configuración;
- reiniciar un servicio;
- escalar un incidente;
- aplicar un cambio;
- revertir una configuración.
Harness recomendado
Separar acciones por nivel:
operations_agent:
read_only:
- "get_logs"
- "get_metrics"
- "get_service_status"
safe_write:
- "create_incident_note"
- "prepare_restart_plan"
restricted_write:
- "restart_service"
- "apply_config_change"
- "rollback_deployment"Políticas:
policies:
get_logs:
approval: never
redact_secrets: true
prepare_restart_plan:
approval: never
require_impact_analysis: true
restart_service:
approval: required
require_recent_status_check: true
require_rollback_plan: true
allowed_environments:
- staging
- dev
apply_config_change:
approval: required
require_diff: true
require_backup: true
production_allowed: falseUn agente así puede ser muy útil sin convertirse en una ruleta operativa. Puede investigar, ordenar evidencia, sugerir pasos y preparar cambios. Pero el harness decide cuándo se detiene.
Cómo empezar a implementarlo sin sobrediseñar
No hace falta construir una plataforma enorme desde el día uno.
Una forma práctica de empezar es esta.
Paso 1: elegir un workflow concreto
No empieces con “queremos agentes para todo”. Elegí una tarea repetible.
Buenos candidatos:
- triage de tickets;
- resumen de incidentes;
- revisión de PRs;
- generación de documentación;
- análisis de logs;
- preparación de reportes;
- respuesta asistida a clientes;
- mantenimiento de colas editoriales;
- QA de contenido técnico.
El workflow tiene que tener entradas, salidas y criterios de éxito más o menos observables.
Paso 2: mapear acciones y riesgos
Listá qué puede hacer el agente.
Por cada acción, respondé:
- ¿lee o escribe?
- ¿toca sistemas internos o externos?
- ¿puede afectar a clientes?
- ¿puede borrar o modificar datos?
- ¿requiere aprobación?
- ¿tiene rollback?
- ¿deja log?
Una tabla simple alcanza:
Acción Riesgo Approval Observabilidad
leer docs bajo no log básico
resumir ticket bajo no guardar output
crear borrador medio no guardar diff
enviar respuesta cliente alto sí log + aprobación
cambiar config prod alto sí diff + backup + rollbackPaso 3: diseñar el paquete de contexto
Definí qué contexto entra y qué contexto no.
Para cada tarea:
- fuentes permitidas;
- prioridad de fuentes;
- tamaño máximo;
- metadata necesaria;
- tratamiento de contenido no confiable;
- qué hacer si falta información.
Una regla útil: si no podés explicar por qué una fuente entra al contexto, probablemente no debería entrar.
Paso 4: convertir tools en contratos
No expongas funciones vagas.
Cada tool debería tener:
- nombre específico;
- descripción precisa;
- schema estricto;
- errores esperables;
- permisos claros;
- logs;
- comportamiento idempotente cuando aplique;
- modo preview o dry-run para acciones sensibles.
Mal:
{ "tool": "run_command", "command": "lo que haga falta" }Mejor:
{
"tool": "service.restart.preview",
"service_id": "api-gateway",
"environment": "staging",
"reason": "memory leak suspected from alert AL-8831"
}Paso 5: agregar validadores antes de agregar autonomía
Antes de permitir más acciones, agregá más verificación.
Validadores útiles:
- schema validator;
- policy checker;
- secret scanner;
- source checker;
- diff checker;
- risk classifier;
- duplicate action detector;
- output format checker;
- eval scorer.
Esta es una regla sana: la autonomía debería crecer más lento que la validación.
Paso 6: registrar trazas desde el principio
Aunque el sistema sea chico, registrá lo básico:
{
"trace_id": "tr_20260514_001",
"task_type": "ticket_triage",
"model": "...",
"prompt_version": "support-agent-v3",
"context_sources": ["kb/dns.md", "ticket/SUP-2048"],
"tools_called": ["get_customer_plan", "search_docs"],
"policy_decision": "approval_required",
"final_status": "draft_ready"
}Sin trazas, cada problema futuro se vuelve arqueología.
Paso 7: crear una batería chica de evals
No esperes tener cien casos perfectos.
Empezá con 20 casos reales:
- 10 normales;
- 5 ambiguos;
- 3 con datos incompletos;
- 2 casos borde o peligrosos.
Medí:
- si resolvió;
- si pidió aclaración cuando correspondía;
- si usó tools correctas;
- si respetó permisos;
- si citó fuentes;
- si dejó output válido;
- si evitó acciones peligrosas.
Con eso ya podés detectar regresiones importantes.
Ejemplo práctico 4: agente de facturación y administración
Este caso sirve porque mezcla lectura de documentos, extracción estructurada, reglas de negocio y aprobaciones.
Supongamos que una empresa quiere un agente que procese facturas entrantes.
Qué haría una demo
La demo probablemente sube un PDF, le pide al modelo que extraiga datos y recibe algo como:
{
"proveedor": "Acme S.A.",
"monto": 1240.50,
"moneda": "USD",
"fecha": "2026-05-14"
}Eso parece útil, pero en producción faltan muchas preguntas:
- ¿el proveedor existe?
- ¿el número de factura ya fue procesado?
- ¿la moneda coincide con la orden de compra?
- ¿el monto supera el umbral de aprobación?
- ¿el PDF vino de un dominio confiable?
- ¿hay señales de fraude?
- ¿qué pasa si el modelo leyó mal un dígito?
- ¿quién autorizó el pago?
Harness propuesto
Un harness razonable separa pasos:
1. ingest_email
2. extract_attachments
3. classify_document_type
4. extract_invoice_fields
5. validate_required_fields
6. match_vendor
7. match_purchase_order
8. duplicate_check
9. risk_score
10. create_accounting_draft
11. request_approval_if_needed
12. export_to_accounting_systemEl modelo puede participar en extracción, clasificación y explicación. Pero las validaciones críticas deberían vivir fuera del modelo.
Ejemplo de salida intermedia:
{
"document_type": "invoice",
"invoice": {
"vendor_name": "Acme S.A.",
"vendor_tax_id": "UY-210000000012",
"invoice_number": "A-19384",
"issue_date": "2026-05-14",
"currency": "USD",
"total_amount": 1240.50
},
"extraction_confidence": {
"vendor_tax_id": "high",
"invoice_number": "medium",
"total_amount": "high"
},
"evidence": {
"invoice_number_page": 1,
"amount_page": 1
}
}Después el harness valida:
{
"checks": [
{ "name": "vendor_exists", "status": "pass" },
{ "name": "invoice_not_duplicate", "status": "pass" },
{ "name": "po_match", "status": "fail", "details": "No purchase order found" },
{ "name": "approval_threshold", "status": "review", "details": "Amount exceeds 1000 USD" }
],
"decision": "human_review_required"
}La ventaja no está en que el agente “entienda facturas”. Está en que la comprensión queda conectada a controles verificables.
Ejemplo práctico 5: agente editorial técnico
Un caso muy común es usar agentes para investigación, redacción y publicación de contenido.
Sin harness, un agente puede escribir un artículo correcto en apariencia, pero:
- repetir temas ya publicados;
- inventar fuentes;
- mezclar research privado con contenido publicable;
- publicar sin imagen final;
- usar un tono inconsistente;
- olvidar links internos;
- generar una pieza social débil;
- publicar en la cuenta equivocada;
- no dejar evidencia de build o URL final.
Un harness editorial debería separar capas:
Idea
-> research
-> brief
-> draft
-> QA editorial
-> QA técnico
-> imagen
-> audio opcional
-> build local
-> aprobación humana
-> publish blog
-> publish social
-> verificación pública
-> reporte de runCada paso tiene contrato.
Ejemplo de estado:
{
"slug": "harness-engineering-la-capa-que-convierte-agentes-de-ia-en-sistemas-operables",
"status": "draft_ready",
"required_assets": {
"cover_image": "pending",
"audio": "pending",
"linkedin_copy": "pending"
},
"quality_gates": {
"frontmatter_valid": true,
"internal_links": true,
"no_private_research_in_post": true,
"build_passed": false,
"human_publish_approval": false
}
}Ese estado explícito evita depender de memoria conversacional. El agente no tiene que “recordar” si ya generó imagen o si el post está aprobado. El workflow lo sabe.
Ejemplo de QA editorial automatizado
Un validador simple podría revisar:
- frontmatter completo;
- slug único;
- estado correcto;
- links internos existentes;
- imágenes locales existentes;
- ausencia de rutas privadas;
- longitud mínima;
- presencia de secciones requeridas;
- consistencia de título y excerpt.
Pseudocódigo:
def qa_article(path):
article = parse_mdx(path)
checks = []
checks.append(require_fields(article.frontmatter, [
"title", "slug", "excerpt", "topic", "tags", "date", "status"
]))
checks.append(slug_is_unique(article.frontmatter["slug"]))
checks.append(no_private_paths(article.body))
checks.append(internal_links_resolve(article.body))
checks.append(min_word_count(article.body, 1800))
checks.append(required_sections_present(article.body, [
"qué es", "cómo funciona", "ventajas", "desventajas"
]))
return summarize_checks(checks)Esto no reemplaza al editor humano. Le saca ruido y detecta errores mecánicos antes.
Ejemplo práctico 6: agente de seguridad para triage de alertas
Otro caso donde harness engineering se vuelve crítico es seguridad.
Supongamos un agente que ayuda a triagear alertas de SIEM, EDR o cloud security.
Riesgos específicos
Un agente de seguridad puede cometer errores con impacto alto:
- bajar prioridad a una alerta real;
- recomendar bloquear una IP crítica;
- filtrar indicadores sensibles;
- ejecutar consultas demasiado amplias;
- mezclar tenants;
- tratar una fuente no confiable como evidencia;
- alucinar una técnica MITRE;
- proponer contención sin evaluar impacto.
Diseño de harness
Separar lectura, análisis y acción:
security_triage_agent:
read_tools:
- get_alert
- get_endpoint_context
- get_user_activity
- search_ioc_history
- query_logs_preview
analysis_tools:
- classify_alert
- map_possible_mitre_techniques
- generate_timeline
write_tools:
- add_case_note
- create_escalation_draft
restricted_tools:
- isolate_endpoint
- block_ip
- disable_userPolíticas:
policies:
isolate_endpoint:
approval: required
require_evidence:
- active_malware_signal
- affected_hostname
- business_owner_lookup
require_impact_note: true
block_ip:
approval: required
require_false_positive_check: true
require_scope: "tenant_or_environment"
add_case_note:
approval: never
redact_secrets: trueSalida esperada:
{
"alert_id": "EDR-7731",
"severity_recommendation": "high",
"confidence": "medium",
"timeline": [
"09:12 suspicious powershell execution",
"09:13 outbound connection to rare ASN",
"09:15 credential access pattern detected"
],
"recommended_action": "escalate_to_human",
"restricted_actions_not_taken": [
"isolate_endpoint"
],
"approval_needed_for": [
"endpoint isolation"
]
}La parte importante es que el agente puede ayudar mucho sin ejecutar contención automáticamente. El harness permite usarlo como acelerador de análisis, no como botón rojo sin supervisión.
Patrones de diseño útiles
Hay algunos patrones que aparecen una y otra vez en harnesses sólidos.
Patrón 1: plan primero, ejecución después
Antes de ejecutar, el agente propone un plan.
{
"plan": [
{ "step": 1, "action": "read_logs", "risk": "low" },
{ "step": 2, "action": "summarize_findings", "risk": "low" },
{ "step": 3, "action": "prepare_restart_plan", "risk": "medium" },
{ "step": 4, "action": "restart_service", "risk": "high", "requires_approval": true }
]
}El harness valida el plan antes de permitir tool calls riesgosas.
Esto evita que el agente vaya improvisando acciones encadenadas sin que el sistema entienda la trayectoria.
Patrón 2: preview antes de write
Toda acción sensible debería tener vista previa.
generate_reply_preview -> approve -> send_reply
prepare_config_diff -> approve -> apply_config_diff
invoice_payment_draft -> approve -> submit_paymentEsto reduce errores porque separa intención de ejecución.
Patrón 3: tools específicas, no herramientas universales
Una tool genérica parece cómoda:
{ "tool": "run_sql", "query": "..." }Pero una tool específica es más gobernable:
{
"tool": "customer.get_active_subscriptions",
"account_id": "acc_12345"
}La herramienta específica permite validar permisos, limitar alcance, auditar intención y evitar consultas destructivas.
Patrón 4: recuperación controlada
Los agentes fallan. Las tools también.
Un harness tiene que definir qué hacer ante fallos:
retry_policy:
transient_network_error:
retries: 2
backoff: exponential
validation_error:
retries: 0
action: ask_for_correction
permission_error:
retries: 0
action: request_approval_or_block
ambiguous_tool_output:
retries: 0
action: require_human_reviewNo todos los errores merecen retry. Reintentar una acción mal validada puede duplicar daño.
Patrón 5: memoria con vencimiento
La memoria ayuda, pero también envejece.
Un harness debería distinguir:
- memoria de preferencias;
- memoria operativa;
- estado de workflow;
- conocimiento estable;
- historial conversacional.
Y debería poner vencimientos o fuentes.
{
"memory_item": "Cliente prefiere respuestas breves",
"type": "preference",
"source": "conversation",
"created_at": "2026-05-14",
"expires_at": null
}Para estado operativo, en cambio:
{
"workflow": "incident-8831",
"status": "waiting_for_approval",
"expires_at": "2026-05-15T12:00:00Z"
}No todo recuerdo merece vivir para siempre.
Anti-patrones: señales de que el harness está mal diseñado
Anti-patrón 1: “el modelo decide si puede hacerlo”
Si el mismo modelo decide si tiene permiso para ejecutar una acción sensible, el control es débil.
El modelo puede recomendar. La política debe decidir fuera del modelo.
Anti-patrón 2: contexto gigante sin jerarquía
Meter veinte documentos, historial completo, logs, tickets y políticas en un solo prompt no es buen contexto. Es ruido con apariencia de completitud.
El harness debería priorizar, resumir, etiquetar y recortar.
Anti-patrón 3: logs que solo guardan la respuesta final
Si solo guardás el output final, no podés auditar:
- qué contexto vio;
- qué tool llamó;
- qué parámetros usó;
- qué errores encontró;
- qué versión de prompt estaba activa;
- por qué pidió o no pidió aprobación.
Eso no es observabilidad. Es un recibo incompleto.
Anti-patrón 4: approvals demasiado tarde
Si el humano aprueba cuando la acción ya está semiejecutada, el approval es decorativo.
La aprobación tiene que ocurrir antes del punto de no retorno.
Anti-patrón 5: evals que ignoran la trayectoria
Un agente puede llegar a la respuesta correcta usando herramientas equivocadas o saltándose una política.
Si la eval solo mira el texto final, el harness puede estar fallando silenciosamente.
Métricas para saber si el harness está funcionando
Un harness debería medirse en varias dimensiones.
Calidad funcional
- tasa de resolución;
- exactitud de clasificación;
- outputs válidos;
- fuentes correctas;
- reducción de retrabajo humano.
Seguridad y control
- acciones bloqueadas correctamente;
- approvals solicitados cuando correspondía;
- intentos de tool fuera de permiso;
- detección de secretos;
- separación correcta entre lectura y escritura.
Operación
- latencia por paso;
- costo por tarea;
- retries;
- fallos por tool;
- tareas que quedan esperando aprobación;
- cantidad de intervenciones humanas.
Calidad del contexto
- documentos recuperados relevantes;
- documentos irrelevantes incluidos;
- fuentes faltantes;
- casos donde el agente pidió aclaración;
- uso de memoria correcta o incorrecta.
Regresión
- diferencias entre versiones de prompt;
- diferencias entre modelos;
- cambios en tasa de aprobación;
- aumento de bloqueos;
- aumento de errores de schema.
Estas métricas no tienen que nacer perfectas. Pero si no se mide nada, el equipo queda otra vez dependiendo de sensación.
Cómo se ve un harness en código
Un ejemplo mínimo en Python podría separar responsabilidades así:
class Harness:
def __init__(self, model, tools, policy_engine, validators, tracer):
self.model = model
self.tools = tools
self.policy_engine = policy_engine
self.validators = validators
self.tracer = tracer
def run(self, request, user):
trace = self.tracer.start(request=request, user=user.id)
task = classify_task(request)
risk = classify_risk(task)
context = build_context(task, user=user)
allowed_tools = self.policy_engine.allowed_tools(user, task, risk)
plan = self.model.plan(
request=request,
context=context,
tools=allowed_tools,
policies=self.policy_engine.instructions(task, risk),
)
plan_validation = self.validators.validate_plan(plan, allowed_tools)
if not plan_validation.ok:
return self.block(trace, "invalid_plan", plan_validation)
results = []
for step in plan.steps:
decision = self.policy_engine.decide(step, user=user, risk=risk)
if decision.requires_approval:
return self.request_approval(trace, plan, step, decision)
result = self.execute_step(step, allowed_tools)
result_validation = self.validators.validate_tool_result(step, result)
if not result_validation.ok:
return self.block(trace, "invalid_tool_result", result_validation)
results.append(result)
final = self.model.finalize(request=request, context=context, results=results)
output_validation = self.validators.validate_output(final)
if not output_validation.ok:
return self.block(trace, "invalid_output", output_validation)
self.tracer.finish(trace, final=final)
return finalEsto sigue siendo simplificado, pero muestra la idea: el modelo no está solo; atraviesa policy, validación y trazabilidad.
Implementación progresiva: de nivel 0 a nivel 5
No todos los equipos tienen que construir el harness completo desde el primer día. Una madurez progresiva puede verse así.
Nivel 0: prompt manual
Un humano copia y pega contexto. El modelo responde. No hay tools, logs ni evals.
Útil para exploración. No es producción.
Nivel 1: prompt versionado y outputs estructurados
El prompt vive en el repo, tiene versión, y el modelo devuelve JSON o un formato estable.
Ya se puede comparar mejor.
Nivel 2: contexto controlado
El sistema arma contexto desde fuentes definidas. Se evita pegar todo manualmente.
Aparecen reglas de recuperación, límites y metadata.
Nivel 3: tools con contratos
El agente puede usar herramientas, pero con schemas, permisos y logs.
Todavía conviene limitar writes.
Nivel 4: validadores, approvals y trazabilidad completa
El harness valida planes y outputs, pide aprobación para acciones sensibles y registra la trayectoria.
Acá empieza la operación seria.
Nivel 5: evals continuas y mejora gobernada
Cada cambio de prompt, modelo, tool o política puede medirse contra una batería de casos. Hay monitoreo de regresiones y métricas operativas.
Este nivel no significa autonomía total. Significa control medible.
Plantillas prácticas para empezar
Plantilla de política de tool
tool: customer.reply.send
description: Sends a reply to an external customer.
risk_level: high
allowed_roles:
- support_lead
- account_manager
requires_approval: true
requires_preview: true
validators:
- no_secrets
- source_citations_present
- customer_id_matches_ticket
- tone_policy_check
logs:
store_request: true
store_response: true
redact_fields:
- access_token
- api_key
rollback:
available: falsePlantilla de definición de tarea
task_type: incident_summary
inputs:
- incident_id
- log_window
- affected_service
context_sources:
- incident_ticket
- service_runbook
- recent_deployments
allowed_actions:
- read_logs
- read_metrics
- draft_summary
blocked_actions:
- restart_service
- change_config
success_criteria:
- includes_timeline
- includes_customer_impact
- includes_unknowns
- cites_sourcesPlantilla de trace
{
"trace_id": "tr_001",
"task_type": "incident_summary",
"user_id": "u_123",
"model": "model-name",
"prompt_version": "incident-agent-v4",
"context_sources": [
"ticket/INC-1001",
"runbook/api-gateway",
"deployments/2026-05-14"
],
"tool_calls": [
{
"tool": "logs.search",
"params_hash": "sha256:...",
"status": "success",
"latency_ms": 842
}
],
"policy_decisions": [
{
"action": "send_external_update",
"decision": "approval_required"
}
],
"final_status": "waiting_for_approval"
}Estas plantillas no son universales, pero sirven para empezar con una forma concreta en vez de una intención abstracta.
Ventajas de harness engineering
1. Menos dependencia del modelo
Un buen modelo ayuda, pero un buen harness reduce la fragilidad de cambiar de modelo o versión.
Si el contexto, las tools, los permisos, las evals y los validadores están bien diseñados, el sistema no depende tanto de que el modelo “se porte bien” todo el tiempo.
2. Más confiabilidad operativa
El harness convierte comportamiento probabilístico en un flujo más controlado.
No elimina el riesgo, pero lo encierra en límites más razonables.
3. Mejor seguridad
Permisos, approvals, sandboxing, validación y logs reducen el impacto de errores, prompt injection o mal uso de herramientas.
La seguridad no queda como instrucción escrita en el prompt. Queda implementada en el camino de ejecución.
4. Mejor capacidad de mejora
Si medís trazas y resultados, podés mejorar con evidencia.
Podés comparar modelos, prompts, estrategias de contexto y tools sin depender solo de impresiones.
5. Mejor experiencia humana
Un harness bien hecho no reemplaza al operador humano de forma torpe. Lo usa mejor.
El humano revisa decisiones importantes, no cada paso trivial. Recibe previews, evidencia, diff, riesgo y recomendación. Eso reduce fricción sin eliminar control.
Desventajas y costos
Harness engineering también tiene costos reales.
1. Más complejidad
Pasás de “llamar un modelo” a operar una arquitectura.
Hay más piezas: policies, tools, logs, evals, validadores, estados, permisos. Eso requiere diseño y mantenimiento.
2. Más latencia
Validar, recuperar contexto, ejecutar tools, pedir approvals y correr evals puede hacer el flujo más lento.
La clave es aplicar controles proporcionales al riesgo. No todo necesita el mismo nivel de verificación.
3. Más trabajo inicial
Una demo con prompt se arma rápido. Un harness productivo lleva más tiempo.
Pero ese costo suele pagarse cuando aparecen los primeros cambios de modelo, nuevos casos borde o incidentes evitados.
4. Riesgo de burocracia
Un harness mal diseñado puede frenar todo.
Si cada acción pide aprobación, si cada salida genera diez checks irrelevantes o si las policies son demasiado rígidas, el sistema deja de ayudar.
La meta no es llenar de controles. La meta es poner los controles correctos en los puntos donde reducen riesgo real.
5. Falsa sensación de seguridad
Tener harness no significa estar protegido automáticamente.
Un policy checker mal definido, una eval pobre o un log incompleto pueden dar confianza falsa. El harness también debe evaluarse.
Errores comunes
Confundir harness con prompt largo
Agregar instrucciones no es lo mismo que diseñar controles.
Si todo vive en el prompt, el modelo sigue siendo juez y parte.
Exponer tools demasiado poderosas
Una tool genérica como run_shell, send_email o update_database puede ser útil, pero también peligrosa si no está encapsulada por permisos, validaciones y approvals.
No separar preview de ejecución
Muchas acciones deberían tener dos fases:
- preparar o simular;
- ejecutar después de validar o aprobar.
Sin esa separación, el agente salta demasiado rápido del razonamiento a la acción.
No versionar prompts y policies
Si cambiás reglas sin versionarlas, después no podés saber por qué el agente empezó a comportarse distinto.
Evaluar solo el caso feliz
Un harness se prueba en los bordes:
- datos incompletos;
- tools caídas;
- permisos insuficientes;
- instrucciones contradictorias;
- contenido no confiable;
- acciones duplicadas;
- errores parciales.
Si no probás eso, no sabés cómo opera.
Una arquitectura mínima recomendada
Para un primer harness serio, una arquitectura razonable podría tener estos módulos:
[User / Event]
|
v
[Task Classifier] ---> [Risk Classifier]
|
v
[Context Builder] ---> [Retrieval / Memory]
|
v
[Policy Engine] ---> [Tool Selector]
|
v
[Agent Planner / Executor]
|
v
[Validators]
|
+--> [Approval Queue]
|
v
[Final Output / Action]
|
v
[Trace Logs + Eval Dataset]No todos los equipos necesitan una plataforma sofisticada. Pero casi todos los agentes productivos necesitan alguna versión de estas responsabilidades.
Checklist para llevarlo adelante
Antes de poner un agente a operar, conviene revisar:
- [ ] ¿Está claro qué tarea resuelve?
- [ ] ¿Hay límites explícitos de alcance?
- [ ] ¿El contexto se arma de forma controlada?
- [ ] ¿Las tools tienen schemas estrictos?
- [ ] ¿Hay separación entre leer, preparar y ejecutar?
- [ ] ¿Las acciones riesgosas requieren approval?
- [ ] ¿Hay dry-run o preview donde corresponde?
- [ ] ¿Se registran tool calls y decisiones?
- [ ] ¿Hay validadores de output?
- [ ] ¿Hay tests/evals con casos reales?
- [ ] ¿Se puede auditar una decisión después?
- [ ] ¿Existe rollback o mitigación para acciones importantes?
- [ ] ¿Se bloquea el flujo si falta información crítica?
Si varias respuestas son “no”, probablemente el agente todavía está más cerca de una demo que de un sistema operable.
La idea importante
Harness engineering importa porque desplaza la pregunta correcta.
La pregunta no es solo:
“¿Qué tan bueno es este modelo?”
La pregunta es:
“¿En qué sistema estamos metiendo este modelo para que pueda trabajar sin romper confianza, seguridad ni operación?”
Un modelo potente puede fallar en un harness débil. Un modelo razonable puede rendir mucho mejor dentro de un harness bien diseñado.
Eso no significa que el modelo no importe. Significa que, en producción, el modelo es una pieza. La confiabilidad aparece cuando esa pieza está contenida por contexto, herramientas, permisos, validaciones, observabilidad, evals y control humano donde corresponde.
La demo muestra lo que un agente puede hacer.
El harness define lo que un agente puede hacer de forma repetible, verificable y segura.
