Depuración de agentes de IA por capas: prompt, contexto, aprovechamiento o bucle
Un modelo en capas para los fallos de los agentes de IA: cómo difieren la formulación de instrucciones, el contexto, la ingeniería de aprovechamiento y la ingeniería de bucles, además de un procedimiento basado en el seguimiento para determinar qué capa falló.
Cuando un agente de IA se comporta mal en producción, los equipos tienden a discutir sobre el vocabulario en lugar de las pruebas: un ingeniero quiere una instrucción mejor, otro culpa al contexto y un tercero señala al entorno de ejecución. La ingeniería de instrucciones, la ingeniería de contexto, la ingeniería del entorno y la ingeniería de bucles no son escuelas de pensamiento rivales; son cuatro capas superpuestas, y cada una falla de manera propia y reconocible. Esta guía define cada capa con un pequeño ejemplo de agente de programación y luego le ofrece un procedimiento basado en el seguimiento de trazas para determinar qué capa falló realmente antes de modificar cualquier código.
La versión breve
- Ingeniería de instrucciones: da forma a las indicaciones que se le dan al modelo.
- Ingeniería de contexto: decide qué ve el modelo antes de responder.
- Ingeniería del entorno: crea el entorno en el que actúa el modelo: herramientas, memoria, archivos, permisos y mecanismos de recuperación.
La mayoría de los incidentes más costosos con los agentes se deben a la corrección del nivel incorrecto entre estos.
Cuando la demostración funciona y la producción no
El patrón es conocido: un agente parece impecable en una demostración. Unos días después del lanzamiento comienza a repetir ciclos y a consumir tokens, pierde la pista de algo que le habían indicado una hora antes, o falla la primera vez que una herramienta devuelve un payload inesperado.
El equipo se divide en facciones: alguien propone reescribir el prompt, otro lo considera un problema de contexto, y una tercera persona sospecha del mecanismo de integración. Al no haber una forma compartida de localizar la falla, una solución que debería tomar dos días se convierte en una reescritura de dos semanas, ya que cada parche se aplica a un nivel que funcionaba bien anteriormente.
Esa es la razón práctica para mantener separados los cuatro términos. Cada uno designa un lugar distinto donde pueden ocurrir errores, y una vez que se pueden distinguir, la depuración por parte del agente se convierte en un proceso en lugar de un juego de adivinanzas.
PACT: una mnemónica para las cuatro capas
Una forma compacta de recordar las capas durante un incidente es PACT: Prompt, Awareness, Control, Trajectory. Cada palabra corresponde a una pregunta:
- Prompt: ¿se especificó claramente la tarea?
- Awareness: ¿recibió el modelo la información que necesitaba para este paso?
- Control: ¿puede el entorno de ejecución realizar lo que pidió el modelo, de forma segura y fiable?
- Trajectory: ¿el proceso repetido avanza hacia un final que pueda verificarse?
El objetivo no es añadir otra capa de jerga. Se trata de que los límites entre los tipos de fallos sean lo suficientemente fáciles de recordar para que realmente se utilicen cuando algo está en llamas.
Cómo aparecieron las capas y por qué importa el orden
Los términos surgieron más o menos en secuencia, a medida que los agentes adquirían nuevas capacidades:
- Ingeniería de prompts (aproximadamente de 2022 a 2024) fue la primera habilidad: redacción, ejemplos, restricciones y patrones de pocos ejemplos dirigidos a una sola llamada al modelo.
Estas fechas describen cuándo ganaron popularidad estos términos, no hitos formales, y el vocabulario sigue evolucionando en el momento de escribir esto. La observación importante es que nada fue reemplazado; cada capa se añadió sobre la anterior, ya que cada aumento en la autonomía requería su propia superficie de control.
Ingeniería de prompts: el contrato local
La ingeniería de prompts es el arte de redactar, estructurar e ilustrar una instrucción para que la respuesta sea más predecible. Sin ella se obtienen instrucciones vagas, formatos de salida inestables y un modelo obligado a adivinar lo que se quería decir.
En un agente de programación, un prompt para revisión de código podría verse así:
SYSTEM: You are a code reviewer.
Given a diff, output ONLY valid JSON:
{"issues": [{"line": int,
"severity": "low|medium|high", "note": str}]}
No prose. No markdown fences.
If there are no issues, return {"issues": []}.
Este prompt establece un contrato local. Asigna un rol, describe la transformación (diferencias de entrada, lista de problemas de salida), define con precisión la estructura de la salida hasta los nombres de los campos y los valores de severidad permitidos, e incluso define el caso vacío para que el análisis posterior no tenga que lidiar con texto narrativo o claves faltantes.
Una afirmación común es que la ingeniería de prompts está obsoleta. No lo está; constituye la capa más interna. Cada pipeline de contexto termina entregando al modelo una instrucción, y una instrucción deficiente dentro de un marco excelente sigue produciendo resultados débiles, solo que ahora envueltos en una infraestructura impresionante.
Ingeniería de contexto: curaduría dentro de un presupuesto
La ingeniería de contexto consiste en elegir, para cada solicitud, qué documentos, historial, definiciones de herramientas y memorias ingresarán al campo de visión del modelo, y con la misma intención decidir cuáles no lo harán. Cuando se descuida, el modelo responde con información obsoleta, se desvía por pasajes irrelevantes o pierde el enfoque porque el campo de visión está repleto de material incluido solo por precaución.
Un generador de contexto para un agente de programación podría recuperar candidatos, reordenarlos y comprimir el historial:
def build_context(query, full_history, kb):
relevant = retrieve(query, kb, top_k=8)
reranked = rerank(relevant, query)[:3]
summary = summarize_if_long(
full_history, max_tokens=800
)
return {
"docs": reranked,
"history": summary,
"query": query,
}
Considérelo como un embudo. La recuperación lanza una red amplia con ocho candidatos; el reclasificado mantiene a los tres más relevantes, y el historial de conversaciones se resume a aproximadamente 800 tokens solo cuando se alarga demasiado. La función devuelve una carga útil pequeña y estructurada en lugar de datos brutos. La habilidad que se demuestra es la selección, el ranking y la compresión, no el volumen.
Esa es la razón por la cual el malentendido más común, de que la ingeniería de contexto significa proporcionarle más información al modelo, suele ser incorrecto. Un contexto más grande tiende a contener más ruido: instrucciones obsoletas, hechos repetidos y pruebas contradictorias. Gran parte del trabajo consiste en decidir qué omitir.
La ingeniería de contexto es más amplia que RAG
La generación mejorada por recuperación es una técnica dentro de la ingeniería de contexto que abarca el paso de recuperación. Un pipeline RAG puede extraer ocho fragmentos y reordenarlos a tres, como se mostró anteriormente. La ingeniería de contexto también incluye comprimir el historial, formatear las definiciones de herramientas, mantener activo el estado de tareas críticas, enviar los resultados de verificación de vuelta al modelo y decidir qué omitir.
Un agente de programación sin ningún almacén vectorial sigue teniendo un problema real de contexto que resolver. El estado de Git, los archivos abiertos, los errores del compilador, los resultados de las pruebas, el plan actual y el registro de acciones anteriores deben llegar al modelo en una forma utilizable.
Ingeniería de aprovechamiento: el límite entre intención y efecto
El arnés es la parte no relacionada con el modelo del sistema: las herramientas y el acceso a archivos, la memoria persistente, las reglas de permisos, los entornos aislados, el seguimiento de operaciones y todo lo que ocurre en caso de fallo. Sin uno adecuado, se obtiene un agente que razona bien pero no puede actuar en consecuencia, o uno que sí actúa pero carece de una forma fiable de recuperarse cuando hay errores en las llamadas a herramientas.
Un envoltorio para llamadas a herramientas ilustra esta idea:
def call_tool(tool_name, args, retries=2):
for attempt in range(retries + 1):
try:
result = TOOLS[tool_name](**args)
log_trace(tool_name, args, result, status="ok")
return result
except ToolError as e:
log_trace(tool_name, args, str(e), status="failed")
if attempt == retries:
return {"error": str(e), "recoverable": False}
args = repair_args(args, e)
El envoltorio no intenta resolver la tarea. Se encarga de delimitar lo que solicitó el modelo y lo que hace el sistema real. Cada intento se registra junto con sus argumentos, resultado y estado. Un fallo desencadena un número limitado de intentos de reintentar con argumentos corregidos, y una vez agotados los reintentos se devuelve un error estructurado marcado como no recuperable, de modo que quien llama recibe datos sobre los cuales puede razonar en lugar de una excepción que interrumpe la ejecución.
Es tentador equiparar el arnés con cualquier framework de agente que se haya instalado. Un framework proporciona una estructura básica; el arnés es el conjunto de decisiones concretas que se toman sobre esa estructura: qué se registra, qué hace una llamada fallida a continuación, qué estado sobrevive a una caída, qué comandos están permitidos y cómo se presentan los resultados de la ejecución al modelo.
Ingeniería de bucles: el contrato de terminación
La ingeniería de bucles define el trabajo de cada iteración, la forma en que el agente mide si está avanzando y, lo más importante, las condiciones para detenerse. Su fallo típico es el bucle ilimitado: un agente que sigue invocando herramientas y gastando tokens porque nunca le indican que ha terminado o que está atascado.
Un controlador mínimo se ve así:
def run_loop(task, harness, max_iters=15, stall_limit=3):
state = init_state(task)
stalls = 0
for i in range(max_iters):
action = plan_next_step(state)
result = harness.call_tool(action.tool, action.args)
state = update_state(state, result)
if is_goal_met(state):
return state, "success"
if made_no_progress(state):
stalls += 1
if stalls >= stall_limit:
return state, "stalled — escalate"
else:
stalls = 0
return state, "max iterations reached"
Aquí coexisten varios límites. max_iters establece un tope para el trabajo total, is_goal_met permite salir con éxito, y un contador de estancamiento registra las iteraciones consecutivas sin progreso, reiniciándose cada vez que se vuelve a avanzar. Después de stall_limit pasos en estado de estancamiento, el bucle devuelve un estado específico que solicita una intervención superior en lugar de continuar silenciosamente. Cada ruta de salida indica claramente el motivo, lo que facilita la clasificación posterior de las ejecuciones.
La idea central es el contrato de terminación: un objetivo claro, señales de progreso medibles, límites en los intentos de repetición, presupuestos para tiempo y tokens, un paso de verificación y una política definida sobre qué hacer cuando el progreso se estanca. Para implementaciones en TypeScript de estas mismas ideas, consulte bucles de agente limitados para el uso de herramientas LLM.
A menudo se confunden los conceptos de bucle y mecanismo de aprovechamiento. El mecanismo de aprovechamiento define qué puede interactuar el agente y cómo se manejan los fallos a nivel de las herramientas individuales. El bucle opera por encima de él y determina el comportamiento paso a paso, incluyendo el momento en que debe finalizar la ejecución en su totalidad.
Las cuatro capas una al lado de la otra
- Prompt (P): corresponde a la instrucción. Falla típica: el modelo interpreta mal la intención o devuelve el formato incorrecto. Primer lugar a revisar: el propio resultado.
- Context (A): corresponde al estado listo para el modelo. Falla típica: el modelo actúa con información obsoleta, faltante o distractora. Primer lugar a revisar: las capturas de contexto por turno.
- Harness (C): corresponde a la ejecución y recuperación. Falla típica: error en las llamadas a herramientas, intentos de reintentar sin criterio o imposibilidad de recuperación. Primer lugar a revisar: las entradas fallidas en el seguimiento de herramientas.
- Loop (T): corresponde al progreso y la detención. Falla típica: el agente nunca converge ni se detiene. Primer lugar a revisar: llamadas exitosas repetidas con argumentos casi idénticos.
Diferenciar un error en el harness de un error en el bucle
La observación que ahorra más tiempo es que dos errores diferentes parecen idénticos desde el exterior. Un agente atrapado en un bucle debido a un controlador defectuoso y uno atrapado por un problema con el manejo de herramientas muestran el mismo síntoma: sigue funcionando, la factura sigue aumentando y nadie sabe por qué. Una breve lista de verificación permite distinguirlos de los demás casos.
1. Consulte el rastro de llamadas a herramientas
Las llamadas que tienen éxito todas con resultados plausibles, mientras el agente utiliza una y la misma herramienta con argumentos casi inmutables, indican la presencia de un bucle.
2. Busque fallas repetidas en las herramientas
Si una herramienta falla una y otra vez y el agente vuelve a intentarlo sin cambiar su enfoque, sospeche de un problema con el sistema de conexión.
3. Examine lo que podría ver el modelo
Si parece que el modelo olvida un hecho a mitad de una ejecución, examine la construcción del contexto: truncamiento, reemplazo, compactación o la forma en que se transmite el estado entre turnos.
4. Verifique primero la salida
Si las herramientas funcionaron, el contexto fue preciso y el bucle finalizó correctamente, pero la respuesta sigue siendo incorrecta, revise el prompt.
Una regla práctica
Los errores en los bucles se encuentran en la decisión sobre qué sucederá a continuación. Los errores relacionados con el manejo de situaciones se dan cuando algo falla. Los errores de contexto están en lo que puede ver el modelo. Los errores del prompt se encuentran en lo que usted solicitó.
Responda cuál de las cuatro preguntas es aplicable antes de editar cualquier cosa.
Ejemplo práctico: un revisor de pull requests que no se detiene
Imagínese un equipo que envía un agente de programación para revisar las solicitudes de integración. Las pruebas se realizan sin problemas. En producción, algunas revisiones duran más de 40 minutos por cada solicitud de integración y generan una factura inesperada.
La primera teoría es que la instrucción dada es demasiado vaga y el agente piensa en exceso. Se reescribe la instrucción, pero nada cambia. La segunda teoría se relaciona con el contexto: quizás el agente vuelve a leer todo el repositorio en cada paso. Sin embargo, los registros indican lo contrario; la recuperación de datos se realiza dentro de los límites adecuados, y solo se incluyen los archivos relevantes.
Luego alguien lee con atención el registro de llamadas a las herramientas. El agente invoca repetidamente su herramienta de ejecución de pruebas, y cada llamada se completa sin errores. En realidad, el conjunto de pruebas está fallando debido a una prueba de integración inestable que no tiene relación con la solicitud de integración. El agente sigue intentando solucionar ese fallo mediante cambios en código no relacionados y volviendo a ejecutar las pruebas, ya que nada le indica que ha realizado suficientes intentos con este subobjetivo y debería detenerse y elevar el problema.
Esto no es un problema de prompt, ni de contexto, ni de herramienta de gestión; las herramientas se comportaron exactamente como estaban diseñadas. Se trata puramente de un error de bucle. Analizarlo paso a paso muestra cómo llegar a esa conclusión.
Paso 1: confirmar que las herramientas funcionan
Las ejecuciones exitosas en el registro eliminan los fallos más simples relacionados con la herramienta de gestión, como una orden que nunca se ejecuta o un adaptador que sigue generando errores.
Paso 2: comparar el estado entre iteraciones
La salida de la prueba está presente en el contexto del agente, y la recuperación se realiza dentro del alcance correcto, por lo que el modelo no pierde las pruebas necesarias.
Paso 3: verificar la convergencia
El repositorio cambia en cada iteración, pero la señal de verificación relevante nunca mejora. No existe un detector de estancamiento ni límite en los intentos para alcanzar el mismo subobjetivo.
Paso 4: enseñar al controlador a detectar la estancación
La solución consiste en un pequeño fragmento de lógica del controlador que compara una firma de progreso entre pasos:
if progress_signature == previous_signature:
stagnant_steps += 1
else:
stagnant_steps = 0
if stagnant_steps >= 3:
escalate("no measurable progress")
stop()
progress_signature puede ser cualquier cosa que refleje un progreso significativo, por ejemplo el conjunto de pruebas fallidas junto con sus mensajes de error. Si no cambia, el contador de estancamiento aumenta; después de tres pasos sin avance, el controlador eleva la situación indicando el motivo y se detiene. Cualquier cambio real reinicia el contador.
Puede ir más allá y establecer un límite para los intentos por cada firma de fallo, no solo para el total de iteraciones. La distinción es importante: quince iteraciones productivas pueden ser perfectamente aceptables, mientras que quince intentos frente a un fallo de prueba irremediable son una pérdida total de tiempo. La solución real no consiste en hacer que el modelo sea menos terco, sino en proporcionar al controlador una definición clara de qué se considera estancamiento.
Ejemplo práctico: una restricción que desaparece del contexto
Imagínese ahora un agente que, al inicio de una migración, establece que nada debe dañar a los clientes existentes. Cuarenta turnos después, la conversación se compacta y la restricción se pierde en el resumen. El agente propone entonces un cambio de esquema que sí provoca daños.
Parece un razonamiento defectuoso, pero la causa está en otro lugar. Compare el contexto que el modelo recibió realmente en diferentes turnos. Si la restricción estaba presente en el turno cinco y faltaba en el turno cuarenta, la solución radica en la ingeniería de contexto: almacenar las invariantes críticas por separado de la conversación, hacer que los resúmenes transmitan explícitamente las restricciones y dejar de considerar la historia bruta como la única fuente de verdad.
“El modelo lo olvidó” nunca es un diagnóstico completo. La pregunta útil es qué fue lo que realmente se le dio al modelo.
Capas, no reemplazos
Cada disciplina más reciente se basa en las anteriores en lugar de reemplazarlas. Un agente de producción envuelve una instrucción clara dentro de un contexto cuidadosamente seleccionado, la ejecuta mediante un mecanismo fiable y dirige todo el proceso a través de un bucle deliberado. La sucesión de elementos refleja lo que los equipos han ido añadiendo con el tiempo: instrucciones más claras, luego información mejor seleccionada, después un entorno de ejecución para el modelo y, finalmente, un controlador que mantiene ese entorno funcionando sin intervención humana. Si está decidiendo si su propio entorno de ejecución o un framework debe encargarse de ese bucle externo, la comparación entre entornos de ejecución y frameworks compuestos aborda los compromisos a considerar.
Reformulado mediante PACT:
- Instrucción: definir la instrucción a seguir.
Luego, asociar la solución al fallo. Un modelo que interpreta mal una tarea claramente especificada necesita correcciones inmediatas. Un modelo al que le faltan datos en los que depende necesita información de contexto. Las decisiones razonables que no se traducen en acciones fiables requieren trabajos de adaptación. Las acciones que tienen éxito mientras la ejecución general no converge necesitan ajustes en los bucles.
Preguntas frecuentes
¿Es la ingeniería de harness simplemente otro nombre para un framework de agentes?
No. Un framework proporciona bloques de construcción. El “arness” está formado por las decisiones que tomas al ensamblarlos: el comportamiento ante fallos de la herramienta, el estado persistido, el registro de logs, los permisos y cómo los resultados regresan al modelo.
¿Necesita un asistente de una sola pregunta ingeniería de bucles?
No realmente. La ingeniería de bucles comienza a ser importante cuando un agente realiza varias acciones por tarea y debe decidir, por sí mismo o a través de código de controlador, que el trabajo está completo. Un bot de preguntas y respuestas de un solo turno tiene poco o ningún bucle que diseñar.
¿Qué capa deberías aprender primero?
Comienza con la ingeniería de prompts y contexto, luego pasa al “arness” y a los bucles. Necesitas distinguir entre instrucciones incorrectas y estado faltante antes de poder depurar el tiempo de ejecución y el controlador en torno a ellos.
¿Puede un error afectar a varias capas?
Sí, y esos suelen ser los más difíciles. Un error de contexto puede ocultar una señal de progreso dentro del bucle, lo que a su vez parece un error del propio bucle. Es mejor seguir el curso del fallo a través de las diferentes capas en lugar de solucionar solo el primer síntoma visible.
Puntos clave
- Los cuatro términos describen superficies de control, no tendencias competitivas: la instrucción, el estado listo para el modelo, la ejecución y recuperación, y el progreso repetido con una regla de detención.
- Comience toda investigación a partir del rastro, no desde la solicitud: pregunte qué vio el modelo, qué hizo el entorno de ejecución, qué cambió entre iteraciones y por qué el controlador decidió continuar.
- Las llamadas a las herramientas que tienen éxito y se repiten con argumentos casi idénticos apuntan al bucle; los fallos repetidos con intentos ciegos apuntan al sistema de gestión.
- Proporcione a los bucles una definición explícita de qué se considera estancamiento, idealmente según la firma del fallo, además de un camino para la escalada.
Lecturas relacionadas
- Cómo el Protocolo de Contexto del Modelo permite a los agentes de IA descubrir y llamar herramientas — Una explicación clara de MCP: cómo los hosts, clientes y servidores permiten que una aplicación de IA descubra herramientas, las llame con entradas estructuradas y entienda cuáles son sus límites.
- CodeBuddy: Recuperación de contexto más inteligente para agentes de programación de IA — Explica cómo un sistema de recuperación de contexto basado en gráficos de dependencias ayuda a estos agentes a evitar tanto la escasez como la sobrecarga de contexto en grandes bases de código.
- De escribir Kotlin a dirigir agentes: el nuevo rol del ingeniero móvil — Cómo los agentes de programación transforman el trabajo de un ingeniero Android hacia las especificaciones, el contexto, las restricciones arquitectónicas y la verificación, y qué principios fundamentales son más importantes que nunca.