Jsiphon - parser JSON para streaming de LLM con seguimiento de delta y detección de ambigüedad
(github.com/webtoon-today)Hola, les presento Jsiphon. Resuelve problemas comunes al usar respuestas estructuradas con streaming en LLM.
Cuando se usan respuestas estructuradas (modo JSON) en un LLM junto con streaming, es muy común toparse con el problema de parsear respuestas parciales. En esos casos no se puede simplemente usar JSON.parse(), así que suele recurrirse a recuperar JSON incompleto de forma repetida.
Sin embargo, si se aprovecha la característica de las respuestas de LLM de ser "append-only, sin inversión del orden", este problema puede resolverse de una forma más limpia, y Jsiphon ofrece las siguientes tres funciones:
-
Parsing append-only — cuando entra una respuesta parcial como
{"msg": "Hel, devuelve de inmediato una respuesta completa como{msg: "Hel"}. En el esquema del ejemplo, se considera que todo lo anterior al campomsgya está completado. -
Seguimiento de delta — cada respuesta emitida incluye, además del snapshot completo, el contenido agregado más recientemente por separado. Por ejemplo, si estás renderizando varios globos de chat, te permite redibujar solo el incremento del último globo en lugar de volver a dibujar todo. Si en el ejemplo anterior el LLM continúa con
lo, World!, podrás encontrar de inmediato{msg: "lo, World!"}dentro dedeltaen la respuesta. Así ya no hace falta hacer recuperación/parseo de JSON y diff cada vez que recibes un snapshot. -
Detección de ambigüedad — devuelve un árbol de ambigüedad (
ambiguity tree) con exactamente la misma estructura de árbol que la respuesta. Indica en varios niveles de profundidad si los datos incluidos en el snapshot ya están confirmados o si todavía se sigue leyendo la respuesta. Por ejemplo, al hacer streaming de los siguientes datos:{"header":{"title": "abcdefghijk","date": "..."},"body": "..."}
Si usas
isAmbiguous(ambiguous.header.title), podrás usartitlede forma segura desde el momento en que se complete (respuesta 3), sin esperar a que se completen los campos posteriores. Como no ofrece solo completitud total sino también completitud parcial en todos los niveles,isAmbiguous(ambiguous.header)devuelveisAmbiguous = falseúnicamente cuando todos los descendientes deheaderestán completos.
Ya existen muchas librerías para recuperación/parseo parcial de JSON (partial-json, gjp-4-gpt, etc.) que resuelven bien el problema fundamental del parsing. Jsiphon, en cambio, aprovecha la característica de que el LLM hace streaming de forma append-only para no limitarse a dar snapshots: también entrega incrementos (delta) por campo y permite determinar qué campos quedaron completos en cada iteración.
Si ya están resolviendo un problema parecido, probablemente les resulte familiar. Yo estoy combinando Jsiphon con SSE de múltiples tipos para que un chatbot pueda hacer streaming de texto y al mismo tiempo determinar en tiempo real varias banderas (is_adult, need_admin, etc.).
Además, en lo práctico incluye cero dependencias, no lanza errores incluso con respuestas inválidas y agrega funciones de conveniencia como eliminar texto irrelevante antes o después del JSON.
GitHub: https://github.com/webtoon-today/jsiphon
npm install jsiphon
Si les sirve, me encantaría que lo probaran y me compartieran su opinión.
El ambiguity tree me parece un diseño bastante desafiante, así que también tengo curiosidad por saber si existe una mejor forma de abordarlo. Agradecería mucho sus comentarios sobre el diseño de la API.
Aún no hay comentarios.