Skip to content

Latest commit

 

History

History
425 lines (358 loc) · 30 KB

README.md

File metadata and controls

425 lines (358 loc) · 30 KB

openai-java

OpenAi API for Java. Including all API from OpenAI official document, and the counting token method.

GitHub version License

Example Application

Supported APIs

Important update

  • [2023-06-18] Support function call by API, and update the method to count tokens for functions after 0613 update by OpenAI
  • [2023-07-25] Return model limit information by passing consumer to OpenAiService instructor.
  • [2023-08-23] Remove api for Fine-tunes and Edits
  • [2023-08-24] Support Fine-tuning
  • [2023-11-08] Add Model Type gpt-4-1106-preview/gpt-4-vision-preview/gpt-3.5-turbo-instruct. Add param tools and tool_call instead of functions and function_call when send create completion request.
  • [2023-11-10] Reconstruct Completion and ChatCompletion
  • [2023-11-11] Update Image API to support dall-e-3
  • [2023-11-13] Update model with latest API
  • [2023-11-14] Add API support for Assistants, Threads, Messages and Runs, all of these are Beta version.
  • [2023-11-24] Add create speech api - Generates audio from the input text.
  • [2023-11-28] Remove api for Completions
  • [2023-12-04] Remove ModeType.GPT_3_5_TURBO_16K stead of GPT_3_5_TURBO_1106 which is the same length but cheaper.
  • [2024-02-02] Add model gpt-3.5-turbo-0125, ```gpt-4-0125-preview, text-embedding-3-small`, `text-embedding-3-large`.
  • [2024-02-07] Support running tool_calls in background which means that client needn't handle the tool_calls at the first response.
  • [2024-04-10] Support stream event for Assistant.
  • [2024-04-17] Add model gpt-4-turbo-2024-04-09. Remove gpt-3-turbo-1106, gpt-4-vision-preview, gpt-4-1106-preview, gpt-4-0125-preview.
  • [2024-04-21] Add api for Batch from version 3.9.2024042101
  • [2024-04-21] Replace Assistants, Thread, Messages, Runs with new version on Apr 17th, 2024 in version 4.0.2024102501
  • [2024-05-13] Add model gpt-4o-2024-05-13 and its new tokenizer o200k_base. Add parameter stream_options, logprobs, top_logprobs for createChatCompletion.
  • [2024-06-08] Add parameter parallel_tool_calls when calling create chat completion.

  • [2024-06-28] Support Baidu AI API, chat(include stream) only for now. see Baidu AI API.
  • [2024-07-19] Add model gpt-4o-mini-2024-07-18 to instead of gpt-3.5-turbo with smarter and cheaper.
  • [2024-08-08] Add model gpt-4o-2024-08-06 to instead of gpt-4o-2024-05-13 to support structure output.
  • [2024-08-08] Add model o1-preview-2024-09-12 and o1-mini-2024-09-12.
  • [2024-10-24] Add parameter input_audio when creating chat completion and support generate audio by new model gpt-4o-audio-preview-2024-10-01.

How to use

Maven

<dependency>
    <groupId>xyz.felh</groupId>
    <artifactId>service</artifactId>
    <version>4.0.2024102501</version>
</dependency>
<!-- get tokens count -->
<dependency>
    <groupId>xyz.felh</groupId>
    <artifactId>jtokkit</artifactId>
    <version>4.0.2024102501</version>
</dependency>

Gradle

implementation group: 'xyz.felh', name: 'service', version: '4.0.2024102501'
implementation group: 'xyz.felh', name: 'jtokkit', version: '4.0.2024102501'

sbt

libraryDependencies += "xyz.felh" % "service" % "4.0.2024102501"
libraryDependencies += "xyz.felh" % "jtokkit" % "4.0.2024102501"

Example (Spring Boot 3)

  • 1. Add maven dependency

<dependency>
    <groupId>xyz.felh</groupId>
    <artifactId>service</artifactId>
    <version>4.0.2024102501</version>
</dependency>
  • 2. Init openAIService

There are multiple ways to init openAIService. Create OpenAiService by passing token, or you can init it with your own OkHttpClient settings.

@Data
@Component
@ConfigurationProperties(prefix = "openai")
public class OpenAiApiConfig {
    // OpenAI API token
    private String token;

    // Init directly with token only
    @Bean(name = "openAiService")
    public OpenAiService openAiService() {
        return new OpenAiService(token);
    }
}
@Data
@Component
@ConfigurationProperties(prefix = "openai")
public class OpenAiApiConfig {
    // OpenAI API token
    private String token;
    // OpenAI API orgId
    private String orgId;
    // OpenAI API timeout
    private Long timeout;

    // Init with OkHttpClient settings
    @Bean(name = "openAiService")
    public OpenAiService openAiService() {
        ObjectMapper mapper = defaultObjectMapper();
        // Add proxy if need
        // Proxy proxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("127.0.0.1", 1086));
        OkHttpClient client = defaultClient(token, orgId, Duration.ofMillis(timeout))
                .newBuilder()
                .addInterceptor(new ExtractHeaderInterceptor(responseHeaders -> log.info("headers: {}", JSON.toJSONString(responseHeaders))))
                .proxy(proxy)
                .build();
        Retrofit retrofit = defaultRetrofit(client, mapper);
        OpenAiApi api = retrofit.create(OpenAiApi.class);
        return new OpenAiService(api, client);
    }
}

Here is the settings in yml file.

openai:
  token: OPEN_AI_API_TOKEN
  org-id: OPEN_AI_ORG_ID
  timeout: 60000

3. Call API

3.1.a Create Chat Completion (Without stream)

public class OpenAiService {

    public void createStreamChatCompletion() {
        CreateChatCompletionRequest request = CreateChatCompletionRequest.builder()
                .messages(Arrays.asList(new ChatMessage(ChatMessageRole.USER, "Hello, Please count 1 to 10")))
                .model("gpt-3.5-turbo")
                .maxTokens(2048)
                .temperature(0.6)
                .stream(false)
                .build();
        log.info("chatCompletion Request:\n{}", JsonUtils.toPrettyJSONString(request));
        ChatCompletion completionResult = openAiService.createChatCompletion(request);
        log.info("chatCompletion Response:\n{}", JsonUtils.toPrettyJSONString(completionResult));
    }
}

3.1.b Create Chat Completion (With stream)

3.1.b.1 Register listener for stream (use Flux to serve server-sent events)
public class OpenAiService {

    private Flux<ServerSentEvent<List<String>>> buildFlux(String messageId) {
        Flux<ServerSentEvent<List<String>>> flux = Flux.create(fluxSink -> {

            StreamChatCompletionListener listener = new StreamChatCompletionListener() {
                @Override
                public void onOpen(String requestId, Response response) {
                    log.debug("onOpen {}", requestId);
                }

                @Override
                public void onEvent(String requestId, xyz.felh.openai.completion.chat.ChatCompletion chatCompletion) {
                    ChatCompletionChoice chatCompletionChoice = chatCompletion.getChoices().get(0);
                    if ("stop".equalsIgnoreCase(chatCompletionChoice.getFinishReason())) {
                        log.info("chatCompletion stream is stopped");
                        // send stop signature to client
                        fluxSink.next(ServerSentEvent.<List<String>>builder()
                                .id(requestId)
                                .event("stop")
                                .data(Collections.singletonList("stop"))
                                .build());
                    } else {
                        if (chatCompletionChoice.getDelta() != null && chatCompletionChoice.getDelta().getContent() != null) {
                            // send delta message to client
                            fluxSink.next(ServerSentEvent.<List<String>>builder()
                                    .id(requestId)
                                    .event("message")
                                    .data(Collections.singletonList(chatCompletionChoice.getDelta().getContent()))
                                    .build());
                        }
                    }
                }
            };

            // create stream chat message
            CreateChatCompletionRequest request = CreateChatCompletionRequest.builder()
                    .messages(Arrays.asList(new ChatMessage(ChatMessageRole.USER, "Hello, Please count 1 to 10")))
                    .model("gpt-3.5-turbo")
                    .maxTokens(2048)
                    .temperature(0.8)
                    .stream(true)
                    .build();
            log.info("chatCompletion Request:\n{}", JsonUtils.toPrettyJSONString(request));
            openAiService.createSteamChatCompletion(messageId, request, listener);

            // unsubscribe when user disconnect
            fluxSink.onCancel(() -> {
                log.info("flux cancel {}", messageId);
                listener.close();
            });
        }, FluxSink.OverflowStrategy.LATEST);
        return flux;
    }
}

3.2 Create Image

public class OpenAiService {
    public void createImage() {
        CreateImageRequest createImageRequest = CreateImageRequest.builder()
                .prompt("A cute baby dea otter")
                .n(1)
                .size(ImageSize.R_1024X1024)
                .responseFormat(ImageResponseFormat.URL)
                .model(ImageModelType.DALL_E_2.value())
                .build();
        ImageResponse imageResponse = getOpenAiService().createImage(createImageRequest);
        log.info("imageResponse: {}", toJSONString(imageResponse));
    }
}

3.3 Create Embedding

public class OpenAiService {
  
    public void createEmbedding() {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 4095; i++) {
            sb.append("AGI ");
        }

        log.info("f:"+ TikTokenUtils.tokens(EncodingType.CL100K_BASE, sb.toString().trim()));

        List<String> inputs = new ArrayList<>();
        inputs.add(sb.toString().trim());
        CreateEmbeddingRequest createEmbeddingRequest = CreateEmbeddingRequest.builder()
            .input(inputs)
            .encodingFormat(CreateEmbeddingRequest.EncodingFormat.FLOAT)
            .model("text-embedding-ada-002")
            .build();
        CreateEmbeddingResponse createEmbeddingResponse = getOpenAiService().createEmbeddings(createEmbeddingRequest);
        log.info("createEmbeddingResponse:  {}", toJSONString(createEmbeddingResponse));
    }
}

3.4 Create Chat Completion with GPT_4_TURBO with Input Image

public class OpenAiService {

    public void createChatCompletionWithImage() {
        String model = "gpt-4-turbo-2024-04-09";
        ChatMessage chatMessage = new ChatMessage();
        chatMessage.setRole(ChatMessageRole.USER);
        chatMessage.addTextToContent("描述一下图片的内容");
        chatMessage.addImageUrlToContent("https://qn.felh.xyz/ai1.jpg", ChatMessage.ImageUrlDetail.LOW);
        // you can also set image with base64 format
        // chatMessage.addImageWithBase642ContentItem("data:image/jpeg;base64,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", ChatMessage.IMG_DETAIL_HIGH);
        List<ChatMessage> chatMessages = Arrays.asList(
            ChatMessage.builder()
                    .role(ChatMessageRole.SYSTEM)
                    .content("You are a helpful assistant. Do not include pleasantries in your responses. Mark code language tag if there is code.")
                    .build(),
            chatMessage);
        CreateChatCompletionRequest chatCompletionRequest = CreateChatCompletionRequest.builder()
            .messages(chatMessages)
            .maxTokens(4096)
            .temperature(0.6)
            .stream(false)
            .user("FU92834923849328943824")
            .model(model)
            .build();
        ChatCompletion chatCompletion = getOpenAiService().createChatCompletion(chatCompletionRequest);
        log.info("chatCompletion: {}", toJSONString(chatCompletion));
    }
}

3.5 Create Chat Completion with Tool Calls in background.

public class OpenAiService {
    
    public void createFunctionCallStreamChatCompletion() {
        final List<ChatMessage> messages = new ArrayList<>();
        messages.add(new ChatMessage(ChatMessageRole.SYSTEM, "You are an assistant."));
        messages.add(new ChatMessage(ChatMessageRole.USER, "What is weather now in Shanghai?"));

        SchemaGeneratorConfigBuilder configBuilder = new SchemaGeneratorConfigBuilder(SchemaVersion.DRAFT_7, OptionPreset.PLAIN_JSON)
                .with(new JacksonModule());
        SchemaGeneratorConfig config = configBuilder.build();
        SchemaGenerator generator = new SchemaGenerator(config);
        JsonNode jsonSchema = generator.generateSchema(GetWeatherParam.class);
        JSONObject jsonObject = JSONObject.parseObject(jsonSchema.toString());

        CreateChatCompletionRequest chatCompletionRequest = CreateChatCompletionRequest.builder()
                .messages(messages)
                .model("gpt-3.5-turbo-0125")
                .tools(List.of(Tool.builder()
                        .type(Type.FUNCTION)
                        .function(Function.builder()
                                .name("get_weather")
                                .description("Get the current weather in a given location")
                                .parameters(jsonObject)
                                .build()).build()))
                .toolChoice("auto")
                .build();
        StreamChatCompletionListener listener = new StreamChatCompletionListener() {
            @Override
            public void onOpen(String requestId, Response response) {log.info("on onOpen {}", requestId);
            }

            @Override
            public void onEvent(String requestId, ChatCompletion chatCompletion) {log.info("chatCompletion: {}", JSON.toJSONString(chatCompletion));
            }

            @Override
            public void onEventDone(String requestId) {log.info("on onEventDone {}", requestId);
            }

            @Override
            public void onClosed(String requestId) {log.info("on onClosed {}", requestId);
            }

            @Override
            public void onFailure(String requestId, Throwable t, Response response) {log.info("on failure {} {}", requestId, JSON.toJSONString(response));
            }
        };
        getOpenAiService().createSteamChatCompletion("1234", chatCompletionRequest, listener,
                (requestId, chatCompletion) -> {
            log.info("request Id {}", requestId);
            log.info("chatCompletion {}", chatCompletion);
            if (Preconditions.isNotBlank(chatCompletion)
                    && Preconditions.isNotBlank(chatCompletion.getChoices())
                    && Preconditions.isNotBlank(chatCompletion.getChoices().get(0).getDelta())
                    && Preconditions.isNotBlank(chatCompletion.getChoices().get(0).getDelta().getToolCalls())) {
                List<ToolCall> toolCalls = chatCompletion.getChoices().get(0).getDelta().getToolCalls();
                messages.add(chatCompletion.getChoices().get(0).getDelta());
                for (ToolCall toolCall : toolCalls) {
                    ChatMessage chatMessage = new ChatMessage(ChatMessageRole.TOOL, "晴");
                    chatMessage.setToolCallId(toolCall.getId());
                    messages.add(chatMessage);
                }
            }
            return StreamToolCallsRequest.builder().request(CreateChatCompletionRequest.builder()
                            .messages(messages)
                            .model("gpt-3.5-turbo-0125")
                            .build())
                    .requestId("3444444").build();
        });
    }
}

You can find more examples in

License

Published under the MIT License (https://github.com/forestwanglin/openai-java/blob/main/LICENSE)