【最佳实践】让大模型返回JSON结构数据的技术方案全解析

JSON格式的优势

在应用开发过程中,其实我们使用的最多的结构为json结构,其有非常明显的优势;

  • 轻量级:格式紧凑,比XML等其他数据交换格式更轻便,因此传输速度更快,占用带宽更少。
  • 易于解析:基于文本,在各种编程语言中非常流行,都可以轻松解析和生成JSON数据。
  • 平台无关性:语言无关性,可以在不同的系统和编程语言之间无缝交换数据。
  • 支持复杂数据结构:表示复杂的对象和数组结构,这使得它非常适合表示层次化数据。
  • 易于人类阅读:键值对格式,易于理解和阅读。
  • 自描述性:有意义的键,这有助于理解数据结构的目的。

所以在AI应用开发,希望AI大模型可以返回Josn结构的数据,方便与现有系统的集成,同时也方便结果的解析。

技术方案

纯提示词方案

在早期大模型并不支持json结构数据返回,到目前为止也不是所有的大模型都支持的。前期只能通过prompt(提示词)来实现。

prompt:查询某个导演最受欢迎的电影,包括:电影名称、电影的描述、电影的发行时间、演员列表,其中演员信息包括:姓名、年龄、参演过的最受欢迎的电影,请以json的格式返回。

通过prompt提示词,我们希望大模型能够返回如下的json结构的数据。

{
    "name":xxxx,
    "description": xxxx,
    "publishDate": xxxx,
    "performers": [
        {
            "name":xxx,
            "age":xxx,
            "films": [xxx,xxx,xxx]
        }
    ]
}

通过提示词让大模型返回json结构数据不够稳定,可能会出现json结构错误、缺失一些符号的情况,所以这种情况基本上不推荐,除非选择的大模型不支持Json mode方式。如果支持该方式,那么毋庸置疑选择json mode方式。

Json mode 方案

Json mode的方式使用上也非常简单,直接在请求时开启即可,比如;

  • 对于OpenAI```
    OpenAiChatModel.builder()

    .responseFormat(“json_object”)
    .build();

    
    
  • 对于Azure OpenAI```
    AzureOpenAiChatModel.builder()

    .responseFormat(new ChatCompletionsJsonResponseFormat())
    .build();

    
    
  • 对于 Vertex AI Gemini```
    VertexAiGeminiChatModel.builder()

    .responseMimeType(“application/json”)
    .build();

    
    
  • 对于 Mistral AI```
    MistralAiChatModel.builder()

    .responseFormat(MistralAiResponseFormatType.JSON_OBJECT)
    .build();

    
    
  • 对于Ollama```
    OllamaChatModel.builder()

    .format(“json”)
    .build();

    
    
    

该方式依然需要写好提示词,然后开启json mode。在可靠性上该方式没有任何问题,但是在返回性能会比普通差一些,这个很好理解,因为要处理json相关内容。

Json Schema 方案

在Json mode的方式,依然需要我们使用自然语言进行描述json的返回。但是当json的结构或者校验逻辑足够复杂时,自然语言描述显得有些力不从心了。

Json Schema不仅能约定Json的结构,还能约定数据类型、文本规则等,也是大模型支持比较好的方式。对Spring AI 结构化输出源码分析时,其就是使用的Json Schema方案。 在这里插入图片描述
然后我们在分析getFormat()方法

// 根据返回值的类型,转换为json schema,使用jackson和jsonschema-generator配合完成
private void generateSchema() {
    JacksonModule jacksonModule = new JacksonModule();
    SchemaGeneratorConfigBuilder configBuilder = new SchemaGeneratorConfigBuilder(DRAFT_2020_12, PLAIN_JSON)
       .with(jacksonModule);
    SchemaGeneratorConfig config = configBuilder.build();
    SchemaGenerator generator = new SchemaGenerator(config);
    JsonNode jsonNode = generator.generateSchema(this.typeRef.getType());
    ObjectWriter objectWriter = new ObjectMapper().writer(new DefaultPrettyPrinter()
       .withObjectIndenter(new DefaultIndenter().withLinefeed(System.lineSeparator())));
    try {
       this.jsonSchema = objectWriter.writeValueAsString(jsonNode);
    }
    catch (JsonProcessingException e) {
       logger.error("Could not pretty print json schema for jsonNode: " + jsonNode);
       throw new RuntimeException("Could not pretty print json schema for " + this.typeRef, e);
    }
}
// 将提示词 + json schema拼接一起
public String getFormat() {
    String template = """
          Your response should be in JSON format.
          Do not include any explanations, only provide a RFC8259 compliant JSON response following this format without deviation.
          Do not include markdown code blocks in your response.
          Remove the ```json markdown from the output.
          Here is the JSON Schema instance your output must adhere to:
          ```%s```
          """;
    return String.format(template, this.jsonSchema);
}

将获取到Json Schema 拼装在提示后,让大模型按照Json Schema返回。这就是 Spring AI框架的实现方式。

一个Json Schema结构如下;

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "description": {
      "type": "string"
    },
    "publishDate": {
      "type": "string"
    },
    "performers": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "age": {
            "type": "string"
          },
          "films": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      }
    }
  }
}

每个字段可以加上 description 加强大模型对Json的理解。使用起来好是好,但是内容不够紧凑,含有一些对大模型无意义的内容,容易导致token超窗口大小等。但是对于Java开发者来说算是比较好的选择了。

prompt:请返回xxx导演最受欢迎的电影,请严格按照 + Json Schema 返回

TS DSL 方案

可以使用TypeScript 语法来约束DSL,AI的理解能力和生成效果都非常稳定。TypeScript描述的DSL如下;

export interface Film {
    name: string; // "电影名字"
    description: string; // "请用50字以内概括电影的内容"
    publisDate: date; // "电影发行时间"
    performers: {
        name: string;
        sex: 男 | 女 ;
    }[];
}

从ts定义的DSL 与 Json Schema对比,很明显 TypeScript 定义的体积更小。

prompt:请返回xxx导演最受欢迎的电影,请严格按照 + TypeScript DSL 返回

Json格式返回适应场景

我们可以分场景进行讨论。

  • 对于非Web交互式的,比如完成函数调用,属于同步调用,非常适合使用json格式。
  • 对于Web交互式的,需要流式返回时,导致json结构被破坏无法完成展示,无法使用json格式。
  • json 格式过大,比如{}, : 无用字符,需要较高的调用成本,对成本要求的 不适合用json格式。

那么我们选择什么格式的数据返回呢?

思考方向就是,既有结构,还的体积小。通过分析yml或者md结构数据满足我们的需求。 原因在于:yml或者md不仅拥有更小的体积,同时支持流式解析。

总结

一般推荐使用:json mode + prompt + typescript 方式。因为Json mode是大模型支持的,是最可靠的。 如果有特殊需求,比如流式输出:yml + prompt + typescript 方式。

在思考技术方案,思维要发散,多种技术结合,才能有创新!!!!

AI大模型学习路线

如果你对AI大模型入门感兴趣,那么你需要的话可以点击这里大模型重磅福利:入门进阶全套104G学习资源包免费分享!

扫描下方csdn官方合作二维码获取哦!

在这里插入图片描述

这是一份大模型从零基础到进阶的学习路线大纲全览,小伙伴们记得点个收藏!

请添加图片描述
第一阶段: 从大模型系统设计入手,讲解大模型的主要方法;

第二阶段: 在通过大模型提示词工程从Prompts角度入手更好发挥模型的作用;

第三阶段: 大模型平台应用开发借助阿里云PAI平台构建电商领域虚拟试衣系统;

第四阶段: 大模型知识库应用开发以LangChain框架为例,构建物流行业咨询智能问答系统;

第五阶段: 大模型微调开发借助以大健康、新零售、新媒体领域构建适合当前领域大模型;

第六阶段: 以SD多模态大模型为主,搭建了文生图小程序案例;

第七阶段: 以大模型平台应用与开发为主,通过星火大模型,文心大模型等成熟大模型构建大模型行业应用。

100套AI大模型商业化落地方案

请添加图片描述

大模型全套视频教程

请添加图片描述

200本大模型PDF书籍

请添加图片描述

👉学会后的收获:👈

• 基于大模型全栈工程实现(前端、后端、产品经理、设计、数据分析等),通过这门课可获得不同能力;

• 能够利用大模型解决相关实际项目需求: 大数据时代,越来越多的企业和机构需要处理海量数据,利用大模型技术可以更好地处理这些数据,提高数据分析和决策的准确性。因此,掌握大模型应用开发技能,可以让程序员更好地应对实际项目需求;

• 基于大模型和企业数据AI应用开发,实现大模型理论、掌握GPU算力、硬件、LangChain开发框架和项目实战技能, 学会Fine-tuning垂直训练大模型(数据准备、数据蒸馏、大模型部署)一站式掌握;

• 能够完成时下热门大模型垂直领域模型训练能力,提高程序员的编码能力: 大模型应用开发需要掌握机器学习算法、深度学习框架等技术,这些技术的掌握可以提高程序员的编码能力和分析能力,让程序员更加熟练地编写高质量的代码。

LLM面试题合集

请添加图片描述

大模型产品经理资源合集

请添加图片描述

大模型项目实战合集

请添加图片描述

👉获取方式:
😝有需要的小伙伴,可以保存图片到wx扫描二v码免费领取【保证100%免费】🆓

### 关于面包板电源模块 MB102 的 USB 供电规格及兼容性 #### 1. **MB102 基本功能** 面包板电源模块 MB102 是一种常见的实验工具,主要用于为基于面包板的小型电子项目提供稳定的电压输出。它通常具有两路独立的稳压输出:一路为 5V 和另一路可调电压(一般范围为 3V 至 12V)。这种设计使得它可以满足多种芯片和传感器的不同工作电压需求。 #### 2. **USB 供电方式** MB102 支持通过 USB 接口供电,输入电压通常是标准的 5V DC[^1]。由于其内部集成了 LM7805 稳压器以及可调节电位器控制的直流-直流变换电路,因此即使输入来自电脑或其他低功率 USB 设备,也能稳定地向负载供应电力。不过需要注意的是,如果项目的功耗较高,则可能超出某些 USB 端口的最大电流能力(一般是 500mA),从而引起不稳定现象或者保护机制启动断开连接的情况发生。 #### 3. **兼容性分析** 该型号广泛适用于各种微控制器单元 (MCU),特别是那些像 Wemos D1 R32 这样可以通过杜邦线轻松接入并共享相同逻辑级别的系统[^2]。另外,在提到 Arduino Uno 板时也表明了良好的互操作性,因为两者均采用相似的标准接口定义与电气特性参数设置[^4]: - 对于需要 3.3V 工作环境下的组件来说,只需调整好对应跳线帽位置即可实现精准匹配; - 当涉及到更多外围扩展应用场合下,例如带有多重模拟信号采集任务的情形里,利用 MB102 提供干净无干扰的基础能源供给就显得尤为重要了[^3]。 综上所述,对于打算构建以单片机为核心的原型验证平台而言,选用具备良好声誉记录且易于获取配件支持服务链路上下游资源丰富的品牌产品——如这里讨论过的这款特定类型的配电装置不失为明智之举之一。 ```python # 示例 Python 代码展示如何检测硬件状态 import machine pin = machine.Pin(2, machine.Pin.IN) if pin.value() == 1: print("Power supply is stable.") else: print("Check your connections and power source.") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值