Bootstrap

如何确保大模型GPT输出结果100%是JSON结构

背景

最近使用大模型对大段自然文本解析,然后按照提示词生成对应的JSON数据结构,发现偶尔返回的json数据结构不正确,看起来是有点不太听话。但是如果不能100%生成json数据结构,那么程序始终会存在隐藏的问题,这篇就是分享下如何确保大模型的输出结果是100%json数据结构。

为什么一定要JSON格式的输出

日常使用没有关系,只要gpt给出合适的答案就可以,但是在程序调用过程中,以及大模型的工作流处理过程中,一个结构化的输出结果是非常重要的,因为数据是要给程序使用的。比如一段非结构化的自然文本:

您好,我们检查到18:29发生宕机,机器暂未恢复,如有任何业务影响请告知,对您造成的不便请谅解。机器信息如下:
cnhb01-bdu-xxx-xxxx    i-xxxxx    171.22.122.18

结构化结果(JSON格式):

{
    "title": "宕机故障通知",
    "eventContent": "检查到18:29发生宕机,机器暂未恢复,如有任何业务影响请告知,对您造成的不便请谅解。机器信息如下:",
    "scope": "",
    "eventStatus": "未恢复",
    "machines": [
        {
            "instanceName": "cnhb01-bdu-xxx-xxxx ",
            "instanceId": "i-xxxxx",
            "ip": "171.22.122.18"
        }
    ],
    "analysisSteps": "根据文本内容提取'未恢复'作为事件状态;提取机器信息行的内容,分离实例名称、实例ID和IP。"
}

自然文本给人看就够用了,但是我们需要结构化的数据存储起来,方便日后查找,比如关联某个ip,某一类事件类型等。
以上说明结构化数据对程序非常重要。

如何保证json结构

通过提示词工程提高准确率

在以前都是通过提示词工程,指定json格式,然后告诉大模型将自然文本解析出的内容映射到合适的字段,比如如下这段提示伺:

角色定位:你是一个运维工程师,会收到一些格式不固定的运维消息通知,现在需要你将这些消息,通过一定的规则,转化为统一的json数据结构。

json数据结构如下:
{
    "title":"",
    "eventContent":"",
    "scope":"",
    "eventStatus":"",
    "machines":[
        {
            "instanceName":"",
            "instanceId":"",
            "ip":""
        }
    ],
    "analysisSteps":""
}

定义解析规则如下:
字段解析规则:
title:标题提取,如果文本有明显的事件标题,如“事件:数据库连接失败”,提取其中的“数据库连接失败”
eventContent: 事件的内容,提取完整的事件描述和操作细节。可以包括细节步骤或者全面的事件背景描述。
scope: 事件的影响范围,比如影响地域、集群等信息
eventStatus: 事件的状态,识别事件目前状态,可以是“已恢复”、“处理中”、“未恢复”等类似的状态词。
machines: 机器相关的信息,实例信息、ip信息等,这是个数组,一个机器信息一般是一行,按照行解析成数组,解析不出保留空数组。
machines.instanceName: 实例名称,类似:icn-xxxx-prod-2-xxx
machines.instanceId: 实例标识, 类似:i-xxxxx
machines.ip: 机器的ip
analysisSteps: 将解析思路和关键判断记录在 analysisSteps 中,便于后续追溯解析过程

解析提示:
1. 尽量从文本中提取明确的关键词匹配字段。
2. 如果某一字段无法明确提取到正确的内容,则留空,或者仅填充在 eventContent 中。
3. 将解析思路和关键判断记录在 analysisSteps 中,便于后续追溯解析过程

案例:
输入内容:
您好,我们检查到12:45发生宕机。12:47虚机已恢复,影响机器信息如下,如有任何业务影响请告知,对您造成的不便影响请谅解
icn-xxxx-prod-2-xxx    i-xxx    173.21.14.15
db-xxx-prod-3-xx    i-xxxxx    173.21.34.29

输出结果:
期望返回的结果不要markdown格式,直接返回json字符串,如下:
{
    "title": "",
    "eventContent": "检查到12:45发生宕机。12:47虚机已恢复,影响机器信息如下,如有任何业务影响请告知,对您造成的不便影响请谅解",
    "scope": "",
    "eventStatus": "已恢复",
    "machines": [
        {
            "instanceName": "icn-xxxx-xxx-2-xx",
            "instanceId": "i-xx",
            "ip": "xxx.xxx"
        },
        {
            "instanceName": "db-xxx-xx-3-xxx",
            "instanceId": "i-xxx",
            "ip": "xxxxxxxxx"
        }
    ],
    "analysisSteps":""
}
The JSON object:json

(以上内容部分数据做了处理,比如ip,实例名称等信息,忽略)
通过这个也能返回json数据结构,准确略基本在90%左右。

OpenAI引入了结构化输出

这块目前只了解了OpenAI的GPT下有这种功能,其他家的大语言模型,暂不了解是不是有这个功能,应该都有了,即使现在没有以后也肯定都会有的。通过这种方式,模型输出现在就可以可靠地遵循开发人员提供的 JSON 模式。实现输出JSON的100%准确率!
在这里插入图片描述
OpenAI输出JSON格式的方法,橙、黄、绿分别代表提示词优化、微调、动态限制解码法的JSON输出准确率
官方文档参考链接:https://platform.openai.com/docs/guides/structured-outputs?context=without_parse

指定json_object

在请求体中指定response-format参数, json_object是一种简单的 JSON 输出模式,没有具体的架构要求,只要求生成的输出是有效的 JSON。适合在输出结构较为简单,仅需一个基础的 JSON 格式时使用。它仅要求模型生成一个有效的 JSON 对象,而不限定具体字段或其数据类型。
在这里插入图片描述

指定json-schema

json_schema 指定了一种严格的 JSON 架构,可以定义输出中每个字段的格式和数据类型。通过提供详细的 JSON Schema 描述(例如字段的名称、类型、是否必填等),模型会确保生成的输出严格遵守该结构。适合在输出需要复杂的结构化数据时使用,比如有多层嵌套、特定数据格式要求的输出。
在这里插入图片描述

何时使用 json_schema 与 json_object:
  • 如果您的应用需要非常精确、严格定义的 JSON 数据结构,请使用 json_schema。
  • 如果只是想要确保输出是 JSON 格式,但不需要具体的字段结构或复杂的格式,使用 json_object 即可。
    总之,json_schema 是一种更精细化的控制,json_object 则更灵活简单。

使用示例

使用json_schema

假设您在构建一个旅游推荐系统,需要输出包含具体信息的 JSON 数据结构,内容包括推荐的目的地名称、地理位置、评分、推荐理由等。这些信息需要有固定的字段和格式,便于前端应用或其他系统进行处理和展示。

示例:

{
  "type": "json_schema",
  "json_schema": {
    "type": "object",
    "properties": {
      "destination": { "type": "string" },
      "location": {
        "type": "object",
        "properties": {
          "latitude": { "type": "number" },
          "longitude": { "type": "number" }
        },
        "required": ["latitude", "longitude"]
      },
      "rating": { "type": "number", "minimum": 1, "maximum": 5 },
      "recommendation_reason": { "type": "string" }
    },
    "required": ["destination", "location", "rating", "recommendation_reason"]
  }
}

输出结果:

{
  "destination": "Paris",
  "location": {
    "latitude": 48.8566,
    "longitude": 2.3522
  },
  "rating": 4.7,
  "recommendation_reason": "A rich cultural experience with iconic landmarks and beautiful scenery."
}

使用json_object

假设您希望获取简单的天气信息,仅需要确保输出是 JSON 格式,但字段和结构并不复杂或严格定义。

{
  "type": "json_object"
}

输出结果:

{
  "city": "New York",
  "temperature": 18,
  "unit": "Celsius",
  "condition": "Partly Cloudy"
}

在这种情况下,json_object 格式的设定仅要求生成 JSON 数据即可,而不需要像 json_schema 那样指定字段的类型和要求。

;