En pocas palabras: Un DSL le da al LLM un vocabulario acotado del dominio para que componga adentro de esos límites en vez de inventar estructura. Unmesh Gundecha, Distinguished Engineer de Thoughtworks, lo documentó en martinfowler.com con Tickloom, un DSL para sistemas distribuidos que funciona como arnés de generación y como interfaz de uso.
Un DSL (lenguaje específico de dominio) es el “arnés” que le falta a los LLMs para generar código confiable: en vez de pedirle a un modelo que escriba software desde una descripción en lenguaje natural, le das un vocabulario acotado del dominio y lo dejás componer adentro de esos límites. Unmesh Gundecha, Distinguished Engineer de Thoughtworks, lo documentó en martinfowler.com con Tickloom, un DSL para sistemas distribuidos.
Los DSLs para LLMs confiables son lenguajes específicos de dominio (Domain-Specific Languages) que definen un vocabulario acotado y un modelo semántico de un problema puntual, para que un modelo de lenguaje genere código dentro de esos límites en vez de inventar estructura desde cero. Según el artículo de Unmesh Gundecha publicado en el sitio de Martin Fowler, el DSL cumple dos roles: es el arnés que guía la generación y es la interfaz de lenguaje natural con la que después usás el sistema.
En 30 segundos
- El problema no es la velocidad, es la precisión. Los LLMs generan sistemas enteros desde una descripción de alto nivel, pero eso asume que la intención está articulada con palabras que el modelo pueda mapear a bloques de código. Casi nunca lo está.
- El DSL es el arnés. Las abstracciones y los lenguajes específicos de dominio le dan límites claros al modelo desde el arranque, según el artículo de Unmesh Gundecha en martinfowler.com.
- No se especifica upfront: se descubre implementando. El diseño aparece durante la implementación, y el LLM es partner de esa construcción iterativa, no ejecutor de un spec cerrado.
- Tickloom es el caso concreto: un modelo de dominio y DSL para ilustrar comportamiento de sistemas distribuidos, escrito por Gundecha, autor de Patterns of Distributed Systems.
- El DSL termina siendo la fuente de verdad del sistema, por encima de la documentación y del prompt.
¿Por qué los LLMs generan código impredecible sin límites claros?
Porque el modelo tiene que adivinar la estructura además del contenido. Gundecha lo plantea así: los LLMs modernos pueden generar grandes cantidades de código, y a veces sistemas completos, a partir de una descripción de alto nivel en lenguaje natural. El supuesto escondido es que la “intención” de lo que hay que construir está bien articulada, con palabras precisas que el modelo pueda mapear a bloques de código. Ese supuesto es el que se rompe.
Ponele que le pedís a un modelo “escribime un test que verifique que el cluster mantiene consistencia cuando cae un nodo”. ¿Qué es un nodo acá? ¿Qué es caer, un proceso muerto o una partición de red? ¿Consistencia lineal o eventual? El modelo va a elegir una interpretación, va a inventar las clases que necesita, y te va a devolver algo que compila y que no significa nada de lo que vos querías.
Y ahí está el punto que a mí me parece el más honesto del artículo: el problema no es que el modelo escriba mal. Escribe bárbaro. El problema es que escribe exactamente lo que le pediste, y lo que le pediste era ambiguo.
¿Qué es un DSL y cómo actúa como arnés para un modelo de lenguaje?

Un DSL (Domain-Specific Language, lenguaje específico de dominio) es un lenguaje diseñado para expresar un problema puntual con el vocabulario de ese problema, en vez de con las primitivas genéricas de un lenguaje de propósito general. SQL es un DSL para consultas. Un DSL de tests de sistemas distribuidos habla de nodos, particiones y quorums, no de threads y sockets. Aplicado a LLMs, Gundecha lo describe como un arnés fuerte que guía al modelo desde el arranque.
La mecánica es directa: si el modelo solo puede componer con las piezas del DSL, el espacio de cosas que puede generar mal se achica muchísimo. No es que el modelo se vuelva más inteligente. Es que tiene menos lugar donde equivocarse. Ya lo cubrimos antes en fundamentos de modelos de lenguaje.
- Vocabulario acotado. El modelo no elige nombres ni inventa conceptos: usa los del dominio, que ya existen y ya significan algo.
- Límites explícitos. Lo que el DSL no expresa, el modelo no lo genera. Eso es una feature, no una limitación.
- Verificable. Un programa en el DSL se puede parsear y validar antes de ejecutar nada. El error aparece al escribir, no en producción.
- Legible por un humano. Podés revisar 20 líneas de DSL. No podés revisar 2.000 de código generado, y seamos honestos, no lo hacés.
¿Alcanza con abstracciones buenas, sin llegar a un DSL?
Sí, en buena medida. El artículo dedica una sección específica a esto (“Even good abstractions help — without a DSL”): un modelo de dominio con abstracciones claras ya mejora lo que el LLM genera, aunque nunca escribas una gramática ni un parser. El DSL es el escalón siguiente, no el precio de entrada.
Esto me parece la parte más útil para alguien que arranca. No necesitás construir un lenguaje. Necesitás nombrar bien las cosas de tu dominio y darle esas piezas al modelo.
¿Se diseña el DSL entero antes de empezar o se descubre implementando?
Se descubre implementando. Gundecha titula la sección “The Limits of Upfront Specification” y la que sigue “Design Is Discovered Through Implementation”, y esa secuencia es la tesis: no podés escribir el spec completo del DSL antes de usarlo, porque recién al implementar casos reales aparecen los conceptos que faltaban. El LLM entra como partner de esa construcción incremental, no como ejecutor de una especificación rígida.
Para quien viene de la ola “escribí un spec largo y que el agente lo implemente”, esto es un cachetazo útil. La especificación upfront tiene límites que no desaparecen porque ahora el que codea sea un modelo. Escribís un caso, ves qué te falta expresar, agregás la primitiva, reescribís el caso más corto, y así.
¿Y el LLM dónde ayuda acá? En las dos puntas. Te sugiere primitivas mirando los casos que ya escribiste, y después escribe el código en el DSL que acabás de definir.
¿Qué es Tickloom y cómo funciona su modelo semántico?
Tickloom es un modelo de dominio y DSL para ilustrar el comportamiento de sistemas distribuidos, creado por Unmesh Gundecha, Distinguished Engineer de Thoughtworks radicado en Pune, India, y autor del libro Patterns of Distributed Systems. Es el ejemplo central del artículo y muestra los dos usos del LLM: como partner para construir el DSL de forma iterativa, y como interfaz de lenguaje natural para después usarlo. Cubrimos ese tema en detalle en limitaciones y comportamiento de Claude.
Esa dualidad es lo interesante. El DSL no es solamente un formato de entrada: es el punto donde la conversación en lenguaje natural aterriza en algo verificable. Vos escribís “quiero ver qué pasa si el líder se particiona durante una escritura”, el modelo lo traduce a construcciones del DSL, y ahí ya tenés un artefacto que se puede leer, versionar, revisar en un pull request y ejecutar. Si la traducción está mal, lo ves en el DSL, no en un stack trace tres semanas después.
El dominio elegido no es casual. Sistemas distribuidos es exactamente el tipo de problema donde los escenarios son combinatorios, repetitivos en estructura y distintos en detalle. Ahí un DSL rinde.
¿Qué otros casos de uso menciona el artículo?
Gundecha incluye un segundo ejemplo bastante distinto: usar LLMs para generar presentaciones de PowerPoint ricas en diagramas. Mismo patrón, dominio opuesto. Y un tercero: construir un DSL para testear escenarios de sistemas distribuidos, que es donde Tickloom se aplica de lleno.
El hilo común entre generar slides con diagramas y testear consenso distribuido es que en los dos casos hay una estructura repetida con contenido variable. Ese es el olfato que te tiene que saltar.
¿En qué se diferencia un DSL del prompt engineering y del fine-tuning?
El DSL cambia el artefacto que el modelo produce; el prompt engineering y el fine-tuning cambian cómo el modelo se comporta. Un prompt mejor te sube la probabilidad de una buena salida sin garantizar nada verificable. El DSL te da una salida que se parsea: o es válida en el lenguaje o no lo es, y eso lo decide un parser, no tu paciencia leyendo el diff.
- Prompt engineering: ajustás las instrucciones. Barato, inmediato, y frágil, porque el mismo prompt con otro modelo o otra versión te da otra cosa.
- Fine-tuning: ajustás los pesos. Caro, lento, y te ata a un modelo puntual. Cuando sale el siguiente, volvés a empezar.
- DSL: ajustás el espacio de salidas posibles. La inversión queda en tu repo, no en el proveedor, y sobrevive al cambio de modelo.
Ojo con leer esto como una competencia. Son capas: seguís necesitando un prompt decente para que el modelo use bien tu DSL. Lo que cambia es dónde ponés la garantía. Sobre eso hablamos en cómo mejora la confiabilidad de ChatGPT.
¿Por qué el DSL debería ser la fuente de verdad del sistema?
Porque es el único artefacto que expresa la intención y se ejecuta al mismo tiempo. Gundecha cierra el artículo con esta idea: un DSL así puede ser la fuente de verdad clave de los sistemas de software en el mundo de los LLMs. La documentación se desactualiza. Los prompts se pierden en un historial de chat. El código generado es demasiado largo para que alguien lo lea entero. El programa en el DSL no tiene esos problemas: si cambia, el sistema cambia.
Pensalo al revés. Hoy, en un proyecto donde el código lo escribe mayormente un modelo, ¿cuál es el artefacto que realmente revisás? Si la respuesta es “el diff, cuando tengo tiempo”, tenés un problema de escala que no se arregla contratando más revisores.
Con el DSL como fuente de verdad, el código generado pasa a ser un artefacto derivado, y eso cambia la conversación entera: regenerás cuando sale un modelo mejor, versionás lo que importa, revisás 30 líneas que un humano entiende en dos minutos, y dejás de tratar 5.000 líneas de output como si fueran patrimonio del equipo cuando en realidad son un subproducto reemplazable.
¿Cuándo conviene invertir en un DSL y cuándo no?
Conviene cuando el dominio es complejo, repetitivo en estructura, y lo vas a recorrer muchas veces: escenarios de sistemas distribuidos, generación de diagramas y presentaciones, pipelines de datos. No conviene en un prototipo de una sola pasada, donde el costo de construir el lenguaje se come el beneficio antes de que llegues a usarlo dos veces.
Mi regla práctica, y esto es criterio mío, no del artículo: si vas a expresar el mismo tipo de cosa más de veinte veces con variaciones, empezá por las abstracciones. Si esas abstracciones se estabilizan y siguen apareciendo, ahí formalizás el DSL. Al revés no funciona.
Y si estás corriendo esto sobre infra propia (agentes que generan y ejecutan código necesitan un lugar donde vivir), el DSL además te acota qué se ejecuta, que en un VPS de donweb.com es una diferencia bastante concreta entre dormir tranquilo o no.
Errores comunes al construir un DSL para LLMs
- Diseñar el lenguaje completo antes de escribir un caso real. Es contra lo que advierte el artículo de forma explícita. El diseño se descubre implementando. Corrección: escribí tres casos a mano, feos, y mirá qué se repite.
- Hacer el DSL tan expresivo que vuelve a ser un lenguaje general. Si le agregás loops, condicionales y variables arbitrarias, felicitaciones, escribiste Python de nuevo y perdiste los límites que eran el punto.
- Confundir el DSL con un formato de salida. Pedirle JSON estructurado a un modelo no es un DSL: es serialización. El DSL trae el modelo semántico del dominio adentro, y eso es lo que restringe.
- Tratar el código generado como fuente de verdad. Si editás a mano el output en vez de mejorar el DSL, en dos semanas tenés dos verdades que se contradicen y ninguna documentada.
- Saltear el modelo semántico. El artículo tiene una sección entera sobre construirlo (“Building the Semantic Model”). Sin eso, tenés sintaxis linda arriba de nada.
Preguntas Frecuentes
¿Qué es un DSL para LLMs?
Un DSL para LLMs es un lenguaje específico de dominio que define el vocabulario y el modelo semántico de un problema puntual, para que un modelo de lenguaje genere código dentro de esos límites. Según Unmesh Gundecha en martinfowler.com, funciona como arnés que guía al LLM desde el arranque y como interfaz de lenguaje natural para usar el sistema. Complementá con arquitectura y capacidades de GPT.
¿Cómo hago más confiable la generación de código con un LLM?
Dándole límites claros en vez de instrucciones más largas. Las abstracciones de dominio ya mejoran el resultado sin necesidad de un DSL formal, y el DSL es el paso siguiente cuando el patrón se repite. La clave es que la salida del modelo sea verificable por un parser, no revisable a ojo.
¿Qué es Tickloom?
Tickloom es un modelo de dominio y DSL para ilustrar el comportamiento de sistemas distribuidos, creado por Unmesh Gundecha, Distinguished Engineer de Thoughtworks y autor de Patterns of Distributed Systems. Es el ejemplo central del artículo publicado en el sitio de Martin Fowler sobre DSLs y LLMs.
¿Un DSL reemplaza al prompt engineering?
No, son capas distintas. El prompt engineering ajusta cómo le pedís las cosas al modelo; el DSL acota qué puede producir. Seguís necesitando un prompt razonable para que el modelo use bien el DSL, pero la garantía de validez la da el lenguaje, no la instrucción.
¿Cuándo no vale la pena construir un DSL?
En prototipos de una sola pasada y en dominios que vas a tocar una o dos veces. El costo de descubrir el lenguaje solo se amortiza si vas a expresar el mismo tipo de escenario muchas veces con variaciones. Para todo lo demás, empezá por abstracciones claras: según el artículo, eso solo ya ayuda.
Conclusión
Lo que cambia acá no es una herramienta: es dónde ponés el esfuerzo de diseño. Durante dos años la industria empujó prompts cada vez más largos y specs cada vez más detallados, apostando a que si describías bien el problema el modelo lo resolvía. Gundecha argumenta lo contrario: la especificación upfront tiene límites, el diseño aparece implementando, y lo que hay que construir no es un prompt mejor sino un vocabulario acotado del dominio.
Qué hacer con esto, concreto. Mirá el lugar de tu sistema donde el modelo genera lo mismo con variaciones y nombralo bien: entidades, operaciones, restricciones. Eso es el modelo semántico, y ya te sirve sin escribir un parser. Si el patrón se sostiene, formalizalo. Y a partir de ahí, tratá al DSL como la fuente de verdad y al código generado como lo que es, un derivado que regenerás cuando salga el próximo modelo.
La apuesta de fondo del artículo es fuerte y todavía no está probada a escala: que el DSL sea el artefacto central del software en la era de los LLMs. Habría que ver cómo aguanta en dominios menos estructurados que sistemas distribuidos. Pero la parte barata, nombrar bien tu dominio antes de pedirle código a un modelo, la podés hacer esta semana.
Fuentes
- DSLs Enable Reliable Use of LLMs – Unmesh Gundecha (Thoughtworks) en martinfowler.com: el artículo original con el caso Tickloom y el modelo semántico
- Domain-Specific Languages – Martin Fowler: la definición canónica de DSL y la distinción entre internos y externos
- DomainSpecificLanguage – bliki de Martin Fowler: qué cuenta como DSL y qué no
- Thoughtworks: la consultora donde Unmesh Gundecha es Distinguished Engineer
