• java实现chatGPT SDK


    搭建一个 ChatGPT-SDK 组件工程,专门用于封装对 OpenAI 接口的使用。由于 OpenAI 接口本身较多,并有各类配置的设置,所以开发一个共用的 SDK 组件,更合适我们在各类工程中扩展使用

     整个流程为:以会话模型为出口,,驱动整个服务的调用链路。并对外提供会话工厂的创建和使用。

     通过工厂模式,开启一个使用okhttp3封装的OpenAi会话服务,进行流程的调用。同时这里还包括请求拦截的处理,因为我们需要对http请求设置一些必要的参数信息,如:apiKey、token。

    这里还用到Retrofit2,Retrofit2可以将HTTP API转化为java接口,并通过注解的方式描述请求参数和响应结果等信息,从而方便的发送网络请求。

    具体实现

    工程目录

    定义IOpenAiApi 接口

    1. String v1_chat_completions = "v1/chat/completions";
    2. /**
    3. * 默认 GPT-3.5 问答模型
    4. * @param chatCompletionRequest 请求信息
    5. * @return 返回结果
    6. */
    7. @POST(v1_chat_completions)
    8. Single completions(@Body ChatCompletionRequest chatCompletionRequest);

     在IOpenAiApi接口里定义访问接口,后续可直接扩展功能如画图等

    会话接口

    1. public interface OpenAiSession {
    2. /**
    3. * 默认 GPT-3.5 问答模型
    4. * @param chatCompletionRequest 请求信息
    5. * @return 返回结果
    6. */
    7. ChatCompletionResponse completions(ChatCompletionRequest chatCompletionRequest);
    8. /**
    9. * 问答模型,流式响应接口
    10. * @param chatCompletionRequest 请求信息
    11. * @param eventSourceListener 实现监听;通过监听的 onEvent 方法接收数据
    12. * @return 返回结果
    13. */
    14. EventSource completions(ChatCompletionRequest chatCompletionRequest, EventSourceListener eventSourceListener) throws JsonProcessingException;
    15. }

    会话工厂

    1. public class DefaultOpenAiSessionFactory implements OpenAiSessionFactory {
    2. private final Configuration configuration;
    3. public DefaultOpenAiSessionFactory(Configuration configuration) {
    4. this.configuration = configuration;
    5. }
    6. @Override
    7. public OpenAiSession openSession() {
    8. // 1. 日志配置
    9. HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
    10. httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS);
    11. // 2. 开启 Http 客户端
    12. OkHttpClient okHttpClient = new OkHttpClient
    13. .Builder()
    14. .addInterceptor(httpLoggingInterceptor)
    15. .addInterceptor(new OpenAiInterceptor(configuration.getApiKey()))
    16. .connectTimeout(450, TimeUnit.SECONDS)
    17. .writeTimeout(450, TimeUnit.SECONDS)
    18. .readTimeout(450, TimeUnit.SECONDS)
    19. //.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 21284)))
    20. .build();
    21. configuration.setOkHttpClient(okHttpClient);
    22. // 3. 创建 API 服务
    23. IOpenAiApi openAiApi = new Retrofit.Builder()
    24. .baseUrl(configuration.getApiHost())
    25. .client(okHttpClient)
    26. .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
    27. .addConverterFactory(JacksonConverterFactory.create())
    28. .build().create(IOpenAiApi.class);
    29. configuration.setOpenAiApi(openAiApi);
    30. return new DefaultOpenAiSession(configuration);
    31. }
    32. }

    你可以想象一下,只要你想调用OpenAI官网的接口,就一定需要用到HTTP服务。那么这些类似零件的装配就需要一个统一收口的地方进行管理。所以我使用工厂模型封装。

    会话接口的实现

    下面只展示流式会话的接口实现

    1. @Override
    2. public EventSource completions(ChatCompletionRequest chatCompletionRequest, EventSourceListener eventSourceListener) throws JsonProcessingException {
    3. return this.completions(Constants.NULL, Constants.NULL, chatCompletionRequest, eventSourceListener);
    4. }
    5. @Override
    6. public EventSource completions(String apiHostByUser, String apiKeyByUser, ChatCompletionRequest chatCompletionRequest, EventSourceListener eventSourceListener) throws JsonProcessingException{
    7. // 核心参数校验;不对用户的传参做更改,只返回错误信息。
    8. if (!chatCompletionRequest.isStream()) {
    9. throw new RuntimeException("illegal parameter stream is false!");
    10. }
    11. // 动态设置 Host、Key,便于用户传递自己的信息
    12. String apiHost = Constants.NULL.equals(apiHostByUser) ? configuration.getApiHost() : apiHostByUser;
    13. String apiKey = Constants.NULL.equals(apiKeyByUser) ? configuration.getApiKey() : apiKeyByUser;
    14. // 构建请求信息
    15. Request request = new Request.Builder()
    16. // url: https://api.openai.com/v1/chat/completions - 通过 IOpenAiApi 配置的 POST 接口,用这样的方式从统一的地方获取配置信息
    17. .url(apiHost.concat(IOpenAiApi.v1_chat_completions))
    18. .addHeader("apiKey", apiKey)
    19. // 封装请求参数信息,如果使用了 Fastjson 也可以替换 ObjectMapper 转换对象
    20. .post(RequestBody.create(MediaType.get(ContentType.JSON.getValue()), new ObjectMapper().writeValueAsString(chatCompletionRequest)))
    21. .build();
    22. // 返回结果信息;EventSource 对象可以取消应答
    23. return factory.newEventSource(request, eventSourceListener);
    24. }

    下面是测试代码

    1. @Slf4j
    2. public class ApiTest {
    3. private OpenAiSession openAiSession;
    4. @Before
    5. public void test_OpenAiSessionFactory() {
    6. // 1. 配置文件
    7. Configuration configuration = new Configuration();
    8. configuration.setApiHost("转发地址");
    9. configuration.setApiKey("你的apiKey");
    10. // 2. 会话工厂
    11. OpenAiSessionFactory factory = new DefaultOpenAiSessionFactory(configuration);
    12. // 3. 开启会话
    13. this.openAiSession = factory.openSession();
    14. }
    15. /**
    16. * 【常用对话模式,推荐使用此模型进行测试】
    17. * 此对话模型 3.5/4.0 接近于官网体验 & 流式应答
    18. */
    19. @Test
    20. public void test_chat_completions_stream_channel() throws JsonProcessingException, InterruptedException {
    21. // 1. 创建参数
    22. ChatCompletionRequest chatCompletion = ChatCompletionRequest
    23. .builder()
    24. .stream(true)
    25. .messages(Collections.singletonList(Message.builder().role(Constants.Role.USER).content("用java写一个冒泡排序").build()))
    26. .model(ChatCompletionRequest.Model.GPT_3_5_TURBO.getCode())
    27. .maxTokens(1024)
    28. .build();
    29. // 2. 用户配置 【可选参数,支持不同渠道的 apiHost、apiKey】- 方便给每个用户都分配了自己的key,用于售卖场景
    30. String apiHost = "转发地址";
    31. String apiKey = "你的apiKey";
    32. // 3. 发起请求
    33. EventSource eventSource = openAiSession.completions(apiHost, apiKey, chatCompletion, new EventSourceListener() {
    34. @Override
    35. public void onEvent(EventSource eventSource, String id, String type, String data) {
    36. log.info("测试结果 id:{} type:{} data:{}", id, type, data);
    37. }
    38. @Override
    39. public void onFailure(EventSource eventSource, Throwable t, Response response) {
    40. log.error("失败 code:{} message:{}", response.code(), response.message());
    41. }
    42. });
    43. // 等待
    44. new CountDownLatch(1).await();
    45. }
    46. }

    这样一个简单的java chatGPT-SDK就实现了,现在你可以在其他的项目使用chatgpt了哦

  • 相关阅读:
    Web前端大作业、基于HTML+CSS+JavaScript响应式个人相册博客网站
    学习笔记:机器学习之支持向量机(七、求核函数)
    全部售罄!1,000 多个Sports Land NFT 在 24 小时内被抢空!
    2024年第十五届蓝桥杯C/C++B组复盘(持续更新)
    数据分析思维与模型:群组分析法
    自动镜像打包&&互联网企业规范化上线流程 —— k8s从入门到高并发系列教程 (六)
    axios进阶——取消已经发出去的请求
    Java自定义注解以及Spring的AOP详解,通过AOP和自定义注解实现日志记录
    链表面试题(图文详解)
    AIGC做题能力谁家强呢?
  • 原文地址:https://blog.csdn.net/yusheng_xyb/article/details/137975141