结构化输出
OpenAI提供自定义的结构化输出API,确保您的模型生成的响应严格符合您提供的JSON Schema。除了现有的Spring AI模型无关的结构化输出转换器之外,这些API还提供了增强的控制和精度。
Configuration配置
Spring AI允许您使用OpenAiChatOptions构建器或通过应用程序属性以编程方式配置响应格式。
使用聊天选项生成器
您可以使用OpenAiChatOptions builder以编程方式设置响应格式,如下所示:
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() .model(ChatModel.GPT_4_O_MINI) .responseFormat(new ResponseFormat(ResponseFormat.Type.JSON_SCHEMA, this.jsonSchema)) .build());ChatResponse response = this.openAiChatModel.call(this.prompt);
与BeanOutputConverter实用程序集成
您可以利用现有的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 = this.outputConverter.getJsonSchema();Prompt prompt = new Prompt("how can I solve 8x + 7 = -23", OpenAiChatOptions.builder() .model(ChatModel.GPT_4_O_MINI) .responseFormat(new ResponseFormat(ResponseFormat.Type.JSON_SCHEMA, this.jsonSchema)) .build());ChatResponse response = this.openAiChatModel.call(this.prompt);String content = this.response.getResult().getOutput().getContent();MathReasoning mathReasoning = this.outputConverter.convert(this.content);
Kotlin
data class MathReasoning( val steps: Steps, @get:JsonProperty(value = "final_answer") val finalAnswer: String) { data class Steps(val items: Array<Items>) { data class Items( val explanation: String, val output: String) }}val outputConverter = BeanOutputConverter(MathReasoning::class.java)val jsonSchema = outputConverter.jsonSchema;val prompt = Prompt("how can I solve 8x + 7 = -23", OpenAiChatOptions.builder() .model(ChatModel.GPT_4_O_MINI) .responseFormat(ResponseFormat(ResponseFormat.Type.JSON_SCHEMA, jsonSchema)) .build())val response = openAiChatModel.call(prompt)val content = response.getResult().getOutput().getContent()val mathReasoning = outputConverter.convert(content)
虽然这对于JSON Schema是可选的,但OpenAI要求结构化响应必须有字段才能正确运行。Kotlin反射用于根据类型的可空性和参数的默认值来推断哪些属性是必需的,因此对于大多数用例,不需要@get:JsonProperty(required = true)。@get:JsonProperty(value = "custom_name")可以用于自定义属性名称。确保使用此@get:语法在相关getter上生成注释。
通过应用程序属性进行配置
在使用OpenAI自动配置时,您也可以通过以下应用程序属性配置所需的响应格式:
spring.ai.openai.api-key=YOUR_API_KEYspring.ai.openai.chat.options.model=gpt-4o-minispring.ai.openai.chat.options.response-format.type=JSON_SCHEMAspring.ai.openai.chat.options.response-format.name=MySchemaNamespring.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