Escribir buenos prompts

El agente sigue un ciclo interno: ANALIZAR → PLANIFICAR → EJECUTAR → VERIFICAR → CORREGIR. Un buen prompt guía cada fase de ese ciclo.

Sé específico sobre el qué y el dónde

# Malo — vago, obliga al agente a adivinar
architect run "arregla el bug del login"

# Bueno — indica archivo, síntoma y pista
architect run "el endpoint POST /login retorna 401 con credenciales válidas. \
  El problema está probablemente en src/auth.py en la función validate_token(). \
  Verifica la comprobación de expiración del JWT."

Un prompt específico ahorra entre 5 y 10 pasos de exploración. Cada paso cuesta tokens y consume contexto.

Describe el resultado esperado

# Malo — no dice qué quiere como resultado
architect run "mejora el módulo de users"

# Bueno — describe el estado final deseado
architect run "en src/models/user.py, cambia la clase User de dataclass \
  a Pydantic BaseModel. Mantén los valores por defecto. Añade \
  model_config = {'extra': 'forbid'}. Actualiza los imports en \
  los archivos que usan User."

Un objetivo por ejecución

El agente funciona mejor con tareas focalizadas. En lugar de un prompt largo con 5 tareas, ejecuta 5 veces con prompts cortos.

# Peor — demasiados objetivos en un solo prompt
architect run "refactoriza utils.py, añade tests, actualiza docs, \
  corrige el bug de parseo y migra a async"

# Mejor — una tarea por ejecución
architect run "migra las funciones de utils.py a Pydantic v2" --mode yolo
architect run "genera tests para los nuevos modelos Pydantic" --mode yolo
architect run "actualiza docs/models.md con los nuevos schemas" --mode yolo

Menciona el contexto que el agente no puede deducir

El agente ve el árbol del proyecto y puede leer archivos, pero no sabe cosas como:

  • Convenciones del equipo que no están documentadas en el código.
  • Por qué se eligió un patrón sobre otro.
  • Requisitos de negocio que no se reflejan en el código.
# Incluir contexto no visible en el código
architect run "añade validación de NIF español al campo tax_id de User. \
  Usamos la librería stdnum para validaciones fiscales (ya está en requirements). \
  El formato esperado es con letra al final, sin guiones."

Elegir el agente correcto

TareaAgentePor qué
Implementar códigobuild (default)Tiene todas las tools: lectura, escritura, búsqueda, comandos
Entender códigoresumeRápido, barato, 15 pasos máximo
Planificar antes de implementarplanSolo lectura, produce un plan sin tocar nada
Code reviewreviewFocalizado en feedback, no modifica archivos
Tarea sensible (producción)build con confirm-allConfirma cada operación
Automatización CIbuild o review con yoloSin confirmaciones interactivas

Patrón recomendado para tareas grandes:

# 1. Planificar (barato, solo lectura)
architect run "¿cómo añadir autenticación JWT?" -a plan --json > plan.json

# 2. Revisar el plan
cat plan.json | jq -r '.output'

# 3. Implementar con el plan como referencia
PLAN=$(jq -r '.output' plan.json)
architect run "Implementa este plan: ${PLAN}" --mode yolo --self-eval basic

Edición de archivos

Jerarquía de edición

SituaciónHerramientaMotivo
Cambiar un bloque contiguoedit_filePreciso, genera diff, preferido
Cambios en múltiples seccionesapply_patchUn solo paso para multi-hunk
Archivo nuevo o reescritura completawrite_fileCrea desde cero

Regla de unicidad de edit_file

edit_file requiere que el old_str sea único en el archivo. Si aparece 0 o 2+ veces, falla.

Cómo evitar problemas:

El agente normalmente maneja esto bien. Pero si ves errores de “old_str aparece N veces”, puedes ayudar en el prompt:

# Mencionar contexto para que el agente incluya líneas de alrededor
architect run "en config.py, cambia el timeout de la función connect() \
  (no el timeout de la función retry()) de 30 a 60 segundos"

Prefer edit_file sobre write_file para cambios

write_file sobreescribe todo el contenido. Si el agente lee un archivo de 500 líneas y lo reescribe para cambiar 2, puede perder formateo o introducir errores. edit_file solo toca el bloque exacto.


Ejecución de comandos

Habilitar cuando lo necesites

Por defecto, run_command está habilitado pero el agente build requiere confirmación para comandos “dev” (pytest, mypy, ruff). Con --mode yolo se ejecutan sin preguntar.

# Que el agente pueda ejecutar tests sin confirmar
architect run "corrige el bug y ejecuta pytest para verificar" \
  --mode yolo --allow-commands

Comandos seguros, dev y peligrosos

El sistema clasifica cada comando automáticamente:

CategoríaEjemplosConfirmación en confirm-sensitive
safels, cat, git status, git log, python --versionAuto-aprobado
devpytest, mypy, ruff, npm test, cargo test, makeAuto-aprobado
dangerousScripts custom, comandos desconocidosRequiere confirmación

Si usas herramientas no estándar, añádelas a la config:

commands:
  safe_commands:
    - "my-linter --check"
    - "custom-test-runner"

Timeouts

El timeout por defecto es 30 segundos. Si tus tests o builds tardan más:

commands:
  default_timeout: 120   # 2 minutos

Lo que siempre se bloquea

Estos patrones están bloqueados en todas las circunstancias:

  • rm -rf / — Destrucción del sistema.
  • sudo — Escalación de privilegios.
  • curl | bash, wget | sh — Ejecución remota de código.
  • dd of=/dev/ — Escritura directa a disco.
  • chmod 777 — Permisos inseguros.
  • mkfs — Formateo de disco.
  • Fork bombs.

No hay override para estos. Es una decisión de diseño para seguridad.


Gestión del contexto

El agente mantiene un historial de mensajes con el LLM. A medida que se acumulan pasos, el contexto crece y puede saturarse.

Los tres niveles de protección

  1. Truncado de tool results: Los resultados de tools mayores a max_tool_result_tokens se cortan, manteniendo principio y final del output.
  2. Compresión de pasos antiguos: Después de N pasos con tool calls, los más antiguos se resumen con el LLM (coste extra: ~500 tokens por compresión).
  3. Ventana deslizante: Si el contexto supera max_context_tokens, se eliminan los mensajes más antiguos.

Cómo evitar llenar el contexto

  • Busca antes de leer. Usa search_code o grep para localizar el código relevante en vez de leer archivos enteros.
  • Una tarea por ejecución. No pidas 5 refactorizaciones en un solo prompt.
  • Controla el número de pasos. Si ves que una tarea consume 30+ pasos regularmente, divídela.
  • Ajusta los umbrales para proyectos grandes:
context:
  max_tool_result_tokens: 2000     # Tokens por resultado de tool
  summarize_after_steps: 8         # Comprimir tras 8 pasos con tools
  keep_recent_steps: 4             # Mantener los 4 pasos más recientes
  max_context_tokens: 80000        # Límite hard del contexto total

Cuándo aumentar max_context_tokens

Depende del modelo:

ModeloContext window realValor recomendado
gpt-4o128K80,000–100,000
gpt-4o-mini128K80,000–100,000
claude-sonnet-4-6200K120,000–160,000
claude-opus-4-6200K120,000–160,000
ollama/llama3 (8B)8K4,000–6,000

Deja un 20-30% de margen para el system prompt y el índice del proyecto.


Optimización de costes

Elegir el modelo según la tarea

TareaModelo recomendadoCoste relativo
Review, resumen, planificacióngpt-4o-miniMuy bajo
Implementación simple (1-3 archivos)gpt-4oMedio
Refactorización complejaclaude-sonnet-4-6Medio-alto
Tareas críticas con auto-eval fullgpt-4o / claude-sonnet-4-6Alto
# Review barato
architect run "revisa src/auth.py" -a review --model gpt-4o-mini

# Implementación con modelo potente
architect run "refactoriza el ORM completo" --model claude-sonnet-4-6

Activar prompt caching

Reduce el coste del system prompt un 90% en llamadas consecutivas al mismo modelo. El cache dura ~5 minutos.

llm:
  prompt_caching: true

Es especialmente útil cuando ejecutas varias tareas seguidas sobre el mismo proyecto:

architect run "paso 1..." --model claude-sonnet-4-6
architect run "paso 2..." --model claude-sonnet-4-6   # 90% más barato en system prompt
architect run "paso 3..." --model claude-sonnet-4-6   # idem

Establecer budget

Siempre usa --budget en automatización para evitar costes descontrolados:

architect run "..." --budget 2.00 --show-costs

El agente se detiene con status: "partial" y stop_reason: "budget_exceeded" si supera el límite. Antes de parar, genera un resumen de lo que hizo.

# Config con warning temprano
costs:
  enabled: true
  budget_usd: 5.00
  warn_at_usd: 2.00    # Log warning al llegar a $2

Cache local para desarrollo

Si estás iterando sobre el mismo prompt (debugging, ajuste de config), activa el cache local:

architect run "..." --cache
# Segunda ejecución con mismo prompt → respuesta instantánea, 0 tokens

No usar en producción: las respuestas cacheadas pueden quedar obsoletas si el código cambia.


Hooks post-edición

Cuándo usarlos

Los hooks ejecutan automáticamente linters, formateadores o type checkers después de cada edición. El resultado vuelve al agente, que puede auto-corregir errores.

hooks:
  post_edit:
    - name: format
      command: "black {file}"
      file_patterns: ["*.py"]
      timeout: 10

    - name: lint
      command: "ruff check {file}"
      file_patterns: ["*.py"]
      timeout: 10

    - name: typecheck
      command: "mypy {file} --ignore-missing-imports"
      file_patterns: ["*.py"]
      timeout: 30

Buenas prácticas con hooks

Mantén los hooks rápidos. Cada hook añade tiempo y potencialmente una iteración extra si falla. Un hook de 30s en cada edición suma rápido.

Evita tests en hooks. Los tests suelen ser lentos. Es mejor que el agente los ejecute explícitamente con run_command una vez al final, no después de cada edición.

# Bien — hooks rápidos de formateo y lint
hooks:
  post_edit:
    - name: format
      command: "black {file}"
      file_patterns: ["*.py"]
      timeout: 10

# Mal — test suite completa en cada edición
hooks:
  post_edit:
    - name: tests
      command: "pytest tests/ -x"
      file_patterns: ["*.py"]
      timeout: 120     # 2 minutos por cada edición

Si un hook está roto, desactívalo. Un linter mal configurado que siempre falla causa que el agente entre en un bucle intentando corregir errores que no son suyos.

# Deshabilitar un hook individual
hooks:
  post_edit:
    - name: broken-lint
      command: "..."
      enabled: false     # Desactivado

Auto-evaluación

Cuándo usar cada modo

ModoCoste extraCuándo usarlo
off0Tareas triviales, exploración, desarrollo rápido
basic~500 tokensQuality gate en CI, verificación post-implementación
full2-5x del coste baseTareas críticas que deben estar correctas
# CI — verificar que la tarea se completó
architect run "..." --self-eval basic

# Tarea crítica — re-ejecutar si falla la evaluación
architect run "..." --self-eval full

# Desarrollo rápido — sin evaluación extra
architect run "..." --self-eval off

Cuidado con full mode

El modo full puede re-ejecutar el agente hasta max_retries veces (default: 2). Esto significa que el coste puede multiplicarse por 3-5x:

Ejecución base:    1000 tokens    $0.02
Evaluación 1:       500 tokens    $0.01  → "incompleto"
Re-ejecución 1:     800 tokens    $0.015
Evaluación 2:       500 tokens    $0.01  → "completado"
─────────────────────────────────────────
Total:             2800 tokens    $0.055 (2.75x del coste base)

Usa --budget junto con --self-eval full para limitar el gasto:

architect run "..." --self-eval full --budget 1.00

Umbral de confianza

El evaluador retorna una confianza entre 0 y 1. Si es menor que confidence_threshold (default: 0.8), se considera incompleto.

evaluation:
  mode: full
  max_retries: 2
  confidence_threshold: 0.8   # 80% mínimo para aceptar

Baja el umbral si tus tareas son inherentemente ambiguas (documentación, refactorizaciones grandes):

evaluation:
  confidence_threshold: 0.6   # Más permisivo

Modos de confirmación

Cuándo usar cada modo

ModoUso idealRiesgo
confirm-sensitiveDesarrollo diarioBajo: solo confirmas escrituras
confirm-allOperaciones en producciónNulo: confirmas todo
yoloCI/CD, automatización, tareas de confianzaMedio: el agente actúa sin preguntar

confirm-sensitive (default del build agent)

Es el balance recomendado para desarrollo diario:

  • Lecturas y búsquedas se ejecutan automáticamente.
  • Escrituras de archivos piden confirmación.
  • Comandos safe/dev se ejecutan automáticamente.
  • Comandos desconocidos piden confirmación.

yolo — imprescindible en CI

En entornos sin terminal (CI/CD, contenedores, cron), confirm-sensitive y confirm-all bloquean la ejecución porque no hay terminal para responder. Siempre usa --mode yolo:

# CI headless
architect run "..." --mode yolo --budget 2.00

Combinación segura para yolo

Si usas yolo pero quieres limitar el riesgo:

workspace:
  allow_delete: false          # Prohibir borrado de archivos

commands:
  allowed_only: true           # Solo comandos safe + dev
  blocked_patterns:
    - "git push"               # Prohibir push desde el agente
    - "docker rm"              # Prohibir borrado de contenedores

costs:
  budget_usd: 2.00             # Límite de gasto

Configuración del workspace

Prevención de path traversal

Architect confina todas las operaciones de archivos al workspace root. El agente no puede leer ni escribir fuera de este directorio, ni con paths relativos (../../etc/passwd) ni con symlinks.

# El workspace es el directorio actual por defecto
architect run "..." -w /home/user/mi-proyecto

Excluir directorios del indexador

Si tu proyecto tiene directorios pesados que no necesitan indexarse:

indexer:
  exclude_dirs:
    - vendor
    - .terraform
    - coverage
    - data
  exclude_patterns:
    - "*.generated.go"
    - "*.pb.go"

Esto acelera el startup y reduce el tamaño del system prompt.

Proyectos grandes

Para repos con más de 300 archivos, el indexador genera un árbol compacto agrupado por directorio. Si el indexador tarda mucho, desactiva el cache en disco durante desarrollo:

indexer:
  use_cache: true   # Cache en disco, TTL 5 minutos

Uso en CI/CD

Checklist para CI

  1. Usar --mode yolo (sin terminal interactivo).
  2. Usar --quiet --json (salida parseable).
  3. Establecer --budget (control de costes).
  4. Verificar exit code (0=ok, 1=fallo, 2=parcial).
  5. API key como secret del CI, nunca en código.
architect run "..." \
  --mode yolo \
  --quiet --json \
  --budget 1.00 \
  > result.json

EXIT_CODE=$?
STATUS=$(jq -r '.status' result.json)

if [ "$EXIT_CODE" -ne 0 ] || [ "$STATUS" != "success" ]; then
  echo "Architect falló: status=${STATUS}, exit=${EXIT_CODE}"
  jq -r '.output // empty' result.json
  exit 1
fi

Config recomendada para CI

llm:
  model: gpt-4o-mini
  stream: false
  prompt_caching: true

commands:
  enabled: true
  allowed_only: true

evaluation:
  mode: basic

costs:
  enabled: true
  budget_usd: 1.00

Errores comunes y cómo evitarlos

1. El agente se queda colgado esperando confirmación

Causa: Modo confirm-sensitive o confirm-all en un entorno sin terminal.

Solución: Usar --mode yolo.

2. edit_file falla con “old_str aparece N veces”

Causa: El texto a reemplazar no es único en el archivo.

Solución: El agente normalmente reintenta con más contexto. Si persiste, el prompt puede ayudar indicando la función o sección exacta donde hacer el cambio.

3. Coste inesperadamente alto

Causa: Tarea compleja + --self-eval full + muchas iteraciones de hooks.

Solución:

  • Usar --budget siempre.
  • Usar --self-eval basic en vez de full.
  • Elegir modelo más barato para tareas simples.
  • Activar prompt_caching: true.

4. El agente no encuentra archivos que existen

Causa: El archivo está en un directorio excluido por el indexador (node_modules, .venv, etc.).

Solución: Ajustar indexer.exclude_dirs en la config o indicar el path exacto en el prompt.

5. run_command falla con “comando bloqueado”

Causa: El comando coincide con un patrón de la blocklist.

Solución: Los comandos de la blocklist están bloqueados por seguridad y no se pueden desbloquear. Si el comando es legítimo pero similar (por ejemplo, rm -rf ./build/ se confunde con rm -rf /), el agente normalmente reintenta con una alternativa segura.

6. Timeout del agente

Causa: La tarea es demasiado grande para el timeout configurado.

Solución: Aumentar --timeout o dividir la tarea en subtareas.

architect run "..." --timeout 600   # 10 minutos

7. “Budget exceeded” con status partial

Causa: El coste acumulado superó el budget antes de completar la tarea.

Solución: El agente genera un resumen de lo que hizo antes de parar. Puedes continuar desde donde lo dejó:

# Primera ejecución (se queda en partial)
architect run "refactoriza todo el módulo auth" --budget 1.00 --json > result1.json

# Continuar si quedó parcial
STATUS=$(jq -r '.status' result1.json)
if [ "$STATUS" = "partial" ]; then
  OUTPUT=$(jq -r '.output' result1.json)
  architect run "Continúa esta tarea. Progreso anterior: ${OUTPUT}" \
    --budget 1.00
fi

8. El indexador tarda mucho en repos grandes

Causa: Repo con miles de archivos o archivos muy grandes.

Solución:

indexer:
  max_file_size: 500000       # 500KB en vez de 1MB
  exclude_dirs:
    - data
    - vendor
    - assets
  use_cache: true              # Cache 5 min en disco

Resumen rápido

PrácticaRecomendación
PromptsEspecíficos, un objetivo por ejecución
Agentereview/plan para análisis, build para cambios
EdiciónPreferir edit_file sobre write_file
ComandosHooks rápidos, tests solo con run_command
ContextoBuscar antes de leer, dividir tareas grandes
Costesprompt_caching: true, --budget, modelo adecuado
Evaluaciónbasic para CI, full solo para tareas críticas
Modoconfirm-sensitive en local, yolo en CI
Seguridadallowed_only: true y allow_delete: false en CI