Java中的OpenAI流响应

yftpprvb  于 2023-04-19  发布在  Java
关注(0)|答案(2)|浏览(859)

OpenAI chat/completions API通过传递stream=true来支持流响应。这使得响应能够以数据块的形式出现,而不是一个完整的响应。这将类似于ChatGPT输出答案的方式。
我在不同的语言或技术栈(如here)中看到了类似的问题,但我找不到如何在java(或Kotlin)中使用OkHttp客户端实现的完整示例。
如何以流的形式获取OpenAI的API响应?谢谢!

bvpmtnay

bvpmtnay1#

我修改了代码,现在ChatGPT可以完全通过Java在控制台实现流媒体会话。

import com.theokanning.openai.completion.chat.*;
import com.theokanning.openai.service.OpenAiService;
import io.reactivex.Flowable;
import java.util.*;

public class Starter {
    // Create a new OpenAiService instance with the given API key
    public static OpenAiService service = new OpenAiService("Your API Token");

    public static void main(String[] args) {
        System.out.println("Streaming chat completion...");
        Scanner scanner = new Scanner(System.in);
        String userInput = scanner.nextLine();
        // Create a list of ChatMessage objects
        List<ChatMessage> message = new ArrayList<ChatMessage>();
        message.add(new ChatMessage(ChatMessageRole.USER.value(), userInput));
        // Create a ChatCompletionRequest object
        ChatCompletionRequest chatCompletionRequest;
        boolean running = true;
        // Run the loop until the user enters "exit"
        while (running) {
            chatCompletionRequest = ChatCompletionRequest
                    .builder()
                    .model("gpt-3.5-turbo")
                    .messages(message)
                    .n(1)
                    .maxTokens(500)
                    .logitBias(Collections.emptyMap())
                    .build();
            // Create a Flowable object to stream the chat completion
            Flowable<ChatCompletionChunk> flowableResult = service.streamChatCompletion(chatCompletionRequest);
            // Create a StringBuilder object to store the result
            StringBuilder buffer = new StringBuilder();
            // Subscribe to the Flowable object and print the result
            flowableResult.subscribe(chunk -> {
                chunk.getChoices().forEach(choice -> {
                    String result = choice.getMessage().getContent();
                    if (result != null) {
                        buffer.append(result);
                        System.out.print(choice.getMessage().getContent());
                    }
                });
            }, Throwable::printStackTrace, () -> System.out.println());
            // Get the user input
            userInput = scanner.nextLine();
            // Add the user input to the list of ChatMessage objects
            message.add(new ChatMessage(ChatMessageRole.SYSTEM.value(), buffer.toString()));
            message.add(new ChatMessage(ChatMessageRole.USER.value(), userInput));
            // Exit the loop if the user enters "exit"
            if (userInput.equals("exit")) {
                running = false;
            }
        }
        scanner.close();
        service.shutdownExecutor();
    }
}
dluptydi

dluptydi2#

这是使用java的okhttp来接收来自ChatGPT的流响应:

public static void okHttpEvent(SseEmitter emitter, String prompt, String openAiKey) {
        Request request = new Request.Builder()
                .url("https://{open-api-address}/v1/chat/stream/completions?q=" + prompt + "&eid=" + RequestContext.getRequestId())
                .build();
        OkHttpClient okHttpClient = new OkHttpClient.Builder().addInterceptor(new Interceptor() {
                    @NonNull
                    @Override
                    public Response intercept(@NonNull Interceptor.Chain chain) throws IOException {
                        Request original = chain.request();
                        Request request = original.newBuilder()
                                .header("Authorization", "Bearer " + openAiKey)
                                .header("Accept", MediaType.TEXT_EVENT_STREAM.toString())
                                .method(original.method(), original.body())
                                .build();
                        return chain.proceed(request);
                    }
                })
                .connectTimeout(3, TimeUnit.MINUTES)
                .readTimeout(3, TimeUnit.MINUTES)
                .build();

        RealEventSource realEventSource = new RealEventSource(request, new EventSourceListener() {

            @Override
            public void onOpen(EventSource eventSource, Response response) {

            }

            @Override
            public void onEvent(EventSource eventSource, String id, String type, String data) {
                try {
                    HttpUrl url = eventSource.request().url();
                    String reqId = url.queryParameter("eid");
                    SseChatService.getInstance().appendMsg(data, reqId);
                    emitter.send(data);
                } catch (IOException e) {
                    emitter.completeWithError(e);
                    log.error("send sse to client error", e);
                }
            }

            @Override
            public void onClosed(EventSource eventSource) {
                emitter.complete();
            }

            @Override
            public void onFailure(EventSource eventSource, Throwable t, Response response) {
                emitter.completeWithError(t);
                log.error("event source failure", t);
            }
        });

        realEventSource.connect(okHttpClient);
    }

相关问题