Skip to content

English · Español

02 — Systems Design para LLMs: 5 Prompts de Whiteboard

5 prompts de systems design para LLMs en producción. Cada uno con pizarra, matemáticas de capacidad (ley de Little, presupuesto de GPU), modos de fallo y disciplina de costes (CpQU de la Fase 38).

Cómo atacar un prompt de systems-design

  1. Aclara antes de dibujar. "10M DAU" — ¿cuál es el objetivo de latencia? ¿P50 o P99? ¿Streaming o batch? ¿Cuál es el presupuesto? "No sé" es una respuesta válida del entrevistador; fija supuestos y procede.
  2. Capacidad primero. Tokens/seg necesarios → conteo de GPUs → memoria necesaria → coste por request. La mayoría de candidatos se zambullen en diagramas K8s sin estas matemáticas; esa es la señal de fallo.
  3. Modos de fallo segundo. Enumera al menos 4: OOM de modelo, saturación de cola, hot-shard, partición de red, agotamiento de cuota. Los entrevistadores de labs adoran esto.
  4. Disciplina de coste al final. Elige el diseño más barato que cumpla el SLA. "Coste por unidad de calidad" (CpQU, Fase 38) es el encuadre.

Prompt 1 — Diseña un chatbot sirviendo 10M DAU

Preguntas de aclaración (haz estas en voz alta)

  • ¿DAU vs MAU? Asume 10M DAU.
  • ¿Promedio de conversaciones por usuario al día? Asume 5.
  • ¿Promedio de turnos por conversación? Asume 8.
  • ¿Promedio de tokens por turno? Input 200, output 300.
  • ¿SLA de latencia? P50 < 1s al primer token, P99 < 3s; respuesta completa < 15s.
  • ¿Tamaño del modelo? Asume 70B denso.

Matemáticas de capacidad

  • Turnos totales/día: 10M * 5 * 8 = 400M turnos/día.
  • QPS pico (asume 3x promedio para pico diario): 400M / 86400 * 3 ≈ 14k QPS.
  • Tokens por turno: 200 in + 300 out = 500 total. Los tokens de output dominan el coste (decode es secuencial, prefill es paralelo).
  • Tokens de output/seg totales en pico: 14k * 300 = 4.2M tokens out/seg.
  • Una sola H100 en 70B fp16 genera aproximadamente 30-50 tokens/seg single-stream; con continuous batching (vLLM, batch ~32 efectivo) obtienes 1000-2000 tokens/seg/GPU.
  • GPUs necesarias para decode: 4.2M / 1500 ≈ 2800 H100s. Redondea hacia arriba por margen → 3500 GPUs.

Pizarra

        Client                                    Region B (warm standby)
           |                                              ^
           v                                              |
   [Edge: TLS, auth, abuse]                   [Region failover, BGP/DNS]
           |
           v
   [Load balancer: L7, header-aware] -- routes by user_id sticky for KV-cache reuse
           |
           v
   [API gateway: rate-limit, billing meter]
           |
           v
   [Conversation service]
        |        \
        |         \--> [KV-cache reuse store: per-user warm prefix on Redis-tier]
        v
   [LLM inference fleet: vLLM, continuous batching, paged attention]
        |     |     |
       GPU   GPU   GPU  ... (sharded by model replica, ~250 replicas of TP=8 70B)
        |
        v
   [Streaming: SSE / WebSocket back to client]
   [Async sink: logs, prompt/response store, eval sampling]

Modos de fallo

  • OOM de GPU en prompt largo: mitiga con aplicación de max-context en el gateway; rechaza 422 antes de programar.
  • Hot shard (un usuario spammeando): rate-limit en gateway; backpressure; aislamiento de cola por tenant.
  • Cold start: mantén N+2 réplicas warm por región; pre-calienta KV cache para el top 1% de usuarios.
  • Saturación de cola: ley de Little — L = lambda * W. Si el request promedio toma 8s y tenemos 1000 slots in-flight, max QPS sostenido es 125 por réplica. Planifica con picos.
  • Tormentas de reintentos en cascada: backoff exponencial con jitter; circuit breaker en gateway.
  • NCCL deadlock durante inferencia tensor-parallel: watchdog + reinicio de réplica.

Disciplina de coste (CpQU)

  • 3500 H100s × \(2/hr × 24h × 30d = ~\)15M/mes a precios on-demand.
  • Palancas de optimización: (1) cuantizar a int8 / fp8 → 2x throughput, ~$7.5M/mes, pequeño hit de calidad; (2) modelo GQA / MQA → KV cache más pequeño → batches más grandes; (3) speculative decoding con un modelo draft → 2-3x throughput; (4) prompt caching (estilo Anthropic) → recicla cómputo de prefijo para usuarios warm.
  • Encuadre CpQU: mide calidad (e.g. tasa de preferencia vs referencia) por dólar; elige el diseño que maximiza calidad/dólar en el SLA.

→ Fase 33, Fase 34, drill 12.


Prompt 2 — Diseña un agente coding-assistant con tool use

Preguntas de aclaración

  • ¿Herramientas disponibles? Asume: lectura/escritura de filesystem, shell exec (sandboxed), búsqueda web, intérprete de código.
  • ¿Concurrencia por usuario? Asume 1 agente activo por usuario (sin sub-agentes paralelos en v1).
  • ¿Latencia? P50 < 30s end-to-end (tareas multi-paso); streaming visible.
  • ¿Seguridad? El sandbox debe contener shell exec; sin acceso de red arbitrario.

Matemáticas de capacidad

  • Cada turno de agente: 1-5 tool calls; cada tool call añade ~500 tokens de input (spec de herramienta + resultado) y 200 tokens de output.
  • Una tarea compleja: 10 turnos × 4 tool calls × 700 tokens = ~28k tokens de trabajo LLM por tarea.
  • Si una tarea toma 30s y ~28k tokens, eso es ~1000 tokens/seg/agente-activo — consistente con un solo stream decodificado.
  • Para 100k agentes activos concurrentes: 100k streams. Si una instancia vLLM maneja 32 streams concurrentes: ~3000 instancias vLLM necesarias en pico.

Pizarra

   Client (IDE)
      |
      v
   [Agent orchestrator]
      |
      v
   [Planner LLM]  <----+
      |               |  (loop: think -> act -> observe)
      v               |
   [Tool router]      |
   / | \              |
  fs shell web        |  [Trace store: every tool call, every model turn]
  |   |   |           |
  v   v   v           |
 [Sandbox VM per session: ephemeral, network-isolated, FS-jailed]
      |               |
      +---------------+

Modos de fallo

  • Loop infinito / runaway: tope duro de tool calls por tarea (e.g. 50); tope de tokens totales; tope de tiempo de pared.
  • Escape de sandbox: seccomp + user namespace + sin volumen host montado; gVisor o Firecracker.
  • Tool flakes (HTTP 503): reintenta con backoff; el agente debe observar el fallo y adaptarse — no reintentar para siempre.
  • Input adversarial de herramienta (prompt injection desde búsqueda web): nunca confíes en outputs de herramienta como instrucciones; marca procedencia; usa outputs estructurados.
  • Pico de coste de un solo usuario: presupuesto de tokens por usuario; alerta al 80%.

Disciplina de coste

  • La mayoría de tareas de agente están dominadas por contexto LLM repetido (system prompt + spec de herramienta + history crece cada turno).
  • Palanca: prompt caching — cachea el prefijo estático (system + tools); solo re-prefilea el sufijo dinámico. Anthropic y OpenAI ambos lo exponen.
  • Palanca: modelo "router" más pequeño para selección de herramienta; rutea al modelo grande solo para pasos "think".

→ Fase 31, Fase 32, Fase 37.


Prompt 3 — Diseña un servicio multi-tenant de ajuste fino

Preguntas de aclaración

  • ¿Modelos base? Asume 3 tamaños: 7B, 13B, 70B.
  • ¿Método de ajuste fino? Solo LoRA en v1 (barato, aislable).
  • ¿Escala de clientes? 10k clientes, promedio 100k ejemplos de entrenamiento cada uno.
  • ¿SLA en inicio de entrenamiento? < 5 min desde la sumisión del job.

Matemáticas de capacidad

  • Entrenamiento LoRA en modelo 7B con 100k ejemplos (batch 8, seq 2048, 3 épocas): aproximadamente 2 H100-horas.
  • LoRA 70B en 100k ejemplos: ~20 H100-horas.
  • Si 100 jobs/hora promedio sumidos, mezcla ponderada: ~200 H100-horas/hora → 200 H100s continuamente ocupadas.
  • Más flota de inferencia para servir los ajustes finos: ver prompt 1 con intercambio de adapter.

Pizarra

   Customer dashboard
        |
        v
   [API: dataset upload, job submit]
        |
        v
   [Object store: encrypted, per-tenant KMS key]
        |
        v
   [Job queue: priority by tier; per-tenant fairness]
        |
        v
   [Training scheduler]
        |
        v
   [Trainer pods: vLLM-trainer / nanotron / Axolotl]
        |          (LoRA adapter saved per tenant)
        v
   [Adapter store: tenant_id -> base_model -> adapter blob]
        |
        v
   [Inference fleet: vLLM + multi-LoRA serving (load N adapters on one base)]
        |
        v
   Customer hits inference endpoint with model_id = (base, adapter_id)

Modos de fallo

  • Contaminación de data entre tenants: aislamiento estricto; KMS por tenant; audit logging.
  • Data mala → entrenamiento divergente: valida antes de programar; eleva NaN-loss al cliente con un error útil.
  • Hot-loading de adapter en inferencia: vLLM multi-LoRA puede servir cientos de adapters en un base; tope y desalojo LRU.
  • Agotamiento de recursos (un tenant monopoliza la cola): cuota por tenant; scheduler weighted-fair-queue.

Disciplina de coste

  • LoRA en 7B es ~$10 de cómputo; precio a $50 → margen 5x. 70B es $200 → precio a $500.
  • Usa instancias spot para jobs de entrenamiento que puedan hacer checkpoint barato (LoRA: sí, los checkpoints son diminutos).

→ Fase 28, Fase 38.


Prompt 4 — Diseña un servicio de inferencia de baja latencia para completado de código (estilo Copilot)

Preguntas de aclaración

  • ¿P99 latencia? < 200ms al primer carácter (esta es la barra real de Copilot).
  • ¿Tamaño del modelo? Asume modelo de código especializado 7B.
  • ¿Longitud promedio de sugerencia? 30 tokens (las sugerencias son cortas).
  • ¿Tasa de cancelación? ~70% — los usuarios siguen escribiendo y cancelan.

Matemáticas de capacidad

  • 30 tokens de output × ~30ms/token (single-stream H100, 7B) = 900ms — demasiado lento.
  • Necesario: gran batching para compartir overhead de lanzamiento de kernel, y speculative decoding para baja latencia single-stream.
  • Con speculative decoding (modelo draft 1B, target 7B, tasa de aceptación 0.7), tokens/seg/stream efectivos ~120 → 30 tokens en 250ms. Más ajustado con continuous batching.
  • La cancelación mata el 70% de decodes a mitad de vuelo — preempt agresivamente; no desperdicies cómputo en streams cancelados.

Pizarra

   IDE plugin -- debounces keystrokes (150ms)
      |
      v
   [Edge gateway: cancellation-aware]
      |
      v
   [Inference fleet: vLLM with speculative decoding]
        |
        v
   [Result streamed token-by-token; client cancels on next keystroke]
        |
        +--> [Cancellation propagates to scheduler immediately; abort decode]

Modos de fallo

  • Race de cancelación: un nuevo keystroke llega mientras un request viejo está a mitad de vuelo; cancellation token; cliente idempotente.
  • Contaminación de cache: mismo prefijo escrito por muchos usuarios — comparte KV cache entre usuarios si y solo si el prompt no contiene PII (gate de seguridad).
  • Regresión de calidad tras actualización de modelo: shadow traffic; A/B con eval offline en repos internos.
  • Privacidad: sin logging de código de usuario por default; opt-in para data de entrenamiento.

Disciplina de coste

  • El batching agresivo reduce $/token 10x al coste de varianza de latencia.
  • Speculative decoding es una ganancia neta en $/token y latencia para código (alta tasa de aceptación en contextos sintácticos).
  • Destilación de modelo: un modelo 1B + speculative puede vencer a un modelo 7B en coste-por-aceptación.

→ Fase 22, Fase 27, Fase 33.


Prompt 5 — Diseña un harness de evaluación para un release de modelo frontera

Preguntas de aclaración

  • ¿Qué tipo de release? Bump de versión mayor; suite completa de eval.
  • ¿Cuántas evals? 100+ benchmarks más red-team interno.
  • ¿Presupuesto de cómputo? 10k GPU-horas.
  • ¿SLA de turnaround? 24 horas desde modelo candidato a reporte go/no-go.

Matemáticas de capacidad

  • Tamaño del eval set: 100k prompts entre benchmarks.
  • Output promedio: 500 tokens (algunos long-form, algunos cortos).
  • 100k prompts × 500 tokens = 50M tokens de output a 1000 tokens/seg/GPU → 50k GPU-segundos → 14 GPU-horas por pase de eval.
  • Más 100x para ablations y semillas → 1400 GPU-horas por suite de eval. Cabe en el presupuesto.
  • LLM-as-judge para pares: 100k pares × 2 calls (intercambio posicional) × ~1k tokens = 200M tokens de juez. Usa API de Claude / GPT-4 o modelo juez interno.

Pizarra

   [Model candidate registry]
        |
        v
   [Eval orchestrator: forks one job per benchmark]
        |
        +--> Capabilities (MMLU, HumanEval, MATH, GPQA, ...)
        +--> Safety (red-team prompts, refusal calibration)
        +--> Alignment (constitutional adherence, sycophancy)
        +--> Robustness (paraphrases, adversarial suffixes)
        |
        v
   [Result aggregator]
        |
        v
   [Report generator: html + JSON + dashboards]
        |
        v
   [Human reviewer: go / no-go meeting]

Modos de fallo

  • Fuga del eval set: mantén el eval set privado air-gapped; rota trimestralmente.
  • Sesgo de juez LLM: position bias (intercambia), verbosity bias (normaliza longitud), self-preference (usa un modelo juez diferente).
  • Evals flaky: tamaño de muestra suficientemente grande para que el 95% CI excluya el score del release previo si pretendes reclamar una regresión.
  • Goodhart en benchmarks: nunca entrenes en el eval set; spot-check overlap con el corpus de entrenamiento; pre-registra la métrica "primaria" antes de ejecutar.

Disciplina de coste

  • Evals baratas primero (perplejidad en held-out, benchmarks pequeños): mata candidatos malos temprano.
  • Evals caras (red-team, juez long-form) solo en candidatos que pasen los gates baratos.
  • Reutiliza generaciones: juzga múltiples criterios desde una sola generación.

→ Fase 20, Fase 37.


Qué busca un entrevistador

Comportamiento Señal
Pregunta cuestiones de aclaración antes de dibujar + senior
Matemáticas de capacidad en una servilleta + ha visto producción
Nombra un modo de fallo específico sin prompting + experimentado
Habla de coste no solo factibilidad + listo para un rol real
Dibuja un diagrama de 50 cajas sin números - superficial
Dice "usaríamos Kubernetes" sin contexto - cargo-cult
Nunca menciona modos de fallo - nunca ha ejecutado nada

→ Siguiente: 03-paper-read-drill.md