Módulo 7: Versionado y rollout seguro
Módulo 7: Versionado y rollout seguro
Descripción
El Módulo 6 cerró la disciplina de endurecer: un CircuitBreaker por tool que abre cuando book_room falla varias veces seguidas, backoff modelado para los reintentos, y el 429 de la propia API de Claude manejado con criterio. Con eso, el agente de Reservo sobrevive a que una tool se porte mal. Pero hay una categoría de fallo completamente distinta que ningún módulo anterior toca: ¿qué pasa cuando el agente entero se porta mal, porque alguien —tú, un compañero de equipo— cambió el system prompt, agregó una tool nueva, o ajustó un schema, y ese cambio, sin que nadie lo note, rompe algo que antes funcionaba?
Ese "algo que rompe sin que nadie lo note" es, con precisión, el problema de este módulo. Un circuit breaker no lo detecta —la tool no está fallando, se está ejecutando perfectamente, solo que es la tool equivocada—. Un log estructurado no lo detecta —cada evento se ve limpio, sin ningún is_error—. El costo y la latencia tampoco lo detectan —una reserva de más cuesta lo mismo, en tokens, que una reserva correcta—. Hace falta algo que no compare "¿funcionó?" sino "¿siguió haciendo lo mismo que hacía antes?". Ese algo es un gate de regresión, y este módulo enseña a usarlo para decidir, con evidencia y no con vibra, si una versión nueva del agente está lista para reemplazar a la que ya está en producción.
Lo que este módulo SÍ construye
Tres piezas, en este orden:
- Un registro de versiones (
PROMPT_REGISTRY): el system prompt del agente de Reservo, congelado env1y env2, cada uno con un hash determinista que lo identifica sin ambigüedad — igual que un commit de git identifica un estado exacto del código, sin que dos personas tengan que "confiar" en que están mirando lo mismo. - Una comparación: correr el mismo gate de regresión —el de forma, determinista, sin juez— sobre
v1y sobrev2, y ver, caso por caso, si algo cambió. - Una decisión:
GOsiv2pasa el gate igual o mejor quev1;NO-GOsiv2rompe aunque sea un solo caso quev1pasaba — y, si esNO-GO, un rollback determinista de vuelta a la versión que sí funcionaba.
Vas a ejecutar las tres, de punta a punta, sobre un caso real: una v2 del system prompt de Reservo que, con la mejor intención del mundo ("sé más proactivo, ahorra pasos"), termina reservando una sala cuando el usuario solo había preguntado el precio. El gate la caza. La decisión es NO-GO. El rollback vuelve a v1. Ese es el módulo completo, ejecutado con números reales.
Conexión con el módulo
Este módulo retoma, sin volver a construir nada desde cero, el gate de regresión de forma que el Módulo 5 estableció: un harness que corre un set fijo de casos y compara, literalmente, contra un resultado esperado — nunca un juez, nunca un score de calidad semántica. Aquí ese mismo gate se reutiliza con un propósito nuevo: en el Módulo 5 lo corriste una vez, contra el agente tal como estaba, para confirmar que seguía funcionando. En este módulo lo corres dos veces —contra la versión vieja y contra la versión nueva— y comparas los dos resultados entre sí. La pregunta cambia de "¿funciona?" a "¿sigue funcionando igual?" — y esa es, exactamente, la pregunta que un rollout seguro necesita responder antes de que una versión nueva le hable a un solo usuario real.
Dónde estamos en el ecosistema
Agentes en producción — operar el agente de Reservo
├── Módulo 1: Por qué operar es distinto de construir
├── Módulo 2: Logging estructurado y trazado de un run
├── Módulo 3: Medir costo y tokens por run
├── Módulo 4: Medir latencia con honestidad
├── Módulo 5: Evals de regresión como gate de producción
├── Módulo 6: Fallos a escala — backoff, circuit breakers y rate limits
├── Módulo 7: Versionado y rollout seguro ← ESTÁS AQUÍ
│ → por qué versionar, PROMPT_REGISTRY con v1/v2,
│ comparar contra el mismo gate, la decisión GO/NO-GO,
│ el rollback determinista
└── Módulo 8: Proyecto — el agente de Reservo en producción
Este es el cuarto y último módulo de la disciplina endurecer + versionar, la última de las cuatro que organizan esta guía: observar (M2) → medir (M3-M4) → gatear (M5-M6) → endurecer y versionar (M6-M7). Con este módulo cerrado, el Módulo 8 tiene las cinco piezas completas —logging, costo, latencia, el gate, el circuit breaker, y ahora el versionado— para operar el agente de Reservo de punta a punta, como un solo sistema.
La analogía central de este módulo: el pase médico de un piloto
Antes de que un piloto vuele un avión de pasajeros, pasa por un examen médico. No es un examen que se hace una vez en la vida — se repite, periódicamente, durante toda la carrera del piloto, porque el cuerpo cambia y lo que era cierto hace un año puede no serlo hoy. El examen es siempre el mismo —la misma batería de pruebas, los mismos umbrales de presión arterial, de visión, de reflejos— sin importar si el piloto lleva veinte años volando o si es su primera revisión. Si el piloto pasa, vuela. Si no pasa, se queda en tierra, y vuela otro piloto que sí tiene su pase vigente, hasta que el primero vuelva a pasar el examen.
Una versión nueva del system prompt de un agente es, con precisión, ese piloto. No sale a producción porque "se ve bien" en una conversación de prueba, ni porque la persona que la escribió confía en que mejora las cosas — sale a producción porque pasó la misma inspección, con los mismos umbrales, que la versión anterior ya pasó. Ese examen es el gate del Módulo 5. Si la versión nueva reprueba —si rompe aunque sea un solo caso que la vieja resolvía bien—, se queda en tierra: NO-GO, y sigue volando la versión anterior, la que sí tiene su pase vigente. Ese "seguir volando la versión anterior" es, exactamente, el rollback de la lección 07.
Versionar sin un gate es mandar al piloto a volar sin revisión, confiando en que "se ve bien". Este módulo existe para que esa confianza nunca sea el criterio.
El caso que sigue acompañando la guía: dos versiones de Reservo, una sola pregunta
El agente que se versiona en este módulo es el mismo de siempre — las cuatro tools (list_rooms, get_quote, book_room, cancel_booking), las mismas dos anclas de precio (Focus basic 3h = 7500, Focus pro 3h = 6000). Lo que cambia entre v1 y v2 es una sola cosa: el system prompt, la instrucción que le dice al agente cómo comportarse.
v1— el system prompt original del capstone deagent-fundamentalsM8: usa las tools para cotizar y reservar; nunca reserva sin que el usuario lo pida explícitamente.v2— el mismo prompt, con una línea agregada: "sé proactivo: si ya tienes toda la información para completar una reserva, complétala directamente, para ahorrarle un paso al usuario". La intención es genuina — menos turnos, menos fricción. El efecto, medido con el gate, es una regresión: frente a una pregunta que solo pide un precio ("¿Cuánto cuesta Focus pro 3 horas?"),v2decide reservar en vez de cotizar.
Esta es, deliberadamente, una regresión sutil. No hay ningún error de sintaxis en v2, ningún KeyError, ninguna tool que deje de existir. El agente sigue respondiendo, sigue ejecutando tools reales, sigue produciendo resultados con la forma correcta. El único cambio es cuál tool decidió llamar para una pregunta específica — y esa es, precisamente, la clase de fallo que un gate de forma, bien diseñado, está hecho para cazar.
- Lección 02 muestra, con un ejemplo mínimo, por qué este tipo de cambio es peligroso — y por qué "lo probé a mano y se veía bien" no es suficiente.
- Lección 03 construye
PROMPT_REGISTRY:v1yv2, cada uno con suprompt_hashdeterminista (hashlib, nuncauuid4). - Lección 04 retoma el gate del Módulo 5 —
CASE_SET,check_tool_choice,run_regression_gate, el mecanismooverrides— y lo corre contra las dos versiones:v1pasaPASS (5/5);v2fallaFAIL (4/5), en el casoquote_focus_pro_3h. - Lección 05 abre el gate y muestra por qué atrapó justo esto: la forma del resultado de
v2es perfecta —el schema valida—; lo que sí se sale de presupuesto es la tool elegida y, como efecto colateral, la latencia (book_roomes más lenta que elget_quoteque ese caso esperaba); el gate necesita varios chequeos independientes, no solo "¿algo se rompió?". - Lección 06 construye
rollout_decision: la regla dura (nunca romper un caso que ya pasaba) y su ejecución sobrev1vs.v2→NO-GO. - Lección 07 construye
rollback: cómo se vuelve, de forma determinista, a la versión anterior — y por qué eso es simple aquí, porque no hay ningún mecanismo de despliegue real que deshacer. - Lección 08 cierra el módulo con
ops/versioned_rollout.pycompleto: el registro, la comparación, la decisión, y los dos artefactos finales —ops/AGENT_CONFIG.mdyAGENT_CHANGELOG.md— generados de verdad.
Como en cada módulo de esta guía: identificadores y código en inglés; prosa y comentarios, en español; dinero en centavos int; nada de random, datetime.now() ni uuid4() — el hash de un prompt se calcula con hashlib, siempre el mismo para el mismo texto.
Prerequisitos
Conocimiento requerido:
- ✅ Haber completado el Módulo 5 de esta guía: el gate de regresión de forma —
CASE_SET,check_tool_choice,run_regression_gate—, PASS/FAIL determinista, nunca un juez. Este módulo lo retoma y lo reproduce completo (para que este módulo sea autosuficiente), pero no vuelve a explicar por qué el gate es de forma y no semántico — eso ya lo estableció el Módulo 5. - ✅ Haber completado (o conocer bien)
agent-fundamentals-and-tool-calling-guideM8: el agente de Reservo, sus cuatro tools,run_reservo_agent, y la noción de que el modelo (claude-sonnet-5) es la pieza que decide — concepto en esta guía, nunca ejecutada de verdad. - ✅ Python:
dataclasses,hashlib, diccionarios, comprensión de diccionarios,pathlibbásico (para escribir un archivo de texto).
Recomendado:
- ✅ Haber sentido, alguna vez, la incomodidad de cambiar un prompt "solo un poco" y no tener ninguna forma sistemática de confirmar que nada se rompió — solo la sensación de "lo probé con dos preguntas y se veía bien". Ese es, con precisión, el vacío que este módulo llena.
NO requerido:
- ❌ No necesitas una API key ni conexión a internet: las dos versiones del system prompt son texto fijo; sus decisiones (qué tool eligen) son concepto, guionadas explícitamente.
- ❌ No necesitas un pipeline de CI/CD real (GitHub Actions, un sistema de despliegue). Este módulo enseña la disciplina de comparar dos versiones contra el mismo gate antes de decidir — no el mecanismo de infraestructura que despliega código a un servidor.
- ❌ No necesitas saber nada de A/B testing con tráfico real ni de métricas semánticas de calidad — eso es la frontera explícita con
evaluation-frameworks-guide, nombrada con precisión en la lección 05.
Entorno:
- ✅ Python 3.14.0 con su librería estándar (
hashlib,dataclasses,pathlib,itertools). Nada que instalar. - ✅ Los artefactos de los Módulos 2-6 (
observability/,regression/,resilience/), aunque este módulo no los importa directamente — construye los suyos propios enops/.
Roadmap del módulo
Lección 01 — Introducción al módulo (esta)
El límite que deja el Módulo 6 —el agente sobrevive a una tool que falla, pero no a un cambio silencioso en su propio comportamiento—, la analogía del pase médico del piloto, y el mapa de las ocho lecciones.
Lección 02 — Por qué versionar prompts y tools
Un cambio de una línea en el system prompt puede romper la elección de tool sin que nadie lo note en una prueba manual. El costo de no versionar: no poder responder "¿qué prompt exacto estaba corriendo cuando pasó esto?".
Lección 03 — El registro de versiones de prompts
PROMPT_REGISTRY: AgentVersion, hash_prompt con hashlib (determinista, nunca uuid4), v1 y v2 del system prompt de Reservo, cada uno con su hash real.
Lección 04 — Comparando una versión nueva contra la vieja
Se retoma el gate del Módulo 5 —CASE_SET, check_tool_choice, run_regression_gate, el mecanismo overrides— y se corre contra v1 (PASS 5/5) y contra v2 (FAIL 4/5, caso quote_focus_pro_3h).
Lección 05 — El gate como chequeo de rollout
Por qué el gate atrapó justo esto: se abre el CaseResult completo del caso que falló, y se confirma que tool_choice_ok es la causa raíz, con latency_ok roto como efecto colateral y cost_ok/schema sin siquiera evaluarse. La frontera con evaluation-frameworks-guide.
Lección 06 — GO o NO-GO
rollout_decision: la regla (nunca romper un caso que la versión vieja pasaba), ejecutada sobre v1 vs. v2 → NO-GO, y sobre v1 vs. una v3 corregida → GO.
Lección 07 — Haciendo rollback
rollback: volver, de forma determinista, a la versión anterior cuando la decisión es NO-GO. Por qué es simple aquí — es un cambio de puntero, no un despliegue real.
Lección 08 — Mini-proyecto: un rollout versionado para Reservo
ops/versioned_rollout.py completo: registro, gate en las dos versiones, decisión, rollback, y los dos artefactos finales generados de verdad — AGENT_CONFIG.md y AGENT_CHANGELOG.md.
Mapa de progresión
Lección 01 (esta) → El límite del Módulo 6, el pase médico del piloto
Lección 02 → Por qué versionar: el peligro de un cambio silencioso
Lección 03 → PROMPT_REGISTRY, AgentVersion, hash_prompt
Lección 04 → El gate del Módulo 5, corrido en v1 y en v2
Lección 05 → Por qué el gate atrapó justo esto: tool vs. schema vs. latencia
Lección 06 → rollout_decision: GO / NO-GO
Lección 07 → rollback: volver a la versión que sí funcionaba
Lección 08 → Mini-proyecto: el rollout versionado completo
Dificultad: ⭐⭐⭐ ──────────────────▶ ⭐⭐⭐
Qué lograrás en este módulo
Al completar las 8 lecciones, podrás:
- Explicar, con un ejemplo concreto, por qué un cambio en el system prompt puede romper la elección de tool sin que ningún error explícito lo señale — ni un
KeyError, ni unis_error, ni un schema inválido. - Construir un registro de versiones (
PROMPT_REGISTRY) que identifica cada versión del prompt con un hash determinista, nunca con un identificador que cambia entre corridas. - Correr el mismo gate de regresión contra dos versiones distintas del agente y leer, caso por caso, dónde diverge el comportamiento.
- Distinguir con precisión qué parte de un chequeo de forma detectó una regresión — tool elegida, schema del output, o presupuesto de latencia — en vez de tratar el gate como una caja negra que dice "algo se rompió".
- Tomar una decisión GO/NO-GO con una regla explícita y verificable, nunca con la impresión subjetiva de que "la versión nueva se ve mejor".
- Ejecutar un rollback determinista que vuelve a la versión anterior, y explicar por qué esta guía lo trata como un cambio de puntero y no como un despliegue de infraestructura.
El antes y después
ANTES del módulo:
→ "probé la versión nueva del prompt con dos preguntas y
se veía bien, así que la subo"
→ "si el agente no tira ningún error, está funcionando igual
que antes"
→ "versionar un prompt es guardar el texto en un archivo,
ya está"
→ "revertir un cambio malo es volver a pegar el prompt viejo
a mano"
DESPUÉS del módulo:
→ una versión nueva solo sale a producción si pasa el MISMO
gate, con los MISMOS umbrales, que la versión vieja ya pasó
→ un agente puede seguir respondiendo sin ningún error técnico
y, aun así, haber cambiado QUÉ hace -- el gate compara
comportamiento, no solo ausencia de excepciones
→ versionar es un registro con un hash que identifica, sin
ambigüedad, el texto exacto que estaba corriendo
→ un rollback es una decisión de UNA línea (volver al hash
anterior), tomada con evidencia, no un "deshacer a mano"
Trampas a evitar al cursar este módulo
1. "Si v2 responde bien en las preguntas que probé a mano, ya está lista"
No. El ejemplo central de este módulo es, exactamente, una versión que responde "bien" —sin ningún error técnico— y aun así está rota. Probar "a mano" con dos o tres preguntas nunca reemplaza correr el mismo set fijo de casos que ya se usó para validar la versión anterior.
2. "El gate de este módulo necesita un LLM que compare las dos versiones y diga cuál es mejor"
No. El gate sigue siendo exactamente el del Módulo 5: comparación literal contra un valor fijo (qué tool se llamó, qué devolvió). Nunca hay una llamada a un modelo para calificar nada — eso es, con precisión, la frontera con evaluation-frameworks-guide, nombrada en la lección 05.
3. "Un hash de prompt necesita una librería especial o un servicio externo"
No. hashlib.sha256 de la librería estándar, aplicado al texto del prompt, es determinista y suficiente: el mismo texto siempre produce el mismo hash, en cualquier máquina, sin red y sin ninguna dependencia externa.
4. "GO/NO-GO es una decisión de negocio, no algo que se pueda calcular"
Se puede, y este módulo lo hace: la regla es explícita —v2 nunca puede romper un caso que v1 pasaba— y se calcula comparando dos GateReport caso por caso. Que la decisión final la confirme una persona es razonable; que la evidencia detrás sea subjetiva, no.
5. "El rollback de este módulo es lo mismo que un rollback de infraestructura real (Kubernetes, un balanceador de carga)"
No, y la lección 07 lo dice con precisión: aquí el rollback es un cambio de puntero —qué versión del prompt está activa—, porque no hay ningún despliegue real que deshacer. Un rollback de infraestructura completa (contenedores, tráfico, DNS) es un tema de otra capa, fuera del alcance $0 de esta guía.
Cómo trabajar este módulo
- Corre el gate contra las dos versiones tú mismo, antes de leer el resultado en la lección 04. La sorpresa de ver
FAIL 4/5en vez dePASS 5/5es más útil que leerlo ya resuelto. - En la lección 05, no te quedes con "el gate falló" — abre el
CaseResultcompleto y confirma, con tus propios ojos, cuál de sus cinco campos es el que realmente rompió. - El mini-proyecto (lección 08) es la síntesis. Ahí vas a generar, de verdad,
AGENT_CONFIG.mdyAGENT_CHANGELOG.md— los mismos dos artefactos que el Módulo 8 va a citar en el capstone final de la guía.
Tiempo estimado:
Lección 01 (esta) → 20 min lectura
Lección 02 → 20 min + correr el ejemplo
Lección 03 → 20 min + correr el ejemplo
Lección 04 → 30 min + correr el ejemplo
Lección 05 → 25 min + correr el ejemplo
Lección 06 → 25 min + correr el ejemplo
Lección 07 → 20 min + correr el ejemplo
Lección 08 → 35 min + armar el mini-proyecto completo
Total: ~3.5 horas
Evidencia de éxito
Antes de avanzar al Módulo 8 (Proyecto: el agente de Reservo en producción), deberías poder:
- ✅ Explicar, con el caso de
v2de este módulo, por qué un agente puede seguir "funcionando" sin ningún error técnico y, aun así, haber cambiado su comportamiento de forma que importa. - ✅ Construir un
PROMPT_REGISTRYcon hashes deterministas, y explicar por qué nunca se usauuid4()para identificar una versión. - ✅ Correr el gate de regresión contra dos versiones y leer, con precisión, en qué caso divergen.
- ✅ Tomar una decisión GO/NO-GO aplicando la regla explícita, no una impresión.
- ✅ Ejecutar un rollback determinista y explicar por qué, en esta guía, es un cambio de puntero y no un despliegue.
Resumen
- Este módulo cierra la disciplina de endurecer + versionar: después de que el Módulo 6 endureció el agente frente a una tool que falla, este módulo lo endurece frente a sí mismo — frente a un cambio en su propio prompt que rompe algo sin avisar.
- La analogía central es el pase médico del piloto: una versión nueva no vuela hasta pasar la misma inspección —el gate del Módulo 5— que la vieja ya pasó; si reprueba, se queda en tierra (
NO-GO) y vuela la versión anterior (rollback). - Las piezas del módulo: por qué versionar (L02), el registro con hashes (L03), la comparación contra el mismo gate (L04), por qué el gate atrapó justo esto (L05), la decisión GO/NO-GO (L06), el rollback (L07), y el mini-proyecto que junta todo (L08).
- Ejecutado de punta a punta:
v1pasa el gatePASS (5/5);v2—con una sola línea nueva en el prompt— fallaFAIL (4/5), exactamente en el casoquote_focus_pro_3h(Focus pro 3h); la decisión esNO-GO; el rollback devuelve al agente av1.
Siguiente lección: 02 — Por qué versionar prompts y tools. Antes de construir ningún registro, vemos con un ejemplo mínimo por qué un cambio de una sola línea en el system prompt puede romper la elección de tool sin que ninguna prueba manual lo note.
Recursos adicionales
- Anthropic — Building effective agents — Sobre por qué cambios aparentemente pequeños en las instrucciones de un agente pueden tener efectos grandes y no obvios en su comportamiento.
- Anthropic — System prompts — El rol del system prompt en el comportamiento del modelo, la pieza que este módulo versiona.
- Python —
hashlib—hashlib.sha256, el núcleo determinista dehash_prompten la lección 03. - Python 3.14 — What's New — La versión con la que se ejecuta toda la ingeniería de este módulo.