Módulo 2: Agentic Research con Explore Subagent

Patrones de Exploración — Top-Down, Dependency-Following, Feature-Tracing

Patrones de Exploración — Top-Down, Dependency-Following, Feature-Tracing

Descripción de la cápsula

Saber usar Explore y entender la diferencia entre búsqueda semántica y grep es necesario pero no suficiente. Lo que separa a un investigador eficiente de uno que da vueltas sin rumbo es tener patrones de exploración — estrategias predefinidas para abordar diferentes tipos de preguntas sobre un codebase.

En esta cápsula vas a aprender tres patrones de exploración que cubren el 90% de las investigaciones que harás en código: top-down (de lo general a lo específico), dependency-following (siguiendo imports y llamadas), y feature-tracing (rastreando un feature de punta a punta). Cada patrón tiene un propósito, un punto de inicio, y una secuencia de pasos.

La conexión con el proyecto es directa: en la cápsula 05, las preguntas que debes responder requieren diferentes patrones. "¿Cuál es la arquitectura general?" es top-down. "¿De qué depende el módulo de pagos?" es dependency-following. "¿Cómo fluye un request de login?" es feature-tracing. Sin estos patrones, vas a improvisar y perder tiempo.


El Problema: Exploración sin Estrategia

Cómo se ve la exploración sin patrón

# Sesión típica sin estrategia:
> "Explora este proyecto"
# Resultado: lista genérica de archivos y directorios

> "¿Qué hace este proyecto?"
# Resultado: descripción vaga basada en el README

> "Muéstrame el código importante"
# Resultado: ¿importante para qué? Sin contexto, sin dirección

# 15 minutos después: tienes datos pero no comprensión

El problema no es la herramienta — es la falta de estrategia. Explorar sin patrón es como caminar por una ciudad sin mapa: ves cosas, pero no construyes un modelo mental coherente.

Cómo se ve la exploración con patrón

# Sesión con estrategia top-down:
> "Usa Explore para describir la estructura de directorios
   de primer nivel y el propósito de cada carpeta principal"
# Resultado: mapa claro de componentes principales

> "Ahora profundiza en src/api/ — ¿qué rutas expone
   y cómo están organizadas?"
# Resultado: lista de endpoints agrupados por dominio

> "Profundiza en el endpoint POST /api/orders —
   ¿qué funciones llama y qué servicios usa?"
# Resultado: cadena completa de llamadas

# 15 minutos después: tienes un mental model por capas

Patrón 1: Top-Down (De lo General a lo Específico)

Cuándo usarlo

Usa top-down cuando necesitas entender la estructura general de un codebase o un módulo. Es el patrón de inicio — casi siempre empiezas aquí.

Analogía

Es como ver Google Maps: empiezas en el nivel de país, luego ciudad, luego calle, luego edificio. Nunca empiezas por el edificio.

Secuencia de pasos

Nivel 1: Estructura de proyecto
    ↓
Nivel 2: Componentes principales
    ↓
Nivel 3: Módulos dentro de un componente
    ↓
Nivel 4: Funciones clave dentro de un módulo
    ↓
Nivel 5: Implementación de una función específica

Implementación con Explore

Nivel 1 — Estructura del proyecto:

> "Usa Explore para describir la estructura de directorios
   de primer nivel de este proyecto. Para cada carpeta
   principal, indica su propósito en una frase."

# Output esperado:
# /src — Código fuente principal
#   /api — Endpoints HTTP (FastAPI routes)
#   /services — Lógica de negocio
#   /models — Modelos de datos (SQLAlchemy)
#   /utils — Utilidades compartidas
#   /config — Configuración de la app
# /tests — Tests unitarios y de integración
# /migrations — Migraciones de base de datos (Alembic)
# /scripts — Scripts de deployment y mantenimiento
# /docs — Documentación

Nivel 2 — Componentes principales:

> "Usa Explore para profundizar en src/api/. ¿Cuántos
   endpoints hay, cómo están organizados, y cuál es
   el patrón de routing?"

# Output esperado:
# src/api/ usa un patrón de routers por dominio:
#   /routes/auth.py — 4 endpoints (login, register, logout, refresh)
#   /routes/users.py — 5 endpoints (CRUD + profile)
#   /routes/orders.py — 6 endpoints (CRUD + status + payment)
#   /routes/products.py — 4 endpoints (CRUD)
#   /middleware/ — auth, cors, logging, rate_limit
# Total: 19 endpoints, organizados por dominio de negocio

Nivel 3 — Módulo específico:

> "Usa Explore para analizar src/services/order_service.py.
   ¿Qué métodos expone, qué dependencias tiene, y cuál
   es la lógica principal de create_order()?"

# Output esperado: desglose completo del servicio
# con métodos, dependencias, y flujo de create_order

Nivel 4 — Función específica:

> "Usa Explore para analizar la función create_order()
   en detalle. ¿Qué validaciones hace, qué servicios
   externos llama, y cómo maneja errores?"

# Output esperado: análisis línea por línea de la función

Errores comunes con top-down

  • Saltarse niveles: ir directo de estructura a una función específica pierde contexto
  • Quedarse en el nivel alto: explorar solo la estructura sin profundizar no produce comprensión real
  • No documentar cada nivel: el valor de top-down es el mapa que construyes progresivamente

Patrón 2: Dependency-Following (Siguiendo las Conexiones)

Cuándo usarlo

Usa dependency-following cuando necesitas entender qué depende de qué. Es esencial antes de refactorizar (Módulo 4) porque un cambio en un módulo afecta a todos sus dependientes.

Analogía

Es como tirar de un hilo: empiezas por un módulo y sigues cada conexión (import, call, herencia) para mapear toda la red de dependencias.

Secuencia de pasos

Módulo inicial (el que investigas)
    ↓
¿Qué importa? (dependencias salientes)
    ↓
¿Quién lo importa? (dependientes entrantes)
    ↓
Para cada dependencia crítica: repetir
    ↓
Resultado: grafo de dependencias

Implementación con Explore

Paso 1 — Dependencias salientes (¿de qué depende?):

> "Usa Explore para listar todas las dependencias
   de src/services/payment_service.py. Incluye imports
   internos y externos, y para cada uno indica qué
   se usa de ese módulo."

# Output esperado:
# Dependencias externas:
#   - stripe (stripe.Charge, stripe.Customer)
#   - sqlalchemy (Session, select)
#   - pydantic (BaseModel)
#
# Dependencias internas:
#   - src/models/transaction.py (Transaction model)
#   - src/models/user.py (User model)
#   - src/services/email_service.py (send_receipt)
#   - src/utils/currency.py (convert_currency)
#   - src/config/settings.py (STRIPE_API_KEY)

Paso 2 — Dependientes entrantes (¿quién depende de este?):

> "Usa Explore para encontrar todos los archivos que
   importan o usan PaymentService o payment_service"

# Output esperado:
# Dependientes:
#   - src/api/routes/checkout.py — llama create_payment()
#   - src/api/routes/orders.py — llama process_refund()
#   - src/services/order_service.py — llama verify_payment()
#   - src/tasks/recurring_payments.py — llama charge_subscription()
#   - tests/test_payment_service.py — tests del servicio

Paso 3 — Profundizar en dependencias críticas:

> "Usa Explore para analizar la dependencia entre
   payment_service y email_service. ¿Qué funciones
   de email_service usa payment_service, y qué pasa
   si email_service falla?"

# Output esperado: análisis de acoplamiento
# y comportamiento en caso de fallo

Paso 4 — Construir el grafo:

> "Usa Explore para generar un diagrama mermaid de las
   dependencias de payment_service, mostrando dependencias
   salientes y entrantes en 2 niveles de profundidad"

# Output esperado:
# ```mermaid
# graph LR
#     checkout --> PaymentService
#     orders --> PaymentService
#     order_service --> PaymentService
#     recurring --> PaymentService
#     PaymentService --> Transaction
#     PaymentService --> User
#     PaymentService --> EmailService
#     PaymentService --> Currency
#     PaymentService --> Stripe
# ```

Señales de alerta en dependency-following

  • Dependencias circulares: A depende de B, B depende de A → indica acoplamiento alto
  • Fan-out excesivo: un módulo que importa 15+ otros módulos → posible god object
  • Fan-in excesivo: un módulo del que dependen 20+ otros → cambio aquí afecta a todo
  • Dependencias ocultas: comunicación vía eventos, globals, o side effects

Patrón 3: Feature-Tracing (Rastreo End-to-End)

Cuándo usarlo

Usa feature-tracing cuando necesitas entender cómo funciona un feature específico de punta a punta. Es el patrón más valioso para entender lógica de negocio.

Analogía

Es como seguir una pelota en un partido: empieza en un punto (request del usuario) y la sigues a través de cada jugador (función/servicio) hasta que llega al gol (respuesta).

Secuencia de pasos

Entry point (request/evento/CLI command)
    ↓
Middleware / interceptors
    ↓
Route handler / controller
    ↓
Service layer (lógica de negocio)
    ↓
Repository / data access
    ↓
Database / external service
    ↓
Response construction
    ↓
Return al usuario

Implementación con Explore

Trace completo — Flujo de login:

> "Usa Explore para rastrear el flujo completo de login
   en este proyecto. Empieza desde el endpoint POST /login
   y sigue cada función que se llama hasta la respuesta
   final. Para cada paso, indica: archivo, función, y qué
   hace."

# Output esperado:
#
# 1. src/api/routes/auth.py:login()
#    → Recibe POST /login con {email, password}
#    → Valida formato con LoginRequest (pydantic)
#
# 2. src/services/auth_service.py:authenticate()
#    → Busca usuario por email
#    → Verifica password con bcrypt
#    → Si falla: raise AuthError("Invalid credentials")
#
# 3. src/models/user.py:User.get_by_email()
#    → Query: SELECT * FROM users WHERE email = ?
#    → Retorna User object o None
#
# 4. src/utils/security.py:verify_password()
#    → bcrypt.checkpw(password, hashed)
#    → Retorna bool
#
# 5. src/services/auth_service.py:create_tokens()
#    → Genera JWT access token (15 min)
#    → Genera JWT refresh token (7 días)
#    → Guarda refresh token en DB
#
# 6. src/api/routes/auth.py:login()
#    → Retorna {access_token, refresh_token, user_info}
#    → HTTP 200

Trace de datos — Cómo se transforma el input:

> "Usa Explore para rastrear cómo se transforman los datos
   en un request de crear orden. Desde el JSON que envía
   el cliente hasta lo que se guarda en la base de datos."

# Output esperado:
#
# Input del cliente:
#   {"product_id": 123, "quantity": 2, "coupon": "SAVE10"}
#
# Transformación 1 (route handler):
#   → Validación con Pydantic → OrderCreateRequest object
#   → Se agrega user_id del token JWT
#
# Transformación 2 (order_service):
#   → Se busca producto → se calcula precio
#   → Se aplica cupón → precio ajustado
#   → Se calcula tax → precio final
#
# Transformación 3 (payment_service):
#   → Se crea charge en Stripe
#   → Se obtiene transaction_id
#
# Lo que se guarda en DB:
#   Order(user_id=456, product_id=123, quantity=2,
#         subtotal=49.98, discount=5.00, tax=4.05,
#         total=49.03, stripe_tx="ch_abc123",
#         status="confirmed", created_at=...)

Feature-tracing en profundidad

Rastreo de errores:

> "Usa Explore para rastrear qué pasa cuando el pago
   falla durante la creación de una orden. ¿Cómo se
   propaga el error desde Stripe hasta el usuario?"

# Output esperado: cadena de error handling desde
# stripe.CardError → PaymentError → orden no creada
# → HTTP 402 con mensaje al usuario

Rastreo de side effects:

> "Usa Explore para encontrar todos los side effects
   de crear una orden exitosamente. ¿Qué más pasa
   además de guardar la orden en la DB?"

# Output esperado:
# 1. Se envía email de confirmación (email_service)
# 2. Se actualiza inventario (inventory_service)
# 3. Se publica evento OrderCreated (event_bus)
# 4. Se actualiza analytics (analytics_service)
# 5. Se crea entrada en audit log

Combinando Patrones

El workflow de investigación completa

Los tres patrones se complementan. En una investigación real los combinas:

# 1. Top-Down: entender estructura general
> "Estructura del proyecto y componentes principales"

# 2. Feature-Tracing: entender un flujo crítico
> "Rastrear el flujo de checkout de punta a punta"

# 3. Dependency-Following: entender impacto de cambios
> "¿Qué depende de payment_service? Si lo cambio,
   ¿qué se rompe?"

Cuándo usar cada patrón

PreguntaPatrónPor qué
"¿Cómo está organizado este proyecto?"Top-DownNecesitas estructura general
"¿Cómo funciona el login?"Feature-TracingNecesitas flujo end-to-end
"¿Qué pasa si cambio UserModel?"Dependency-FollowingNecesitas impacto de cambios
"¿Cuál es la arquitectura?"Top-DownNecesitas capas y componentes
"¿Cómo se procesan pagos?"Feature-TracingNecesitas flujo de negocio
"¿Qué módulos usa el scheduler?"Dependency-FollowingNecesitas conexiones

El principio fundamental

Investigar antes de modificar. Este principio se repite en toda la guía. Los tres patrones son herramientas de investigación. Explores es la herramienta. Los patrones son la estrategia. Juntos producen comprensión profunda que informa decisiones de refactoring.


Conexión con Proyecto

En el Proyecto del Módulo (cápsula 05) vas a usar los tres patrones para responder preguntas sobre un codebase:

  • Top-Down: "¿Cuál es la arquitectura general del proyecto?"
  • Feature-Tracing: "¿Cómo fluye un request de login desde el endpoint hasta la DB?"
  • Dependency-Following: "¿Qué dependencias tiene el módulo de pagos?"

El proyecto evalúa que puedas elegir el patrón correcto para cada pregunta y ejecutarlo eficientemente con Explore.


Troubleshooting

Problema 1: No sé qué patrón usar

Causa: La pregunta es ambigua.

Solución: Clasifica la pregunta:

  • ¿Pregunta sobre estructura? → Top-Down
  • ¿Pregunta sobre un flujo? → Feature-Tracing
  • ¿Pregunta sobre conexiones? → Dependency-Following

Problema 2: Top-Down se pierde en detalles

Causa: Bajaste de nivel demasiado rápido.

Solución: Mantén disciplina de niveles. No bajes al nivel 3 sin haber documentado el nivel 2 completo.

Problema 3: Feature-Tracing se ramifica demasiado

Causa: El feature tiene muchos side effects.

Solución: Primero traza el happy path (flujo principal sin errores). Después traza error paths y side effects por separado.

Problema 4: Dependency-Following encuentra dependencias circulares

Causa: Diseño acoplado del codebase (no es tu error).

Solución: Documéntalo como finding. Las dependencias circulares son un anti-pattern que se aborda en el Módulo 3 (Architecture) y se resuelve en el Módulo 4 (Refactoring).

Problema 5: Explore no sigue el patrón que pedí

Causa: El prompt no especifica la estrategia claramente.

Solución: Sé explícito sobre el patrón:

# Vago:
> "Analiza el módulo de pagos"

# Explícito:
> "Usa un approach top-down para analizar el módulo
   de pagos. Empieza por la estructura de archivos,
   luego describe los componentes principales, y
   finalmente detalla las funciones clave de
   payment_service.py"

Ejercicios

Ejercicio 1: Clasificar preguntas por patrón (Fácil)

Clasifica cada pregunta con el patrón correcto (Top-Down, Dependency-Following, o Feature-Tracing):

  1. "¿Cuántos módulos tiene este proyecto y qué hace cada uno?"
  2. "¿Qué pasa cuando un usuario sube una imagen?"
  3. "¿Qué se rompe si elimino la clase Logger?"
  4. "¿Cómo está organizado el directorio de tests?"
  5. "¿Cómo se procesa un webhook de Stripe?"
  6. "¿Quién usa la función calculate_tax()?"
Ver solución
  1. Top-Down — pregunta sobre estructura general
  2. Feature-Tracing — pregunta sobre flujo end-to-end de un feature
  3. Dependency-Following — pregunta sobre impacto de un cambio (dependientes)
  4. Top-Down — pregunta sobre estructura de un directorio
  5. Feature-Tracing — pregunta sobre flujo de un evento
  6. Dependency-Following — pregunta sobre quién depende de una función

Regla: estructura = top-down, flujo = feature-tracing, impacto = dependency-following

Ejercicio 2: Diseñar prompts top-down (Fácil)

Escribe una secuencia de 4 prompts top-down para investigar el directorio src/services/ de un proyecto, yendo de nivel 1 (overview) a nivel 4 (función específica):

Ver solución
# Nivel 1: Overview
> "Usa Explore para listar todos los archivos en src/services/
   y describir el propósito de cada servicio en una frase"

# Nivel 2: Componente
> "Usa Explore para analizar src/services/order_service.py.
   ¿Qué métodos públicos expone y cuál es la responsabilidad
   de cada uno?"

# Nivel 3: Método
> "Usa Explore para detallar el método create_order() de
   OrderService. ¿Qué pasos ejecuta, qué valida, y qué
   servicios externos llama?"

# Nivel 4: Implementación
> "Usa Explore para analizar el manejo de errores dentro
   de create_order(). ¿Qué excepciones puede lanzar y
   cómo se manejan?"

Clave: cada nivel usa el resultado del anterior para decidir dónde profundizar.

Ejercicio 3: Feature-Tracing completo (Medio)

Escribe los prompts de Explore necesarios para rastrear el flujo completo de "usuario se registra" en una app web típica. Incluye happy path y al menos 2 error paths.

Ver solución
# Happy Path:
> "Usa Explore para rastrear el flujo completo de registro
   de usuario. Empieza desde el endpoint POST /register y
   sigue cada función hasta la respuesta. Incluye: archivo,
   función, qué datos recibe, qué datos produce."

# Error Path 1 — Email duplicado:
> "Usa Explore para rastrear qué pasa cuando un usuario
   intenta registrarse con un email que ya existe. ¿Dónde
   se detecta, qué error se lanza, y qué respuesta HTTP
   recibe el usuario?"

# Error Path 2 — Validación fallida:
> "Usa Explore para rastrear qué pasa cuando el request
   de registro tiene datos inválidos (password corto,
   email malformado). ¿En qué capa se valida y cómo
   se comunica el error?"

# Side Effects:
> "Usa Explore para encontrar todos los side effects
   de un registro exitoso. ¿Se envía email de verificación?
   ¿Se crea algún registro adicional? ¿Se notifica a algún
   servicio externo?"

Por qué 4 prompts: happy path te da el flujo normal, error paths te muestran robustez, side effects te muestran el impacto completo.

Ejercicio 4: Dependency map de un módulo (Medio)

Elige un módulo de un proyecto que conozcas (o usa un proyecto open-source). Escribe los prompts para construir un dependency map completo usando Explore:

Ver solución
# Paso 1: Dependencias salientes
> "Usa Explore para listar todas las dependencias de
   [módulo]. Separa en: dependencias externas (pip packages)
   y dependencias internas (otros módulos del proyecto).
   Para cada una, indica qué se importa/usa."

# Paso 2: Dependientes entrantes
> "Usa Explore para encontrar todos los archivos del
   proyecto que importan o usan [módulo]. Indica qué
   función o clase usan de [módulo]."

# Paso 3: Dependencias transitivas (1 nivel más)
> "Para las 3 dependencias internas más importantes
   de [módulo], ¿de qué dependen ellas a su vez?"

# Paso 4: Generar diagrama
> "Genera un diagrama mermaid mostrando [módulo] al
   centro, sus dependencias salientes a la derecha,
   y sus dependientes entrantes a la izquierda."

# Paso 5: Análisis de riesgo
> "Basándote en el dependency map, ¿cuál es el cambio
   en [módulo] que tendría mayor impacto en el resto
   del proyecto? ¿Y cuál tendría menor impacto?"

Valor: este ejercicio produce un artefacto real (dependency map) que puedes usar para planificar refactoring.

Ejercicio 5: Investigación combinada (Difícil)

Un compañero te pide que investigues por qué el endpoint /api/reports/generate tarda 30 segundos. Diseña un plan de investigación de 6 pasos usando los 3 patrones:

Ver solución
# 1. Top-Down: entender el módulo de reports
> "Usa Explore para describir la estructura del módulo
   de reports. ¿Qué archivos lo componen, qué servicios
   usa, y cómo está organizado?"

# 2. Feature-Tracing: rastrear el flujo del endpoint
> "Usa Explore para rastrear el flujo completo de
   GET /api/reports/generate. Desde el request hasta
   la respuesta, ¿qué funciones se ejecutan y en qué
   orden?"

# 3. Feature-Tracing: identificar bottlenecks
> "Del flujo anterior, ¿cuáles pasos involucran I/O
   (database queries, API calls, file system)? Esos
   son los candidatos a causar los 30 segundos."

# 4. Dependency-Following: analizar dependencias pesadas
> "Usa Explore para analizar las dependencias del
   report generator. ¿Usa algún servicio externo, query
   compleja, o procesamiento intensivo?"

# 5. Feature-Tracing: buscar N+1 queries
> "Usa Explore para analizar las database queries en
   el flujo de generate_report(). ¿Hay alguna que se
   ejecute en un loop (N+1 problem)?"

# 6. Top-Down: buscar soluciones existentes
> "Usa Explore para verificar si el proyecto tiene
   algún sistema de cache, background jobs, o queries
   optimizadas que el report generator no esté usando."

Patrón: Top-Down (contexto) → Feature-Tracing (flujo + bottleneck) → Dependency-Following (causas) → Top-Down (soluciones existentes).


Resumen

En esta cápsula aprendiste:

  • Tres patrones de exploración cubren el 90% de investigaciones: top-down, dependency-following, y feature-tracing
  • Top-Down va de lo general a lo específico: estructura → componentes → módulos → funciones
  • Dependency-Following mapea conexiones: ¿de qué depende? ¿quién depende de esto?
  • Feature-Tracing rastrea flujos end-to-end: request → procesamiento → respuesta
  • Cada patrón tiene un propósito: estructura (top-down), impacto (dependencies), flujos (tracing)
  • Combinar patrones produce investigaciones completas y eficientes
  • Investigar antes de modificar es el principio que todos los patrones refuerzan

Próxima cápsula: Proyecto del Módulo — Exploración de Codebase con Explore. Vas a poner en práctica los tres patrones respondiendo preguntas específicas sobre un codebase real.


Recursos Adicionales

  1. Explore Subagent - Claude Code Docs - Documentación oficial del subagent Explore
  2. Code Reading: The Open Source Perspective - Libro clásico sobre lectura sistemática de código
  3. Working Effectively with Legacy Code - Michael Feathers - El libro de referencia sobre trabajar con código existente
  4. Dependency Analysis Tools - Python - pydeps para generar grafos de dependencia en Python
  5. Architecture Decision Records - Documentar decisiones arquitecturales que encuentras
  6. The Art of Code Review - Google Engineering - Prácticas de revisión que complementan la exploración