Spring AI 擁抱 OpenAI 的結構化輸出:增強 JSON 響應的可靠性

工程 | Christian Tzolov | 2024年8月9日 | ...

OpenAI 最近推出了一項強大的功能,稱為結構化輸出(Structured Outputs),它確保了 AI 生成的響應嚴格遵循預定義的 JSON Schema。此功能顯著提高了 AI 生成內容在實際應用中的可靠性和可用性。今天,我們很高興地宣佈 Spring AI (1.0.0-SNAPSHOT) 已完全整合支援 OpenAI 的結構化輸出,以無縫、Spring Native 的方式將此能力帶給 Java 開發者。

下圖展示了新的結構化輸出功能如何擴充套件OpenAI Chat API

Restored Spring AI (2)

注意: Spring AI 已經提供了強大的、模型無關的結構化輸出工具,可與包括 OpenAI 在內的各種 AI 模型一起使用。OpenAI 結構化輸出功能提供了一個額外的、一致的、但模型特定的解決方案,目前僅適用於 gpt-4ogpt-4o-mini 及後續模型。

OpenAI 的 Structured Outputs 功能保證 AI 模型生成的響應符合提供的JSON Schema。這解決了 AI 驅動應用中的幾個常見挑戰:型別安全:不再擔心缺少必需的鍵或無效的列舉值;顯式拒絕:基於安全的模型拒絕變得可以透過程式檢測;簡化提示:無需使用過於具體的提示即可實現一致的格式化。

Spring AI 允許開發者以最少的配置利用此功能。讓我們探討如何在 Spring 應用中使用它。

程式化配置

您可以使用 OpenAiChatOptions 構建器以程式化方式設定響應格式,如下所示

String jsonSchema = """
  {
      "type": "object",
      "properties": {
          "steps": {
              "type": "array",
              "items": {
                  "type": "object",
                  "properties": {
                      "explanation": { "type": "string" },
                      "output": { "type": "string" }
                  },
                  "required": ["explanation", "output"],
                  "additionalProperties": false
              }
          },
          "final_answer": { "type": "string" }
      },
      "required": ["steps", "final_answer"],
      "additionalProperties": false
  }
  """;

Prompt prompt = new Prompt("how can I solve 8x + 7 = -23",
  OpenAiChatOptions.builder()
      .withModel(ChatModel.GPT_4_O_MINI)
      .withResponseFormat(new ResponseFormat(ResponseFormat.Type.JSON_SCHEMA, jsonSchema))
      .build());

ChatResponse response = this.openAiChatModel.call(prompt);

注意:您必須遵循 OpenAI JSON Schema 的子集語言格式。

使用 BeanOutputConverter

Spring AI 提供了一個方便的 BeanOutputConverter 工具,可以自動從您的領域物件生成 JSON Schema,並將結構化響應轉換為 Java 例項

record MathReasoning(
  @JsonProperty(required = true, value = "steps") Steps steps,
  @JsonProperty(required = true, value = "final_answer") String finalAnswer) {

  record Steps(
    @JsonProperty(required = true, value = "items") Items[] items) {

    record Items(
      @JsonProperty(required = true, value = "explanation") String explanation,
      @JsonProperty(required = true, value = "output") String output) {}
  }
}

var outputConverter = new BeanOutputConverter<>(MathReasoning.class);

var jsonSchema = outputConverter.getJsonSchema();

Prompt prompt = new Prompt("how can I solve 8x + 7 = -23",
  OpenAiChatOptions.builder()
      .withModel(ChatModel.GPT_4_O_MINI)
      .withResponseFormat(new ResponseFormat(ResponseFormat.Type.JSON_SCHEMA, jsonSchema))
      .build());

ChatResponse response = this.openAiChatModel.call(prompt);
String content = response.getResult().getOutput().getContent();

MathReasoning mathReasoning = outputConverter.convert(content);

注意:請確保使用 @JsonProperty(required = true,…​) 註解。這對於生成準確標記欄位為必需的 Schema 至關重要。OpenAI 強制要求它才能使結構化響應正常工作。

透過 Application Properties 配置

或者,在使用OpenAI 自動配置時,您可以透過以下聊天應用屬性來配置所需的響應格式

spring.ai.openai.api-key=YOUR_API_KEY
spring.ai.openai.chat.options.model=gpt-4o-mini

spring.ai.openai.chat.options.response-format.type=JSON_SCHEMA
spring.ai.openai.chat.options.response-format.name=MySchemaName
spring.ai.openai.chat.options.response-format.schema={"type":"object","properties":{"steps":{"type":"array","items":{"type":"object","properties":{"explanation":{"type":"string"},"output":{"type":"string"}},"required":["explanation","output"],"additionalProperties":false}},"final_answer":{"type":"string"}},"required":["steps","final_answer"],"additionalProperties":false}
spring.ai.openai.chat.options.response-format.strict=true

拒絕響應

使用結構化輸出時,出於安全原因,OpenAI 模型有時可能會拒絕滿足請求。由於拒絕響應不一定遵循您在 response_format 中提供的 Schema,因此 API 響應包含一個名為 refusal 的新欄位,以指示模型拒絕滿足請求。

Spring AI 將此 refusal 欄位對映到 AssistantMessage 的元資料(metadata)中。透過 refusal 鍵進行搜尋。

未來工作

我們正在探索將新的 OpenAI 特定結構化輸出功能整合到 Spring AI 模型無關的結構化輸出工具集中的可能性。

參考資料

如需更多資訊,請查閱 Spring AI 和 OpenAI 的參考文件。

結論

Spring AI 對 OpenAI 結構化輸出功能的支援使得 AI 驅動的應用更加可靠且易於開發。透過確保型別安全和一致的結構化格式,開發者可以專注於構建創新功能,而不是費力處理不可預測的 AI 輸出。

我們可以強調 Spring 開發者的以下益處

  • 無縫整合:無需離開 Spring 生態系統即可利用結構化輸出。
  • 型別安全:使用強型別 Java 物件,減少執行時錯誤。
  • 靈活性:在程式化配置和基於屬性的配置之間進行選擇。
  • 領域驅動設計:使用您的領域物件定義預期的 AI 輸出結構。

請探索這一新能力並分享您的經驗。一如既往,我們歡迎反饋和貢獻,以幫助改進 Spring AI,使其更加強大和使用者友好。

敬請關注更多更新,我們將繼續增強 Spring AI 與尖端 AI 技術的整合!

獲取 Spring 新聞通訊

訂閱 Spring 新聞通訊以保持聯絡

訂閱

領先一步

VMware 提供培訓和認證,助力您快速進步。

瞭解更多

獲取支援

Tanzu Spring 透過一個簡單的訂閱提供對 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位制檔案。

瞭解更多

即將舉辦的活動

檢視 Spring 社群所有即將舉辦的活動。

檢視全部