Saltar a contenido

Templates de agente

Desde 0.8.0 (Novedades de 0.8.0).

AgentTemplate es una receta fija sobre el DSL de Template que instala, en una sola imagen, todo lo que Agente en el sandbox necesita: el binario de OpenCode, ripgrep (sus herramientas de búsqueda lo necesitan y, si no lo encuentra, intentaría descargarlo — bajo egress cerrado eso falla) y, opcionalmente, un venv con deepagents. La receta es la que validó el spike en AWS real (docs/research/2026-10-agent-spike.md).

Todos los campos tienen valor por defecto: AgentTemplate().build(bucket=...) construye rayito-agent sobre rayito-base-caps con OpenCode, deepagents y el prefetch. El ejemplo los escribe para que se vean:

from rayito import AgentTemplate

info = AgentTemplate(
    name="rayito-agent",
    base="rayito-base-caps",
    runtimes=("opencode", "deepagents"),
    prefetch=True,
    kernel_warmup=False,
    memory_mib=2048,
).build(bucket="amzn-s3-demo-bucket", on_build_logs=print)
print(info)
from rayito import AsyncAgentTemplate


async def build() -> None:
    info = await AsyncAgentTemplate(runtimes=("opencode",)).build(bucket="amzn-s3-demo-bucket")
    print(info)
import { AgentTemplate } from "rayito";

const info = await new AgentTemplate({
  name: "rayito-agent",
  base: "rayito-base-caps",
  runtimes: ["opencode", "deepagents"],
  prefetch: true,
  kernelWarmup: false,
  memoryMib: 2048,
}).build({ bucket: "amzn-s3-demo-bucket" });
console.log(info);
rayito agent template build --name rayito-agent --bucket amzn-s3-demo-bucket
Campo (Python / TypeScript) CLI Por defecto Qué es
name --name rayito-agent nombre de la imagen que se crea o actualiza
base --base rayito-base-caps imagen base; la variante con capabilities es la única donde allow_internet_access=False se aplica
base_version / baseVersion — la última versión de la imagen base
runtimes --deepagents / --no-deepagents ("opencode", "deepagents") qué se instala; la CLI siempre instala OpenCode
prefetch --prefetch / --no-prefetch True hornea el demonio de prefetch
kernel_warmup / kernelWarmup --kernel-warmup / --no-kernel-warmup False deja el calentamiento del kernel de run_code como en la imagen base
memory_mib / memoryMib --memory-mb 2048 (mínimo) memoria de la imagen

build() acepta bucket (obligatorio), force, timeout (segundos; TS: timeoutMs), on_build_logs/onBuildLogs, region y session (TS: credentials), como Template.build; la CLI, --bucket, --force y --timeout (1800 s por defecto). Devuelve el BuildInfo del build. Sin construir nada, to_dockerfile()/toDockerfile() enseña la receta y manifest() el manifiesto que hornea.

memory_mib/memoryMib por debajo de 2048 lanza InvalidArgumentException/InvalidArgumentError antes de cualquier llamada: el spike midió 575 MiB de RSS para OpenCode solo, y el guest de 2048 MB ve 8016 MiB (Límites: tamaño ya documenta que el guest ve más memoria que la configurada).

Coste y activación

  • Por defecto: no se construye nada hasta llamar a .build() / usar la CLI (rayito agent template build).
  • Build: 271–320 s medidos en AWS real (2026-10-07, tres builds; necesita salida a Internet para GitHub y PyPI; el sandbox que arranca desde la imagen resultante, no).
  • Almacenamiento de la versión: tres snapshots medidos, código 2,10 GB + memoria 0,86 GB + disco 0,03 GB ≈ 3,0 GB × $0,08/GB-mes, con el mínimo de una semana por versión de imagen ⇒ ≈ $0,056/semana (≈ $0,24/mes) por versión (medido 2026-10-09, Q156; con kernel_warmup=True la memoria vuelve a 0,92 GB). Asume que el almacenamiento es la suma de los tres snapshots. Precios de lista, us-east-1, consultados 2026-10-06: ver Precios.
  • Lanzamiento: lectura del snapshot de memoria (0,86 GB) ≈ $0,0013.
  • IAM: RayitoTemplateBuilder, la misma política que Templates declarativos (pila templates).
  • Cómo apagarla: no construyas el template; borra sus versiones con rayito image prune. Un sandbox normal (rayito-base/rayito-base-caps) no cambia.

Qué instala

Pieza Licencia Pin Verificado por
OpenCode MIT versión + sha256 del asset de la release scripts/check_pins.py contra limits.json/agentRuntimes
ripgrep MIT/Unlicense versión + sha256 idem
deepagents + langchain-aws, langchain-anthropic, langchain-openai y langchain-google-genai MIT requirements-deepagents.txt con --hash, pip install --require-hashes --no-deps --only-binary=:all: pip check en el propio run_cmd; el smoke test del build importa los cuatro paquetes; pip-audit en CI

Todo queda root:root y 0755: el usuario del sandbox (uid 1000) no puede reemplazar los binarios ni el venv (T30). Las variables OPENCODE_DISABLE_AUTOUPDATE, OPENCODE_DISABLE_MODELS_FETCH, OPENCODE_DISABLE_LSP_DOWNLOAD, OPENCODE_DISABLE_DEFAULT_PLUGINS, OPENCODE_PURE y OPENCODE_DISABLE_CLAUDE_CODE apagan todo lo que OpenCode intentaría bajar de Internet al arrancar y evitan que lea un .claude/ del workdir. OPENCODE_EXPERIMENTAL_WEBSOCKETS=0 impide que el proveedor openai abra un WebSocket hacia la Responses API: la pasarela sólo reenvía HTTP. El manifiesto horneado en /opt/agents/rayito-agent.json (rayito.agent-template/1) lista versiones, sha256 y las rutas que el prefetch calienta. sbx.agent no lo lee: AgentSpec.runtime_version no se compara con él.

Prefetch

Con prefetch=True (por defecto), el template añade un start_cmd que hace dos cosas. En el build, antes del snapshot, lee una vez los binarios de OpenCode y ripgrep, y el ready_cmd del template retiene el snapshot hasta que termina: así el snapshot de memoria ya lleva esas páginas y el primer exec tras create() no las lee del disco de código. Los módulos de deepagents no se hornean (inflarían el snapshot para el runtime que no es el de por defecto). Y desde el arranque detecta si la VM viene de restaurar un snapshot (un salto de reloj mayor que AGENT_PREFETCH_RESTORE_JUMP_SECONDS). Entonces espera a que el guest lleve 1 s seguido sin E/S en curso (como mucho 60 s) y precalienta con prioridad baja (nice -n 19) el binario de OpenCode y, con el runtime deepagents instalado, el import de deepagents/langchain_aws. Espera porque la restauración también lee del disco (la rotación del kernel que create() espera): leer a la vez alargaba create(). Después no cede el paso: el primer sbx.agent.run() lee el mismo binario, así que leerlo por delante le adelanta páginas. sbx.agent.prepare() dispara el mismo calentamiento cuando no hay demonio (por ejemplo, sin prefetch, o para forzarlo tras un rato de inactividad). Cuándo conviene cada opción de arranque rápido: Agente en el sandbox.

Medido en AWS real (2026-10-07, n=5)

El demonio no cambia el tamaño del snapshot de memoria (916–925 MB con y sin él). Antes del arreglo (el demonio leía nada más restaurar): tras create(), el primer token de OpenCode llegaba en 4,7 s de mediana con prefetch frente a 19,6 s sin él (−76 %), pero create() tardaba 16,6 s frente a 8,7 s, así que de extremo a extremo (de create() al primer token) la mejora era 28,3 s → 20,5 s (−28 %). Con el demonio que espera a que el guest se calme (Q153, n=5, con un control sin prefetch en la misma tanda): create() 9,2 s frente a 8,8 s, así que ya no lo retrasa; el tramo tras create() 3,8 s frente a 5,2 s; de extremo a extremo 14,7 s frente a 13,3 s, dentro del ruido. El control salió mucho más rápido que en la primera medida, así que hoy la ganancia de A es pequeña; sigue encendido por defecto porque ya no cuesta tiempo de create(). Los primeros lanzamientos de una versión recién publicada son más lentos (create() de 26 a 65 s): no midas justo después del build. Detalle en AWS_API_NOTES.md Q146 y Q150.

Medido en AWS real (2026-10-09, n=6, AWS_API_NOTES.md Q156)

Con el binario horneado en el snapshot y el kernel sin calentar, el snapshot de memoria pesa 858 MB (62 MB menos que antes) y create() vuelve en 6,4 s de mediana frente a 19,1 s de la imagen de antes en la misma tanda. El primer token adelantó su mediana 2,8 s (20,9 s frente a 23,7 s) y, en otra tanda con deepagents también horneado, 3,2 s, pero con mucha dispersión: la ventana lenta tras restaurar cambia mucho de una tanda a otra.

Kernel de run_code sin calentar

La imagen base calienta el kernel de run_code cada vez que arranca, también en la rotación que create() espera: importa numpy, pandas, matplotlib, scipy y scikit-learn para que la primera celda que los use sea rápida. Un sandbox de agente rara vez lo necesita, así que AgentTemplate lo apaga por defecto (kernel_warmup=False): escribe el mismo marcador slim que rayito image zip --variant slim. run_code sigue funcionando igual; sólo la primera celda que importe ese stack paga la importación. Con kernel_warmup=True (--kernel-warmup) el kernel queda como en la imagen base.

Medido en AWS real (2026-10-09, n=6, AWS_API_NOTES.md Q155)

Sin el calentamiento, create() vuelve 4,4 s antes (p50 7,65 s frente a 12,0 s) y el snapshot de memoria pesa 248 MB menos (671 MB frente a 920 MB), así que cada lanzamiento lee menos y la versión cuesta menos de almacenar. Por sí solo no adelanta el primer token (16,3 s frente a 16,4 s): el primer exec de OpenCode paga la ventana lenta tras la restauración que antes pagaba el kernel. Lo que sí lo adelanta es hornear el binario en el snapshot (Prefetch).

--no-deepagents, --no-prefetch, --kernel-warmup

rayito agent template build --bucket amzn-s3-demo-bucket --no-deepagents   # sólo OpenCode: salta el venv (~409 MB menos)
rayito agent template build --bucket amzn-s3-demo-bucket --no-prefetch      # sin el start_cmd: el primer exec paga siempre el coste de disco
rayito agent template build --bucket amzn-s3-demo-bucket --kernel-warmup    # kernel de run_code calentado, como en la imagen base

Ver también