Spring/[P] AI 챗봇 기반 맞춤형 레시피 서비스

[SpringBoot/ChatGPT] ChatGPT API (3) 일반 대화 - 메세지 전송

alsruds 2024. 2. 26. 20:56

 

 

SpringBoot 를 이용하는 백엔드 서버에서 ChatGPT 로 메세지를 전송해 봅시다 ~

 

1. Configuration : ChatGPT 설정 정보 + 데이터 전송 시 필요한 데이터 세팅
2. Controller : 프론트 서버 요청 동작 처리
3. Service : 백엔드 → ChatGPT 메세지 데이터 전송
4. DTO : 프론트 → 백 & 백 → ChatGPT 서버로 전송할 메세지 데이터 세팅

 


 

[ Configuration ]

🤖 ChatGPT API 기종 선택 + 요청 시 필요한 데이터 정보 입력

 

1. 필요한 데이터 확인하기

🏠 https://platform.openai.com/docs/api-reference/chat/create

 

요청 예시

curl https://api.openai.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "model": "gpt-3.5-turbo",
    "messages": [
      {
        "role": "system",
        "content": "You are a helpful assistant."
      },
      {
        "role": "user",
        "content": "Hello!"
      }
    ]
  }'

· Http Method : POST

· 요청 경로 : https://api.openai.com/v1/chat/completions 

· Header 에 포함해야 하는 값 : Content-Type, API Key

· Request Body : model, messages (필수값만 포함해서 요청할 예정, optional 값들 추가 가능)

 

2. ChatGptConfig

@Configuration
public class ChatGptConfig {
    public static final String AUTHORIZATION = "Authorization";
    public static final String BEARER = "Bearer ";
    public static final String MODEL = "gpt-3.5-turbo";
    public static final String MEDIA_TYPE = "application/json; charset=UTF-8";
    public static final String URL = "https://api.openai.com/v1/chat/completions";
}

 

 

[ Controller ]

🤖 클라이언트 측에서 들어오는 요청 동작 처리

 

ChatGptController

@Slf4j
@RestController
@RequestMapping("/ai-chat")
@RequiredArgsConstructor
@Tag(name = "AI Recipe Chatbot", description = "레시피 추천 챗봇 관련 API")
public class ChatGptController {
    private final ChatGptService chatGPTService;

    // 일반 대화
    @PostMapping()
    @Operation(summary = "일반 대화 API", description = "챗봇과 일반적인 대화를 할 수 있는 API 입니다")
    public ApiResponse<UserChatGptResponseDTO.UserGptResponseDTO> getChatTalk(@RequestBody @Valid UserChatGptRequestDTO.UserGptRequestDTO request) {
        String response = chatGPTService.askQuestion(request.getQuestion()).getChoices().get(0).getMessage().getContent();
        return ApiResponse.onSuccess(ChatGptConverter.toUserGptResponseDTO(response));
    }
}

 

· 클라이언트에서 서버로 넘어오는 질문 DTO : UserChatGptRequestDTO.UserGptRequestDTO

· 일반 대화 구현 메소드 호출 후 응답 반환

 

 

[ Service ]

🤖 백엔드 서버에서 ChatGPT 서버로 메세지 전송

 

0.  ChatGPT API Key 등록

2024.02.21 - [Spring/[Project] AI 챗봇 기반 맞춤형 레시피 서비스] - [SpringBoot/ChatGPT] ChatGPT API (1) API Key 발급

 

[SpringBoot/ChatGPT] ChatGPT API (1) API Key 발급

ChatGPT API 를 사용하기 위해 API Key 를 발급받아 봅시다 ~ [ API Key 발급받기 ] 🏠 https://platform.openai.com/api-keys 1. 새로운 키 생성 2. 키 이름 작성 3. 생성된 키 복사 ✔️ 생성된 secret key 는 다시 열람

alsrudalsrudalsrud.tistory.com

2024.02.22 - [Spring/[Project] AI 챗봇 기반 맞춤형 레시피 서비스] - [SpringBoot/ChatGPT] ChatGPT API (2) 프로젝트 설정

 

[SpringBoot/ChatGPT] ChatGPT API (2) 프로젝트 설정

스프링부트 프로젝트에서 ChatGPT API 를 사용할 수 있도록 설정 정보를 입력해 봅시다 ~ [ SpringBoot 프로젝트 설정하기 ] 0. ChatGPT API Key 발급 2024.02.21 - [Spring/[Project] AI 챗봇 기반 맞춤형 레시피 서비

alsrudalsrudalsrud.tistory.com

 

1. Interface

public interface ChatGptService {

    // 일반 대화
    ChatGptResponseDTO askQuestion(String question);
}

 

2. Implementation

@Service
@RequiredArgsConstructor
@Transactional
@Slf4j
public class ChatGptServiceImpl implements ChatGptService {

    @Value("${chatgpt.api-key}")
    private String apiKey;

    // ChatGPT 에 요청할 때 포함해야 하는 값 세팅하기
    @Transactional
    public HttpEntity<ChatGptRequestDTO> buildHttpEntity(ChatGptRequestDTO requestDTO) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.parseMediaType(ChatGptConfig.MEDIA_TYPE));
        headers.add(ChatGptConfig.AUTHORIZATION, ChatGptConfig.BEARER + apiKey);
        return new HttpEntity<>(requestDTO, headers);
    }

    // ChatGPT API 요청하기 - 일반 대화
    @Override
    public ChatGptResponseDTO askQuestion(String question) {
        // ChatGPT API 사용 시 지켜야 할 DTO 맞추기
        List<ChatGptMessageDto> messages = new ArrayList<>();
        messages.add(ChatGptMessageDto.builder()
                .role("user")
                .content(question)
                .build());

        // 응답 반환
        ...
    }
}

 

 

[ DTO ]

🤖 전달하는 메세지 데이터 세팅

 

1. 프론트엔드 → 백엔드

public class UserChatGptRequestDTO implements Serializable {

    @Getter
    public static class UserGptRequestDTO {
        private String question;
    }
}

 

2. 백엔드 → ChatGPT

@Getter
@NoArgsConstructor
public class ChatGptRequestDTO implements Serializable {

    private List<ChatGptMessageDto> messages;
    private String model;

    @Builder
    public ChatGptRequestDTO(List<ChatGptMessageDto> messages, String model) {
        this.messages = messages;
        this.model = model;
    }
}

 

@Getter
@NoArgsConstructor
public class ChatGptMessageDto implements Serializable {

    private String role;
    private String content;

    @Builder
    public ChatGptMessageDto(String role, String content) {
        this.role = role;
        this.content = content;
    }
}