WQuestions

Parte IV · Del lenguaje a los hechos

14

El lexicon como compilador

El catálogo de tipos es exacto pero ilegible; el lenguaje de las personas es fluido pero ambiguo. Entre ambos hace falta un traductor. Ese traductor es el lexicon: la única cara que el modelo le muestra al mundo.

Un vendedor de turno escribe en la tablet del local una sola palabra para cerrar la operación: tomar. Lo hace cien veces al día y nunca duda. «El cliente tomó la camiseta visitante talla M.» La frase es transparente para cualquier hispanohablante. El problema empieza cuando esa misma palabra viaja por el resto del edificio. En la sala de reuniones del primer piso, la gerente anota que el comité «tomó una decisión sobre el nuevo proveedor». En la cancha del torneo que la tienda patrocina, el relator narra que el delantero «tomó el balón en el área». Y en el municipio de la esquina, un funcionario certifica que el alcalde le «tomó juramento» al nuevo regidor. Cuatro veces el mismo verbo; cuatro hechos que no tienen nada en común salvo seis letras.

Si el sistema del capítulo anterior tomara el verbo al pie de la letra, haría lo que hace un parser ingenuo: leería tomar, dispararía una única firma (digamos tomar(agente, tema)) y guardaría las cuatro frases como instancias del mismo tipo de evento. El resultado sería una base de datos que cree que entregar una camiseta, deliberar en comité, recibir un balón y administrar un juramento son la misma clase de cosa. Las consultas posteriores heredarían el desastre: preguntar «¿qué decisiones se tomaron este mes?» devolvería también las ventas y las jugadas. El error no se nota al escribir; se cobra al leer.

El capítulo 13 nos dejó con el verbo entendido como signatura: cada verbo declara qué roles exige y de qué eje sale cada uno. Pero acabamos de ver que un verbo no basta como llave. Tomar no es una signatura: es una familia de signaturas que comparten ortografía. Para elegir la correcta hace falta mirar también qué acompaña al verbo. Y ese trabajo (el de pasar del lenguaje a la firma exacta) no lo hace el verbo solo. Lo hace una pieza dedicada, que es el verdadero protagonista de este capítulo.

Dos lenguajes que no deberían tocarse

Conviene nombrar con precisión los dos mundos que el capítulo 13 puso frente a frente. Por un lado está el catálogo canónico: el conjunto cerrado y versionado de roles (agente, tema, beneficiario, experimentador, causado_por…) con sus firmas, sus ejes de origen y sus reglas de obligatoriedad. Es exacto, estable y completamente ilegible para quien no diseñó el modelo. Ningún recepcionista, ningún médico, ningún relator deportivo va a escribir experimentador para registrar que a un cliente le encantó el postre.

Por el otro lado está el lenguaje del usuario: «vendedor», «comprador», «paciente», «socio», «el que pierde». Vocabulario vivo, distinto en cada gremio, lleno de sinónimos y de polisemia. Es lo único que la gente sabe escribir, y es lo único que un modelo de lenguaje recibe cuando lee una frase suelta. Si forzáramos a estos dos mundos a tocarse (si el catálogo canónico fuera la interfaz) habríamos construido una pieza de ingeniería impecable y socialmente inútil. La adopción se moriría en la primera capacitación.

La solución es interponer una capa de traducción entre ambos. Una capa que por fuera hable el idioma del usuario y por dentro emita tipos canónicos. A esa capa la llamamos lexicon, y su diseño descansa sobre dos decisiones que conviene enunciar de frente.

D8 El catálogo es invisible; el lexicon es la interfaz

El catálogo canónico de roles existe, es exacto y es la base sobre la que se valida cada hecho —pero nunca se expone directamente. La única superficie con la que el mundo exterior interactúa es el lexicon. Por dentro, los ingenieros pueden renombrar un rol, fusionar dos o versionar el catálogo entero; por fuera, nada cambia, porque la cara visible del sistema es el diccionario, no el catálogo.

Si D8 fija qué pieza es la interfaz, su consecuencia natural es una promesa hacia el usuario final, que merece su propio número porque otras partes del libro la invocan:

D9 El usuario nunca toca etiquetas canónicas

Un humano jamás debe verse obligado a escribir agente, beneficiario o experimentador para que el sistema funcione. El usuario emplea su propio vocabulario («vendedor», «comprador», «cliente», «el que anota») y el lexicon lo traduce en silencio a la etiqueta canónica correspondiente. La complejidad del idioma se resuelve en el diccionario, no en la cabeza de quien escribe.

El par D8–D9 reparte responsabilidades con nitidez. D8 mira hacia adentro: garantiza a los ingenieros que pueden mover los engranajes (agregar roles, cambiar códigos internos, reorganizar el catálogo) sin romperle nada a nadie, porque la fachada permanece. D9 mira hacia afuera: garantiza a las personas que pueden seguir hablando como hablan. El lexicon es el contrato que sostiene ambas promesas a la vez: estable hacia afuera, flexible hacia adentro.

El catálogo canónico es el corazón del sistema; el lexicon es su rostro. Y al mundo solo se le muestra el rostro.El contrato de D8

El lexicon en capas

Vale la pena ver la arquitectura completa de un vistazo antes de bajar al detalle de una entrada. La frase del usuario entra por arriba con su vocabulario natural; el lexicon la desambigua y la traduce a roles canónicos; el almacenamiento, ya en el fondo, solo trabaja con identificadores internos. Tres capas, y cada una puede cambiar sin perturbar a las otras.

CAPA 1 · EL USUARIO — habla su idioma «el vendedor le facturó al cliente» «la enfermera vacunó al paciente» CAPA 2 · EL LEXICON — traduce aliases → canónico · resuelve polisemia · valida firma "vendedor" agente "cliente" beneficiario "factura" tema "vacuna" tema CAPA 3 · EL ALMACENAMIENTO — solo identificadores (accion_facturar, agente=usr_91, tema=fac_0042, beneficiario=usr_77) ∈ K
Figura 14.1. Las tres capas del lexicon. Arriba, el usuario escribe con el vocabulario de su gremio. En el centro, el lexicon traduce cada alias al rol canónico (en magenta, el eje M: la traducción es trabajo de predicados) y valida la firma. Abajo, el almacenamiento solo ve tipos e identificadores internos. Cualquiera de las tres capas puede cambiar sin tocar a las otras: eso es D8 hecho geometría.

Autopsia de una entrada

Bajemos al detalle. Una entrada del lexicon es una «página» del diccionario, y cada pieza tiene un trabajo concreto. Tomemos un verbo del mundo de la tienda (el local de la escena inicial despacha camisetas al público) y desarmemos su entrada de vender:

lexicon
{
  "verbo": "vender",
  "tipo_situacion": "accion_vender",
  "roles": {
    "agente":       { "canonico": "agente",       "aliases": ["vendedor", "el que vende", "el que despacha"] },
    "tema":         { "canonico": "tema",         "aliases": ["producto", "lo vendido", "camiseta"] },
    "beneficiario": { "canonico": "beneficiario", "aliases": ["comprador", "cliente", "el que compra"] },
    "por_cuanto":   { "canonico": "por_cuanto",   "aliases": ["precio", "monto", "importe"] }
  },
  "obligatorios": ["agente", "tema", "beneficiario", "por_cuanto"],
  "opcionales":   ["momento", "lugar_de", "moneda", "instrumento"],
  "ejemplo": "El vendedor le vendió una camiseta al cliente por 49.90 dólares"
}

Son seis piezas, y conviene leerlas como lo que son: la declaración de una función con su manual de uso adjunto.

  1. verbo. La llave que activa la entrada. Puede ser una palabra suelta (vender) o un patrón compuesto (tomar [decisión]), como veremos al resolver la polisemia.
  2. tipo_situacion. El código interno exacto con el que el evento se ancla en la caja K. Es el motor oculto; el usuario nunca lo ve ni lo escribe.
  3. roles y sus aliases. Aquí vive D9. El rol canónico es agente, pero la lista de aliases le enseña al sistema que «vendedor», «el que vende» y «el que despacha» significan lo mismo. Gracias a eso, «el vendedor le vendió una camiseta al cliente» y «el agente transfirió un producto al beneficiario» producen el idéntico registro.
  4. obligatorios y opcionales. Las reglas de seguridad de la firma. Dictan qué roles no pueden faltar para que el hecho se acepte. Una venta sin precio se rechaza; una venta sin lugar, no.
  5. ejemplo. Una frase humana real. No es adorno: el motor de pruebas (y, cada vez más, el modelo de lenguaje) lee este ejemplo para aprender cómo se usa el verbo en la práctica.

Visto así, el lexicon deja de parecerse a un glosario y empieza a parecerse a otra cosa: a un compilador. Un compilador toma código fuente legible para humanos y lo traduce a instrucciones exactas que la máquina ejecuta, verificando de paso que los tipos cuadren. El lexicon hace exactamente eso con el lenguaje: toma una frase, la traduce a una tripleta tipada y comprueba que la firma se cumpla. El «código fuente» es el español; el «binario» es el hecho atómico del capítulo 7.

El idioma de los modelos: function calling

Aquí ocurre una de esas convergencias que parecen casualidad y no lo son. Los modelos de lenguaje de uso corporativo (entre ellos Claude, de Anthropic) se conectan al software de la empresa mediante un mecanismo estándar: el function calling, o uso de herramientas. El patrón es simple. La aplicación le entrega al modelo un catálogo en formato JSON que describe cada herramienta disponible, sus parámetros y cuáles son obligatorios. Cuando un usuario pide algo en lenguaje natural, el modelo elige la herramienta adecuada y emite una llamada estructurada, con cada parámetro en su sitio.

Lo notable es que ese formato JSON es estructuralmente idéntico a una entrada del lexicon. Tomemos la misma entrada de vender y reescribámosla en el esquema que un modelo espera recibir:

tool schema (function calling)
{
  "name": "accion_vender",
  "description": "Registrar una venta: transferencia de un bien con compensación monetaria",
  "input_schema": {
    "type": "object",
    "properties": {
      "agente":       { "type": "string", "eje": "Q", "description": "vendedor, el que vende, el que despacha" },
      "tema":         { "type": "string", "eje": "O", "description": "producto, camiseta, lo vendido" },
      "beneficiario": { "type": "string", "eje": "Q", "description": "comprador, cliente, el que compra" },
      "por_cuanto":   { "type": "number", "eje": "N", "description": "precio, monto, importe" },
      "momento":      { "type": "string", "eje": "T", "description": "cuándo ocurrió" },
      "lugar_de":     { "type": "string", "eje": "L", "description": "dónde ocurrió" }
    },
    "required": ["agente", "tema", "beneficiario", "por_cuanto"]
  }
}

Las correspondencias son uno a uno, y vale la pena nombrarlas para que no quede como una impresión vaga:

El tipo_situacion del lexicon se vuelve el name de la herramienta. Los aliases de cada rol se vuelven la description, que es justamente la pista que el modelo usa para saber qué significa el parámetro. El eje de origen (Q, O, N…) determina el type y aporta una validación semántica extra.

Y la lista de obligatorios es, literalmente, el campo required del esquema. No hay que traducir nada a mano ni mantener dos artefactos en paralelo: el lexicon es el catálogo de herramientas. Exponerlo a un modelo es serializarlo a JSON y entregarlo. Lo que en otras arquitecturas es un proyecto de integración, aquí es una función de exportación.

El efecto práctico es que una frase suelta se convierte en un hecho estructurado sin que nadie escriba un parser. El prompt que recibe el modelo es casi todo catálogo:

prompt
SISTEMA. Eres un extractor de hechos WQuestions. Dada una frase en español,
devuelve SOLO un JSON con la situación y sus roles canónicos.

Catálogo (verbo → situación · roles obligatorios):
  vender → accion_vender · [agente, tema, beneficiario, por_cuanto]
  tomar  → accion_consumir · [agente, tema]

Frase del usuario: "El vendedor le vendió una camiseta al cliente por 49.90 dólares"

Y la respuesta llega lista para asentarse en el grafo, ya traducida a roles canónicos:

respuesta del modelo
{
  "tipo_situacion": "accion_vender",
  "agente": "vendedor_17",
  "tema": "camiseta_88",
  "beneficiario": "cliente_1042",
  "por_cuanto": 49.90
}

Esa salida es exactamente el conjunto de tripletas tipadas del capítulo 7. Cada par rol–valor se vuelve un cable; por ejemplo, el beneficiario se lee como una tripleta del eje M que sale del evento y aterriza en una persona:

venta_001O beneficiarioM(O→Q) cliente_1042Q

Y una vez asentada, la situación completa se descompone en los cables que ya conocemos:

tripletas
(venta_001, instancia_de,  accion_vender)   ∈ M(O, K)
(venta_001, agente,        vendedor_17)     ∈ M(O, Q)
(venta_001, tema,          camiseta_88)     ∈ M(O, O)
(venta_001, beneficiario,  cliente_1042)    ∈ M(O, Q)
(venta_001, por_cuanto,    49.90)           ∈ M(O, N)

El modelo nunca vio la palabra por_cuanto hasta que el lexicon se la nombró; el usuario nunca la verá en absoluto. Esa es la promesa de D9 cumplida de extremo a extremo: el español entra por arriba, la tripleta canónica sale por abajo, y la etiqueta interna jamás se le exige a una persona.

Y esa promesa no caduca al escribir el hecho: vale también al preguntar por muchos. El gerente pide «el total vendido por cada vendedor este mes» con sus palabras, y el lexicon resuelve «vendedor» contra agente, «total» contra por_cuanto, sin que él vea jamás una etiqueta canónica. El reporte recorre miles de ventas, pero se pide y se devuelve en el idioma de la tienda, no en el del catálogo.

Resolver la polisemia: tomar, otra vez

Volvamos a la escena del principio. Tenemos cuatro frases que comparten el verbo tomar y no comparten nada más. ¿Cómo evita el lexicon confundirlas? La respuesta es decepcionantemente directa, y por eso funciona: una entrada distinta para cada significado. El lexicon no busca una regla mágica que cubra todos los usos de tomar; declara una lista de patrones, cada uno apuntando a su propio tipo de situación, y deja que el complemento decida.

lexicon · polisemia de «tomar»
{
  "tomar [decisión | acuerdo | resolución]": {
    "tipo_situacion": "accion_decidir",
    "obligatorios": ["agente", "tema"],
    "ejemplo": "El comité tomó una decisión sobre el nuevo proveedor"
  },
  "tomar [el balón | la pelota | el pase]": {
    "tipo_situacion": "accion_recuperar_posesion",
    "obligatorios": ["agente", "tema"],
    "ejemplo": "El delantero tomó el balón en el área"
  },
  "tomar [juramento]": {
    "tipo_situacion": "acto_juramentacion",
    "obligatorios": ["agente", "paciente"],
    "ejemplo": "El alcalde le tomó juramento al nuevo regidor"
  },
  "tomar": {
    "tipo_situacion": "accion_consumir",
    "obligatorios": ["agente", "tema"],
    "ejemplo": "El cliente tomó un refresco en la cafetería del estadio"
  }
}

El procedimiento de resolución es, otra vez, el de un compilador: el sistema intenta encajar la frase desde el patrón más específico hacia el más general. Si aparece «tomar el balón», gana la entrada de fútbol. Si aparece «tomar juramento», gana el acto de juramentación. Y solo cuando ningún patrón con complemento coincide («tomar un refresco») cae la regla genérica de consumir. El orden importa: lo específico siempre primero, lo genérico como red de seguridad. La figura siguiente lo muestra con los colores de cada eje para que se vea adónde va a parar cada hecho.

tomar ¿qué complemento? …decisión …el balón …juramento (sin patrón) accion_decidir comité · sala de reuniones recuperar_posesion delantero · cancha acto_juramentacion alcalde · municipio consumir cliente · refresco [agente, tema] [agente, tema] [agente, paciente] [agente, tema] K cuál · el zócalo de tipos cada situación aterriza como una clase distinta El parser prueba de lo específico (izquierda, con patrón) a lo genérico (derecha, sin patrón). Un mismo verbo, cuatro firmas, cuatro tipos: la polisemia se resuelve en el diccionario, no en la base de datos.
Figura 14.2. Resolución de la polisemia de tomar. El complemento (decisión, balón, juramento, o ninguno) desambigua entre cuatro unidades léxicas que conducen a cuatro tipos de situación distintos en el eje K, cada uno con su propia firma de roles. El patrón genérico (a trazos) actúa solo como red de seguridad.

La consecuencia arquitectónica es la que da título al capítulo. La complejidad del lenguaje no se elimina (sería imposible) sino que se traslada al lugar correcto: al diccionario. Un modelador de datos puede registrar un nuevo significado de tomar («tomar un préstamo», por ejemplo) agregando una entrada de texto, sin tocar una sola línea del núcleo. La base de datos sigue siendo ignorante sobre el español; el lexicon hace todo el trabajo lingüístico.

Dos clases de alias: por rol y por dominio

Hasta aquí los aliases han sido por rol: dentro de la entrada de vender, «vendedor» equivale a agente. Pero hay un segundo nivel de traducción, indispensable para que el modelo funcione de verdad en una empresa. Hay palabras que aplican transversalmente a todo un dominio, sin importar qué verbo se use. Una tienda siempre habla de «vendedor», «boleta» y «caja»; una clínica siempre habla de «paciente», «historia» y «diagnóstico». Repetir esos aliases en cada entrada sería absurdo. Para eso el lexicon admite dialectos de dominio: un pequeño archivo de traducción que se carga encima del catálogo base.

dialecto de dominio
{
  "dominio": "tienda_central",
  "aliases_de_dominio": {
    "vendedor":      "agente",
    "boleta":        "comprobante",
    "caja":          "lugar_de",
    "catálogo":      "catalogo",
    "despachar":     "verbo_vender",
    "talla":         "atributo_medida"
  }
}

Con este dialecto cargado, un vendedor puede escribir «despaché una camiseta talla M en la caja dos» y el sistema traduce «despaché» al verbo vender, «caja» al rol lugar_de y «talla» al atributo de medida: todo sin que ninguna entrada de verbo mencione la palabra «caja». El núcleo permanece intacto, pero la tienda, la clínica y el municipio sienten, cada uno, que el software fue hecho a su medida. Es el mismo motor universal hablando tres jergas distintas.

A hombros de gigantes

Sería ingenuo —y arrogante— presentar el lexicon como una invención sin ancestros. La lingüística computacional lleva tres décadas construyendo catálogos inmensos con esta misma lógica de verbos, roles y firmas. Cualquier implementación seria del lexicon debería alimentarse de ellos en lugar de empezar de cero.

Precedente · FrameNet, VerbNet y PropBank

FrameNet(14) (Universidad de Berkeley, años noventa) clasifica el idioma en escenarios conceptuales o frames. Su escenario de «Comercio» define roles predefinidos como Buyer, Seller y Goods: casi calcados de nuestra entrada de vender. Sus más de mil doscientos escenarios son una mina para poblar la caja K con tipos de situación ya pensados por lingüistas.

VerbNet(15) (Universidad de Pensilvania) agrupa miles de verbos del inglés que comparten una misma estructura lógica (verbos de transferencia, verbos de encuentro, verbos de cambio de estado) de modo que un verbo nuevo hereda la firma de su clase en lugar de definirse a mano.

PropBank prioriza la cobertura: etiqueta masivamente textos reales con roles genéricos (Arg0 a Arg5). Es menos elegante, pero su escala lo convierte en la base preferida para entrenar modelos modernos a extraer estructura argumental.

WQuestions no compite con estas obras: actúa como una capa de agregación por encima de ellas. Se pueden extraer las signaturas de FrameNet, alinear las clases de VerbNet y usar los datos de PropBank para entrenar el extractor. El camino, en buena medida, ya está pavimentado; lo que aporta el lexicon es atarlo todo a un catálogo único de roles tipados por eje, y exponerlo con una sola interfaz.

Un vistazo al catálogo en acción

Para que esto no quede en abstracto, vale la pena ver varias entradas juntas, de dominios sin relación entre sí. Mientras las recorres, fíjate en tres cosas: que los roles se reciclan, que los aliases cambian con el gremio aunque el esqueleto no, y que los casos «raros» (verbos sin agente, verbos invertidos) encajan sin forzar nada.

lexicon · cuatro dominios
{
  "vacunar": {
    "tipo_situacion": "accion_vacunar",
    "roles": {
      "agente":      ["enfermera", "personal sanitario"],
      "paciente":    ["paciente", "vacunado"],
      "tema":        ["vacuna", "antígeno"]
    },
    "obligatorios": ["agente", "paciente", "tema"],
    "ejemplo": "La enfermera vacunó a 47 niños con la triple viral el sábado"
  },

  "multar": {
    "tipo_situacion": "accion_multar",
    "roles": {
      "agente":          ["autoridad", "ente regulador"],
      "paciente":        ["multado", "infractor"],
      "monto":           ["importe de la multa"],
      "justificado_por": ["norma aplicada", "artículo"]
    },
    "obligatorios": ["agente", "paciente", "monto", "justificado_por"],
    "ejemplo": "La municipalidad multó al local por ocupar la vereda"
  },

  "invocar": {
    "tipo_situacion": "accion_invocar_funcion",
    "roles": {
      "agente":      ["llamador", "cliente API", "el modelo"],
      "tema":        ["función invocada", "herramienta"]
    },
    "obligatorios": ["agente", "tema"],
    "ejemplo": "El modelo invocó la función accion_vender con los parámetros extraídos"
  },

  "llover": {
    "tipo_situacion": "evento_meteorologico",
    "roles": {
      "lugar_de":    ["región", "ciudad"],
      "intensidad":  ["leve", "moderada", "torrencial"]
    },
    "obligatorios": [],
    "notas": "Verbo impersonal: no exige agente ni ningún rol obligatorio.",
    "ejemplo": "Llovió torrencialmente sobre la ciudad durante seis horas"
  }
}

El catálogo entero, mirado en perspectiva, revela tres cosas que valen oro para quien implementa.

1  Los mismos cables, siempre

Vacunar, multar, invocar y vender comparten un puñado de roles (agente, tema, paciente, lugar_de). El catálogo base de roles basta para dominios que no se parecen en nada.

2  Los aliases son el poder

Lo que distingue salud de banca no son los códigos internos, sino las palabras naturales. «Enfermera» y «autoridad» mapean ambos a agente; «vacuna» y «factura», ambos a tema. La base de datos ignora el negocio.

3  Lo raro también encaja

llover no tiene agente y se modela sin forzar nada: la lista de obligatorios queda vacía. Un agente de IA como invocar ocupa el mismo rol agente que un humano, tal como anticipó la regla de agencia contextual.

Un sistema empresarial maduro puede tener un lexicon de varios miles de entradas. Las que acabas de ver son apenas el cimiento, pero ya muestran el patrón: el conocimiento del dominio vive en texto declarativo, no en código, y crece agregando entradas, no reescribiendo el motor.

Qué gana quien lo implementa

Conviene cerrar nombrando con claridad la diferencia entre tener un lexicon y no tenerlo.

El lexicon en producción

Habla el idioma real de tu gente. Sin lexicon, habría que enseñarle a cada empleado los campos robóticos del sistema. Con él, un vendedor escribe «el cliente tomó la camiseta visitante» y el hecho queda registrado en la jerga de la tienda, sin capacitación.

Es la puerta de entrada de la IA. El lexicon ya tiene la forma de un catálogo de function calling. Un modelo conectado a él empieza a redactar y auditar hechos sin que nadie reprograme el sistema: basta serializarlo y entregarlo.

Desambigua antes de escribir en disco. La polisemia (el caos de tomar) se resuelve en el diccionario. La base de datos recibe siempre hechos limpios, ya etiquetados con su tipo exacto en K.

Escala agregando texto. Abrir un dominio nuevo (logística, por decir) no exige crear cuarenta tablas: exige añadir un bloque de verbos al lexicon. El motor central hereda ese conocimiento de inmediato.

La genialidad de los siete ejes es el corazón del modelo, sí. Pero su adopción (el que una clínica, un banco o una tienda lo usen sin sentir que cambiaron de idioma) depende entera y exclusivamente de este traductor. El catálogo es el motor; el lexicon es el volante. Y nadie conduce agarrando el motor.

Un compilador no le pide al programador que escriba en binario. El lexicon no le pide al usuario que escriba en canónico. Esa es toda la diferencia entre un modelo elegante y un modelo que la gente usa.La tesis del capítulo

Nos queda un frente abierto. El lexicon resuelve la polisemia y la jerga, pero el lenguaje guarda trampas más finas: la negación, la modalidad, el tiempo verbal que no coincide con el tiempo del hecho, las metáforas que ningún diccionario anticipa. Es hora de poner el modelo completo (ejes, hecho atómico, lexicon) a prueba contra los casos que de verdad duelen. Eso es el próximo capítulo.