Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backend : feat] gpt api response dto 수정 #44

Merged
merged 10 commits into from
Mar 9, 2024
3 changes: 3 additions & 0 deletions backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ dependencies {
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'

//GSON
implementation 'com.google.code.gson:gson:2.8.8'

}

tasks.named('test') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,53 @@ public class GptConfig {
public static final String AUTHORIZATION = "Authorization";
public static final String BEARER = "Bearer ";
public static final String CHAT_MODEL = "gpt-3.5-turbo";
public static final Integer MAX_TOKEN = 300;
public static final Integer MAX_TOKEN = 3000;
public static final Boolean STREAM = false;
public static final String ROLE = "user";
public static final Double TEMPERATURE = 0.6;
public static final String MEDIA_TYPE = "application/json; charset=UTF-8";
public static final String CHAT_URL = "https://api.openai.com/v1/chat/completions";
public static final String PROMPT = """
I would like you to plan a package tour program to plan your travel itinerary.Destination: %s
Purpose of travel: %s
Departure date: %s
Entry date: %s
The flight schedule is as follows.

Also, plan your itinerary based on the travel distance and famous tourist destinations.
If possible, create the schedule in one-hour intervals.
Make sure to plan for at least 10 hours of activity each day.

I would like the format to be as follows:
For example
---
2024-02-06
1. Go to location
2. See the place
3. Eat the Lunch
4. Go to location
5. See the place
6. Eat the dinner
7. shopping

2024-02-07
1. Go to location
2. See the place
3. Eat the Lunch
4. Go to location
5. See the place
6. Eat the dinner
7. shopping

2024-02-08
1. Go to location
2. See the place
3. Eat the Lunch
4. Go to location
5. See the place
6. Eat the dinner
7. shopping
---
No need to say anything else, just plan your schedule right away.
Please create the result in Korean.""";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.isp.backend.domain.gpt.constant;

import java.util.List;

public class ParsingConstants {
public static final String DATE_REGEX = "(\\d{4}-\\d{2}-\\d{2})";
public static final String NEW_LINE_REGEX = "\n";
public static final String CURRENT_DATE = "";
public static final int BEGIN_INDEX = 3;
public static final List<String> FILTER_STRINGS = List.of(
"Message(role=assistant, content=", ")"
);
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package com.isp.backend.domain.gpt.controller;

import com.isp.backend.domain.gpt.dto.GptResponseDTO;
import com.isp.backend.domain.gpt.dto.GptScheduleRequestDto;
import com.isp.backend.domain.gpt.entity.GptMessage;
import com.isp.backend.domain.gpt.dto.GptScheduleResponseDto;
import com.isp.backend.domain.gpt.service.GptService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
Expand All @@ -18,8 +17,8 @@ public class GptController {
private final GptService gptService;

@PostMapping("/question")
public ResponseEntity<GptMessage> sendQuestion(@RequestBody GptScheduleRequestDto gptScheduleRequestDto) {
GptResponseDTO gptResponseDTO = gptService.askQuestion(gptScheduleRequestDto);
return ResponseEntity.ok(gptResponseDTO.getChoices().get(0).getMessage());
public ResponseEntity<GptScheduleResponseDto> sendQuestion(@RequestBody GptScheduleRequestDto gptScheduleRequestDto) {
GptScheduleResponseDto gptScheduleResponseDto = gptService.askQuestion(gptScheduleRequestDto);
return ResponseEntity.ok(gptScheduleResponseDto);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.isp.backend.domain.gpt.dto;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.isp.backend.domain.gpt.entity.GptMessage;
import lombok.AllArgsConstructor;
import lombok.Getter;
Expand All @@ -13,30 +12,11 @@
@NoArgsConstructor
@AllArgsConstructor
public class GptResponseDTO {
private String id;
private String object;
private long created;
private String model;
private Usage usage;
private List<Choice> choices;

@Getter
@Setter
public static class Usage {
@JsonProperty("prompt_tokens")
private int promptTokens;
@JsonProperty("completion_tokens")
private int completionTokens;
@JsonProperty("total_tokens")
private int totalTokens;
}

@Getter
@Setter
public static class Choice {
private GptMessage message;
@JsonProperty("finish_reason")
private String finishReason;
private int index;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.List;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class GptScheduleResponseDto {
private GptSchedule gptSchedule;
private List<GptSchedule> schedules;
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.isp.backend.domain.gpt.entity;

import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

Expand All @@ -9,10 +8,11 @@
@Data
@NoArgsConstructor
public class GptSchedule {
private List<GptScheduleDetail> gptScheduleDetails;
private String date;
private List<String> scheduleDetail;

@Builder
public GptSchedule(List<GptScheduleDetail> gptScheduleDetails) {
this.gptScheduleDetails = gptScheduleDetails;
public GptSchedule(String date, List<String> scheduleDetail) {
this.date = date;
this.scheduleDetail = scheduleDetail;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.isp.backend.domain.gpt.entity;

import com.isp.backend.domain.gpt.constant.ParsingConstants;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@RequiredArgsConstructor
@Component
public class GptScheduleParser {

public List<GptSchedule> parseScheduleText(String scheduleText) {
List<GptSchedule> schedules = new ArrayList<>();
Pattern pattern = Pattern.compile(ParsingConstants.DATE_REGEX);

List<String> lines = List.of(scheduleText.split(ParsingConstants.NEW_LINE_REGEX));
List<String> currentScheduleDetail = new ArrayList<>();
String currentDate = ParsingConstants.CURRENT_DATE;

for (String line : lines) {
processLine(line, pattern, schedules, currentScheduleDetail, currentDate);
}

addScheduleIfNotEmpty(currentDate, schedules, currentScheduleDetail);

return schedules;
}

private void processLine(String line, Pattern pattern, List<GptSchedule> schedules, List<String> currentScheduleDetail, String currentDate) {
Matcher dateMatcher = pattern.matcher(line);

if (dateMatcher.find()) {
handleNewDate(currentDate, schedules, currentScheduleDetail, dateMatcher.group(1));
} else {
handleNonDateLine(line, currentScheduleDetail);
}
}

private void handleNewDate(String currentDate, List<GptSchedule> schedules, List<String> currentScheduleDetail, String newDate) {
if (!currentDate.isEmpty()) {
schedules.add(new GptSchedule(currentDate, currentScheduleDetail));
}
}

private void handleNonDateLine(String line, List<String> currentScheduleDetail) {
if (!line.trim().isEmpty() && ParsingConstants.FILTER_STRINGS.stream().noneMatch(line::contains)) {
currentScheduleDetail.add(line.trim().substring(ParsingConstants.BEGIN_INDEX)); // Remove leading index
}
}

private void addScheduleIfNotEmpty(String currentDate, List<GptSchedule> schedules, List<String> currentScheduleDetail) {
if (!currentDate.isEmpty()) {
schedules.add(new GptSchedule(currentDate, currentScheduleDetail));
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
import com.isp.backend.domain.gpt.dto.GptRequestDTO;
import com.isp.backend.domain.gpt.dto.GptResponseDTO;
import com.isp.backend.domain.gpt.dto.GptScheduleRequestDto;
import com.isp.backend.domain.gpt.dto.GptScheduleResponseDto;
import com.isp.backend.domain.gpt.entity.GptMessage;
import com.isp.backend.domain.gpt.mapper.GptMapper;
import com.isp.backend.domain.gpt.entity.GptSchedule;
import com.isp.backend.domain.gpt.entity.GptScheduleParser;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
Expand All @@ -25,7 +27,7 @@
@Service
public class GptService {
private final RestTemplate restTemplate;
private final GptMapper gptMapper;
private final GptScheduleParser gptScheduleParser;

@Value("${api-key.chat-gpt}")
private String apiKey;
Expand All @@ -37,7 +39,7 @@ public HttpEntity<GptRequestDTO> buildHttpEntity(GptRequestDTO gptRequestDTO) {
return new HttpEntity<>(gptRequestDTO, httpHeaders);
}

public GptResponseDTO getResponse(HttpEntity<GptRequestDTO> chatGptRequestHttpEntity) {
public GptScheduleResponseDto getResponse(HttpEntity<GptRequestDTO> chatGptRequestHttpEntity) {

SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setConnectTimeout(60000);
Expand All @@ -48,13 +50,29 @@ public GptResponseDTO getResponse(HttpEntity<GptRequestDTO> chatGptRequestHttpEn
GptConfig.CHAT_URL,
chatGptRequestHttpEntity,
GptResponseDTO.class);
List<GptSchedule> gptSchedules = gptScheduleParser.parseScheduleText(getScheduleText(responseEntity));
return new GptScheduleResponseDto(gptSchedules);
}

private String getScheduleText(ResponseEntity<GptResponseDTO> responseEntity) {
return getGptMessage(responseEntity).toString();
}

private GptMessage getGptMessage(ResponseEntity<GptResponseDTO> responseEntity) {
return getChoices(responseEntity).get(0).getMessage();
}

private List<GptResponseDTO.Choice> getChoices(ResponseEntity<GptResponseDTO> responseEntity) {
return getBody(responseEntity).getChoices();
}

private GptResponseDTO getBody(ResponseEntity<GptResponseDTO> responseEntity) {
return responseEntity.getBody();
}

public GptResponseDTO askQuestion(GptScheduleRequestDto questionRequestDTO) {
public GptScheduleResponseDto askQuestion(GptScheduleRequestDto questionRequestDTO) {
List<GptMessage> messages = new ArrayList<>();
String question = questionRequestDTO.getDepartureDate();
String question = makeQuestion(questionRequestDTO);
messages.add(GptMessage.builder()
.role(GptConfig.ROLE)
.content(question)
Expand All @@ -71,4 +89,13 @@ public GptResponseDTO askQuestion(GptScheduleRequestDto questionRequestDTO) {
)
);
}

private String makeQuestion(GptScheduleRequestDto questionRequestDTO) {
return String.format(GptConfig.PROMPT,
questionRequestDTO.getDestination(),
questionRequestDTO.getPurpose(),
questionRequestDTO.getDepartureDate(),
questionRequestDTO.getReturnDate()
);
}
}
Loading