DEV Community

Aylen Tejas
Aylen Tejas

Posted on

TOON vs JSON en RAG (Java): el Grinch de los formatos cuando cada token cuenta 🎁

En RAG (Retrieval-Augmented Generation) hay un detalle que parece menor hasta que te golpea en producción: cómo representas la evidencia que le pasas al modelo.

Dos sistemas pueden recuperar exactamente la misma información… y aun así comportarse distinto si el prompt queda:

  • demasiado largo (se corta evidencia útil),
  • demasiado ruidoso (el modelo “se pierde” en sintaxis),
  • o demasiado caro (tokens y latencia se disparan).

Por eso TOON (Token-Oriented Object Notation) aparece como un retador interesante frente a JSON: no porque JSON “esté mal”, sino porque JSON fue diseñado para máquinas, mientras que TOON intenta optimizar cómo un LLM consume datos estructurados.

Este post te deja un marco claro para que tú mismo puedas armar tu comparativa con tus datasets (por ejemplo: políticas de cuentas, tarjetas de crédito, retiros, transferencias, etc.), y sin caer en el error más común: mezclar indexación con prompt.

1) Lo esencial: TOON es otra estrategia de empaquetado

TOON está pensado para reducir repetición de claves y ruido estructural cuando el dato es uniforme.

La idea fuerte: en listas de objetos similares, JSON repite el mismo set de keys una y otra vez; TOON intenta declarar “el esquema” una sola vez y luego listar valores.

Ejemplo realista (tarifas / fees tabulares)

JSON minificado (baseline justo)

[{"producto":"Cuenta Ahorro Plus","mantenimiento":0,"moneda":"PEN"},
 {"producto":"Cuenta Sueldo","mantenimiento":0,"moneda":"PEN"},
 {"producto":"Cuenta Premium","mantenimiento":25,"moneda":"PEN"}]
Enter fullscreen mode Exit fullscreen mode

TOON (representación tabular, declarando campos una vez)

accounts[3]{producto,mantenimiento,moneda}:
  Cuenta Ahorro Plus,0,PEN
  Cuenta Sueldo,0,PEN
  Cuenta Premium,25,PEN
Enter fullscreen mode Exit fullscreen mode

Fíjate en lo importante:

  • En TOON no se repiten keys en cada fila.
  • La estructura queda muy parecida a una tabla.
  • Para listas grandes (catálogos, comisiones, condiciones), esa reducción de repetición puede liberar contexto.

2) El error que más veo: “TOON usa menos tokens” (sin separar dos mundos)

Cuando se habla de TOON en RAG, casi siempre aparece la misma afirmación:

“TOON es mejor porque usa menos tokens que JSON”.

El problema no es que la frase sea falsa. El problema es que mezcla efectos distintos y lleva a conclusiones incorrectas. En un sistema RAG hay dos mundos separados, y si no los distingues, cualquier comparación queda contaminada.

2.1 Indexación / embeddings: aquí no compites por tokens

En la fase de indexación, el objetivo no es ahorrar tokens, sino capturar señal semántica. Lo que importa es:

  • qué información llega al embedding
  • cuánto ruido sintáctico introduces
  • cómo fragmentas (chunking)
  • qué tan estable es el vector resultante

En este punto, TOON, JSON minificado o incluso texto plano pueden generar embeddings muy similares si la información real es la misma. El formato no “gana” por ser más corto, sino por no distorsionar el significado.

Si cambias formato, chunking y dataset al mismo tiempo, luego no sabes qué afectó al retrieval. Por eso, el formato aquí compite por semántica, no por tokens.

2.2 Prompt / contexto: aquí sí compites por espacio, costo y latencia

Este es el escenario donde TOON suele marcar diferencia.

Aquí importan cosas como:

  • cuántos tokens ocupa la evidencia
  • cuánta evidencia adicional cabe en la ventana
  • costo por request
  • latencia y TTFT (time to first token)

En esta capa, reducir repetición sí importa, porque te permite meter más información útil sin cortar contexto. Y es aquí donde TOON suele brillar, especialmente cuando la evidencia es tabular y repetitiva.

3) El tipo de dato importa más que el formato

Otro error frecuente es comparar TOON contra JSON “a secas”. Para ser justos, el baseline real debería ser JSON minificado, no el JSON bonito con sangrías que nadie usa en producción.

Además, TOON no compite en un vacío. Dependiendo del tipo de dato, otros formatos pueden funcionar igual o mejor. Por eso, antes de elegir formato, hay que mirar qué tipo de información estás metiendo al RAG.

3.1 Datos tabulares y uniformes (donde TOON suele ganar)

Ejemplos bancarios típicos:

  • tarifas y fees
  • catálogos de productos
  • listas de condiciones con el mismo esquema
  • tablas de comisiones por canal

En estos casos, TOON suele funcionar muy bien porque:

  • evita repetir claves
  • hace explícito el esquema
  • reduce ruido sintáctico

Ejemplo simplificado con tarifas de cuenta:

JSON minificado

[{"producto":"Cuenta Ahorro Plus","mantenimiento":0,"moneda":"PEN"},
{"producto":"Cuenta Sueldo","mantenimiento":0,"moneda":"PEN"}]
Enter fullscreen mode Exit fullscreen mode

TOON

accounts[2]{producto,mantenimiento,moneda}:
  Cuenta Ahorro Plus,0,PEN
  Cuenta Sueldo,0,PEN
Enter fullscreen mode Exit fullscreen mode

La información es la misma, pero el patrón es más evidente y la repetición se reduce.

3.2 Datos anidados o irregulares (donde TOON no siempre gana)

Ejemplos típicos en dominios bancarios:

  • políticas con excepciones
  • reglas con múltiples condiciones
  • configuraciones profundas por segmento o canal
  • objetos donde no todos los ítems comparten los mismos campos

En este tipo de datos no existe un patrón tabular claro. Cada elemento puede tener una estructura distinta, y forzar una representación tipo tabla deja de aportar valor.

En estos escenarios:

  • la compresión de TOON se diluye
  • no hay un esquema uniforme que declarar una sola vez
  • JSON minificado puede empatar o incluso ser más eficiente
  • CSV deja de ser viable porque pierde jerarquía

Aquí es importante decirlo sin rodeos:

TOON no gana siempre.

Y eso no es una debilidad, es una señal de que el formato debe elegirse según el tipo de dato y no por moda o benchmark aislado.

4) TOON no es el formato del sistema, es el formato del prompt

Una decisión arquitectónica clave en RAG es separar el formato del sistema del formato del prompt.

El error común es intentar migrar todo el sistema a TOON. Eso genera fricción innecesaria, rompe tooling existente y dificulta auditoría e integración.

Un enfoque mucho más sano es:

  • Persistir y trabajar los datos en JSON o Markdown
  • Indexar con el formato que ya existe
  • Recuperar documentos sin alterar el pipeline
  • Convertir a TOON solo al ensamblar el prompt, cuando la evidencia lo amerite

Este enfoque tiene varias ventajas:

  • no rompe contratos existentes
  • permite experimentar sin impacto sistémico
  • hace el cambio reversible (feature flag)
  • mantiene la comparación limpia

TOON se convierte así en una optimización localizada, no en una decisión irreversible.

5) Cómo preparar tus datasets para comparar formatos

Usando documentos reales como los que ya venías trabajando:

  • políticas de cuentas
  • información de tarjetas de crédito
  • reglas de retiros y transferencias

Una estrategia práctica y replicable para cualquier lector es:

  1. Mantener archivos .md como fuente base y legible.
  2. Generar una versión JSON minificada con la misma información.
  3. Generar una versión TOON, tabulando solo las partes uniformes.

La clave es que el contenido sea el mismo, solo cambia la representación.

Ejemplo: tarjeta de crédito (estructura realista)

JSON minificado

{"producto":"TC Classic",
"beneficios":["compras nacionales","pago sin contacto"],
"cobros":[{"concepto":"membresía anual","monto":120,"moneda":"PEN"}],
"reglas":[{"si":"pago mínimo fuera de fecha","entonces":"se aplican intereses y mora"}]}
Enter fullscreen mode Exit fullscreen mode

TOON

card{producto}:
  TC Classic

beneficios[2]:
  compras nacionales
  pago sin contacto

cobros[1]{concepto,monto,moneda}:
  membresía anual,120,PEN

reglas[1]{si,entonces}:
  pago mínimo fuera de fecha,se aplican intereses y mora
Enter fullscreen mode Exit fullscreen mode

Nota importante: TOON no tiene por qué ser completamente tabular.
Funciona mejor cuando usas tablas solo donde hay repetición y texto simple donde no la hay.

El “switch” correcto en un RAG real

Para comparar formatos sin contaminar el sistema, el cambio debe estar aislado.

El flujo ideal es:

  • retrieval igual
  • embeddings iguales
  • mismo número de chunks
  • solo cambia la representación en el prompt

Conceptualmente, el punto de decisión se ve así:

String context = switch(format) {
    case TOON -> toonFormatter.render(chunks);
    case JSON_MIN -> jsonMinFormatter.render(chunks);
    case MD -> markdownFormatter.render(chunks);
};
Enter fullscreen mode Exit fullscreen mode

Esto nos permite activar TOON solo cuando conviene, comparar formatos limpiamente, evitar efectos colaterales.

Cómo se ve esto en un RAG real con LangChain4j

Nada de slides bonitas. Algo que sí podría vivir en producción.

ContentRetriever retriever = query -> {
    // retrieval normal
    return vectorStore.search(query);
};

String assemblePrompt(List<Document> docs, Format format) {
    if (format == Format.TOON) {
        return ToonSerializer.from(docs);
    }
    return JsonSerializer.compact(docs);
}

String answer(String question) {
    List<Document> docs = retriever.retrieve(question);
    String context = assemblePrompt(docs, Format.TOON);

    return chatModel.generate(
        "Responde usando solo este contexto:\n" + context +
        "\nPregunta: " + question
    );
}
Enter fullscreen mode Exit fullscreen mode

Fíjate en algo importante:

  • El switch de formato está aislado
  • No contamina retrieval
  • No contamina embeddings

Eso es diseño defensivo.

6) Medir cambia la conversación

Sin medición, todo es opinión. Para evaluar formatos en RAG de forma seria, es clave observar dos capas distintas del sistema y no mezclar conclusiones.

6.1 Métricas de retrieval (indexación)

Estas métricas responden a la pregunta:

¿estoy trayendo la evidencia correcta?

  • Recall@k: ¿el fragmento relevante aparece dentro del top-k?
  • MRR (Mean Reciprocal Rank): ¿qué tan arriba aparece la primera evidencia correcta?
  • Latencia de búsqueda: tiempo de recuperación desde el vector store.

Aquí el formato compite por señal semántica, no por tokens.

6.2 Métricas de prompt y generación

Estas métricas responden a otra pregunta distinta:

¿cómo de eficiente es empacar y usar esa evidencia?

  • tamaño del contexto (tokens o proxies como caracteres/bytes)
  • TTFT (Time To First Token)
  • tiempo total de generación
  • tokens de entrada y salida
  • fidelidad de la respuesta (¿usa la evidencia o inventa?)

Es en esta capa donde TOON suele mostrar ventajas, al reducir repetición y liberar espacio para más contexto útil.

Separar estas métricas evita conclusiones falsas como:

  • “TOON no sirve”
  • “TOON es mágico”

A veces TOON reduce tokens pero no latencia.
A veces permite meter más evidencia y mejora la respuesta.
A veces no cambia nada.

La Conclusión de este 25

TOON no viene a destronar a JSON. Viene a ocupar un lugar específico: optimizar cómo empacas evidencia cuando el dato es repetitivo y la ventana de contexto aprieta.

En RAG, la madurez técnica no está en elegir un formato, sino en:

  • separar indexación de prompt
  • adaptar el formato al tipo de dato
  • instrumentar y medir
  • decidir con evidencia

Un buen sistema no se casa con un formato.

Un buen sistema entiende por qué usa cada uno.

Top comments (0)