JSONSchemaBench: Complexidade de Esquemas do Mundo Real Quebra Garantias de Saída Estruturada de LLMs
A maioria das equipes trata a decodificação restrita como um problema resolvido — adicione um esquema JSON, obtenha um JSON válido de volta. O JSONSchemaBench (arXiv:2501.10868) é a primeira tentativa sistemática de testar essa suposição contra 9.558 esquemas do mundo real, e os resultados são menos tranquilizadores do que o marketing sugere.
O artigo
Saibo Geng, Hudson Cooper, Michał Moskal e colegas da Microsoft Research apresentam o JSONSchemaBench, um benchmark de 9.558 esquemas extraídos de fontes reais de produção: assinaturas de chamada de função da GlaiveAI, repositórios do GitHub estratificados por complexidade de trivial a ultra, configurações da API do Kubernetes, esquemas de análise de eventos Snowplow e a coleção JSONSchemaStore. Eles avaliam seis frameworks de decodificação restrita — Guidance, Outlines, Llamacpp, XGrammar, OpenAI Structured Outputs e Gemini — em três eixos: cobertura (qual fração de esquemas o framework consegue lidar), eficiência (sobrecarga de tokens por segundo em relação à geração irrestrita) e qualidade (precisão da tarefa posterior). A grade de avaliação também inclui o conjunto oficial de testes do JSON Schema (JSON Schema Test Suite), que documenta 45 categorias de recursos que qualquer mecanismo em conformidade deve suportar.
A alegação central é que a complexidade do esquema é a variável decisiva que separa frameworks capazes de frágeis, e que nenhum framework único domina em todos os três eixos.
Principais ideias
- A cobertura desmorona sob a complexidade do esquema. Em esquemas simples da GlaiveAI, todos os frameworks pontuam acima de 86%. Mas em esquemas GitHub-Hard — aninhamento de vários níveis, definições recursivas, restrições de padrão complexas — o Guidance cai para 41%, o Llamacpp para 39%, o XGrammar para 28% e o Outlines para catastróficos 3%. A OpenAI atinge apenas 9% no GitHub-Hard, e o Gemini não produz nenhuma saída válida em esquemas de média complexidade ou superiores.
- O Kubernetes expõe uma fraqueza específica no XGrammar. Apesar das alegações de velocidade do XGrammar, ele atinge apenas 7% de cobertura em esquemas do Kubernetes, provavelmente porque esses esquemas dependem de padrões dependentes do contexto que a pré-computação independente de contexto do XGrammar não consegue gerenciar. A cobertura contra um benchmark que inclui configurações do Kubernetes não é opcional para agentes de produção.
- Ser sub-restrito é mais perigoso do que uma falha de compilação. O XGrammar exibe 38 falhas sub-restritas contra o JSON Schema Test Suite — o que significa que ele emite JSON que viola o esquema declarado enquanto relata sucesso silenciosamente. O Guidance tem apenas 1 falha desse tipo. Para um agente de gravação (write-back), um erro de compilação é detectado no momento do design; uma falha sub-restrita corrompe os dados em tempo de execução sem qualquer sinal.
- O avanço rápido (fast-forwarding) do Guidance oferece um ganho real de 50% na velocidade. Quando sequências determinísticas longas estão presentes (por exemplo, nomes de campos em uma estrutura de objeto fixa), o Guidance pode avançar vários tokens por etapa de decodificação. No Llama-3.1-8B em uma A100, o Guidance roda de 6 a 9 ms por token de saída, enquanto a geração irrestrita roda de 15 a 16 ms. O Outlines é mais lento que a geração irrestrita, operando de 30 a 46 ms, em grande parte devido à compilação inicial do seu autômato, que leva de 3 a 8 segundos por esquema.
- A decodificação restrita melhora modestamente a precisão do raciocínio. No GSM8K (matemática), o Guidance eleva a precisão de 80,1% (irrestrito) para 83,8%. No Last Letter e Shuffle Objects, os ganhos estão na faixa de 1 a 3 pontos. Isso contradiz a preocupação amplamente citada de que forçar o formato JSON degrada a qualidade da resposta — mas o tamanho do efeito é pequeno o suficiente para que a escolha do formato não deva orientar a seleção do framework.
- Nenhum framework cobre todas as 45 categorias de recursos do JSON Schema. O Guidance cobre 13, Llamacpp e XGrammar cobrem 1 cada, e o Outlines cobre 0. A implicação prática é que qualquer esquema que use
if/then/else,unevaluatedPropertiesou definições recursivas$refse comportará de forma imprevisível, dependendo de qual mecanismo está sob o capô.
O que se sustenta — e o que não
A contribuição mais forte do benchmark é a obtenção dos esquemas. Avaliações anteriores usavam esquemas triviais ou coleções de fonte única. Incluir configurações do Kubernetes ao lado de assinaturas de chamadas de função é o tipo certo de diversidade adversária. A estratificação de complexidade (de trivial a ultra) também fornece aos profissionais uma curva de calibração: se seus esquemas se parecem com chamadas de função da GlaiveAI, o XGrammar ou o Guidance servem bem; se eles se parecem com manifestos do Kubernetes, suas opções diminuem rapidamente.
A principal fraqueza é a avaliação gulosa (greedy) de amostra única. Medir a cobertura com uma geração por esquema subestima a capacidade real — um framework pode falhar 20% das vezes, mas ter sucesso em uma nova tentativa. O artigo reconhece isso, mas não relata números de pass@k amostrados por temperatura, o que importaria para sistemas de produção que realizam tentativas em caso de falha.
A comparação também mistura modelos incomparáveis. Frameworks de código aberto (Guidance, Outlines, Llamacpp, XGrammar) são testados no Llama-3.2-1B, enquanto a OpenAI e o Gemini executam seus próprios modelos não divulgados. A cobertura de 9% da OpenAI no GitHub-Hard pode refletir tanto a capacidade do modelo quanto a arquitetura de decodificação restrita. Uma comparação justa precisaria de acesso controlado ao modelo — o que os autores obviamente não podem forçar de provedores proprietários.
Por que isso importa para a IA financeira
Todo agente de gravação (write-back) do Beancount gera saídas estruturadas. Se o agente emite diretivas do Beancount como JSON antes de converter para a sintaxe .beancount, ou se ele chama ferramentas via esquemas JSON, a confiabilidade dessa geração JSON não é um detalhe — é o jogo inteiro. O artigo FinTrace mostrou que modelos de fronteira falham ao raciocinar sobre as saídas de ferramentas; o JSONSchemaBench revela um problema ortogonal: mesmo antes do raciocínio, a camada de formatação pode emitir silenciosamente saídas não conformes.
O resultado do Kubernetes é particularmente revelador para o Beancount. Esquemas de livros-razão (ledgers) não são sacos de chave-valor planos. Hierarquias de contas, metadados de transações e estruturas de tags criam padrões recursivos aninhados semelhantes aos objetos da API do Kubernetes. Um framework que pontua 7% no Kubernetes não está pronto para esquemas complexos de livros-razão, independentemente de quão rápida seja sua sobrecarga por token.
O modo de falha sub-restrito é o que me faria perder o sono. Um agente do Beancount usando XGrammar poderia emitir uma transação que passa na verificação de validação interna do framework, mas viola o esquema real — e o agente não teria motivo para tentar novamente. A corrupção silenciosa é pior do que uma falha visível.
O que ler a seguir
- XGrammar (arXiv:2411.15100, Dong et al.) — o artigo técnico por trás de um dos frameworks mais rápidos testados, explicando a divisão de tokens independente/dependente de contexto e por que os esquemas do Kubernetes o estressam.
- Grammar-Aligned Decoding / ASAp (NeurIPS 2024) — mostra que a máscara de tokens na decodificação restrita pode distorcer a distribuição de probabilidade do modelo e propõe um algoritmo de amostragem corrigido; a base teórica para preocupações de qualidade que o benchmark mede apenas indiretamente.
- XGrammar-2 (arXiv:2601.04426) — uma continuação que estende o XGrammar para esquemas dinâmicos em cenários de agentes onde o próprio esquema muda durante uma sessão de vários turnos, diretamente relevante para agentes Beancount que adaptam seu formato de saída com base em quais tipos de conta estão ativos.
