Hay un tipo de trabajo de ingeniería que todavía no tiene un manual de referencia. No consiste en entrenar modelos, y los prompts son solo una de sus entradas. Es el código que conecta un modelo de lenguaje con el mundo: reúne contexto, expone capacidades, impone límites, conserva estado y decide qué hacer cuando el modelo se equivoca.
Lo llamo ingeniería del harness: el sistema que rodea al modelo. Es buena parte del trabajo y sigue siendo útil cuando actualizas el modelo.
Qué es un harness
Para lo que nos interesa aquí, un modelo funciona como una función pura: recibe tokens, devuelve tokens, sin memoria propia, efectos secundarios ni acceso a recursos. Cada capacidad que asocias con un «producto de IA», como leer archivos, llamar a una API, recordar lo de ayer o rechazar una acción peligrosa, depende del código que escribiste alrededor de esa función.
El harness toma cinco decisiones que determinan si el producto funciona:
- Qué entra en la ventana de contexto y en qué orden.
- Qué herramientas existen y cómo se describen.
- Qué puede hacer el modelo sin preguntar.
- Qué se conserva entre turnos y sesiones.
- Qué ocurre ante un fallo: reintentos, alternativas y escalado.
Son decisiones de producto expresadas en código. Un buen sistema puede compensar limitaciones del modelo en tareas de varios pasos; un modelo más capaz no arregla por sí solo un sistema mal diseñado.
La ventana de contexto tiene un presupuesto
El error más común es tratar el contexto como almacenamiento. Como la ventana es grande, metes el prompt del sistema, la documentación completa, toda la conversación y cada resultado de herramienta sin recortar. Si cabe, parece que todo va bien.
Hay tres problemas.
La atención no se reparte por igual. Los modelos no aprovechan de forma uniforme un contexto largo. Pueden usar menos la información situada en el centro que la de los extremos. Incluir 80 000 tokens no equivale a darles 80 000 tokens de conocimiento de trabajo útil.
El contexto irrelevante puede perjudicar. No es relleno neutral. El modelo puede apoyarse en un resultado de hace seis pasos que contradice el estado actual. Una sección sobre una función que nadie pidió puede desviar la respuesta. Cada token puede influir en la salida.
Vuelves a enviarlo en cada turno. En un ciclo de agente, el contexto se reenvía en cada iteración. Un contexto de 50 000 tokens durante 20 pasos suma un millón de tokens de entrada. El coste y la latencia crecen con aquello que estabas tratando como gratis.
Cada token tiene que justificar su sitio. Recupera información cuando haga falta, resume en lugar de acumular y elimina lo que ya no ayuda.
Bad: [system] + [all docs] + [full history] + [every tool result verbatim]
Good: [system] + [retrieved docs for this step] + [compacted history]
+ [recent results in full, older results summarized]
Una restricción útil: diseña como si la ventana de contexto tuviera una décima parte de su tamaño real. Eso te obliga a construir un sistema que pueda reducir su rendimiento de forma gradual cuando aumenta la carga.
Preparar el contexto requiere varias etapas
Cuando aceptas que el contexto tiene un presupuesto, prepararlo se convierte en trabajo de ingeniería. En un sistema maduro hay etapas distintas:
Recopilar: reúne documentos pertinentes, historial reciente, esquemas de herramientas, estado del usuario y datos del entorno.
Ordenar por relevancia: evalúa cada candidato respecto al paso actual. Lo que importaba en el primer paso puede haber dejado de importar en el duodécimo.
Compactar: sustituye material extenso por equivalentes concentrados. En vez del archivo completo, incluye la función pertinente y una nota sobre el resto. Diez turnos de exploración pueden convertirse en tres frases de hallazgos.
Distribuir: coloca el material más útil donde el modelo pueda aprovecharlo mejor, cerca del principio y del final. Las instrucciones al principio; la tarea actual al final.
Verificar: busca contradicciones antes de enviar el contexto. Si en el tercer paso creías que la configuración estaba en A y en el séptimo descubriste que estaba en B, no dejes ambas afirmaciones compitiendo.
Esa verificación evita que el agente actúe con seguridad sobre información que él mismo ya había descartado.
Los límites de capacidad se aplican en código
«No borres archivos sin confirmar» en un prompt es una instrucción que puede incumplirse. Que funcione casi siempre puede darte una confianza peligrosa al publicar el producto.
Las condiciones obligatorias necesitan una comprobación en código. El patrón es una capa de permisos entre la llamada del modelo y la ejecución real:
type Decision = 'allow' | 'deny' | 'ask';
function authorize(call: ToolCall, ctx: Context): Decision {
const rule = policy[call.name];
if (!rule) return 'deny'; // unknown tool: closed by default
return rule.evaluate(call.args, ctx);
}
Hay tres propiedades necesarias.
Denegar por defecto. Una llamada desconocida se rechaza. Dejarla pasar abre una vía sin límites definidos.
Decisiones deterministas. La misma llamada, en el mismo estado, recibe la misma decisión. Si la política depende de otra llamada al modelo, has trasladado la incertidumbre.
Decisiones auditables. Registra cada decisión y su motivo. Ante un incidente necesitas explicar por qué se permitió una acción sin volver a ejecutarla.
Mucha gente recurre a un «prompt de seguridad» porque parece rápido y considera lenta la alternativa en código. Pero una capa de permisos puede ser pequeña y permite poner el sistema delante de un cliente con controles comprobables. El ahorro inicial puede convertirse después en un incidente de soporte.
Observabilidad: necesitas registrar lo que vas a depurar
Un agente que falla deja una secuencia de decisiones. Cuando te enteras, esa secuencia puede haberse perdido. Registrar solo la respuesta final no explica cómo llegó hasta ella.
En cada paso necesitas conservar:
- El contexto exacto enviado, ya preparado, no solo su plantilla.
- La salida original del modelo, antes de analizarla.
- La herramienta llamada, sus argumentos y el resultado.
- La decisión de permisos y su motivo.
- El consumo de tokens y la latencia de cada etapa.
El contexto exacto suele omitirse por su tamaño, aunque es lo que permite reproducir el fallo. Comprimirlo y definir una caducidad, por ejemplo de treinta días, permite gestionar ese volumen. Esa retención debe ajustarse también a la sensibilidad de los datos y a los permisos del producto.
Las trazas por paso ayudan a crear evaluaciones: un fallo de producción puede convertirse en un caso de prueba al extraer el contexto del paso donde se torció todo.
Lo que diferencia al producto vive alrededor del modelo
La calidad y el precio de los modelos cambian. Una ventaja basada solo en acceder a un modelo mejor que el de la competencia puede desaparecer en cuanto otros obtengan ese mismo acceso.
Tu preparación del contexto recoge lo que aprendiste del dominio. Tus herramientas reflejan lo que necesitan los usuarios. Tu política de permisos conserva tu criterio sobre el riesgo. Tus evaluaciones recogen los fallos que ya resolviste. Eso no se transfiere automáticamente a quien usa el mismo modelo.
Una prueba concreta: cambia de modelo. Si cambiar de proveedor obliga a rehacer el producto, la dependencia es profunda. Si basta con cambiar la configuración, ejecutar las evaluaciones y ajustar algunos prompts, has separado mejor el sistema del modelo.
Conviene hacer esa prueba antes de necesitarla.
Por dónde empezar
Si estás construyendo un agente y todo esto parece abstracto, empieza por tres cambios, en este orden:
- Registra el contexto preparado de cada llamada. Para entender un fallo necesitas saber qué vio el modelo, con los controles de acceso y conservación apropiados.
- Intercala una función de permisos entre las llamadas y su ejecución, aunque al principio todas las reglas devuelvan
allow. Primero crea el punto de control; después amplía las reglas. - Define un presupuesto de contexto con una cifra concreta y aplícala en código. Cuando se supera, hay que retirar algo. Tener que elegir te obliga a diseñar la priorización y la compacción.
Es trabajo de infraestructura. Los productos que funcionan necesitan que alguien lo haga; seguir afinando el prompt no lo sustituye.
Un pequeño voto de confianza
¿Valió la pena leer esta nota?