Se afișează postările cu eticheta Java. Afișați toate postările
Se afișează postările cu eticheta Java. Afișați toate postările

vineri, 16 mai 2025

Generating Structured Output with OpenAI Java SDK

When working with OpenAI's API responses in Java, it's often useful to request structured output instead of plain text. This enables better parsing, validation, and downstream processing. The OpenAI Java SDK supports this through JSON Schema-based formats.

Reference: StructuredOutputsExample.java (GitHub) 

https://github.com/openai/openai-java/blob/main/openai-java-example/src/main/java/com/openai/example/StructuredOutputsExample.java

            ResponseFormatTextJsonSchemaConfig.Schema schema = ResponseFormatTextJsonSchemaConfig.Schema.builder()
                    .putAdditionalProperty("type", JsonValue.from("object"))
                    .putAdditionalProperty(
                        "properties", JsonValue.from(Map.of("employees", Map.of("type", "array", "items", Map.of("type", "string")))))
                    .putAdditionalProperty("required", JsonValue.from(List.of("employees")))
                    .putAdditionalProperty("additionalProperties", JsonValue.from(false))
                    .build();
            createParams = createParams.toBuilder()
//                .instructions(assistant.instructions())
                .text(ResponseTextConfig.builder()
                    .format(ResponseFormatTextJsonSchemaConfig.builder()
                        .name("employee-list")
                        .schema(schema)
                        .build())
                    .build())
                .build();
                
        openAiClient.getClient().responses().create(createParams).output().stream()
                .flatMap(item -> item.message().stream())
                .flatMap(message -> message.content().stream())
                .flatMap(content -> content.outputText().stream())
                .forEach(outputText -> System.err.println(outputText.text()));       

Convert Assistant defined response format. 

Assistant assistant = openAiClient.getClient().beta()
            .assistants()
            .retrieve(AssistantRetrieveParams.builder()
            .assistantId(openAiAssistantId)
                .build());
ResponseFormatJsonSchema.JsonSchema jsonSchema = assistant.responseFormat().get()
                .asResponseFormatJsonSchema()
                .jsonSchema();
                
                
ResponseFormatTextJsonSchemaConfig.Schema schema = ResponseFormatTextJsonSchemaConfig.Schema.builder()
                .additionalProperties(jsonSchema.schema().get()._additionalProperties())
                .build();
        ResponseCreateParams createParams = ResponseCreateParams.builder()
            .input(input)
            .model(model)
            .text(ResponseTextConfig.builder()
                .format(ResponseFormatTextJsonSchemaConfig.builder()
                    .name(jsonSchema.name())
                    .schema(schema)
                    .build())
                .build())
            .build();                

miercuri, 15 februarie 2012

Java: from finite to infinite

In Mathematics there are properties/relations that holds in finite cases, but stops to work in infinite cases.
In common life one can buy a printer made in China and print 5-10 copies per day and the printer will wok to the end of his/her life, but if he/she wil try to print more than 100 copies every day the printer will broke soon.
Mathematics, ordinary life ...? Let's talk about Java!

Case 1. Reading files.
for(File file : fileList) {
  LineIterator it = FileUtils.lineIterator(file);
  while (it.hasNext()) {
     String line = it.nextLine();
     // do something with line
  }
}

For a small number of files the above code will work like a charm, but for a very large fileList, after some time and in some circumstances (depending on CPU, RAM, version of Java etc) we will get IOException: Too many open files.

Case 2. Executing commands.

for(String command : commandList) {
  Process p = Runtime.getRuntime().exec(command, null);
  p.waitFor();
}

The result will be the same as in Case 1 with the same IOException: Too many open files.

Case 3. Requesting URLs

... coming soon...

Solutions.

The exceptions from Case 1  and Case 2 may be avoided with a simple finally block where we must dispose/close some of the used objects.
Here we have the solution for the Case 1

for(File file : fileList) {
  LineIterator it = FileUtils.lineIterator(file, "UTF-8");
  try {
    while (it.hasNext()) {
      String line = it.nextLine();
      // do something with line
    }
  } finally {
    it.close();
  }
}
And in Remember to Close Your Streams When Using Java's Runtime.getRuntime().exec() we have the solution for the Case 2.
for(String command : commandList) {
  Process p = null;
  try {
    p = Runtime.getRuntime().exec(command, null);
    p.waitFor();
  } finally {
    if(p != null) {
      IOUtils.closeQuietly(p.getOutputStream());
      IOUtils.closeQuietly(p.getErrorStream());
      IOUtils.closeQuietly(p.getInputStream());
  }
}