Creo que el futuro del AI coding no pasa solamente por agentes cada vez más grandes a los que les pedís todo, sino por darles mejores herramientas para organizar cómo se reparte y se coordina el trabajo. En tareas chicas y bien acotadas, los agentes ya muestran muy buen desempeño; el problema aparece cuando la feature crece y las partes empiezan a depender entre sí.
Para mi trabajo de tesis de Ingeniería en Sistemas estoy desarrollando un sistema con esa idea, descomponer una tarea compleja de software en un DAG de subtareas con dependencias, coordinar varios agentes en paralelo sobre las que son independientes, ejecutarlas de forma aisladas para que no se pisen e integrar todo de abajo hacia arriba dejando trazas de cada paso.
Lo que me interesa principalmente no es que funcione para desarrollo real, sino el poder compararlo contra un agente monolítico con el mismo modelo y entender el trade-off de granularidad, descomponer poco deja poco paralelismo, descomponer demasiado multiplica las costuras y los conflictos.
En algún punto hay un óptimo, y medir cuánto completa cada enfoque y cuánta intervención humana necesita es parte de la tesis.
Si quieren ver más, pásense por el repo. Me encantaría leer qué opinan del tema, y si alguien quiere sumarse a colaborar, bienvenido 🙌
Repo👇
https://t.co/DC3BWqM51I
SYSTEM DESIGN INTERVIEW
CAPÍTULO 3
UN FRAMEWORK PARA ENTREVISTAS DE DISEÑO DE SISTEMAS
Este capítulo sigue bastante bien al anterior, porque si el capítulo 2 era sobre hacer estimaciones rápidas para no diseñar a ciegas, este va más hacia cómo ordenar la cabeza cuando te tiran un problema abierto en una entrevista de system design.
Y me gustó porque toca algo que creo que a muchos nos pasa cuando estamos aprendiendo estos temas. Escuchás “diseñá Twitter”, “diseñá YouTube” o “diseñá un news feed” y la primera reacción es querer empezar a tirar componentes. Load balancer, cache, database, CDN, queues, replication, lo que sea. Como si demostrar que conocés piezas del sistema fuera lo mismo que diseñar bien.
Pero el capítulo baja bastante esa idea. Una entrevista de system design no parece estar pensada para ver si te sabés una arquitectura de memoria, sino para ver cómo pensás cuando el problema todavía está medio borroso. Cómo preguntás, cómo acotás el scope, cómo manejás supuestos, cómo explicás trade-offs y cómo trabajás con el interviewer mientras el diseño va tomando forma.
La parte que más me quedó es que antes de dibujar cualquier arquitectura tenés que entender qué problema estás resolviendo. Qué features entran, cuáles quedan afuera, cuántos usuarios hay, qué escala se espera, qué cosas importan más para el producto y qué estás asumiendo porque todavía no lo sabés. Parece menor, pero si salteás eso podés terminar diseñando algo muy prolijo para un problema que nadie pidió.
Después recién aparece el high-level design. No como un diagrama perfecto, sino como una primera versión para conversar. Dibujar los bloques principales, explicar por qué están ahí y validar si el rumbo tiene sentido. Me parece interesante esa idea de no pensar la entrevista como “yo contra el entrevistador”, sino más como una conversación técnica donde vas mostrando cómo razonás y vas ajustando con feedback.
Más adelante viene el deep dive, pero tampoco significa meterse en todos los detalles posibles. Ahí el capítulo me hizo ver algo importante, profundizar también es elegir. En un URL shortener quizás tiene sentido hablar más de cómo generar la short URL, collisions o read/write ratio. En un chat quizás importa más latency, presencia online/offline o conexiones persistentes. Meterse en detalles solo por demostrar conocimiento puede jugar en contra si no son los detalles que realmente mueven el diseño.
Y el cierre no es simplemente decir “listo, esta es la arquitectura”. También sirve para mostrar criterio hablando de bottlenecks, failure cases, monitoreo, logs, rollout, qué pasaría si la escala crece 10x y qué cosas mejorarías con más tiempo. Eso me pareció bastante realista, porque en ingeniería casi nunca hay un diseño final perfecto. Hay decisiones, límites y trade-offs que tenés que poder explicar.
Creo que lo que más me llevo del capítulo es esta idea de que preguntar bien también es parte de diseñar. A veces uno quiere demostrar conocimiento yendo rápido al diagrama, pero un buen diseño empieza antes, cuando todavía estás tratando de entender qué sistema tiene sentido construir.
Dejo una foto con la hoja de apuntes que armé para resumir este framework.
CHAPTER 2: BACK-OF-THE-ENVELOPE ESTIMATION
Este capítulo fue súper corto, pero sirve para entender cómo se suelen hacer estimaciones rápidas y a alto nivel. La idea es enseñarte a hacer cuentas aproximadas para ver si lo que estás diseñando tiene sentido en escala, aunque todavía no tengas todos los datos exactos.
Te muestra la forma de pensar para hacer estas estimaciones, aclarando que no hace falta hacer matemática perfecta, sino asumir ciertos números, redondear bastante, cuidar bien las unidades y tratar de llegar a un orden de magnitud razonable. Con eso podés estimar cosas como QPS, peak QPS, storage, cache o hasta cuánto downtime implica cierto nivel de availability. Básicamente, un ayudín para no diseñar a ciegas.
También te recuerda algunas intuiciones básicas sobre los tiempos y tamaños que implican ciertas cosas en sistemas. Por ejemplo, que leer desde memoria es muy rápido, el disco es mucho más lento y enviar datos entre regiones tiene un costo bastante mayor. Lo mismo pasa con las unidades de tamaño, no es lo mismo hablar de MB, GB, TB o PB cuando estimás storage para años. Parecen detalles, pero si te equivocás por varios órdenes de magnitud, probablemente la arquitectura que propongas también arranque mal.
Para dar una idea, el capítulo cierra con un ejemplo donde estima QPS y storage para Twitter, usando números solo para el ejercicio. Dejo una imagen con esas cuentas resumidas.
CHAPTER 2: BACK-OF-THE-ENVELOPE ESTIMATION
Este capítulo fue súper corto, pero sirve para entender cómo se suelen hacer estimaciones rápidas y a alto nivel. La idea es enseñarte a hacer cuentas aproximadas para ver si lo que estás diseñando tiene sentido en escala, aunque todavía no tengas todos los datos exactos.
Te muestra la forma de pensar para hacer estas estimaciones, aclarando que no hace falta hacer matemática perfecta, sino asumir ciertos números, redondear bastante, cuidar bien las unidades y tratar de llegar a un orden de magnitud razonable. Con eso podés estimar cosas como QPS, peak QPS, storage, cache o hasta cuánto downtime implica cierto nivel de availability. Básicamente, un ayudín para no diseñar a ciegas.
También te recuerda algunas intuiciones básicas sobre los tiempos y tamaños que implican ciertas cosas en sistemas. Por ejemplo, que leer desde memoria es muy rápido, el disco es mucho más lento y enviar datos entre regiones tiene un costo bastante mayor. Lo mismo pasa con las unidades de tamaño, no es lo mismo hablar de MB, GB, TB o PB cuando estimás storage para años. Parecen detalles, pero si te equivocás por varios órdenes de magnitud, probablemente la arquitectura que propongas también arranque mal.
Para dar una idea, el capítulo cierra con un ejemplo donde estima QPS y storage para Twitter, usando números solo para el ejercicio. Dejo una imagen con esas cuentas resumidas.
CHAPTER 1: SCALE FROM ZERO TO MILLIONS OF USERS
Lo que más me gustó es que no plantea la arquitectura de un sistema como algo que nace enorme desde el día uno, sino que arranca con lo más simple, una app y una base de datos en un solo servidor. Eso puede estar perfecto al principio, porque te permite construir rápido y validar.
El problema aparece cuando empieza a crecer el tráfico, la carga en la base de datos o la cantidad de usuarios concurrentes.
Ahí empiezan los cambios, como separar el web tier del data tier, pensar en escalado vertical vs horizontal, sumar un load balancer y replicar la base de datos.
De aca extraigo la primera clave, escalar no es “meter infraestructura porque sí”. Es ir entendiendo dónde está el cuello de botella y separar responsabilidades cuando el sistema lo empieza a pedir.
Banco el análisis, pero no termino de coincidir del todo. Me parece que este caso hay que mirarlo como si fuera un análisis amortizado.
No es que River descubre una pérdida de USD 30M hoy, está blanqueando pérdidas que ya se venían pagando en cuotas, con contratos caros, activos devaluados y un pésimo rendimiento deportivo.
Lo grave no es la decisión puntual que se está tomando, que desde mi punto de vista es bastante correcta, sino la acumulación de tantas malas decisiones juntas en los últimos años.
@q_yeon_gyu_kim@OpenAI@justsisyphus how do you keep subagents from stepping on each other’s changes? worktrees? i tried that but it never felt smooth for me
Ya cuando el sistema sigue creciendo, empiezan a aparecer problemas más grandes.
Por ejemplo, múltiples data centers. Con GeoDNS podés mandar al usuario al data center más cercano o hacer failover si uno cae. Suena muy bien, pero también trae complejidad como la sincronización de datos, la consistencia, la latencia entre regiones y la operación que se vuelve más difícil.
También aparece algo que muchas veces se subestima como es la parte operativa. Logging, métricas, monitoreo y automatización dejan de ser “extras” y pasan a ser parte central del sistema. Si no podés medir qué pasa, es muy difícil saber qué escalar o qué está fallando.
Y finalmente está el sharding, que básicamente es partir la data en varios shards cuando una sola base de datos ya no alcanza. Eso ayuda a escalar, pero complica cosas como joins, queries y distribución pareja de datos.
Entonces, como resumen: escalar un sistema es un proceso iterativo.
Empezás simple, medís, encontrás el cuello de botella y vas evolucionando la arquitectura paso a paso.
Al final, diseñar sistemas termina siendo aprender a tomar trade-offs.
Voy a empezar a usar este hilo para ir compartiendo lo que voy aprendiendo mientras leo System Design Interview, de Alex Xu.
Libro recomendadísimo sobre diseño de sistemas, un tema que aparece bastante en entrevistas para roles backend/software y que muchas veces no se ve tan en profundidad en la universidad (aunque se hace bastante llevadero agarrarlo ahora teniendo ciertas bases).
Por eso a modo de obligarme a terminar el libro e ir compartiendo un poco lo que uno sabe y hace (algo que considero clave hoy en dia), voy a empezar este hilo compartiendo un poco sobre lo que fui aprendiendo despues de leer cada capitulo, junto con las notas que fui tomando (despues de una pasada de IA para no hacerlos sufrir)
Espero que les guste y a alguno le sirva para aprender algo nuevo o motivarse a buscar mas data sobre esto
Arranco con el primer capitulo👇
La parte de performance y arquitectura stateless explica como se conectan varias piezas que antes se veían como cosas separadas.
Por ejemplo, si los web servers no guardan estado, las sesiones o datos compartidos tienen que vivir fuera del web server, por ejemplo en un session store, Redis, una DB o algún shared storage, y esto hace que no importe qué servidor atienda el request.
Después aparece el cache, que sirve para evitar ir a la base de datos cada vez que pedimos información repetida. Si hay cache hit, respondés más rápido. Si hay cache miss, vas a la DB, traés el dato y, dependiendo de la estrategia, podés guardarlo en cache para próximos requests.
Para archivos estáticos como imágenes, CSS o JS, existen las CDN (Content Delivery Network), que acercan esos assets al usuario y reduce carga sobre los servidores.
Y para tareas lentas como mandar emails, procesar imágenes o generar reportes, aparecen las message queues y los workers. En vez de hacer todo dentro del request principal, dejás el trabajo pesado en background.
Me gustó porque cambia la forma de pensar, escalar no es solo agregar máquinas, sino que tambien es sacarle presión del flujo principal.
@nicolas_random_@Dj_Emma_@MartinDMarco39@NikoFer78@eudtoxic De nuevo... si en 2014 compró, y lo demuestra dando la wallet, y en 2020/21/22/2x.. esa wallet se usó para meter/sacar tokens de un exchange con KYC, de forma cotidiana, y esa cuenta esta a nombre de Pepito y no de MAdorni, esta hasta las manos