Depurar un test fallido con un agente
Esta guía muestra cómo conseguir que un agente use un depurador con un fallo que las instrucciones print no explican.
La herramienta debug controla una sesión real de Debug Adapter Protocol. Un frame detenido responde de una vez a todas las preguntas sobre ese momento —cada variable local, cada invocador y una expresión evaluada en el propio ámbito del frame—, mientras que una instrucción print solo responde a la pregunta que se te ocurrió hacer antes de ejecutar.
Antes de empezar
Sección titulada «Antes de empezar»La herramienta permanece en la superficie para que el agente pueda preguntar por qué no hay nada utilizable, en lugar de adivinar. Un adaptador solo puede arrancar de verdad cuando se cumplen las dos condiciones siguientes:
- un marcador de proyecto en el checkout, y
- que el binario del adaptador se resuelva.
Pide al agente que compruebe:
debug(op: "adapters")Responde con lo que ha encontrado o explica que un adaptador necesita las dos mitades.
| Lenguaje | Adaptador | Marcador | Instalación |
|---|---|---|---|
| Dart / Flutter | dart debug_adapter |
pubspec.yaml |
Viene con el SDK — no hay nada que hacer |
| Python | python3 -m debugpy.adapter |
pyproject.toml, setup.py, requirements.txt |
pip install debugpy |
| Rust / C / C++ | lldb-dap |
Cargo.toml, CMakeLists.txt |
Viene con LLVM |
| Go | dlv dap |
go.mod |
go install github.com/go-delve/delve/cmd/dlv@latest |
Primero el punto de interrupción, luego el lanzamiento
Sección titulada «Primero el punto de interrupción, luego el lanzamiento»El orden importa y la herramienta lo impone: los puntos de interrupción pueden establecerse antes de que exista una sesión, porque esa es la secuencia que exige el protocolo.
Pide al agente algo como:
La función
computedebin/main.dartdevuelve un valor incorrecto. Establece un punto de interrupción en la línea que asignaproduct, lánzalo bajo el depurador y dime qué valenayben realidad.
Ejecutará algo así:
debug(op: "breakpoints", file: "bin/main.dart", lines: [7])debug(op: "launch", program: "bin/main.dart")El lanzamiento informa de dónde se ha detenido:
Launched bin/main.dart on dart (session dart-1). Stopped: breakpoint. Use `stack` to see where.Leer el frame
Sección titulada «Leer el frame»debug(op: "stack")→ #1 compute (bin/main.dart:7:3) #2 main (bin/main.dart:2:18)Luego profundiza en él:
debug(op: "scopes", frame_id: 1)→ Locals (reference 12)
debug(op: "variables", reference: 12)→ a (int) = 6 b (int) = 7 product (int) = 42Un objeto con hijos informa de [expand: reference N] —pero solo cuando hay algo real detrás—, de modo que nunca se ofrece una expansión que el agente no pueda usar.
Para cualquier cosa que no sea visible como variable local:
debug(op: "evaluate", expression: "config.timeout.inSeconds", frame_id: 1)Ejecutar paso a paso
Sección titulada «Ejecutar paso a paso»| Qué quieres | Operación |
|---|---|
| Ejecutar hasta la siguiente parada | continue |
| Siguiente línea, mismo frame | step_over |
| Entrar en la llamada | step_in |
| Salir al invocador | step_out |
| Detener un programa en ejecución | pause |
Adjuntarse a algo que ya se está ejecutando
Sección titulada «Adjuntarse a algo que ya se está ejecutando»Para un proceso bloqueado en lugar de uno que estás iniciando:
debug(op: "attach", port: 5858)Terminar
Sección titulada «Terminar»debug(op: "terminate")Cierra siempre la sesión. Un adaptador de depuración posee un proceso detenido que retiene todo lo que retiene ese proceso: un puerto, un bloqueo, una conexión a una base de datos.
Salida acotada
Sección titulada «Salida acotada»Una expansión de variables sobre un grafo de objetos profundo es ilimitada por naturaleza: un solo widget de Flutter alcanza todo el árbol de elementos. Los hijos por ámbito están limitados a 50, los valores a 400 caracteres y los frames de pila a 30. Un resultado de herramienta que llena la ventana de contexto es una herramienta que termina con la ejecución a la que estaba ayudando.
Relacionado
Sección titulada «Relacionado»- Inteligencia de código — por qué un depurador, un compilador y un buscador estructural responden a preguntas distintas
- Herramientas de agente integradas — todas las operaciones de
debugy sus argumentos - Diagnosticar un agente — cuando el problema es el agente, no el código