Módulo 2: Latencia y costo como arquitectura
8. Proyecto: diseña el presupuesto de una feature de IA de Mercado
Descripción
Esta es tu graduación del módulo. Durante siete lecciones aprendiste a medir la latencia y el costo de un LLM, a acotarlos con un presupuesto, y a respetarlo con tres técnicas —cascade, caché, streaming— que la lección 7 compuso en un camino de petición. Todo eso lo viste aplicado al agente de soporte. Ahora te toca a ti, de cero, sobre una feature de Mercado distinta: la búsqueda semántica. La razón de cambiar de feature es la de siempre y es dura: si te dejara re-componer el agente de soporte de la lección 7, no sabría si aprendiste el método o memorizaste la tabla. Con una feature nueva, la única forma de resolverlo es aplicar el método —fijar el presupuesto, componer las técnicas, medir contra el naive, justificar que cabe— y esa es, exactamente, la prueba de que el módulo funcionó.
Tu entregable son tres artefactos para la búsqueda semántica: (1) el presupuesto (latency budget y cost budget) con su justificación; (2) la arquitectura consciente del costo (cascade + caché) medida contra el naive, ejecutada en Python; y (3) la justificación de qué técnica resuelve qué, por qué la feature termina dentro de su presupuesto, y dónde va el streaming. Ninguna parte requiere construir el LLM: el modelo se simula con el stub de siempre. Es puro trabajo de diseño —presupuestar, componer, medir, defender— que es justo lo que separa una feature de IA que cabe en su presupuesto de una factura sorpresa. Constrúyelo tú primero; leer la solución de referencia sin haberlo intentado es como leer el marcador de un partido que no jugaste.
Conexión con el módulo: este proyecto cierra el arco. Las lecciones 2 y 3 te dieron la báscula y el presupuesto; las 4, 5 y 6 las técnicas; la 7 las compuso sobre el agente de soporte. Aquí produces los tres artefactos con tus manos, de principio a fin, sobre la búsqueda semántica. Y con esta lección se cierra el módulo: al final está el resumen de las ocho lecciones y el puente hacia el módulo 3 (el eval como compuerta de calidad —la tercera restricción que este módulo no cubrió) y hacia el ecosistema de AI Engineering (donde se construyen las piezas que aquí solo arquitectamos).
El caso del proyecto: la búsqueda semántica de Mercado
La feature que te toca diseñar —tuya para resolver— es esta:
Mercado quiere una búsqueda semántica: cuando un cliente escribe "algo para escuchar música corriendo", el sistema usa un LLM para entender la intención y reordenar los productos por relevancia. Es de alto volumen (cada búsqueda del sitio la toca) y vive en el camino crítico (si tarda, el cliente lo siente). Diséñala para que quepa en su presupuesto.
Es una feature hermana de la del agente de soporte —también se repite, también varía en dificultad— pero con otro perfil: es una búsqueda de un solo tiro (no conversacional), de altísimo volumen, y en el camino crítico de cada búsqueda. No la resolvimos; te toca a ti. No re-enseñes cómo funciona un LLM ni cómo se calculan embeddings —eso es de AI Engineering—; tu trabajo es arquitectar la feature alrededor del LLM para que respete su presupuesto.
Los hechos que te da el equipo (medidos y estimados, para que no tengas que inventarlos): la búsqueda semántica corre a 40,000 búsquedas/día. El presupuesto que el negocio asignó: $5,000/mes de costo, y 800 ms de latencia por búsqueda. Los usuarios buscan lo mismo escrito de muchas formas (bueno para caché) y las búsquedas varían en dificultad —el 30% son difíciles y piden respuestas más largas (350 tokens contra 150 de las fáciles)—. La cola larga (búsquedas raras y difíciles) es el 22% del tráfico. El clasificador acierta el 90%.
Lo que tienes que entregar
Sigue los pasos en orden; cada uno se apoya en el anterior.
Parte 1 — El presupuesto
Escribe el latency budget y el cost budget de la búsqueda semántica, y justifica en una o dos frases por qué esos números (por qué 800 ms para la latencia, por qué $5,000/mes para el costo, atados al contexto de uso y al volumen). No inventes: usa los que te dio el equipo, pero explica por qué tienen sentido para ESTA feature.
Parte 2 — La arquitectura consciente del costo, ejecutada
Escribe y corre el Python que mide, sobre un workload de la búsqueda semántica, cuatro estrategias: naive (todo al strong model), solo caché, solo cascade, y caché+cascade. Reporta para cada una el costo mensual y si cabe en el presupuesto. Reusa el stub y las fórmulas del módulo: la caché sirve los hits gratis; el cascade enruta fácil→cheap, difícil→strong; el mensual es costo_por_workload × (búsquedas_día × 30 / N). Entrega la tabla real (no citada de memoria).
Parte 3 — La justificación y el streaming
Con la tabla en mano, escribe: (a) qué técnica resuelve qué parte del problema; (b) por qué la feature termina dentro de su presupuesto (y cuál combinación eliges, con qué headroom); (c) qué pasa con la latencia de las búsquedas pesadas y dónde entra el streaming; y (d) una frase sobre la tercera compuerta que este diseño NO verifica (la calidad) y a qué módulo pertenece.
La rúbrica
Así se evalúa el proyecto. No es por extensión ni por elegancia: es por si la feature está bien presupuestada y la arquitectura respeta el presupuesto con evidencia.
| Criterio | No cumple | Cumple | Sobresale |
|---|---|---|---|
| Presupuesto | Sin umbrales, o "que sea rápido/barato" | Latency y cost budget explícitos | Además justifica cada número por el contexto de uso y el volumen |
| Arquitectura ejecutada | Números citados de memoria o inventados | Tabla corrida en Python con las 4 estrategias vs presupuesto | Además declara por qué cada técnica ahorra lo que ahorra y anota el solapamiento |
| Composición | Aplica una sola técnica y da por resuelto | Compone caché + cascade y verifica que cabe | Además elige la combinación con headroom y explica que los ahorros no suman |
| Fronteras | No menciona latencia de cola ni calidad | Ubica el streaming (cola) y el eval gate (calidad) | Además dice a qué módulo/ecosistema pertenece cada frontera |
El criterio que más pesa, y el que separa un diseño serio de una opinión, es la arquitectura ejecutada: si entregas todo lo demás pero los números salieron de tu cabeza y no de correr el código, no mediste —adjetivaste con cifras inventadas, que es peor, porque finge rigor—.
La solución de referencia
Intenta el proyecto entero antes de seguir. Lo que viene es una solución correcta, no la única.
Parte 1 — El presupuesto
- Latency budget: 800 ms por búsqueda. Justificación: la búsqueda semántica vive en el camino crítico de cada búsqueda del sitio —el cliente escribe y espera resultados de inmediato—. La evidencia de UX dice que arriba de ~800 ms una búsqueda interactiva empieza a costar abandonos, así que 800 ms es el punto donde la feature deja de sentirse ágil. (Rigurosamente, sobre un percentil alto —p95—, no el promedio, porque la cola es donde vive la mala experiencia.)
- Cost budget: $5,000/mes a 40,000 búsquedas/día. Justificación: es la fracción del margen que el negocio asignó a la feature. La búsqueda ayuda a cerrar ventas, y su costo tiene que ser una porción pequeña de ese margen o la feature destruye valor. A 40,000/día, $5,000/mes es lo que se acordó con quien conoce el margen —no un número que la ingeniería inventó—.
Parte 2 — La arquitectura ejecutada
# Leccion 08 (proyecto) — disenar el presupuesto de la busqueda semantica de Mercado
# Solucion de referencia. Todo SIMULADO. Cero red, cero API, cero claves. Semilla fija.
import random
MODELS = {
"cheap": dict(usd_in=0.0008, usd_out=0.004, base_ms=90, ms_per_tok=0.4),
"strong": dict(usd_in=0.008, usd_out=0.040, base_ms=300, ms_per_tok=3.0),
}
def call_llm(model, in_tokens, out_tokens):
m = MODELS[model]
return m["base_ms"] + out_tokens * m["ms_per_tok"], \
(in_tokens/1000)*m["usd_in"] + (out_tokens/1000)*m["usd_out"]
# --- Paso 1: EL PRESUPUESTO (la restriccion de diseno) ---
LATENCY_BUDGET_MS = 800 # el usuario abandona si la busqueda tarda mas
MONTHLY_COST_BUDGET = 5000.0 # dolares/mes asignados a la feature
SEARCHES_PER_DAY = 40_000
IN_TOK = 300
OUT_EASY, OUT_HARD = 150, 350
HIT_MS, HIT_COST = 2.0, 0.0
CLASSIFIER_MS = 3
# --- El workload: 3000 busquedas. Repeticion (cache) + dificultad (cascade). ---
random.seed(42)
N = 3000
POOL = [f"search_{i:03d}" for i in range(180)]
WEIGHTS = [1.0/(i+1) for i in range(180)]
DIFFICULTY = {q: (random.random() < 0.30) for q in POOL}
_uid = [0]
def make():
if random.random() < 0.22: # cola larga: busqueda nueva y dificil
_uid[0] += 1; return (f"novel_{_uid[0]}", True)
q = random.choices(POOL, weights=WEIGHTS, k=1)[0]
return (q, DIFFICULTY[q])
searches = [make() for _ in range(N)]
def out_for(hard): return OUT_HARD if hard else OUT_EASY
def classify(hard): return hard if random.random() < 0.90 else (not hard)
def run(use_cache, use_cascade):
cache, cost, lats = set(), 0.0, []
for text, hard in searches:
if use_cache and text in cache:
cost += HIT_COST; lats.append(HIT_MS); continue
if use_cache: cache.add(text)
if use_cascade:
model, extra = ("strong" if classify(hard) else "cheap"), CLASSIFIER_MS
else:
model, extra = "strong", 0.0
lat, c = call_llm(model, IN_TOK, out_for(hard))
cost += c; lats.append(lat + extra)
return cost, sum(lats)/len(lats)
def monthly(c): return c * (SEARCHES_PER_DAY * 30 / N)
def v(m): return "OK " if m <= MONTHLY_COST_BUDGET else "VIOLA"
# --- Paso 2: medir naive vs la arquitectura consciente del costo ---
print(f"{'strategy':<20}{'total_cost':>12}{'avg_lat_ms':>12}{'monthly_usd':>13}{'budget':>8}")
for label, uc, ucas in (("all_strong (naive)", False, False),
("cache_only", True, False),
("cascade_only", False, True),
("cache+cascade", True, True)):
cost, avg = run(uc, ucas)
mo = monthly(cost)
print(f"{label:<20}{cost:>12.4f}{avg:>12.1f}{mo:>13,.0f}{v(mo):>8}")
print(f"\nlatency_budget = {LATENCY_BUDGET_MS} ms | monthly_cost_budget = ${MONTHLY_COST_BUDGET:,.0f}/mes"
f" ({SEARCHES_PER_DAY:,} busquedas/dia)")
# --- Paso 3: la query pesada y el latency budget (justifica streaming) ---
heavy_block = MODELS["strong"]["base_ms"] + OUT_HARD * MODELS["strong"]["ms_per_tok"]
heavy_ttft = MODELS["strong"]["base_ms"] + 1 * MODELS["strong"]["ms_per_tok"]
print(f"\nquery pesada al strong: bloqueante {heavy_block:.0f} ms ({v(0) if heavy_block<=LATENCY_BUDGET_MS else 'VIOLA'}"
f" el latency budget), streaming TTFT {heavy_ttft:.0f} ms (OK)")
Qué esperar. Al correrlo:
strategy total_cost avg_lat_ms monthly_usd budget
all_strong (naive) 38.3840 1079.6 15,354 VIOLA
cache_only 12.6508 350.8 5,060 VIOLA
cascade_only 26.7924 778.7 10,717 VIOLA
cache+cascade 10.8321 304.7 4,333 OK
latency_budget = 800 ms | monthly_cost_budget = $5,000/mes (40,000 busquedas/dia)
query pesada al strong: bloqueante 1350 ms (VIOLA el latency budget), streaming TTFT 303 ms (OK)
Lee la tabla como aprendiste. El naive —todo al strong model— cuesta $15,354/mes, más de tres veces el presupuesto de $5,000: la opción ingenua no es rentable. El cascade solo recorta a $10,717 (30% menos) pero sigue muy por encima. Y aquí el detalle fino: la caché sola cuesta $5,060/mes —viola el presupuesto por un pelo (apenas $60, un 1.2% arriba)—. Está tan cerca de caber que es tentador aprobarla, pero un diseño que apenas roza el límite no tiene headroom: en cuanto el tráfico suba un poco, se sale. Solo caché + cascade cabe de verdad: $4,333/mes, OK, con margen frente a los $5,000. Es la arquitectura que se lleva a producción, no porque sea la única que ahorra, sino porque es la única que cabe con holgura.
Y como en la lección 7, los ahorros no suman: la caché sola ahorra ~67% ($38.38 → $12.65) y el cascade solo ~30% ($38.38 → $26.79); si sumaras, esperarías 97%. Pero juntas ahorran 72% ($38.38 → $10.83), no 97% —porque se solapan sobre el mismo tráfico fácil/repetido—. Hay que medir la combinación, no sumar.
Una palanca extra opcional: recortar la salida. La búsqueda semántica no necesita generar 150-350 tokens de prosa; necesita reordenar productos, que se puede pedir como una lista compacta de IDs. Si limitas la salida (por ejemplo a 60 tokens las fáciles, 120 las difíciles), bajas el costo por llamada y la latencia. Añadiendo este bloque al final del script:
# --- Palanca extra (opcional): limitar la longitud de la salida (lista de IDs, no prosa) ---
OUT_EASY, OUT_HARD = 60, 120 # antes 150, 350
cost_capped, avg_capped = run(True, True)
print(f"cache+cascade+salida corta: ${monthly(cost_capped):,.0f}/mes "
f"avg {avg_capped:.0f} ms {v(monthly(cost_capped))}")
produce:
cache+cascade+salida corta: $1,901/mes avg 152 ms OK
Con la salida recortada, caché+cascade baja a $1,901/mes (mucho más headroom) y la latencia promedio a 152 ms. No hacía falta para caber —caché+cascade ya cabía en $4,333— pero es una palanca legítima cuando quieres más margen o cuando el volumen crece. Y —dato clave— resuelve de paso la latencia de la query pesada: con 120 tokens de salida en vez de 350, la pesada al strong baja de 1350 ms a 300 + 120×3 = 660 ms, que ya cabe bajo los 800 ms sin siquiera necesitar streaming. La longitud de la salida es una palanca doble —costo y latencia— justo como enseñó la lección 2.
Parte 3 — La justificación
(a) Qué técnica resuelve qué. La caché elimina el tráfico repetido (los usuarios buscan lo mismo escrito distinto) —de $15,354/mes naive a $5,060 solo con caché, el mayor recorte individual—. El cascade abarata las búsquedas nuevas que sí llegan al LLM, enrutando las fáciles al cheap model. Y la longitud de la salida (pedir IDs, no prosa), como palanca opcional, baja el costo y la latencia por llamada. Cada una ataca una porción distinta: la caché el volumen repetido, el cascade el precio por llamada, la salida corta el tamaño de cada llamada.
(b) Por qué cabe, y con qué headroom. Elijo caché + cascade: cabe en $4,333/mes, bien debajo del presupuesto de $5,000, con margen para crecer. Descarto la caché sola aunque parezca "casi caber" ($5,060) porque viola el presupuesto —y aun si lo rozara desde abajo, quedaría sin headroom, lista para salirse al primer aumento de tráfico—. La regla: no elijas la que apenas cabe; elige la que cabe con holgura. Y —lección de la 7— los ahorros no suman (67% + 30% dan 72%, no 97%), porque la caché ya se comió el tráfico fácil/repetido que el cascade también habría abaratado, así que hay que medir la combinación.
(c) La latencia de cola y el streaming. Mira el avg_lat_ms: caché+cascade lo deja en 305 ms, bajo el presupuesto de 800. Pero eso es el promedio; las búsquedas pesadas que llegan al strong model tardan más. El bloque final del código lo mide: una query pesada bloqueante tarda 1350 ms (con la salida original de 350 tokens) —viola el latency budget—, mientras que con streaming el primer token aparece a los 303 ms (OK). Así que para las búsquedas pesadas, el camino se completa con streaming: el usuario ve resultados apareciendo a los ~300 ms aunque la lista completa tarde más. (Alternativa que vimos arriba: recortar la salida a 120 tokens baja la pesada a 660 ms, que ya cabe bloqueante —dos formas de respetar el latency budget en la cola—.)
(d) La compuerta que este diseño NO verifica. El diseño respeta el cost budget y el latency budget —las dos restricciones de este módulo— pero no verifica la calidad: ¿el cheap model reordena tan bien como el strong? ¿la caché sirve resultados que siguen siendo relevantes? ¿pedir IDs en vez de prosa no degradó la respuesta? Esa tercera compuerta es el eval gate, y es todo el módulo 3 de esta guía. Una búsqueda semántica lista para producción pasa las tres: cabe en costo, cabe en latencia, y pasa el umbral de calidad. Este proyecto entrega las dos primeras.
Ejercicios
Estos ejercicios transfieren el método a otras decisiones de Mercado, para que confirmes que aprendiste a diseñar presupuestos y no a repetir una tabla.
Ejercicio 1 — El presupuesto que se revienta con el éxito. Tu búsqueda semántica cabe en $5,000/mes a 40,000 búsquedas/día con caché+cascade ($4,333/mes). Mercado crece y el tráfico se duplica a 80,000/día. Sin correr código, razona qué pasa con el veredicto del presupuesto y enumera tres formas de reaccionar.
Ver solución
Qué pasa: el costo mensual escala lineal con el volumen (el taxímetro de la lección 2), así que a 80,000/día el costo de caché+cascade se duplica —de $4,333 a ~$8,666/mes— y viola el presupuesto de $5,000. El veredicto se voltea con el crecimiento, exactamente como en el ejercicio 2 de la lección 7: una arquitectura que cabe hoy revienta cuando la feature se vuelve más popular. (Justo por eso elegiste caché+cascade y no la caché sola: la caché sola ya rozaba el límite a 40k/día, así que se habría salido con muchísimo menos crecimiento.)
Tres formas de reaccionar:
- Componer más técnicas. Subir el hit-rate de la caché (clave semántica en vez de exacta, TTL más largo donde el dato lo permita), recortar aún más la salida, o meter un tercer nivel de modelo (diminuto → pequeño → grande) para abaratar más el tráfico. Cada palanca extra da algo de margen.
- Renegociar el cost budget con el negocio. Si la feature al doble de volumen genera al doble de ventas, quizás merece más presupuesto. El presupuesto no es sagrado si quien conoce el margen lo revisa —pero eso es una decisión de negocio, no de ingeniería—.
- Aceptar un trade-off de calidad controlado. Mover más tráfico al cheap model (bajar el umbral del clasificador para que más búsquedas cuenten como "fáciles"), verificando con el eval gate que la relevancia no se cae demasiado. Abaratar a costa de un poco de calidad, medido.
La moraleja: el presupuesto y el volumen están atados, el volumen crece con el éxito, y por eso el diseño necesita headroom y un plan para cuando el headroom se agote —no basta con caber una vez—.
Ejercicio 2 — Otra feature, mismo método. Mercado quiere recomendaciones en la página de inicio: un LLM que, dado el historial del usuario, sugiere productos. Es de alto volumen (cada visita), pero —a diferencia de la búsqueda— la respuesta es personalizada por usuario. Aplica el método: ¿qué latency y cost budget propondrías, y —clave— qué le pasa a la caché cuando la respuesta es personalizada?
Ver solución
Presupuesto: las recomendaciones de la página de inicio están en el camino crítico de cada visita, así que un latency budget parecido al de la búsqueda (del orden de cientos de ms a ~1 s) tiene sentido —el usuario no debe esperar la home—. El cost budget lo fija el negocio según cuánto valen las ventas que las recomendaciones generan; a alto volumen (cada visita), el número importa mucho.
Qué le pasa a la caché —el punto del ejercicio: la caché funciona mucho peor cuando la respuesta es personalizada. En la búsqueda, "iphone" da la misma respuesta para todos, así que un hit sirve para muchos usuarios (hit-rate alto). En las recomendaciones, la respuesta para Ana (basada en su historial) no sirve para Beto —cada usuario tiene su propia respuesta—. Cachear por usuario tiene sentido solo si el mismo usuario vuelve seguido antes de que sus recomendaciones deban refrescarse, y aun así el hit-rate es mucho más bajo que en una búsqueda compartida. La personalización es enemiga de la caché.
Consecuencia para el diseño: como la caché rinde poco aquí, hay que apoyarse más en las otras palancas —cascade agresivo (la mayoría de las recomendaciones quizás las resuelve un modelo barato), async (¿de verdad hay que generar las recomendaciones en vivo en cada visita, o se pueden precalcular en segundo plano y servir de una tabla?), y recortar la salida—. De hecho, para recomendaciones, async/precálculo suele ser la palanca principal: en vez de llamar al LLM en el camino crítico de cada visita, se generan las recomendaciones de cada usuario en un job en segundo plano (cuando cambia su historial) y la home las lee de una tabla —moviendo el costoso trabajo de IA fuera del camino crítico por completo—. La lección: el perfil de la feature (compartida vs personalizada, un tiro vs precalculable) decide qué palancas rinden, y el método es el mismo —presupuestar, componer las técnicas que sí aplican, medir— aunque la mezcla cambie.
Ejercicio 3 — Defiende el naive (una vez). El diseño ingenuo —todo al strong model, sin caché ni cascade— violó el presupuesto por más de tres veces ($15,354 contra $5,000). Pero hay un contexto de Mercado donde el naive es la elección correcta. Encuéntralo y explica por qué, atándolo a las lecciones del módulo.
Ver solución
El contexto donde el naive gana: un prototipo de muy bajo volumen y muy corta vida. Imagina que Mercado quiere validar si la búsqueda semántica siquiera vale la pena, con un experimento de dos semanas para 50 usuarios internos. Volumen: quizás 200 búsquedas al día. A ese volumen, el naive (strong model para todo, ~$0.0128 por búsqueda del workload mixto) cuesta 0.0128 × 200 × 30 ≈ $77/mes —una nada—, y cabe de sobra en cualquier presupuesto razonable. Y la latencia de una búsqueda ocasional en un experimento interno no ahuyenta a nadie que ya sabe que es una prueba.
Por qué es correcto ahí, atado al módulo:
- El taxímetro (lección 2) depende del volumen. El costo que hace inviable al naive a 40,000/día ($15,354/mes) es trivial a 200/día (~$77/mes). La misma llamada cara es un problema a alto volumen y un no-problema a bajo volumen —el veredicto del presupuesto depende del volumen (lección 3)—.
- Componer tiene un costo de complejidad (lección 7). Montar caché, cascade, clasificador y streaming es trabajo real —piezas que construir, afinar y operar—. Para un prototipo de dos semanas que quizás se descarta, ese trabajo es sobre-ingeniería: gastas días optimizando algo que aún no sabes si vive. El naive te deja validar la idea hoy, con la mínima arquitectura, y solo si el experimento funciona y va a producción a volumen real, entonces sí compones las técnicas.
La lección, la misma de todo el módulo aplicada al revés: la arquitectura consciente del costo no es gratis, y solo se justifica cuando el presupuesto la exige. El naive no era "malo"; era prematuro optimizarlo. Diseñar bien no es aplicar todas las técnicas siempre —es aplicar las que el presupuesto y el volumen de ESTA feature necesitan, ni más ni menos—.
Resumen del módulo y hacia dónde sigues
Con este proyecto cierras el módulo 2, donde aprendiste a tratar la latencia y el costo de un LLM como restricciones de primera clase del diseño. Empezaste con la tesis y las tres analogías —el taxímetro (el costo que escala con cada llamada), el call center junior→senior (el cascade), la caja rápida (la caché) y la cocina que avisa (streaming/async)— (lección 1). Mediste las dos físicas nuevas: el LLM es lento (cientos de ms a segundos, y más con los tokens de salida) y cuesta por token, con el taxímetro que convierte $0.008/llamada en $25,200/mes a escala (lección 2). Las acotaste con un presupuesto —latency budget y cost budget—, y viste que "todo al caro" viola los dos (lección 3). Aprendiste las técnicas: el cascade (barato primero, 44% menos costo, pero el p95 no baja) (lección 4); la caché (no repagar, hit-rate = ahorro, exacta vs semántica) (lección 5); el async y streaming (latencia percibida, sacar el trabajo del camino crítico) (lección 6). Las compusiste en el camino de la petición y viste que se acumulan pero no suman, y que ninguna sola basta (lección 7). Y aquí, en el proyecto, lo hiciste todo tú sobre la búsqueda semántica: presupuestaste, compusiste caché+cascade (que cabe con holgura donde la caché sola apenas rozaba el límite), mediste contra el naive, viste la longitud de la salida como palanca extra de costo y latencia, y ubicaste el streaming y el eval gate.
La capacidad que te llevas: ante cualquier feature de IA, puedes fijarle un presupuesto de latencia y costo, estimar su taxímetro a volumen real, componer cascade + caché + streaming (y la longitud de la salida, y async) para meterla dentro del presupuesto, medir la combinación real en vez de sumar ahorros, y saber qué palancas rinden según el perfil de la feature —sin caer ni en "todo al modelo caro por si acaso" ni en "una sola técnica y ya"—. Y siempre con la frontera clara: esto es arquitectura (cómo rodeas al modelo), no optimización de inferencia (cómo corre el modelo por dentro), que es de AI Engineering/infra.
Hacia dónde sigues, dentro de esta guía:
- Módulo 3 — El eval como fitness function. Este módulo te dio dos de las tres compuertas de una feature de IA (costo y latencia); el módulo 3 te da la tercera: la calidad. ¿Cómo "pruebas" un componente probabilístico? Con un eval-set que funciona como compuerta —un cambio de prompt o de modelo que baja el score bloquea el deploy—. Es lo que verifica que el cascade y la caché de este módulo no abarataron a costa de respuestas malas. Las tres compuertas juntas —cost budget, latency budget, quality gate— son lo que hace segura una feature de IA.
Y hacia el resto del ecosistema: cada vez que este módulo simuló el LLM con un stub, se apoyó en que las piezas reales —RAG, agentes, embeddings, el modelo mismo— se construyen en el ecosistema de AI Engineering. Este módulo te enseñó a arquitectar esas piezas alrededor de un presupuesto; construirlas es el siguiente paso. Y el patrón de sacar el trabajo del camino crítico (async), aplicado aquí a la IA, se enseña a fondo en las guías de arquitectura dirigida por eventos y resiliencia del ecosistema. Ahora tienes el método para meter una feature de IA en un sistema real respetando su latencia y su costo; esas guías son las piezas sobre las que lo aplicas.
Recursos
- martinfowler.com — "Emerging Patterns in Building GenAI Applications", Bharani Subramaniam y Martin Fowler — el cierre natural del módulo: el catálogo de patrones de arquitectura para features con LLM (routing, caching, request path, streaming) tratados como un sistema que se compone; la referencia para llevar este método a features reales.
- Chip Huyen — AI Engineering (O'Reilly) — el libro de cabecera para el siguiente paso: construir las piezas (RAG, agentes, embeddings) que este módulo solo arquitectó, y profundizar en el diseño de sistemas de IA por costo, latencia y calidad.
- Anthropic — docs de Claude (models, pricing, prompt caching, streaming, batch processing) — el panorama de familias de modelos y las palancas reales (elegir modelo, cachear el prompt, streaming, procesar por lotes) que corresponden a las técnicas simuladas de este módulo; conceptual, sin fijar versión de modelo.