개요
스프링에서 GPT-4o API를 활용해 이미지를 전송하고 답변을 받아보자.
yml
먼저 GPT 설정을 위해 yml파일을 작성하자
openai:
model: gpt-4o
api:
key: token
url: https://api.openai.com/v1/chat/completions
model과 gpt 사이트에서 발급받은 key를 token에 넣어 둔 후 API를 요청할 url을 작성한다.
이미지 인코딩하기
GPT에 요청을 하려면 이미지를 base64로 인코딩을 해야 한다. 이를 위해 ImageUtils 클래스를 만들어 MultipartFile이미지를 인코딩 하자
public class ImageUtils {
public static String encodeImageToBase64(MultipartFile imageFile) throws IOException {
byte[] fileContent = imageFile.getBytes();
return Base64.getEncoder().encodeToString(fileContent);
}
}
ChatGPTConfig
GPT Config파일을 설정하자
@Configuration
public class ChatGPTConfig {
@Value("${openai.api.key}")
private String secretKey;
@Bean(name = "GPTRestTemplate")
public RestTemplate gptRestTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.getInterceptors().add(((request, body, execution) -> {
request.getHeaders().add("Authorization", "Bearer " + secretKey);
return execution.execute(request, body);
}));
return restTemplate;
}
}
GPT API를 요청하기 위해 RestTemplate를 등혹한다. 이때 헤더에 Bearer토큰으로 발급받은 scretKey를 넣어서 요청을 보내야 한다.
요청에 필요한 Dto 클래스 만들기
JSON.stringify({
model: "gpt-4o", // 사용할 AI 모델
messages: [{
role: "user", // 메시지 역할을 user로 설정
content: [
{"type": "text", "text": "What is this image?"},
{"type": "image_url", "image_url": {"url": `data:image/jpeg;base64,${base64_image}`}}
]
}, ]
위 제이슨은 GPT API에 이미지와 이미지에 대한 텍스트를 전달하기 위해 필요한 Json이다
이를 담을 Dto를 만들어 보자
@Data
public class ChatGPTRequest {
private String model;
private List<GptRequestMessage> messages;
public ChatGPTRequest(String model, String base64image) {
this.model = model;
this.messages = new ArrayList<>();
List<Object> list = List.of(new ImgContent("image_url",new ImgContent.Img("data:image/jpeg;base64," + base64image)), new TextContent("text", "다음 이미지를 설명해 줘"));
this.messages.add(new GptRequestMessage("user", list));
}
}
model과 prompt역할을 하는 message를 담아준다.
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class GptRequestMessage {
private String role;
private List<Object> content;
}
이미지를 담아줄 ImgConent와 텍스트를 담아 줄 TextContent를 만들어 준다.
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class ImgContent {
private String type;
private Img image_url;
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class Img {
private String url;
}
}
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class TextContent {
private String type;
private String text;
}
GPT API 응답에 해당하는 Dto도 말들어 준다.
@Getter
public class ChatGPTResponse {
private String id;
private String object;
private int created;
private String model;
private List<Choice> choices;
private Usage usage;
@Getter
public static class Choice {
private int index;
private Message message;
private String finish_reason;
}
@Getter
public static class Message {
private String role;
private String content;
}
public static class Usage {
private int prompt_tokens;
private int completion_tokens;
private int total_tokens;
}
}
Controller
@RestController
@RequestMapping("/api/v1/gpt")
@RequiredArgsConstructor
public class ChatGPTController {
@Value("${openai.model}")
private String model;
@Value("${openai.api.url}")
private String apiURL;
private final RestTemplate restTemplate;
@PostMapping("/chat")
public String requestGpt(@RequestPart("image") MultipartFile imageFile) {
String responseContent = null;
try {
String base64Image = ImageUtils.encodeImageToBase64(imageFile);
ChatGPTRequest request = new ChatGPTRequest(model, base64Image);
ChatGPTResponse chatGPTResponse = restTemplate.postForObject(apiURL, request, ChatGPTResponse.class);
responseContent = chatGPTResponse.getChoices().get(0).getMessage().getContent().toString();
}
catch (Exception e) {
e.printStackTrace();
}
return responseContent;
}
}
요청으로 이미지를 MultipartFile로 받은 후 Base64로 인코딩을 한 후 CharGPTRequest에 담은 후 RestTemplate를 통해 요청을 한다. 그 후 응답을 받아 반환해 주면 된다.
'스프링' 카테고리의 다른 글
잘 못 처리한 @ControllerAdvice를 수정하기 (0) | 2024.08.05 |
---|---|
enum 타입(key-value)의 Json 반환, 객체를 Json 직렬화 (0) | 2024.05.17 |
@Profile("local") 사용 (0) | 2024.05.09 |
request 웹 스코프와 프록시 (0) | 2023.07.26 |
프로토타입 스코프 빈과 싱글톤 빈을 함께 사용시 문제점 (0) | 2023.07.25 |