首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

OpenAI模块重构

  • 25-02-17 11:01
  • 2507
  • 6682
blog.csdn.net

文章目录

    • 1.common-openai-starter
        • 1.目录结构
        • 2.OpenAiProperties.java 新增apiUrl
        • 3.OpenAIAutoConfiguration.java
        • 4.OpenAiClient.java 使用gson重构
    • 2.common-openai-starter-demo
        • 1.目录结构
        • 2.application.yml 新增api-url
        • 3.OpenAiController.java
        • 4.OpenAiApplication.java
        • 5.测试

1.common-openai-starter

1.目录结构

CleanShot 2025-01-02 at 16.40.21@2x

2.OpenAiProperties.java 新增apiUrl
package com.sunxiansheng.openai.config.properties;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * Description: OpenAI配置属性类
 *
 * @Author sun
 * @Create 2024/12/14 11:44
 * @Version 1.0
 */
@Data
@ConfigurationProperties(prefix = "openai")
public class OpenAiProperties {

    /**
     * OpenAI API Key
     */
    private String apiKey;

    /**
     * OpenAI API URL 有默认值
     */
    private String apiUrl = "https://api.openai.com/v1/chat/completions";
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
3.OpenAIAutoConfiguration.java
package com.sunxiansheng.openai.config;

import com.sunxiansheng.openai.client.OpenAiClient;
import com.sunxiansheng.openai.config.properties.OpenAiProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Description: OpenAI自动配置类
 *
 * @Author sun
 * @Create 2024/12/14 11:39
 * @Version 1.0
 */
@Configuration
@EnableConfigurationProperties({OpenAiProperties.class}) // 启用配置类
public class OpenAIAutoConfiguration {

    /**
     * 创建 OpenAiClient
     *
     * @return
     */
    @Bean
    @ConditionalOnMissingBean
    public OpenAiClient openAiClient() {
        return new OpenAiClient();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
4.OpenAiClient.java 使用gson重构
package com.sunxiansheng.openai.client;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.sunxiansheng.openai.config.properties.OpenAiProperties;
import okhttp3.*;

import javax.annotation.Resource;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Description: OpenAI 客户端类
 *
 * @Author sun
 * @Create 2024/12/14 11:56
 * @Version 1.1
 */
public class OpenAiClient {

    @Resource
    private OpenAiProperties openAiProperties;

    private static final OkHttpClient CLIENT = new OkHttpClient.Builder()
            .connectTimeout(120, TimeUnit.SECONDS)
            .readTimeout(120, TimeUnit.SECONDS)
            .writeTimeout(120, TimeUnit.SECONDS)
            .build();

    private static final Logger LOGGER = Logger.getLogger(OpenAiClient.class.getName());

    /**
     * 向 AI 提问通用方法
     *
     * @param model        使用的 AI 模型,如 "gpt-4o"
     * @param prompt       提示内容
     * @param base64Encode 是否对内容进行 Base64 编码
     * @return AI 的响应内容
     */
    public String askAI(String model, String prompt, boolean base64Encode) {
        try {
            // 处理 Base64 编码
            String encodedPrompt = base64Encode ? encodeBase64(prompt) : prompt;

            // 构造请求体
            RequestBody body = RequestBody.create(
                    createJsonRequest(model, encodedPrompt), MediaType.get("application/json; charset=utf-8")
            );

            // 构建请求
            Request request = new Request.Builder()
                    .url(openAiProperties.getApiUrl())
                    .header("Authorization", "Bearer " + openAiProperties.getApiKey())
                    .header("Content-Type", "application/json")
                    .post(body)
                    .build();

            // 发送请求并获取响应
            try (Response response = CLIENT.newCall(request).execute()) {
                if (!response.isSuccessful()) {
                    throw new IOException("Unexpected response: " + response);
                }

                // 解析 JSON 响应
                return parseResponse(response.body().string());
            }
        } catch (IOException e) {
            LOGGER.log(Level.SEVERE, "Error occurred during API request: " + e.getMessage(), e);
            throw new RuntimeException("API request failed", e);
        }
    }

    /**
     * 对输入内容进行 Base64 编码
     *
     * @param prompt 输入内容
     * @return 编码后的字符串
     */
    private String encodeBase64(String prompt) {
        return Base64.getEncoder().encodeToString(prompt.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 构建请求的 JSON 数据
     *
     * @param model         使用的 AI 模型
     * @param encodedPrompt 编码后的输入内容
     * @return 构建好的 JSON 字符串
     */
    private String createJsonRequest(String model, String encodedPrompt) {
        JsonObject jsonRequest = new JsonObject();
        jsonRequest.addProperty("model", model);

        JsonArray messages = new JsonArray();

        // 添加 system 信息
        JsonObject systemMessage = new JsonObject();
        systemMessage.addProperty("role", "system");
        systemMessage.addProperty("content", "请根据以下内容提供问题的解决方案。使用中文回答,不要使用markdown语法和特殊符号**之类的,注意,内容可能经过 Base64 编码。");
        messages.add(systemMessage);

        // 添加 user 信息
        JsonObject userMessage = new JsonObject();
        userMessage.addProperty("role", "user");
        userMessage.addProperty("content", encodedPrompt);
        messages.add(userMessage);

        jsonRequest.add("messages", messages);

        return jsonRequest.toString();
    }

    /**
     * 解析 API 响应内容
     *
     * @param responseBody 响应的 JSON 内容
     * @return 解析后的结果
     */
    private String parseResponse(String responseBody) {
        JsonObject jsonObject = JsonParser.parseString(responseBody).getAsJsonObject();
        JsonArray choices = jsonObject.getAsJsonArray("choices");

        if (choices != null && choices.size() > 0) {
            JsonObject choice = choices.get(0).getAsJsonObject();
            JsonObject message = choice.getAsJsonObject("message");
            return message.get("content").getAsString();
        }

        throw new RuntimeException("Invalid response: No choices found.");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136

2.common-openai-starter-demo

1.目录结构

CleanShot 2025-01-02 at 16.47.19@2x

2.application.yml 新增api-url
openai:
  api-key: guest # 必填,OpenAI API Key
  api-url: https://api.openai.com/v1/chat/completions # 可选,有默认值,为了防止以后 URL 变化
  • 1
  • 2
  • 3
3.OpenAiController.java
package com.sunxiansheng.openai.controller;

import com.sunxiansheng.openai.client.OpenAiClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * Description: OpenAI 控制器类
 *
 * @Author sun
 * @Create 2024/12/14 12:27
 * @Version 1.0
 */
@RestController
public class OpenAiController {

    @Resource
    private OpenAiClient openAiClient;

    @RequestMapping("/ask")
    public String ask(String question) {
        String res = openAiClient.askAI("gpt-4o", question, false);
        return "AI回答:" + res;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
4.OpenAiApplication.java
package com.sunxiansheng.openai;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * Description: OpenAI启动类
 *
 * @Author sun
 * @Create 2024/12/14 12:23
 * @Version 1.0
 */
@SpringBootApplication
public class OpenAiApplication {

    public static void main(String[] args) {
        SpringApplication.run(OpenAiApplication.class, args);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
5.测试

CleanShot 2025-01-02 at 16.48.52@2x

一起学习,一起进步!
微信名片
注:本文转载自blog.csdn.net的S-X-S的文章"https://blog.csdn.net/m0_64637029/article/details/145335395"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

108
Python
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top