\
CONTEXT/academy
Lección 04 · ≈ 18 min

Producción

Hosting, seguimiento de coste y despliegue seguro de tu agente.

Producción

Tu agente funciona en local. Llevarlo a producción añade tres preocupaciones: dónde corre, cuánto cuesta y cómo se despliega de forma segura. Esta lección las recorre cerrando el bucle con el mismo agent.py de la lección 2 — y cierra el plan de estudios.

Dónde corre: empaquetar el agente en Docker

El Agent SDK corre en tu proceso, en tu infraestructura. Eso te da control total y se despliega como cualquier app: en un contenedor Docker, en la nube o dentro de un job de CI/CD (justo lo que viste en el curso de CI: el modo headless es el SDK por línea de comandos).

Empaqueta el agente que ya tienes. En la misma carpeta que tu agent.py, crea un Dockerfile:

FROM python:3.12-slim

WORKDIR /app

# El SDK de Python; trae empaquetado el binario nativo de Claude Code
RUN pip install --no-cache-dir claude-agent-sdk

COPY agent.py utils.py ./

# Sin interfaz: arranca, hace su trabajo y termina (headless)
CMD ["python", "agent.py"]

Python 3.10+ es el requisito del SDK; slim mantiene la imagen pequeña. Si tu agente usa Bash para llamar a git, npm, etc., añádelos con apt-get install.

Construye la imagen y lánzala pasando la clave como variable de entorno — nunca horneada en la imagen:

docker build -t bug-fixer .

docker run --rm -e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" bug-fixer

Eso es: el mismo agente de la lección 2, ahora en un artefacto reproducible que corre igual en tu máquina, en un servidor o en CI.

La alternativa, si no quieres operar tú la infraestructura: Managed Agents, una API REST hosteada donde Anthropic corre el agente y un sandbox por sesión. Un camino habitual es prototipar con el SDK en local y pasar a Managed Agents para producción asíncrona o de larga duración.

Cuánto cuesta: seguimiento

Un agente autónomo en producción puede gastar sin que mires. El SDK te da el dato: el ResultMessage final (y la salida --output-format json del headless) incluye total_cost_usd, el coste estimado de esa ejecución. Añade esta rama al async for de tu agent.py para que lo loguee en cada run:

elif isinstance(message, ResultMessage):
    # total_cost_usd puede venir como None; usa "or 0"
    print(f"Coste: ${message.total_cost_usd or 0}")

Esa línea Coste: $... es lo que vas a buscar en el log del contenedor para confirmar que el despliegue funciona (ver Pruébalo).

El total_cost_usd es una estimación local del cliente, no la factura oficial; sirve para vigilar el gasto en desarrollo y poner topes, no para facturar a terceros. Para datos de facturación reales, la API de Usage & Cost o la consola.

Con eso puedes alertar, poner topes, o elegir un modelo más barato (Haiku) para los agentes mecánicos — la misma lógica de coste de toda la academia, ahora medida por agente.

Cómo se despliega: seguro

Tu bug-fixer autónomo con tools es justo el escenario de riesgo del curso de seguridad, llevado a producción. Aterriza cada principio en este agente:

El secreto, fuera del código. Tu agent.py ya confía en que ANTHROPIC_API_KEY esté en el entorno (lo inyectaste con -e en el docker run). Si en local cargas un .env, hazlo explícito al arrancar — pero la clave nunca se hornea en la imagen ni se commitea:

import os
from dotenv import load_dotenv   # pip install python-dotenv

load_dotenv()   # lee .env en local; en CI/Docker la var ya viene del entorno

if "ANTHROPIC_API_KEY" not in os.environ:
    raise SystemExit("Falta ANTHROPIC_API_KEY en el entorno")

En producción la clave viene del secret store de tu plataforma (GitHub Secrets, AWS Secrets Manager, etc.), no de un fichero.

Mínimo privilegio, con precisión. Tu agente arranca con allowed_tools=["Read", "Edit", "Glob"]. Ojo al matiz del curso de permisos: allowed_tools pre-aprueba tools (evita el prompt de permiso), no restringe qué tools existen. Para bloquear de verdad una tool peligrosa en headless, usa disallowed_tools:

options=ClaudeAgentOptions(
    allowed_tools=["Read", "Edit", "Glob"],
    disallowed_tools=["Bash"],          # bloqueada de verdad, no solo "sin pre-aprobar"
    permission_mode="dontAsk",          # headless: solo corre lo pre-aprobado, sin prompts
)
  • Permission mode adecuado: dontAsk para un agente headless bloqueado (corre solo lo pre-aprobado, sin parar a preguntar — ideal en CI/contenedor); bypassPermissions solo dentro de un entorno aislado.
  • Aislamiento: el contenedor ya separa el agente de tu host; endurécelo con flags como --cap-drop ALL, --read-only y montar el código en solo lectura (-v $PWD:/workspace:ro) cuando solo deba analizar.
  • Inyección de prompt: tu agente lee utils.py, pero si en el futuro lee contenido externo (issues, webs, MCP), trátalo como hostil; combina permisos y sandbox como defensa en profundidad.

Lo mismo, en CI: un job headless

El paso natural desde Docker: que el agente corra en cada push dentro de GitHub Actions. Es el modo headless del curso de CI, ahora ejecutando tu propio agente. Un workflow mínimo en .github/workflows/agent.yml:

name: bug-fixer
on: [push]
jobs:
  run-agent:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with: { python-version: "3.12" }
      - run: pip install claude-agent-sdk
      - run: python agent.py
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}

La clave llega como GitHub Secret (Settings → Secrets → Actions), inyectada en env: — el mismo patrón "secreto fuera del código" que en Docker.

¿Y la Action oficial anthropics/claude-code-action@v1? Esa orquesta el Claude Code interactivo (respondes con @claude en un PR), no tu agent.py. Para correr tu agente del SDK, lo que quieres es ejecutarlo en headless como arriba: python agent.py.

Pruébalo

Cierra el bucle de verdad: del artefacto al deploy, en tres comandos.

docker build -t bug-fixer .
docker run --rm -e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" bug-fixer

En el log del contenedor verás el razonamiento del agente, las tools que llama y, al final, la línea que confirma que el ciclo completó:

Tool: Read
Tool: Edit
Done: success
Coste: $0.0143

Si ves esa línea Coste: $..., tu agente se ha desplegado y ejecutado dentro del contenedor con el coste medido. Ese contenedor que corre el agente es el cierre del curso.

Si falla

  • Coste: $0 o None, o un error de autenticación → la ANTHROPIC_API_KEY no llegó al proceso, o la clave no tiene créditos. Comprueba que la variable existe en tu shell (echo $ANTHROPIC_API_KEY) antes del docker run, y que pasaste -e ANTHROPIC_API_KEY=...: sin ese flag, la var de tu host no entra al contenedor. Revisa el saldo en la consola.
  • El agente arranca pero no toca utils.py → el COPY no incluyó el fichero, o el contenedor corre en un workdir sin él. Confirma que utils.py está junto al Dockerfile y aparece en la línea COPY.

Cierre del curso

Has cruzado la última frontera: de usar Claude Code a construir tu propio agente sobre su motor. Sabes arrancar el agent loop con query(), extenderlo con tools propias y MCP, empaquetarlo en Docker o un job de CI, y los criterios para llevarlo a producción con coste y seguridad bajo control.

Has terminado el plan de estudios

Si has llegado hasta aquí, has recorrido los seis niveles completos:

  • Fundamentos → qué es Claude Code y cómo conducir una sesión.
  • Contexto y configuraciónCLAUDE.md, memoria, permisos, seguridad.
  • Extender → slash commands, skills, subagentes, hooks.
  • Integración → MCP y plugins.
  • Escalar y producción → CI y orquestación de agentes.
  • Capstone → construir tu propio agente con el SDK.

De abrir claude por primera vez a programar un agente a medida. El motor es el mismo en todo el camino; lo que ha cambiado es cuánto sabes pedirle — y cuánto puedes construir con él.

Fuente oficial: Hosting · Cost tracking · Secure deployment

¿Quieres llevar la cuenta de las lecciones que has terminado?

Entrar para guardar progreso