Deploy de Agentes — Módulo 4: estructura del proyecto, entornos y secretos
Cuarto módulo del Curso de Deploy de Agentes y cierre del bloque básico: cómo se estructura el repo de un agente, los principios 12-factor con la config en el entorno, la diferencia entre dev, staging y prod, y cómo manejar secretos con .env y secret managers sin que una API key termine nunca en Git.
☰ Índice del contenido
Con el Módulo 3 ya sabes trabajar en equipo sobre Git. Pero, ¿sobre qué? Un agente en producción no es un solo agent.py: es un repositorio con una estructura que el equipo — y las herramientas de CI y deploy — esperan encontrar. Y dentro de ese repo hay un tema que, mal manejado, es una de las causas más comunes de incidentes de seguridad: los secretos. Este módulo cierra el bloque básico ordenando la casa antes de contenerizar.
La tesis del módulo
El código dice qué hace tu agente; la configuración dice dónde y con qué credenciales. Mantenerlos separados — código en Git, config y secretos en el entorno — es lo que te deja pasar de dev a producción sin cambiar una sola línea.
La estructura de un repo de agente
Un agente listo para producción tiene una estructura reconocible. Cada carpeta tiene un dueño y un propósito:
agente/
src/ código de la aplicación
agent.py
tools/
config/ config por entorno
tests/ tests unitarios y evals
infra/ Terraform (IaC)
.github/
workflows/ pipelines de CI/CD
Dockerfile receta del contenedor
requirements.txt dependencias (o pyproject.toml)
.env secretos LOCALES (en .gitignore)
.env.example plantilla SIN valores (sí va a Git)
.gitignore
| Carpeta / archivo | Qué vive ahí |
|---|---|
src/ | El código del agente: lógica, tools, prompts |
src/config/ | Cómo se lee la configuración según el entorno |
tests/ | Tests unitarios (Módulo 6) y evals (Módulo 7) |
infra/ | Terraform, la infraestructura como código (Módulo 10) |
.github/workflows/ | Los pipelines de GitHub Actions (Módulo 8) |
Dockerfile | La receta del contenedor (Módulo 5) |
requirements.txt / pyproject.toml | Las dependencias y sus versiones |
.env | Secretos locales — nunca sube a Git |
.env.example | Plantilla con los nombres de las variables, sin valores |
El .env.example es un truco clave: sube a Git con los nombres de las variables pero sin los valores, para que quien clone el repo sepa qué necesita configurar sin que le filtres tus claves.
Los principios 12-factor
12-factor es una guía clásica de doce principios para construir apps que se despliegan bien en la nube. No necesitas los doce hoy; uno manda sobre el resto para agentes:
Config en el entorno, no en el código.
Es decir: cualquier cosa que cambie entre tu máquina, staging y producción — URLs, API keys, nombres de modelo, límites — no va escrita en el código. Va en variables de entorno que el código lee al arrancar. Así el mismo código, sin tocar una línea, corre distinto según dónde esté desplegado.
Otros principios 12-factor útiles para agentes:
- Dependencias declaradas explícitamente (tu
requirements.txtcon versiones fijas, como vimos en cursos previos). - Logs como flujo de eventos: el agente escribe a la salida estándar y la plataforma se encarga de recogerlos (Módulo 13).
- Paridad entre entornos: dev, staging y prod lo más parecidos posible, para que “en mi máquina funciona” deje de ser una excusa.
Así se lee la config desde el entorno en Python:
import os
# El código NO conoce la clave; la pide al entorno al arrancar.
API_KEY = os.environ["OPENAI_API_KEY"] # obligatoria: falla si falta
MODEL = os.environ.get("MODEL", "gpt-4o-mini") # opcional: con valor por defecto
ENV = os.environ.get("APP_ENV", "dev") # dev | staging | prod
Fíjate: os.environ["OPENAI_API_KEY"] falla ruidosamente si la variable no está — y eso es lo que quieres. Mejor que reviente al arrancar a que corra media hora y muera en la primera llamada al modelo.
Entornos: dev, staging, prod
Un agente serio vive en tres entornos, con config distinta en cada uno:
| Entorno | Para qué | Datos y modelo |
|---|---|---|
| dev | Tu desarrollo local | Datos de juguete, modelo barato, claves de prueba |
| staging | Ensayo idéntico a prod, antes de liberar | Copia de prod, claves de prueba, tráfico interno |
| prod | Los usuarios reales | Datos reales, claves reales, todo monitoreado |
La variable APP_ENV (o como la llames) le dice al código en cuál está corriendo, y a partir de ahí carga la config correspondiente. El código es uno solo; el entorno decide el comportamiento.
Secretos: el tema que no se puede improvisar
Un secreto es cualquier credencial que da acceso a algo: API keys, tokens, contraseñas de base de datos. La regla absoluta:
Un secreto jamás se escribe en el código ni sube a Git.
Dónde vive cada secreto según el entorno:
| Entorno | Dónde viven los secretos | Cómo llegan al código |
|---|---|---|
| Local (dev) | Archivo .env (en .gitignore) | Cargado como variables de entorno |
| CI (GitHub Actions) | GitHub Secrets | Inyectados en el pipeline |
| Producción | Secret manager de la nube | Leídos por la app al arrancar |
Un secret manager es un servicio de la nube diseñado para guardar secretos de forma cifrada, con control de acceso y auditoría. Los que verás:
- GCP Secret Manager (Google Cloud) — lo usaremos en el módulo de deploy.
- AWS Secrets Manager (Amazon).
- GitHub Secrets — para los secretos que necesita tu pipeline de CI/CD.
El flujo completo de un secreto, de tu máquina a producción:
LOCAL CI/CD PRODUCCIÓN
┌───────────┐ ┌───────────────┐ ┌───────────────┐
│ .env │ │ GitHub │ │ Secret │
│ (ignorado)│ │ Secrets │ │ Manager (GCP) │
└─────┬─────┘ └───────┬───────┘ └───────┬───────┘
│ │ │
▼ ▼ ▼
┌────────────────────────────────────────────────────┐
│ Variables de entorno que el código lee al arrancar │
└───────────────────────┬────────────────────────────┘
▼
os.environ["API_KEY"]
Lo elegante del patrón: tu código siempre hace lo mismo — os.environ["API_KEY"] — sin importar de dónde salió el valor. Cambia la fuente (.env, GitHub Secrets, Secret Manager) pero el código nunca cambia.
Ojo: si una API key llega a subir a Git, no basta con borrarla en el siguiente commit: queda en la historia y se considera comprometida para siempre. La única respuesta correcta es rotar la clave (generar una nueva y revocar la vieja) y limpiar el historial. Prevenir con
.gitignorecuesta una línea; el incidente cuesta un día.
Errores comunes
- Hardcodear la API key “solo para probar”. Ese
key = "sk-..."es el que se te olvida borrar y termina en Git. - No tener
.enven.gitignoredesde el primer commit. El orden importa: primero el.gitignore, después el.env. - Config repartida por el código (URLs y modelos escritos en medio de la lógica). Cuando cambias de entorno, tienes que cazarlos uno por uno. Van todos al entorno.
- Usar las mismas claves en dev y prod. Un error en dev no debería tocar datos reales. Claves separadas por entorno, siempre.
- Guardar secretos de producción en GitHub Secrets “y listo”. GitHub Secrets es para lo que necesita el pipeline; los secretos que consume la app en producción viven en el secret manager de la nube.
- No versionar
.env.example. Sin la plantilla, quien clona el repo no sabe qué variables configurar y pierde una tarde adivinando.
La frase para llevarse
“El mismo código en dev y en prod; lo único que cambia es el entorno. El día que lograste eso, tu agente dejó de depender de tu notebook.”
Qué viene
Cerramos el bloque básico: ya tienes Git, convenciones, estructura y secretos bajo control. El Módulo 5 arranca el bloque de contenedores con Docker: cómo empaquetar tu agente en una imagen que corre igual en tu máquina, en CI y en la nube — el fin definitivo del “en mi máquina funciona”.
Material relacionado
Preguntas sobre este curso
Regístrate gratis para hacer preguntas y guardar tu progreso.
✉ Entérate de lo nuevo
Recibe un aviso cuando publique nuevos cursos, workshops o investigaciones. Sin spam.