Jsiphon - parser JSON para streaming de LLM com rastreamento de delta e detecção de ambiguidade
(github.com/webtoon-today)Olá, apresento o Jsiphon. Ele resolve problemas comuns ao usar respostas estruturadas em streaming com LLMs.
Ao usar respostas estruturadas (modo JSON) de LLM junto com streaming, é comum esbarrar no problema de analisar respostas parciais. Nesses casos, não dá para simplesmente usar JSON.parse(), então costuma-se recorrer a abordagens que recuperam repetidamente JSONs incompletos.
No entanto, aproveitando a característica "append-only, sem inversão de ordem" das respostas de LLM, dá para resolver esse problema de forma mais elegante, e o Jsiphon oferece três funcionalidades nesse sentido.
-
Parsing append-only — quando chega uma resposta parcial como
{"msg": "Hel, ele retorna imediatamente uma resposta completa como{msg: "Hel"}. Para o esquema anterior ao campomsgno exemplo, ele já considera que está concluído. -
Rastreamento de delta — cada resposta emitida fornece, além do snapshot completo, também apenas o conteúdo mais recentemente acrescentado. Por exemplo, se você estiver desenhando vários balões de fala de um chatbot, isso ajuda a redesenhar só o incremento do último balão, sem precisar renderizar tudo de novo. No exemplo anterior, se o LLM continuar emitindo
lo, World!, você poderá encontrar imediatamente{msg: "lo, World!"}emdeltada resposta. Assim, não é mais necessário fazer recuperação de JSON ediffa cada snapshot recebido. -
Detecção de ambiguidade — retorna uma árvore de ambiguidade (
ambiguity tree) com exatamente a mesma estrutura de árvore da resposta. Ela informa, em vários níveis de profundidade, se os dados incluídos no snapshot já estão confirmados ou se ainda dependem da continuação da leitura da resposta. Por exemplo, durante o streaming dos dados abaixo:{"header":{"title": "abcdefghijk","date": "..."},"body": "..."}
ao usar
isAmbiguous(ambiguous.header.title), passa a ser possível usartitlecom segurança a partir do momento em que ele foi concluído (resposta nº 3), sem precisar esperar a conclusão dos campos seguintes. Como ele oferece conclusão parcial em todos os níveis, e não apenas a conclusão total,isAmbiguous(ambiguous.header)retornaráisAmbiguous = falsequando todos os descendentes deheadertiverem sido concluídos.
Já existem muitas bibliotecas para recuperação/parsing parcial de JSON (partial-json, gjp-4-gpt etc.), e elas resolvem muito bem o problema fundamental de parsing. O Jsiphon, porém, aproveita a característica de que os LLMs fazem streaming de forma append-only para não apenas fornecer snapshots, mas também deltas por campo e a capacidade de determinar, a cada iteração, quais campos já foram concluídos.
Se você já estiver resolvendo um problema parecido, talvez se identifique com essa proposta. Eu estou combinando o Jsiphon com SSE de múltiplos tipos para que o chatbot faça streaming de texto enquanto, ao mesmo tempo, avalia em tempo real várias flags (is_adult, need_admin etc.).
Além disso, em termos práticos, ele é zero dependency, não lança erro mesmo com respostas inválidas e inclui conveniências como remoção de texto irrelevante antes e depois do JSON.
GitHub: https://github.com/webtoon-today/jsiphon
npm install jsiphon
Se isso puder ajudar, experimentem usar e me deem um feedback.
A ambiguity tree me parece um design relativamente desafiador, então também tenho curiosidade em saber se existe uma abordagem melhor. Agradeço feedback sobre o design da API.
Ainda não há comentários.