文章目录 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.目录结构
2.OpenAiProperties.java 新增apiUrl
package com. sunxiansheng. openai. config. properties ; import lombok. Data ;
import org. springframework. boot. context. properties. ConfigurationProperties ;
@Data
@ConfigurationProperties ( prefix = "openai" )
public class OpenAiProperties { private String apiKey; private String apiUrl = "https://api.openai.com/v1/chat/completions" ;
}
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 ;
@Configuration
@EnableConfigurationProperties ( { OpenAiProperties . class } )
public class OpenAIAutoConfiguration { @Bean @ConditionalOnMissingBean public OpenAiClient openAiClient ( ) { return new OpenAiClient ( ) ; }
}
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 ;
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 ( ) ) ; public String askAI ( String model, String prompt, boolean base64Encode) { try { 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) ; } 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) ; } } private String encodeBase64 ( String prompt) { return Base64 . getEncoder ( ) . encodeToString ( prompt. getBytes ( StandardCharsets . UTF_8 ) ) ; } private String createJsonRequest ( String model, String encodedPrompt) { JsonObject jsonRequest = new JsonObject ( ) ; jsonRequest. addProperty ( "model" , model) ; JsonArray messages = new JsonArray ( ) ; JsonObject systemMessage = new JsonObject ( ) ; systemMessage. addProperty ( "role" , "system" ) ; systemMessage. addProperty ( "content" , "请根据以下内容提供问题的解决方案。使用中文回答,不要使用markdown语法和特殊符号**之类的,注意,内容可能经过 Base64 编码。" ) ; messages. add ( systemMessage) ; JsonObject userMessage = new JsonObject ( ) ; userMessage. addProperty ( "role" , "user" ) ; userMessage. addProperty ( "content" , encodedPrompt) ; messages. add ( userMessage) ; jsonRequest. add ( "messages" , messages) ; return jsonRequest. toString ( ) ; } 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." ) ; }
}
2.common-openai-starter-demo
1.目录结构
2.application.yml 新增api-url
openai : api-key : guest api-url : https: //api.openai.com/v1/chat/completions
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 ;
@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; }
}
4.OpenAiApplication.java
package com. sunxiansheng. openai ; import org. springframework. boot. SpringApplication ;
import org. springframework. boot. autoconfigure. SpringBootApplication ;
@SpringBootApplication
public class OpenAiApplication { public static void main ( String [ ] args) { SpringApplication . run ( OpenAiApplication . class , args) ; }
}
5.测试