El chat siempre responde, y ese es el problema

Poner un chat delante del warehouse parece el último paso que faltaba. Cualquiera pregunta en su idioma, el modelo escribe el SQL, y por fin se acaba la cola de peticiones al equipo de datos.

Y entonces alguien pregunta cuántos clientes activos hubo el trimestre pasado, recibe un número, y lo lleva a una reunión. Nadie sabe qué contó ese número como cliente, ni como activo, ni si excluyó las cuentas de prueba.

La capa conversacional no falla en el lenguaje. Falla en el significado.

El fallo no se ve como error, se ve como una cifra

Un sistema que no entiende una pregunta puede hacer dos cosas: negarse, o responder algo. Un modelo de lenguaje casi siempre hace lo segundo, y lo hace con una prosa impecable.

dbt Labs lo formula así: con text-to-SQL, el fallo tiene la forma de una respuesta plausible pero incorrecta; con una capa declarada, tiene la forma de un mensaje de error.

Es una distinción útil, y conviene saber de quién viene: dbt Labs vende esa capa, y la página que la formula es su propio benchmark comparándose. Volveré sobre eso.

Pero la distinción se sostiene sin creerle ninguna cifra. Un error interrumpe a alguien y se arregla. Una cifra plausible entra en una diapositiva y se propaga.

Preguntar no es acordar

La pregunta en lenguaje natural no elimina las decisiones de modelado. Las desplaza a un sitio donde nadie las revisa.

flowchart TD
    Q["How many active customers<br/>last quarter?"] --> M{"Is 'active customer'<br/>declared anywhere?"}
    M -- yes --> S["Resolved against entity,<br/>grain and filters"]
    M -- no --> G["Inferred from column names<br/>and a best guess"]
    S --> A["One answer, or an error"]
    G --> P["A plausible number"]
theory of small decisions

La rama de la izquierda existe solo si alguien escribió antes qué es un cliente activo. Si nadie lo hizo, el modelo no se detiene a preguntarlo: elige por su cuenta, y esa elección no queda registrada en ningún sitio.

Es la misma tensión que discutí en la ontología de la capa semántica, con una diferencia incómoda. Allí el desacuerdo acababa saliendo a la luz porque dos equipos reportaban distinto.

Aquí cada uno pregunta solo, en su ventana de chat, y nadie compara.

Lo que miden los benchmarks, y lo que no

Conviene mirar los números que sí están medidos con método, y con cuidado de no pedirles lo que no dicen.

El benchmark BIRD, presentado en NeurIPS 2023 y construido sobre bases de datos grandes y sucias, midió que ChatGPT alcanzaba un 40,08% de precisión de ejecución frente al 92,96% de los humanos. Antes, Spider había establecido dónde estaba lo difícil: no en generar SQL, sino en generalizar a esquemas nunca vistos.

Los modelos de hoy puntúan bastante por encima de aquellos. Y el matiz que importa es otro: esos benchmarks no miden el problema de este post. Comparan la consulta generada contra un SQL de oro que un anotador escribió, lo que significa que alguien ya decidió qué quería decir la pregunta.

La ambigüedad de “cliente activo” es exactamente lo que queda fuera de esa medición. El laboratorio mide si el modelo traduce bien una intención ya fijada. En tu empresa, la intención es lo que nadie fijó.

Un agente no puede razonar sobre lo que nadie escribió

La alternativa no es prohibir el chat. Es escribir la definición en algún sitio, y que ese sitio sea el que el agente consulta.

# La pregunta del principio, resuelta contra algo escrito.
metric:
  name: active_customers
  entity: customer
  grain: "one row per account, not per contract"
  filters:
    - "status = 'active'"
    - "is_test = false"
  time_dimension: subscription_period

Diez líneas que un chat no puede inventar de tres maneras distintas. Con esto delante, la pregunta del primer párrafo tiene una sola resolución posible.

flowchart LR
    Q["active customers<br/>last quarter"] --> E["entity: customer"]
    E --> G["grain: one per account"]
    G --> F["filters: active,<br/>not test"]
    F --> T["time: subscription_period"]
    T --> A["One resolved query"]
theory of small decisions

Cada paso de esa cadena es una decisión que alguien tomó una vez. Sin el archivo, el modelo toma las cinco por su cuenta y en cada pregunta puede tomarlas distinto.

Conviene decir de dónde viene la evidencia de esta mitad del post. Cube y Malloy documentan este enfoque, y ambos venden productos que lo implementan. Open Semantic Interchange es un estándar neutral respecto al proveedor, pero neutral significa aquí neutral entre proveedores: lo impulsan Snowflake, dbt Labs, Databricks y Salesforce.

Cuatro de las siete fuentes de este post venden la solución que propone. No conozco una medición independiente y revisada por pares de cuánto mejora una capa declarada — incluido el benchmark de dbt que cité arriba. El argumento hay que juzgarlo por su mecanismo, no por sus cifras.

Lloyd Tabb, que creó LookML y Looker antes que Malloy, expone el mecanismo en un seminario de investigación y no en una demo de producto.

Su argumento es que SQL obliga a reconstruir el significado en cada consulta, y que declararlo una vez cambia quién tiene que acertar.

Modos de fallo que conviene nombrar

SíntomaSuele significar
Dos personas preguntan lo mismo y obtienen cifras distintasCada consulta reinventó la definición, y nadie las comparó
El chat nunca dice “no sé”No hay nada declarado contra lo que fallar
La respuesta cambia al reformular la preguntaEl modelo está infiriendo el filtro del enunciado
Nadie sabe qué contó como “cliente” en una cifra que ya circulóLa decisión se tomó en una ventana de chat, no en el modelo
El equipo de datos audita respuestas en vez de definicionesSe revisa la salida porque la entrada no está escrita
Funciona en la demo y falla con el esquema realLa demo no tenía columnas ambiguas que desempatar

El patrón es el mismo en las seis: se pide al modelo que decida algo que nadie acordó.

Por dónde empezar

No conectes el chat todavía. Toma las tres preguntas que más te llegan por Slack y escribe para cada una un bloque como el de arriba: qué entidad responde, con qué grano y con qué filtros.

Si al escribirlas descubres que dos personas del equipo no coinciden, acabas de encontrar lo que el chat habría respondido igualmente, sin avisar a nadie.

Referencias

  1. dbt Labs — Semantic Layer vs. Text-to-SQL: 2026 Benchmark Update, dbt Developer Blog
  2. Cube Dev — Introduction, Cube Documentation
  3. Jinyang Li et al. — Can LLM Already Serve as A Database Interface? A BIg Bench for Large-Scale Database Grounded Text-to-SQLs, NeurIPS 2023
  4. Tao Yu et al. — Spider: A Large-Scale Human-Labeled Dataset for Complex and Cross-Domain Semantic Parsing and Text-to-SQL Task, EMNLP 2018
  5. Malloy Data — Querying a Semantic Model, Malloy Documentation
  6. Open Semantic Interchange — Introduction, OSI specification
  7. Lloyd Tabb — Malloy: A Modern Open Source Language for Analyzing, Transforming, and Modeling Data, CMU Database Group, 2025
Capa semántica - Text-to-SQL - Producto de datos - LLM