22
33<!-- x-release-please-start-version -->
44
5- [ ![ Maven Central] ( https://img.shields.io/maven-central/v/com.openai/openai-java )] ( https://central.sonatype.com/artifact/com.openai/openai-java/2.4 .0 )
6- [ ![ javadoc] ( https://javadoc.io/badge2/com.openai/openai-java/2.4 .0/javadoc.svg )] ( https://javadoc.io/doc/com.openai/openai-java/2.4 .0 )
5+ [ ![ Maven Central] ( https://img.shields.io/maven-central/v/com.openai/openai-java )] ( https://central.sonatype.com/artifact/com.openai/openai-java/2.5 .0 )
6+ [ ![ javadoc] ( https://javadoc.io/badge2/com.openai/openai-java/2.5 .0/javadoc.svg )] ( https://javadoc.io/doc/com.openai/openai-java/2.5 .0 )
77
88<!-- x-release-please-end -->
99
1010The OpenAI Java SDK provides convenient access to the [ OpenAI REST API] ( https://platform.openai.com/docs ) from applications written in Java.
1111
1212<!-- x-release-please-start-version -->
1313
14- The REST API documentation can be found on [ platform.openai.com] ( https://platform.openai.com/docs ) . Javadocs are available on [ javadoc.io] ( https://javadoc.io/doc/com.openai/openai-java/2.4 .0 ) .
14+ The REST API documentation can be found on [ platform.openai.com] ( https://platform.openai.com/docs ) . Javadocs are available on [ javadoc.io] ( https://javadoc.io/doc/com.openai/openai-java/2.5 .0 ) .
1515
1616<!-- x-release-please-end -->
1717
@@ -22,7 +22,7 @@ The REST API documentation can be found on [platform.openai.com](https://platfor
2222### Gradle
2323
2424``` kotlin
25- implementation(" com.openai:openai-java:2.4 .0" )
25+ implementation(" com.openai:openai-java:2.5 .0" )
2626```
2727
2828### Maven
@@ -31,7 +31,7 @@ implementation("com.openai:openai-java:2.4.0")
3131<dependency >
3232 <groupId >com.openai</groupId >
3333 <artifactId >openai-java</artifactId >
34- <version >2.4 .0</version >
34+ <version >2.5 .0</version >
3535</dependency >
3636```
3737
@@ -533,6 +533,200 @@ If you use `@JsonProperty(required = false)`, the `false` value will be ignored.
533533must mark all properties as _ required_ , so the schema generated from your Java classes will respect
534534that restriction and ignore any annotation that would violate it.
535535
536+ ## Function calling with JSON schemas
537+
538+ OpenAI [ Function Calling] ( https://platform.openai.com/docs/guides/function-calling?api-mode=chat )
539+ lets you integrate external functions directly into the language model's responses. Instead of
540+ producing plain text, the model can output instructions (with parameters) for calling a function
541+ when appropriate. You define a [ JSON schema] ( https://json-schema.org/overview/what-is-jsonschema )
542+ for functions, and the model uses it to decide when and how to trigger these calls, enabling more
543+ interactive, data-driven applications.
544+
545+ A JSON schema describing a function's parameters can be defined via the API by building a
546+ [ ` ChatCompletionTool ` ] ( openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionTool.kt )
547+ containing a
548+ [ ` FunctionDefinition ` ] ( openai-java-core/src/main/kotlin/com/openai/models/FunctionDefinition.kt )
549+ and then using ` addTool ` to set it on the input parameters. The response from the AI model may then
550+ contain requests to call your functions, detailing the functions' names and their parameter values
551+ as JSON data that conforms to the JSON schema from the function definition. You can then parse the
552+ parameter values from this JSON, invoke your functions, and pass your functions' results back to the
553+ AI model. A full, working example of _ Function Calling_ using the low-level API can be seen in
554+ [ ` FunctionCallingRawExample ` ] ( openai-java-example/src/main/java/com/openai/example/FunctionCallingRawExample.java ) .
555+
556+ However, for greater convenience, the SDK can derive a function and its parameters automatically
557+ from the structure of an arbitrary Java class: the class's name provides the function name, and the
558+ class's fields define the function's parameters. When the AI model responds with the parameter
559+ values in JSON form, you can then easily convert that JSON to an instance of your Java class and
560+ use the parameter values to invoke your custom function. A full, working example of the use of
561+ _ Function Calling_ with Java classes to define function parameters can be seen in
562+ [ ` FunctionCallingExample ` ] ( openai-java-example/src/main/java/com/openai/example/FunctionCallingExample.java ) .
563+
564+ Like for [ Structured Outputs] ( #structured-outputs-with-json-schemas ) , Java classes can contain
565+ fields declared to be instances of other classes and can use collections. Optionally, annotations
566+ can be used to set the descriptions of the function (class) and its parameters (fields) to assist
567+ the AI model in understanding the purpose of the function and the possible values of its parameters.
568+
569+ ``` java
570+ import com.fasterxml.jackson.annotation.JsonClassDescription ;
571+ import com.fasterxml.jackson.annotation.JsonPropertyDescription ;
572+
573+ @JsonClassDescription (" Gets the quality of the given SDK." )
574+ static class GetSdkQuality {
575+ @JsonPropertyDescription (" The name of the SDK." )
576+ public String name;
577+
578+ public SdkQuality execute () {
579+ return new SdkQuality (
580+ name, name. contains(" OpenAI" ) ? " It's robust and polished!" : " *shrug*" );
581+ }
582+ }
583+
584+ static class SdkQuality {
585+ public String quality;
586+
587+ public SdkQuality (String name , String evaluation ) {
588+ quality = name + " : " + evaluation;
589+ }
590+ }
591+
592+ @JsonClassDescription (" Gets the review score (out of 10) for the named SDK." )
593+ static class GetSdkScore {
594+ public String name;
595+
596+ public int execute () {
597+ return name. contains(" OpenAI" ) ? 10 : 3 ;
598+ }
599+ }
600+ ```
601+
602+ When your functions are defined, add them to the input parameters using ` addTool(Class<T>) ` and then
603+ call them if requested to do so in the AI model's response. ` Function.argments(Class<T>) ` can be
604+ used to parse a function's parameters in JSON form to an instance of your function-defining class.
605+ The fields of that instance will be set to the values of the parameters to the function call.
606+
607+ After calling the function, use ` ChatCompletionToolMessageParam.Builder.contentAsJson(Object) ` to
608+ pass the function's result back to the AI model. The method will convert the result to JSON form
609+ for consumption by the model. The ` Object ` can be any object, including simple ` String ` instances
610+ and boxed primitive types.
611+
612+ ``` java
613+ import com.openai.client.OpenAIClient ;
614+ import com.openai.client.okhttp.OpenAIOkHttpClient ;
615+ import com.openai.models.ChatModel ;
616+ import com.openai.models.chat.completions.* ;
617+ import java.util.Collection ;
618+
619+ OpenAIClient client = OpenAIOkHttpClient . fromEnv();
620+
621+ ChatCompletionCreateParams . Builder createParamsBuilder = ChatCompletionCreateParams . builder()
622+ .model(ChatModel . GPT_3_5_TURBO )
623+ .maxCompletionTokens(2048 )
624+ .addTool(GetSdkQuality . class)
625+ .addTool(GetSdkScore . class)
626+ .addUserMessage(" How good are the following SDKs and what do reviewers say: "
627+ + " OpenAI Java SDK, Unknown Company SDK." );
628+
629+ client. chat(). completions(). create(createParamsBuilder. build()). choices(). stream()
630+ .map(ChatCompletion . Choice :: message)
631+ // Add each assistant message onto the builder so that we keep track of the
632+ // conversation for asking a follow-up question later.
633+ .peek(createParamsBuilder:: addMessage)
634+ .flatMap(message - > {
635+ message. content(). ifPresent(System . out:: println);
636+ return message. toolCalls(). stream(). flatMap(Collection :: stream);
637+ })
638+ .forEach(toolCall - > {
639+ Object result = callFunction(toolCall. function());
640+ // Add the tool call result to the conversation.
641+ createParamsBuilder. addMessage(ChatCompletionToolMessageParam . builder()
642+ .toolCallId(toolCall. id())
643+ .contentAsJson(result)
644+ .build());
645+ });
646+
647+ // Ask a follow-up question about the function call result.
648+ createParamsBuilder. addUserMessage(" Why do you say that?" );
649+ client. chat(). completions(). create(createParamsBuilder. build()). choices(). stream()
650+ .flatMap(choice - > choice. message(). content(). stream())
651+ .forEach(System . out:: println);
652+
653+ static Object callFunction(ChatCompletionMessageToolCall . Function function) {
654+ switch (function. name()) {
655+ case " GetSdkQuality" :
656+ return function. arguments(GetSdkQuality . class). execute();
657+ case " GetSdkScore" :
658+ return function. arguments(GetSdkScore . class). execute();
659+ default :
660+ throw new IllegalArgumentException (" Unknown function: " + function. name());
661+ }
662+ }
663+ ```
664+
665+ In the code above, an ` execute() ` method encapsulates each function's logic. However, there is no
666+ requirement to follow that pattern. You are free to implement your function's logic in any way that
667+ best suits your use case. The pattern above is only intended to _ suggest_ that a suitable pattern
668+ may make the process of function calling simpler to understand and implement.
669+
670+ ### Usage with the Responses API
671+
672+ _ Function Calling_ is also supported for the Responses API. The usage is the same as described
673+ except where the Responses API differs slightly from the Chat Completions API. Pass the top-level
674+ class to ` addTool(Class<T>) ` when building the parameters. In the response, look for
675+ [ ` RepoonseOutputItem ` ] ( openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseOutputItem.kt )
676+ instances that are function calls. Parse the parameters to each function call to an instance of the
677+ class using
678+ [ ` ResponseFunctionToolCall.arguments(Class<T>) ` ] ( openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseFunctionToolCall.kt ) .
679+ Finally, pass the result of each call back to the model.
680+
681+ For a full example of the usage of _ Function Calling_ with the Responses API using the low-level
682+ API to define and parse function parameters, see
683+ [ ` ResponsesFunctionCallingRawExample ` ] ( openai-java-example/src/main/java/com/openai/example/ResponsesFunctionCallingRawExample.java ) .
684+
685+ For a full example of the usage of _ Function Calling_ with the Responses API using Java classes to
686+ define and parse function parameters, see
687+ [ ` ResponsesFunctionCallingExample ` ] ( openai-java-example/src/main/java/com/openai/example/ResponsesFunctionCallingExample.java ) .
688+
689+ ### Local function JSON schema validation
690+
691+ Like for _ Structured Outputs_ , you can perform local validation to check that the JSON schema
692+ derived from your function class respects the restrictions imposed by OpenAI on such schemas. Local
693+ validation is enabled by default, but it can be disabled by adding ` JsonSchemaLocalValidation.NO ` to
694+ the call to ` addTool ` .
695+
696+ ``` java
697+ ChatCompletionCreateParams . Builder createParamsBuilder = ChatCompletionCreateParams . builder()
698+ .model(ChatModel . GPT_3_5_TURBO )
699+ .maxCompletionTokens(2048 )
700+ .addTool(GetSdkQuality . class, JsonSchemaLocalValidation . NO )
701+ .addTool(GetSdkScore . class, JsonSchemaLocalValidation . NO )
702+ .addUserMessage(" How good are the following SDKs and what do reviewers say: "
703+ + " OpenAI Java SDK, Unknown Company SDK." );
704+ ```
705+
706+ See [ Local JSON schema validation] ( #local-json-schema-validation ) for more details on local schema
707+ validation and under what circumstances you might want to disable it.
708+
709+ ### Annotating function classes
710+
711+ You can use annotations to add further information about functions to the JSON schemas that are
712+ derived from your function classes, or to exclude individual fields from the parameters to the
713+ function. Details from annotations captured in the JSON schema may be used by the AI model to
714+ improve its response. The SDK supports the use of
715+ [ Jackson Databind] ( https://github.com/FasterXML/jackson-databind ) annotations.
716+
717+ - Use ` @JsonClassDescription ` to add a description to a function class detailing when and how to use
718+ that function.
719+ - Use ` @JsonTypeName ` to set the function name to something other than the simple name of the class,
720+ which is used by default.
721+ - Use ` @JsonPropertyDescription ` to add a detailed description to function parameter (a field of
722+ a function class).
723+ - Use ` @JsonIgnore ` to omit a field of a class from the generated JSON schema for a function's
724+ parameters.
725+
726+ OpenAI provides some
727+ [ Best practices for defining functions] ( https://platform.openai.com/docs/guides/function-calling#best-practices-for-defining-functions )
728+ that may help you to understand how to use the above annotations effectively for your functions.
729+
536730## File uploads
537731
538732The SDK defines methods that accept files.
0 commit comments