Casi todos pegamos datos en los prompts como JSON, muchas veces directo de JSON.stringify(data, null, 2). Nunca había medido cuántos tokens cuesta eso, así que tomé una tabla, la escribí en siete formatos y conté.
Resumen: el JSON con un objeto por fila y con sangría usa unas 3 veces más tokens que el CSV. Los mismos datos en JSON columnar cuestan casi lo mismo que el CSV. Lo caro son las claves repetidas, no el JSON en sí.
Actualización: un lector señaló que faltaba el JSON columnar (un objeto con un array por campo). Lo medí con la misma tabla y el mismo tokenizador y lo añadí abajo.
El experimento
Una tabla de productos: 20 filas, 5 campos (id, nombre, precio, en_stock, categoría). Una fila en CSV:
1001,Wireless Mouse,9.99,false,electronics
Los mismos datos en siete formatos, contados con o200k_base, el tokenizador de GPT-4o y los modelos posteriores de OpenAI:
import { getEncoding } from "js-tiktoken";
const enc = getEncoding("o200k_base");
const count = (s) => enc.encode(s).length;
count(csv); // 300
count(JSON.stringify(rows)); // 525
count(JSON.stringify(rows, null, 2)); // 884
Resultados
| Formato | Tokens | Frente a CSV |
|---|---|---|
| TSV | 296 | 0,99× |
| CSV | 300 | 1,00× |
JSON columnar minificado {"id":[...],"name":[...]}
|
297 | 0,99× |
JSON cabecera + filas {"columns":[...],"rows":[[...]]}
|
320 | 1,07× |
| Tabla Markdown | 373 | 1,24× |
| JSON columnar con sangría | 520 | 1,73× |
| JSON por filas, minificado | 525 | 1,75× |
| YAML | 649 | 2,16× |
| JSON por filas, con sangría (2 espacios) | 884 | 2,95× |
| XML | 1.088 | 3,63× |
Con el tokenizador anterior (cl100k_base) los números fueron casi iguales: menos de un 2 % de diferencia en todos los formatos.
Por qué la diferencia es tan grande
-
Las claves se repiten en cada fila. JSON, YAML y XML escriben
"name":y"price":veinte veces. CSV las escribe una sola vez, en la cabecera, y el JSON columnar también; por eso queda al nivel del CSV. - La puntuación también son tokens. Comillas, llaves y dos puntos cuentan. XML es el peor: cada valor lleva una etiqueta de apertura y otra de cierre.
- La sangría es para humanos. El modelo no la necesita. Solo el formateado añadió 359 tokens (+68 %) frente al JSON minificado.
YAML es el caso curioso: tiene menos caracteres que el JSON minificado, pero más tokens, porque cada campo va en su propia línea con su propia clave.
También medí código
Los agentes de programación envían mucho código, así que probé algunas cosas:
| Prueba | Resultado |
|---|---|
| Archivo Python de 16 líneas: 4 espacios vs 2 espacios vs tabs | 135 / 135 / 133 tokens, casi sin diferencia |
| El mismo archivo sin su docstring de una línea | 135 → 123 (−9 %) |
| Función JS de 10 líneas, minificada | 92 → 47 (−49 %) |
| Un UUID | 18 tokens |
- La sangría sale casi gratis. Los tokenizadores modernos agrupan los espacios seguidos en un solo token. No reformatees tu código para ahorrar tokens.
-
El código minificado usa la mitad de tokens, pero no lo hagas. Pierdes nombres como
subtotalotaxRate, que es justo lo que ayuda al modelo a entender el código. - Los UUID son caros. Si tu prompt tiene una columna de IDs largos, cámbialos por números de fila y vuelve a mapearlos en tu código.
Lo que uso ahora
- Tablas planas como entrada: CSV o TSV. TSV si los valores tienen comas, así no hace falta entrecomillar.
-
Si tiene que ser JSON: usa formato columnar (
{"id":[...],"name":[...]}) o cabecera + filas. Mismos datos, casi el costo del CSV. - Datos que devuelve el modelo: JSON minificado con un esquema. Que se pueda parsear sin errores vale más que unos pocos tokens; usa structured output si tu API lo permite.
- Datos anidados: JSON minificado. Aplanarlos a mano en CSV muchas veces cuesta más de lo que ahorra.
- Tablas que también va a leer una persona: Markdown, solo un 24 % más que CSV.
- Evita el JSON con sangría y el XML en los prompts, salvo que una herramienta los exija.
Quitar campos que no se usan, campos null y decimales de más también ayuda.
Lo que cuesta
Supongamos que adjuntas una tabla de 20 filas a cada petición, 1.000 peticiones al día, 30.000 al mes, a $2 por millón de tokens de entrada:
| Formato | Tokens al mes | Costo al mes |
|---|---|---|
| CSV | 9,0 M | $18 |
| JSON columnar | 8,9 M | $18 |
| JSON por filas, minificado | 15,8 M | $32 |
| JSON por filas, con sangría | 26,5 M | $53 |
| XML | 32,6 M | $65 |
No se nota en una petición, pero sí en un producto, y crece con tablas más grandes, resultados de RAG y respuestas largas de APIs.
Limitaciones
- Una tabla y un tokenizador. Claude y Gemini tokenizan distinto, así que los números absolutos cambian. El orden (las claves y etiquetas repetidas son lo más caro) viene de cómo están construidos los formatos, así que debería mantenerse.
- Si el formato cambia la calidad de las respuestas en tu caso, prueba los dos. Un prompt más barato con peores respuestas no es más barato.
Pruébalo con tus datos
Hice un contador de tokens gratis para esto. Usa el mismo tokenizador o200k dentro de tu navegador, así que nada de lo que pegas se sube a ningún servidor. Pega tus datos en dos formatos y compara tokens y costo por modelo.
Y si escribes tus prompts en español: el español usa unas 1,18 veces los tokens del inglés. Lo medí aquí: ¿Cuántos tokens más usa el español?
Top comments (0)