Contei os tokens dos mesmos dados em vários formatos: JSON indentado custa 3x o CSV, JSON colunar custa o mesmo
A maioria de nós cola dados no prompt como JSON, muitas vezes direto do JSON.stringify(data, null, 2). Eu nunca tinha medido quantos tokens isso custa, então peguei uma tabela, escrevi em sete formatos e contei.
Resumo: JSON com um objeto por linha e indentado usa cerca de 3 vezes mais tokens que CSV. Os mesmos dados em JSON colunar custam praticamente o mesmo que CSV. O caro são as chaves repetidas, não o JSON em si.
Atualização: um leitor apontou que faltou o JSON colunar (um objeto com um array por campo). Medi com a mesma tabela e o mesmo tokenizador e adicionei abaixo.
O teste
Uma tabela de produtos: 20 linhas, 5 campos (id, nome, preço, em_estoque, categoria). Uma linha em CSV:
1001,Wireless Mouse,9.99,false,electronics
Os mesmos dados em sete formatos, contados com o o200k_base, o tokenizador do GPT-4o e dos modelos mais novos da 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 | Em relação ao CSV |
|---|---|---|
| TSV | 296 | 0,99× |
| CSV | 300 | 1,00× |
JSON colunar minificado {"id":[...],"name":[...]} | 297 | 0,99× |
JSON cabeçalho + linhas {"columns":[...],"rows":[[...]]} | 320 | 1,07× |
| Tabela Markdown | 373 | 1,24× |
| JSON colunar indentado | 520 | 1,73× |
| JSON por linha, minificado | 525 | 1,75× |
| YAML | 649 | 2,16× |
| JSON por linha, indentado (2 espaços) | 884 | 2,95× |
| XML | 1.088 | 3,63× |
Com o tokenizador antigo (cl100k_base) os números ficaram quase iguais: menos de 2% de diferença em todos os formatos.
Por que a diferença é tão grande
- As chaves se repetem em cada linha. JSON, YAML e XML escrevem
"name":e"price":vinte vezes. O CSV escreve uma vez só, no cabeçalho, e o JSON colunar também; por isso ele fica no nível do CSV. - Pontuação também é token. Aspas, chaves e dois-pontos contam. XML é o pior: cada valor tem uma tag de abertura e outra de fechamento.
- Indentação é para humanos. O modelo não precisa dela. Só a formatação adicionou 359 tokens (+68%) em relação ao JSON minificado.
O YAML é o caso curioso: tem menos caracteres que o JSON minificado, mas mais tokens, porque cada campo fica numa linha própria com a própria chave.
Também medi código
Agentes de programação mandam muito código, então testei algumas coisas:
| Teste | Resultado |
|---|---|
| Arquivo Python de 16 linhas: 4 espaços vs 2 espaços vs tab | 135 / 135 / 133 tokens, praticamente igual |
| O mesmo arquivo sem a docstring de uma linha | 135 → 123 (−9%) |
| Função JS de 10 linhas, minificada | 92 → 47 (−49%) |
| Um UUID | 18 tokens |
- Indentação sai quase de graça. Os tokenizadores atuais juntam vários espaços seguidos num único token. Não vale a pena reformatar código para economizar.
- Código minificado usa metade dos tokens, mas não faça isso. Você perde nomes como
subtotaletaxRate, que são justamente o que ajuda o modelo a entender o código. - UUID é caro. Se o seu prompt tem uma coluna de IDs longos, troque por números de linha e faça o mapeamento de volta no código.
O que eu uso agora
- Tabelas simples como entrada: CSV ou TSV. TSV se os valores tiverem vírgula, assim não precisa de aspas.
- Se precisar ser JSON: use o formato colunar (
{"id":[...],"name":[...]}) ou cabeçalho + linhas. Mesmos dados, praticamente o custo do CSV. - Dados que o modelo devolve: JSON minificado com schema. Conseguir fazer o parse sem erro vale mais que alguns tokens; use structured output se a sua API tiver.
- Dados aninhados: JSON minificado. Achatar na mão para CSV muitas vezes custa mais do que economiza.
- Tabelas que uma pessoa também vai ler: Markdown, só 24% a mais que CSV.
- Evite JSON indentado e XML no prompt, a não ser que alguma ferramenta exija.
Tirar campos que não são usados, campos null e casas decimais sobrando também ajuda.
Quanto custa
Imagine que você anexa uma tabela de 20 linhas em cada requisição, 1.000 requisições por dia, 30.000 por mês, a US$ 2 por milhão de tokens de entrada:
| Formato | Tokens por mês | Custo por mês |
|---|---|---|
| CSV | 9,0 M | US$ 18 |
| JSON colunar | 8,9 M | US$ 18 |
| JSON por linha, minificado | 15,8 M | US$ 32 |
| JSON por linha, indentado | 26,5 M | US$ 53 |
| XML | 32,6 M | US$ 65 |
Numa requisição não aparece, mas num produto aparece, e cresce com tabelas maiores, resultados de RAG e respostas longas de API.
Limitações
- Uma tabela e um tokenizador. Claude e Gemini tokenizam diferente, então os números absolutos mudam. A ordem (chaves e tags repetidas custam mais) vem da forma como os formatos são construídos, então deve se manter.
- Se o formato mudar a qualidade das respostas no seu caso, teste os dois. Prompt mais barato com resposta pior não é mais barato.
Teste com seus dados
Fiz um contador de tokens gratuito para isso. Ele roda o mesmo tokenizador o200k dentro do navegador, então nada do que você cola é enviado para servidor nenhum. Cole seus dados em dois formatos e compare tokens e custo por modelo.