大模型公主病诊疗室-结构化JSON输出

一、前言

十年NLP无人问,一朝LLM天下知。

大模型几乎送走了传统NLP。所谓乱拳打倒老师傅,功夫再高,也怕飞刀。大模型大力出奇迹的同时,不得不说有一些硬伤,结构化JSON输出算是一个。

二、 病症

JSON输出不就是一个json.loads()的事吗?听起来没毛病。但实际情况可能是如下:

  • JSON字符串前后有解释性语句。比如,下面是JSON输出:{…}
  • JSON字符串内有行注释。
  • 非标JSON字符串:使用单引号替代标准的双引号、全角双引号、字典最后一个字段后多了一个逗号等等。
  • ……

以上每一种情况都会让脆弱的json.loads()分分钟崩掉。

虽然头部闭源大模型像OpenAI、Claude已经官方支持JSON输出,但对于广大开源大模型,JSON输出,sft最基本的指令任务,还是任重道远,可以说各家都还是在八仙过海,抓耳挠腮。

本文旨在探讨常用的一些规范大模型JSON输出的方法,力争给出一版开源大模型的JSON结构化输出最佳实践。

三、处方

1、json prompt

通过提示词强调输出JSON格式,例如,

从上下文中抽取“时间”、“地点”、“事件”三要素。

上下文:xxxxxx

请直接输出JSON格式,不要做任何解释。

2、json prompt + few shot

结合few shot进行输出格式加强,例如,

从上下文中抽取“时间”、“地点”、“事件”三要素。

上下文:xxxxxx

参考样例输出:
{
"time":"2024-10-01",
"location": "人民广场",
"event": "欢度国庆文艺汇演"
}

请直接输出JSON格式,不要做任何解释。

few shot的缺点是,对于一些尺寸小一点的大模型,给出的样例有可能会导致模型产生幻觉,在实际输出的时候输出了样例中的值。

3、后处理

无论prompt怎么加强,都难以避免偶发性地生成一些非标JSON字符串,给大家推荐一个后处理库json-repair(GitHub – mangiucugna/json_repair: A python module to repair invalid JSON, commonly used to parse the output of LLMs)。原理是通过BNF来解析 JSON,通过给数组或对象添加未闭合的括号、给字符串添加引号、调整空白或换行等启发式规则,尝试修复 JSON。

以下是五个常见的格式错误,都可以处理。

a. 解释性语句+json

下面是json输出```json
{
"time":"2024-10-01",
"location": "人民广场",
"event": "欢度国庆文艺汇演"
}
```

----------------后处理之后如下------------------

{
"time":"2024-10-01",
"location": "人民广场",
"event": "欢度国庆文艺汇演"
}

b. json中为单引号

{    
'time':'2024-10-01',
'location': '人民广场',
'event': '欢度国庆文艺汇演'
}

----------------后处理之后如下------------------

{
"time":"2024-10-01",
"location": "人民广场",
"event": "欢度国庆文艺汇演"
}

c. json中为全角双引号

{    
“time”: “2024-10-01”,
“location”: “人民广场”,
“event”: “欢度国庆文艺汇演”
}

----------------后处理之后如下------------------

{
"time":"2024-10-01",
"location": "人民广场",
"event": "欢度国庆文艺汇演"
}

d. json中最后一个字段多了一个逗号

{    
“time”: “2024-10-01”,
“location”: “人民广场”,
“event”: “欢度国庆文艺汇演”,
}

----------------后处理之后如下------------------

{
"time":"2024-10-01",
"location": "人民广场",
"event": "欢度国庆文艺汇演"
}

e. json中包含行注释

{    
"time":"2024-10-01", # 时间
"location": "人民广场", # 地点
"event": "欢度国庆文艺汇演" # 事件
}

----------------后处理之后如下------------------

{
"time":"2024-10-01",
"location": "人民广场",
"event": "欢度国庆文艺汇演"
}

四、  总结

你以为的大模型应用开发是在各种cot与agent中指点江山、挥斥方遒,实际上是在和标点符号与各种格式斗智斗勇。

大家可以根据实际情况,结合prompt + few shot + json-repair库来进行JSON输出的标准化。如果大模型尺寸比较小,可以取消few shot以减少不必要的幻觉产生。

柚子

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Index