Phase 19 - Lesson 01
Capstone 01 — Terminal-Native Coding Agent
Para 2026, el formato de un agente de programación ya está consolidado. Un arnés TUI, un estado de planificación persistente, una superficie de herramientas en sandbox y un bucle que planifica, actúa, observa y se recupera. Claude Code, Cursor 3 y OpenCode se ven todos idénticos cuando se observan desde la distancia. Este proyecto final (capstone) te desafía a construir un agente de extremo a extremo — desde el CLI de entrada hasta la pull request de salida — y evaluarlo en comparación con mini-swe-agent y Live-SWE-agent en SWE-bench Pro. Aprenderás por qué la parte más difícil no es la llamada al modelo, sino el bucle de herramientas, el sandbox y el techo de costo en una ejecución de 50 turnos.
Type: Capstone Languages: TypeScript / Bun (harness), Python (eval scripts) Prerequisites: Phase 11 (LLM engineering), Phase 13 (tools and protocols), Phase 14 (agents), Phase 15 (autonomous systems), Phase 17 (infrastructure) Phases exercised: P0 · P5 · P7 · P10 · P11 · P13 · P14 · P15 · P17 · P18 Time: 35 hours
Problem
Los agentes de programación se convirtieron en la categoría dominante de aplicación de IA en 2026. Claude Code (Anthropic), Cursor 3 con Composer 2 y Agent Tabs (Cursor), Amp (Sourcegraph), OpenCode (112 mil estrellas), Factory Droids y Google Jules distribuyen variaciones de la misma arquitectura: un arnés de terminal, una superficie de herramientas con permisos, un sandbox y un bucle de planificar-actuar-observar construido alrededor de un modelo de frontera. La frontera de éxito es estrecha — Live-SWE-agent alcanzó 79.2% en SWE-bench Verified con Opus 4.5 —, pero la ingeniería involucrada es amplia. La mayoría de los modos de fallo no proceden de errores del modelo, sino de la inestabilidad del bucle de herramientas, envenenamiento de contexto, costo descontrolado de tokens y operaciones destructivas en el sistema de archivos.
No es posible comprender verdaderamente estos agentes desde una perspectiva externa. Tienes que construir uno, observar el bucle fallar en el turno 47 cuando ripgrep devuelve 8MB de coincidencias y reconstruir la capa de truncamiento. Ese es el objetivo de este capstone.
Concept
El arnés posee cuatro superficies principales. Plan mantiene un objeto de estado al estilo TodoWrite que el modelo reescreve a cada turno. Act despacha llamadas de herramientas (read, edit, run, search, git). Observe captura la salida estándar (stdout), salida de error (stderr) y códigos de salida, aplica truncamiento y envía el resumen de vuelta al modelo. Recover maneja errores de herramientas sin saturar la ventana de contexto o entrar en bucles infinitos. El formato de 2026 añade un elemento más: hooks. PreToolUse, PostToolUse, SessionStart, SessionEnd, UserPromptSubmit, Notification, Stop y PreCompact — puntos de extensión configurables donde el operador inyecta políticas, telemetría y protecciones.
El sandbox se ejecuta en E2B o Daytona. Cada tarea corre en un devcontainer nuevo con un git worktree montado con permisos de lectura y escritura. El arnés nunca toca el sistema de archivos del host. El worktree se destruye tras el éxito o fallo de la tarea. El control de costos se aplica en tres capas: un límite de tokens por turno, un presupuesto financiero por sesión y un límite rígido de turnos (generalmente 50). La capa de observabilidad utiliza spans OpenTelemetry con las convenciones semánticas de GenAI, enviados a una instancia propia de Langfuse.
Architecture
user CLI -> harness (Bun + Ink TUI)
|
v
plan / act / observe loop <---> Claude Sonnet 4.7 / GPT-5.4-Codex / Gemini 3 Pro
| (via OpenRouter, model-agnostic)
v
tool dispatcher (MCP StreamableHTTP client)
|
+------------+------------+----------+
v v v v
read/edit ripgrep tree-sitter git/run
| | | |
+------------+------------+----------+
|
v
E2B / Daytona sandbox (worktree isolated)
|
v
hooks: Pre/Post, Session, Prompt, Compact
|
v
OpenTelemetry -> Langfuse (spans, tokens, $)
|
v
PR via GitHub app
Stack
- Runtime del arnés: Bun 1.2 + Ink 5 (React-en-terminal)
- Acceso al modelo: API unificada de OpenRouter con Claude Sonnet 4.7, GPT-5.4-Codex, Gemini 3 Pro, Opus 4.5 (para las tareas más complejas)
- Transporte de herramientas: Model Context Protocol StreamableHTTP (revisión de 2026 del MCP)
- Sandbox: Sandboxes E2B (JS SDK) o devcontainers Daytona
- Búsqueda de código: subproceso ripgrep, analizadores tree-sitter precompilados para 17 lenguajes
- Aislamiento:
git worktree addpor tarea, con limpieza en caso de éxito o fallo - Arnés de evaluación: SWE-bench Pro (subconjunto verificado) + Terminal-Bench 2.0 + tu propio conjunto de validación de 30 tareas
- Observabilidad: SDK de OpenTelemetry con semconv
gen_ai.*→ Langfuse hospedado localmente - Envío de PR: GitHub App con token de granularidad fina, con alcance limitado al repositorio objetivo
Build It
TUI y bucle de comandos. Estructura un proyecto Bun con Ink. Acepta
agent run <repo> "<task>". Muestra una vista dividida: panel del plan (arriba), flujo de llamadas de herramientas (medio), presupuesto de tokens (abajo). Añade cancelación en Ctrl-C que active el hookSessionEndantes de salir.Estado del plan. Define un esquema TodoWrite tipado (ítems pendientes / en progreso / completados con notas). El modelo debe reescribir el estado completo a cada turno mediante una llamada de herramienta — no permitas mutaciones incrementales. Persiste el plan en
.agent/state.jsonpara que la ejecución pueda reanudarse tras fallos.Superficie de herramientas. Define seis herramientas:
read_file,edit_file(con vista previa de diff),ripgrep,tree_sitter_symbols,run_shell(con límite de tiempo) ygit(status / diff / commit / push). Exponlas vía MCP StreamableHTTP para que el arnés sea independiente de transporte. Cada herramienta debe retornar salidas truncadas (límite máximo de 4k tokens por llamada).Envoltura del sandbox. Cada tarea inicia un sandbox E2B. Crea una rama limpia con
git worktree add -b agent/$TASK_ID. Todas las llamadas de herramientas deben ejecutarse dentro del sandbox. El sistema de archivos del host debe ser inaccesible.Hooks. Implementa todos los ocho tipos de hooks de 2026. Conecta al menos cuatro hooks personalizados: (a) protección de comandos destructivos en
PreToolUseque impidarm -rffuera del worktree, (b) contabilidad de tokens enPostToolUse, (c) inicialización del presupuesto enSessionStarty (d) grabación del paquete final de rastreo enStop.Bucle de evaluación. Clona un subconjunto de 30 tareas de SWE-bench Pro en Python. Ejecuta tu arnés contra cada una. Compara con mini-swe-agent (la línea base mínima) en relación a pass@1, turnos por tarea y costo financiero por tarea. Salva los resultados en
eval/results.jsonl.Control de costos. Límites rígidos: 50 turnos, 200k de contexto, $5 por tarea. El hook
PreCompactdebe resumir turnos antiguos en un bloque de estado anterior al alcanzar la marca de 150k tokens, liberando espacio para nuevas observaciones sin perder el plan.Envío de PR. En caso de éxito, el paso final consiste en ejecutar
git push+ una llamada a la API de GitHub que abra un PR que contenga el plan y el resumen del diff en el cuerpo del mensaje.
Use It
$ agent run ./my-repo "Fix the race condition in worker.rs"
[plan] 1 locate worker.rs and enumerate mutex uses
2 identify shared state under contention
3 propose fix, verify tests
[tool] ripgrep mutex.*lock -t rust (44 matches, truncated)
[tool] read_file src/worker.rs 120..180
[tool] edit_file src/worker.rs (+8 -3)
[tool] run_shell cargo test worker:: (passed)
[plan] 1 done · 2 done · 3 done
[done] PR opened: #482 turns=9 tokens=38k cost=$0.41
Ship It
La habilidad entregable se detalla en outputs/skill-terminal-coding-agent.md. Dado el camino de un repositorio y la descripción de una tarea, el sistema ejecuta el bucle completo de planificar-actuar-observar en un sandbox y retorna la URL del PR junto con el paquete de rastreo. Criterios de evaluación para este capstone:
| Weight | Criterion | How it is measured |
|---|---|---|
| 25 | SWE-bench Pro pass@1 vs baseline | Tu arnés vs mini-swe-agent en 30 tareas Python equivalentes |
| 20 | Claridad arquitectónica | Separación de planificar/actuar/observar, superficie de hooks y esquema de herramientas — revisados en relación a la estructura de Live-SWE-agent |
| 20 | Seguridad | Pruebas de escape del sandbox, prompts de permiso y protección contra comandos destructivos aprobados en pruebas adversarias (red-team) |
| 20 | Observabilidad | Rastreo completo (100% de las llamadas de herramientas cubiertas por spans) y contabilidad de tokens por turno |
| 15 | UX del desarrollador | Inicialización en frío < 2s, recuperación de fallos retomando el plan y cancelación limpia de herramientas en Ctrl-C |
| 100 |
Exercises
Reemplaza el modelo de soporte de Claude Sonnet 4.7 por el Qwen3-Coder-30B servido en vLLM. Compara el pass@1 y el costo financiero por tarea. Reporta los puntos donde el modelo de código abierto presenta un desempeño inferior.
Añade un subagente
reviewerque revise el diff antes de enviar el PR y que pueda solicitar un bucle de revisión adicional. Mide si revisiones falso-positivas reducen la tasa de éxito de SWE-bench por debajo de la línea base de agente único (pista: generalmente sí).Prueba los límites de seguridad del sandbox: escribe una tarea que intente ejecutar un
curla una URL externa y otra que intente escribir fuera del worktree. Confirma que ambas tentativas son bloqueadas por el hookPreToolUse. Registra las tentativas en log.Implemente la compactación en
PreCompactutilizando un modelo menor (Haiku 4.5). Mide la pérdida de fidelidad del plan tras una compactación de 3x.Reemplaza el transporte MCP StreamableHTTP por stdio. Realiza un benchmark del tiempo de inicialización en frío y de la latencia por llamada. Elige el ganador para uso local únicamente.
Key Terms
| Term | What people say | What it actually means |
|---|---|---|
| Harness | "El bucle del agente" | El código que envuelve al modelo y gestiona las herramientas, el estado del plan y el presupuesto |
| Hook | "Oyente de eventos del agente" | Un script personalizado ejecutado en uno de los ocho eventos del ciclo de vida del arnés |
| Worktree | "Sandbox de Git" | Un checkout de Git vinculado a un camino separado; desechable sin afectar el clon principal |
| TodoWrite | "Estado del plan" | Una lista tipada de ítems pendientes, en progreso o completados que el modelo reescribe a cada turno |
| StreamableHTTP | "Transporte MCP" | Revisión de 2026 del MCP: conexión HTTP de larga duración con streaming bidirecional que reemplaza SSE |
| Token ceiling | "Presupuesto de contexto" | Límite por turno o por sesión para tokens de entrada y salida; activa la compactación o la terminación |
| pass@1 | "Tasa de éxito en el primer intento" | Fracción de tareas de SWE-bench resueltas en la primera ejecución, sin intentos adicionales o visualización del conjunto de pruebas |
Further Reading
- Claude Code documentation — arnés de referencia de Anthropic
- Cursor 3 changelog — notas sobre Agent Tabs y Composer 2
- mini-swe-agent — línea base mínima para comparación de arneses de SWE-bench
- Live-SWE-agent — 79.2% en SWE-bench Verified con Opus 4.5
- OpenCode — arnés de código abierto con 112 mil estrellas
- SWE-bench Pro leaderboard — la evaluación a la que apunta este capstone
- Model Context Protocol 2026 roadmap — StreamableHTTP y metadados de capacidad
- OpenTelemetry GenAI semantic conventions — esquema de spans para llamadas de herramientas y uso de tokens