json-brook - 解析流式json数据的另一种方案

4 阅读2分钟

背景

大模型发展迅猛后,但是很多场景下模型返回速度堪忧,为了保证用户体验,前后端交互往往采用流式形式。在非结构化数据例如 markdown 形式时,这么操作基本没啥影响,但是针对结构化数据,例如常见的 json,流式过程中的不完整 json 因为无法直接解析变得比较棘手。在拜读了json-to-ast的源码,尝试开发了json-brook这个小工具库来解决这个问题

使用方式

在线文档:json-brook 介绍

import { createJsonBrook } from 「json-brook」;

const jsonBrook = createJsonBrook();

const sample = JSON.stringify(
        {
                a: 1001,
                b: 「hello」,
                C: [1, 2, 3],
                d: null,
        },
        null,
        4,
);

for (const char of sample) {
  jsonBrook.parse(char);
  console.log(jsonBrook.generate());
}

jsonBrook.end();
console.log(jsonBrook.generate());

与 json-repair 对比

目前针对大模型中针对流式 json 目前已有一种解决方法,就是使用jsonrepair先将已拿到的部分内容修复成完整 json 字符串,再解析该字符串。

相比之下,jsonrepair有以下优势

  • 支持“非法”json 字符串,这种“非法”既可以是不完整的 json 字符串,也可以是大模型幻觉带来额外字符,譬如注释语法、markdown 中 code 标记(```json ```)或者省略号之类,相比之下 json-brook 遇到后者只会解析失败
  • 热度很高,迭代频率也很高,使用量也很大,这意味着使用的安全性更好,相比之下,json-brook 目前只有一些基本的单测

那么,json-brook就没有自身的优势吗?

有的兄弟,有的,因为json-brook是流式解析字符串,所以内部会保留当前解析状态,即 api 中获取的rootcurrent,虽然目前仅导出了兜底的生成器,但是考虑有些数据,例如 id 之类的,附带额外业务属性而不能分割解析的 case,可以支持业务编写自定义生成器

结语

如果你是找个简单安全的方案在生产环境使用,那么我还是推荐你使用jsonrepair
但如果你能保证大模型给你的是合法的 json :) 并且你确实有上述自定义解析的诉求,那么你可以尝试下json-brook
另外的,如果你觉得我的想法不错,也欢迎给我的仓库点点 star

更多