The "tiny teams" direction is concrete for ML engineers: routine model maintenance — retrain on fresh data, backtest, compare against the champion, write up the result — is agent-automatable, but promotion to production must stay behind a human gate.
Tier: Advanced · Workflow area: Agentic systems
This playbook composes patterns you already have (code-executing agent, MLOps APIs, approval gating) into a scheduled agent that does the maintenance work and files a promotion request instead of promoting.
Do not automate a retrain you have not run manually at least five times — the agent inherits your procedure's maturity, including its gaps.
train.py --data-window ...) with MLflow tracking already wired in.@champion.Write the retrain runbook as the agent's task spec. The exact steps you do manually: pull data window, run integrity checks, train, evaluate on the fixed holdout and a fresh backtest window, compare to champion metrics, decide recommend/reject. If a step relies on your judgment, write down the rule you actually use — that forcing function is half the value.
Give the agent narrow tools, not a shell. run_training(config), run_backtest(model_uri, window), get_champion_metrics(), log_report(text), request_promotion(model_uri, evidence) — each a thin wrapper over your pipeline and MLflow client. No general bash, no registry-write beyond opening a request.
Make request_promotion a request, not an action. It tags the run and notifies a human (Slack webhook/email) with the evidence table; it never touches the @champion alias:
@beta_tool
def request_promotion(model_uri: str, evidence: str) -> str:
"""File a promotion request for human review. Does NOT promote.
Args:
model_uri: MLflow model URI of the challenger.
evidence: Markdown table comparing challenger vs champion.
"""
mlflow.set_tag("promotion_requested", "true")
notify_reviewers(model_uri, evidence)
return "Promotion request filed; awaiting human approval."
Approval itself is a human running one command (or clicking in the MLflow UI) that moves the alias — the credential able to do that is never in the agent's environment.
Wire the loop and schedule it. The agent (Anthropic tool runner or a LangGraph graph) executes the runbook with a step budget of ~15 and a token/dollar cap. Schedule via cron/Actions; each run writes a full report — data window, checks passed, metrics vs champion, recommendation and why — to MLflow artifacts.
Handle the three exit states explicitly. (a) Challenger better → promotion request filed; (b) challenger worse or checks failed → report filed, no request, and that is a successful run; (c) budget/error → alert a human with partial findings. State (b) being normal is what keeps the gate meaningful.
Shadow it for two cycles. Run the agent alongside your manual process; diff its recommendation against yours before letting it replace the manual run.
The design boundary is capability, not instruction: the agent's credentials can train, evaluate, and file requests — and structurally cannot promote. Gates enforced by IAM survive prompt injection; gates enforced by prompts do not.
interrupt() (pb-41): model approval as a durable pause instead of an external notification — reviewer resumes the same run with approve/reject.Fully self-hostable: local model via vLLM for the agent loop, self-hosted MLflow, cron on your infra — no data or metrics leave the environment. For client engagements, the promotion gate maps naturally onto the client's existing change-approval process: the agent files the change request in their system, which usually makes this pattern easier to approve than any auto-deploy proposal.
A scheduled agent fails silently on schedule too — alert on "run did not complete" (dead-man's switch), not just on bad outcomes.