Search

Open AI API 와 사람인 API를 사용해서 직업 추천을 해보자

Status
UPLOADING
Date
2024/02/19
Tags
Open Source

1. 개요

개발 중인 화면 중 일부입니다.
위 화면을 간단하게 요약하면 70일 간의 미션을 통해 사용자의 성향을 파악하고 그에 맞는 직업을 추천해주는 기능입니다.
직업을 추천하기 위해서 사람인 API를 사용하고자 합니다. 참고로 사람인은 한국의 취업 포털 중 하나입니다.
오늘 포스팅에서는 사람인 API 그리고 Open AI를 활용해서 기능을 어떻게 구현하는지 다뤄보도록 하겠습니다.

2. 사람인 API

사람인 API를 사용하기 위해서는 이용신청을 해야 합니다. 이용신청의 경우 몇일 이내에 된다고 확답할 수는 없지만 저의 경우 고객 센터 전화 후 바로 승인 됐습니다
우선 사용하기 전 Access Key를 발급받아야 합니다.

2-1. Access Key 발급

발급 방법은 간단합니다.
앱 이름을 등록해주면 바로 Access Key가 발급됩니다.

2-2 요청 방식

베이스 URL은 다음과 같습니다.
https://oapi.saramin.co.kr/job-search?access-key={key}
다양하게 응용이 가능한데 단순한 예제를 보여드리면 다음과 같습니다.
https://oapi.saramin.co.kr/job-search?access-key={키}&keywords={키워드}&ind_cd={직무코드}
예시 응답은 다음과 같습니다.
이 외에도 공채 정보, 근무지, 직무 코드, 학력 조건 등의 조건을 넣어서 세부적으로 검색이 가능합니다.
예시) ind_cd = 1 → 서비스업

3. Open AI

그렇다면 사람인 APIOpen AI는 어떻게 결합할 수 있을까요?
앞서 말씀 드렸듯 앱에서는 70일 간의 미션을 통해 사용자의 특성을 파악할 수 있습니다. 이러한 특성들을 Open AI에 제공 후 몇 가지의 키워드로 전처리 하는 과정을 거칠 예정입니다.
추려진 키워드를 통해 직무를 검색하고 이에 대한 결과를 사용자에게 반환합니다.
build.gradle에 다음 의존성을 추가해주어야 합니다.
implementation 'com.theokanning.openai-gpt3-java:service:0.18.2'
Java
복사
해당 라이브러리에 대한 소개는 잠시 제쳐두고 코드를 통해 어떻게 사용하는지 간단하게나마 알아보겠습니다.
Open API에서 데이터를 전처리하고 싶다면 어떻게 해야할까요?
저는 챗봇과 유사한 형태로 사용하는데, 전처리 하고 싶은 데이터와 전처리 방식을 Open AI 에게 전달하는 방식으로 진행하고 있습니다.
Open AI의 API Reference를 보면 채팅은 다음 엔드 포인트로 이루어집니다.
POST https://api.openai.com/v1/chat/completions
따라서 이번 포스팅에서는 라이브러리를 통해 해당 엔드 포인트로 쉽게 메세지를 전달하는 과정을 다뤄볼 예정입니다.
@Transactional public SaraminJobRequest generateSaraminRequest(String text) { ChatCompletionResult chatCompletion = openAiService.createChatCompletion( ChatGptRequest.from(text)); String response = ChatGptResponse.of(chatCompletion).messages().get(0).message(); try { SaraminJobRequest request = objectMapper.readValue(response, SaraminJobRequest.class); return request; } catch (Exception e) { throw new IllegalArgumentException("Invalid response"); } }
Java
복사
제가 원하는 건 사용자의 정보를 Saramin API가 받을 수 있는 형태의 Request DTO로 변환하는 것입니다.
openAiService.createChatCompletion()은 오픈소스 라이브러리가 제공하는 메소드인데, 해당 메소드에 ChatGptRequest를 담아 호출하면 ChatCompletionResult에 응답이 담겨서 옵니다.
public record ChatGptRequest(String model, List<ChatMessage> messages, Double temperature) { private static String prefixMessage = "사용자의 주관식 답변을 모아놨어. 여기에서 사용자의 관심사를 추려서 직무코드와 키워드를 반환해줘." + "직무코드는 다음과 같아. (1 - 서비스업, 2 - 제조/화학, 3 - IT, 4 - 은행/금융업, 5 - 미디어/디자인, 6 - 교육업, 7 - 의료 제약/복지, 8 - 판매/유통, 9 - 건설업, 10 - 기관/협회" + "키워드는 사용자의 취향에 맞게 추려서 반환해줘" + "이 때 반환 값은 JSON 형태로 반환하고, 직무 코드는 ind_cd, 키워드는 keyword로 반환해줘"; public static ChatCompletionRequest from(String text) { return ChatCompletionRequest.builder() .model("gpt-3.5-turbo") .messages(List.of(new ChatMessage("user", prefixMessage + text))) .temperature(0.7) .build(); } }
Java
복사
이제 조금 감이 오실 수 있는데, 저는 prefixMessage를 통해 전처리 요구 사항을 명시해두었고, 전달되는 text 파라미터를 통해 전처리 하고 싶은 데이터를 받았습니다. 따라서 해당 요청을 생성하고 이를 openAiService를 통해 Open API 측에 보내면 제가 원하는 데이터가 생성이 됩니다.
+ 참고로 위에서 언급되는 직무코드는 모두 Saramin API를 사용하는데 필요한 정보입니다.

4. Saramin API

사람인 API를 호출하기 위해 외부 API를 호출할 수 있는 WebClient를 사용하였습니다.
public List<SaraminJobResponse> inquire(SaraminJobRequest request) { WebClient webClient = WebClient.create(baseUrl); Mono<JobsContainer> mono = webClient.get() .uri(uriBuilder -> uriBuilder .queryParam("access-key", accessKey) .queryParam("keywords", request.keyword()) .queryParam("ind_cd", request.ind_cd()) .build()) .retrieve() .bodyToMono(JobsContainer.class); ArrayList<SaraminJobResponse> responses = new ArrayList<>(); for (Job job : mono.block().getJobs().getJobList()) { responses.add(SaraminJobResponse.of(job, request.ind_cd())); System.out.println(SaraminJobResponse.of(job, request.ind_cd()).toString()); } return responses; }
Java
복사
엔드 포인트는 사람인에 명시된 가이드라인을 따랐으며, ind_cd에 전처리된 직무 코드 값을 넣으므로써 사용자의 관심사 내에 있는 직업을 추천할 수 있었습니다.