Trackio documentation
Ejecución de experimentos de ML con agentes
Ejecución de experimentos de ML con agentes
Trackio está diseñado desde cero para soportar la experimentación autónoma de ML impulsada por agentes de LLM. Esta guía explica cómo estructurar el código de entrenamiento, configurar alertas y conectar el bucle de retroalimentación para que un agente pueda lanzar experimentos, monitorearlos, reaccionar ante problemas e iterar sobre hiperparámetros, todo ello sin intervención humana.
¿Por qué Trackio para agentes?
La mayoría de los rastreadores de experimentos asumen que una persona está observando un panel de control. Trackio ofrece a los agentes acceso programático de primer nivel a través de múltiples canales:
- CLI con salida en JSON — cada comando de
trackioadmite--json, lo que facilita su análisis en cualquier lenguaje - API de Python —
trackio.Api()proporciona acceso directo a ejecuciones, métricas y alertas - API HTTP / MCP — el panel de Trackio expone puntos finales de la API de Gradio y puede ejecutarse como un servidor MCP para que los LLM llamen a herramientas directamente
- Alertas con webhooks — los agentes pueden insertar llamadas a
trackio.alert()como si fueran sentencias print y consultarlas más tarde - filtrado con
since— sondeo eficiente de nuevas alertas sin volver a leer todo el historial
El bucle de retroalimentación del agente
Un bucle de experimentación autónoma típico se ve así:
┌─────────────────────────────────────┐
│ 1. Agent writes training script │
│ with trackio.init(), log(), │
│ and alert() calls │
├─────────────────────────────────────┤
│ 2. Agent launches the script │
├─────────────────────────────────────┤
│ 3. Agent polls for alerts and │
│ metrics while training runs │
├─────────────────────────────────────┤
│ 4. Agent reads results, decides │
│ next hyperparameters │
├─────────────────────────────────────┤
│ 5. Agent writes a new script │
│ and repeats from step 1 │
└─────────────────────────────────────┘El resto de esta guía explica cada paso con código concreto.
Paso 1: Estructurar el código de entrenamiento para agentes
La clave es que un agente puede insertar llamadas a trackio.alert() de la misma manera en que insertaría declaraciones print() para depurar. Las alertas son más estructuradas que las declaraciones print: tienen un título, una descripción opcional, un nivel de severidad y se persisten y consultan automáticamente.
Aquí hay un script de entrenamiento escrito de la manera en que lo escribiría un agente, con alertas en cada punto de decisión:
import trackio
import torch
trackio.init(
project="cifar10-hparam-search",
name="run-lr0.001-bs64",
config={
"learning_rate": 0.001,
"batch_size": 64,
"optimizer": "adamw",
"epochs": 50,
"weight_decay": 1e-4,
},
)
model = build_model()
optimizer = torch.optim.AdamW(
model.parameters(), lr=0.001, weight_decay=1e-4
)
best_val_loss = float("inf")
patience_counter = 0
patience_limit = 5
for epoch in range(50):
train_loss = train_one_epoch(model, train_loader, optimizer)
val_loss, val_acc = evaluate(model, val_loader)
trackio.log({
"train_loss": train_loss,
"val_loss": val_loss,
"val_accuracy": val_acc,
"learning_rate": optimizer.param_groups[0]["lr"],
})
# Alert on loss divergence
if train_loss > 10.0:
trackio.alert(
title="Training diverged",
text=f"train_loss={train_loss:.4f} at epoch {epoch}. "
"Learning rate is likely too high.",
level=trackio.AlertLevel.ERROR,
)
break
# Alert when validation stops improving
if val_loss < best_val_loss:
best_val_loss = val_loss
patience_counter = 0
torch.save(model.state_dict(), "best_model.pt")
else:
patience_counter += 1
if patience_counter >= patience_limit:
trackio.alert(
title="Early stopping triggered",
text=f"No improvement for {patience_limit} epochs. "
f"Best val_loss={best_val_loss:.4f} at epoch "
f"{epoch - patience_limit}.",
level=trackio.AlertLevel.WARN,
)
break
# Alert on overfitting
if epoch > 10 and (train_loss < 0.1 and val_loss > 1.5):
trackio.alert(
title="Overfitting detected",
text=f"train_loss={train_loss:.4f} vs val_loss={val_loss:.4f}. "
"Consider adding regularization or reducing model capacity.",
level=trackio.AlertLevel.WARN,
)
# Alert on good results
if val_acc > 0.93:
trackio.alert(
title="High accuracy reached",
text=f"val_accuracy={val_acc:.4f} at epoch {epoch}.",
level=trackio.AlertLevel.INFO,
)
trackio.alert(
title="Training complete",
text=f"Final val_loss={val_loss:.4f}, val_accuracy={val_acc:.4f}. "
f"Best val_loss={best_val_loss:.4f}.",
level=trackio.AlertLevel.INFO,
)
trackio.finish()Las alertas aquí no son solo para humanos: son señales estructuradas que el agente leerá más adelante para decidir qué hacer a continuación.
Directrices para alertas aptas para agentes
- Use
ERRORpara las condiciones que deben detener la ejecución (divergencia, pérdida NaN, memoria insuficiente). - Use
WARNpara condiciones que sugieren que los hiperparámetros deberían cambiar (sobreajuste, detención temprana, convergencia lenta). - Usa
INFOpara hitos (entrenamiento completado, alta precisión alcanzada, punto de control guardado). - Incluya valores numéricos en
textpara que el agente pueda analizarlos y razonar sobre ellos. - Incluya sugerencias accionables en
text(p. ej., “Learning rate is likely too high”) para ayudar al agente a decidir qué cambiar.
Paso 2: Lanzamiento del script
El agente puede lanzar el script en un subproceso o un proceso en segundo plano. En la mayoría de los marcos de agentes, esto es tan simple como ejecutar un comando de shell:
python train.py
Si el agente utiliza un LLM conectado a MCP, también puede ejecutar scripts a través de una herramienta de shell.
Paso 3: Monitoreo durante el entrenamiento
Mientras se ejecuta el entrenamiento, el agente consulta las alertas y métricas. La bandera --since hace que esto sea eficiente: solo se devuelven las alertas nuevas desde la última verificación.
Consultas mediante CLI
# First poll — get all alerts
trackio get alerts --project "cifar10-hparam-search" --run "run-lr0.001-bs64" --json
# Subsequent polls — only new alerts
trackio get alerts --project "cifar10-hparam-search" --since "2025-06-15T14:30:00" --jsonConsultas periódicas mediante la API de Python
import trackio
from datetime import datetime, timezone
api = trackio.Api()
last_check = None
while training_is_running():
alerts = api.alerts(
"cifar10-hparam-search",
run="run-lr0.001-bs64",
since=last_check,
)
if alerts:
last_check = alerts[0]["timestamp"] # alerts are sorted newest-first
for a in alerts:
print(f"[{a['level'].upper()}] {a['title']}: {a['text']}")
if a["level"] == "error":
# Stop the run and re-plan
handle_error(a)
time.sleep(30)Encuestas mediante MCP
Si el panel de Trackio se está ejecutando como un servidor MCP, el agente puede llamar a la herramienta get_alerts directamente a través del protocolo MCP. Consulte Trackio como API y servidor MCP para obtener instrucciones de configuración.
Paso 4: Lectura de resultados y decisión de los próximos pasos
Después de que una ejecución termina, el agente lee los resultados completos:
# Get run summary (metrics, config, step count)
trackio get run --project "cifar10-hparam-search" --run "run-lr0.001-bs64" --json
# Get the loss curve
trackio get metric --project "cifar10-hparam-search" --run "run-lr0.001-bs64" --metric "val_loss" --json
# Get all alerts (the most useful signal for decision-making)
trackio get alerts --project "cifar10-hparam-search" --run "run-lr0.001-bs64" --jsonLas alertas proporcionan un resumen conciso de lo que ocurrió durante el entrenamiento. En lugar de analizar miles de valores de métricas, el agente puede leer unas pocas alertas para comprender:
- ¿La ejecución divergió? → Reduce la tasa de aprendizaje
- ¿Se sobreajustó? → Añade regularización o reduce la capacidad
- ¿Se detuvo antes de tiempo? → Los hiperparámetros están en el rango adecuado, pero es posible que necesiten ajustes
- ¿Alcanzó una alta precisión? → Esta configuración funciona bien
Paso 5: Iteración sobre hiperparámetros
El agente utiliza las alertas de la ejecución anterior para elegir nuevos hiperparámetros. A continuación se muestra un ejemplo concreto de la lógica de decisión que podría seguir un agente:
import json
import subprocess
import trackio
api = trackio.Api()
# Read alerts from the last run
alerts = api.alerts("cifar10-hparam-search", run="run-lr0.001-bs64")
# Read the config from the last run
runs = api.runs("cifar10-hparam-search")
last_run = [r for r in runs if r.name == "run-lr0.001-bs64"][0]
config = last_run.config
# Decision logic based on alerts
new_config = dict(config)
for alert in alerts:
if "diverged" in alert["title"].lower():
new_config["learning_rate"] = config["learning_rate"] * 0.1
elif "overfitting" in alert["title"].lower():
new_config["weight_decay"] = config.get("weight_decay", 1e-4) * 10
elif "early stopping" in alert["title"].lower():
new_config["learning_rate"] = config["learning_rate"] * 0.5
elif "high accuracy" in alert["title"].lower():
# This config is good — try fine-tuning
new_config["learning_rate"] = config["learning_rate"] * 0.5
new_config["epochs"] = config["epochs"] + 20A continuación, el agente genera un nuevo script de entrenamiento con la configuración actualizada y lo inicia, repitiendo el bucle.
Comparación de ejecuciones
Tras varias iteraciones, el agente puede comparar todas las ejecuciones del proyecto:
# List all runs
trackio list runs --project "cifar10-hparam-search" --json
# Get a summary of each run
trackio get run --project "cifar10-hparam-search" --run "run-lr0.001-bs64" --json
trackio get run --project "cifar10-hparam-search" --run "run-lr0.0001-bs64" --jsonO en Python:
api = trackio.Api()
runs = api.runs("cifar10-hparam-search")
for run in runs:
alerts = run.alerts()
errors = [a for a in alerts if a["level"] == "error"]
warns = [a for a in alerts if a["level"] == "warn"]
infos = [a for a in alerts if a["level"] == "info"]
print(f"{run.name}: {len(errors)} errors, {len(warns)} warnings, {len(infos)} info")Enviando alertas al agente mediante webhooks
Si su marco de trabajo de agentes tiene un punto final HTTP o puede recibir mensajes de Slack/Discord, puede usar webhooks para enviar alertas al agente en tiempo real en lugar de hacer sondeos:
trackio.init(
project="cifar10-hparam-search",
webhook_url="https://hooks.slack.com/services/T.../B.../xxx",
)De esta manera, las alertas se envían a un canal de Slack que el agente monitorea, cerrando el ciclo sin necesidad de sondeo. Consulte la Guía de alertas para obtener instrucciones detalladas de configuración para Slack y Discord.
Ejemplo completo: Búsqueda autónoma de hiperparámetros
Aquí hay un ejemplo completo y autónomo que une todo. Este script ejecuta una búsqueda de cuadrícula de hiperparámetros simple con decisiones automatizadas basadas en alertas:
import trackio
import random
import time
def run_experiment(config):
"""Simulate a training run. Replace with real training code."""
run = trackio.init(
project="auto-hparam-search",
config=config,
)
lr = config["learning_rate"]
best_val_loss = float("inf")
patience = 0
for epoch in range(config["epochs"]):
# Simulated metrics — replace with real training
noise = random.gauss(0, lr * 10)
train_loss = max(0.01, 1.0 / (epoch + 1) + noise)
val_loss = train_loss + random.uniform(0, 0.3)
val_acc = max(0, min(1, 1.0 - val_loss + random.uniform(-0.05, 0.05)))
trackio.log({
"train_loss": train_loss,
"val_loss": val_loss,
"val_accuracy": val_acc,
})
if train_loss > 5.0:
trackio.alert(
title="Training diverged",
text=f"train_loss={train_loss:.4f}, lr={lr}",
level=trackio.AlertLevel.ERROR,
)
break
if val_loss < best_val_loss:
best_val_loss = val_loss
patience = 0
else:
patience += 1
if patience >= 5:
trackio.alert(
title="Early stopping",
text=f"Best val_loss={best_val_loss:.4f}",
level=trackio.AlertLevel.WARN,
)
break
time.sleep(0.05)
trackio.alert(
title="Run complete",
text=f"Final val_loss={val_loss:.4f}, val_acc={val_acc:.4f}, "
f"best_val_loss={best_val_loss:.4f}",
level=trackio.AlertLevel.INFO,
)
trackio.finish()
return run.name
def analyze_and_decide(api, project, run_name, config):
"""Read alerts from a run and suggest new hyperparameters."""
alerts = api.alerts(project, run=run_name)
new_config = dict(config)
for alert in alerts:
title = alert["title"].lower()
if "diverged" in title:
new_config["learning_rate"] *= 0.1
elif "early stopping" in title:
new_config["learning_rate"] *= 0.5
elif "run complete" in title and "val_acc" in (alert.get("text") or ""):
# Slight refinement
new_config["learning_rate"] *= 0.8
new_config["epochs"] += 10
return new_config
api = trackio.Api()
project = "auto-hparam-search"
config = {
"learning_rate": 0.01,
"batch_size": 64,
"epochs": 30,
}
for iteration in range(5):
print(f"\n--- Iteration {iteration + 1} ---")
print(f"Config: {config}")
run_name = run_experiment(config)
config = analyze_and_decide(api, project, run_name, config)Este ejemplo es autónomo y utiliza métricas simuladas. Reemplaza el cuerpo de la función run_experiment con tu código de entrenamiento real y el patrón se mantiene igual.
Uso de alertas con Transformers y TRL
Al usar report_to="trackio" con el Trainer de Hugging Face, el TrackioCallback integrado gestiona trackio.init(), trackio.log() y trackio.finish() automáticamente. Dado que trackio.init() se llama antes de que comience el entrenamiento, la ejecución actual se establece y trackio.alert() funciona desde cualquier otro callback en el mismo proceso.
Para agregar alertas, escriba un pequeño TrainerCallback y páselo al Trainer mediante callbacks=:
Transformers
import trackio
from transformers import Trainer, TrainerCallback, TrainingArguments
class AlertCallback(TrainerCallback):
def on_log(self, args, state, control, logs=None, **kwargs):
if "trackio" not in args.report_to or logs is None:
return
loss = logs.get("loss")
if loss is not None and loss > 5.0:
trackio.alert(
title="Training loss spike",
text=f"loss={loss:.4f} at step {state.global_step}. "
"Consider lowering the learning rate.",
level=trackio.AlertLevel.ERROR,
)
def on_evaluate(self, args, state, control, metrics=None, **kwargs):
if "trackio" not in args.report_to or metrics is None:
return
eval_loss = metrics.get("eval_loss")
if eval_loss is not None and eval_loss > 2.0:
trackio.alert(
title="High eval loss",
text=f"eval_loss={eval_loss:.4f} at step {state.global_step}.",
level=trackio.AlertLevel.WARN,
)
trainer = Trainer(
model=model,
args=TrainingArguments(
report_to="trackio",
project="my-project",
output_dir="./output",
num_train_epochs=3,
eval_strategy="steps",
eval_steps=100,
),
train_dataset=train_dataset,
eval_dataset=eval_dataset,
callbacks=[AlertCallback()],
)
trainer.train()Un agente que genere este código solo necesita definir la clase AlertCallback con las condiciones adecuadas y luego añadirla a la lista callbacks. El patrón es el mismo, independientemente del modelo o del conjunto de datos.
TRL
El mismo enfoque funciona con los entrenadores de TRL como GRPOTrainer o SFTTrainer. A continuación, se muestra un ejemplo de aprendizaje por refuerzo con alertas sobre el colapso de la recompensa y la divergencia de KL:
import trackio
from transformers import TrainerCallback
class RLAlertCallback(TrainerCallback):
def on_log(self, args, state, control, logs=None, **kwargs):
if "trackio" not in args.report_to or logs is None:
return
reward = logs.get("train/reward")
if reward is not None and reward < -1.0:
trackio.alert(
title="Reward collapse",
text=f"reward={reward:.4f} at step {state.global_step}. "
"Consider lowering the learning rate or checking the "
"reward model.",
level=trackio.AlertLevel.ERROR,
)
kl = logs.get("train/kl")
if kl is not None and kl > 10.0:
trackio.alert(
title="KL divergence too high",
text=f"kl={kl:.4f} at step {state.global_step}. "
"The policy is drifting too far from the reference model.",
level=trackio.AlertLevel.WARN,
)
completion_length = logs.get("train/completion_length")
if completion_length is not None and completion_length < 5.0:
trackio.alert(
title="Completions too short",
text=f"Mean completion length={completion_length:.1f} tokens. "
"The model may be collapsing to short outputs.",
level=trackio.AlertLevel.WARN,
)Luego, pásalo a cualquier entrenador de TRL:
from trl import GRPOTrainer, GRPOConfig
trainer = GRPOTrainer(
model=model,
config=GRPOConfig(
report_to="trackio",
project="rl-experiment",
output_dir="./output",
),
train_dataset=dataset,
callbacks=[RLAlertCallback()],
)
trainer.train()Consejos para agentes que escriben callbacks de alertas
- Mantenga las condiciones simples. Cada bloque
ifdebe comprobar una métrica contra un umbral. Esto facilita que un agente añada, elimine o ajuste condiciones entre ejecuciones. - Incluye el valor de la métrica y el paso en
text. Esto proporciona al agente números concretos sobre los que razonar al decidir los próximos hiperparámetros. - Incluye sugerencias accionables. Textos como «Considera reducir la tasa de aprendizaje» ayudan al agente a decidir qué cambiar a continuación.
- Use
on_evaluatefor eval metrics. Los métricas de evaluación solo están disponibles enon_evaluate, no enon_log. Las métricas de entrenamiento comolossaparecen enon_log.
Resumen de las mejores prácticas
Usa las alertas como señales estructuradas, no solo como notificaciones. Incluye valores numéricos y sugerencias accionables en
textpara que el agente pueda analizarlos y actuar en consecuencia.Utilice los niveles de gravedad de forma coherente.
ERROR= deténgase y cambie de enfoque.WARN= ajuste los parámetros.INFO= hito alcanzado.Realiza consultas con
sincepara mejorar la eficiencia. Guarda la marca de tiempo de la última alerta que procesaste y pásala comosinceen la siguiente consulta para evitar volver a leer alertas antiguas.Mantener todas las ejecuciones en el mismo proyecto. Esto permite que el agente compare las ejecuciones lado a lado y vea el historial completo de lo que se probó.
Registra la configuración en cada ejecución. Pasa siempre
config=atrackio.init()para que el agente pueda leer qué hiperparámetros produjeron qué resultados.Usa la CLI con
--jsonpara scripts de agentes. La salida JSON es fiable para analizar y no se romperá si cambia el formato legible por humanos.Considere MCP para una integración estrecha. Si su marco de agentes admite MCP, ejecutar
trackio show --mcp-serverpermite que el agente llame directamente a las herramientas de Trackio sin generar subprocesos.