준비물 : OpenAI Secret API Key
https://firstws.tistory.com/63
0. Postman으로 Test 해보기
method : POST
url : https://api.openai.com/v1/chat/completions
Headers Setting
Content-Type : application/json
Authorization : ${OpenAI Secret API Key}
Body-JSON
{
"model": "gpt-3.5-turbo",
"stream" : true,
"messages": [{"role": "user", "content": "Springboot의 장점이 뭐야?"}]
}
'Send' 클릭해서 요청보내기 - 결과
위와 같이 응답이 여러개 온다면 성공한 겁니다.
실제 ChatGPT를 사용할 때 답변을 한번에 주는게 아니라 마치 타이핑 치는 것 처럼 출력됩니다. 그 기능을 활성화
시키려면 Stream Parameter에 True값을 셋팅해 요청하면 됩니다. (False일 때는 완성된 답변을 반환합니다.)
Stream은 SSE(Server-Sent-Events) 즉, 서버와 한번 연결을 맺고나면 일정 시간동안 서버에서 변경이 발생할 때마다
데이터를 전송받는 방식을 사용합니다.
ref : https://tecoble.techcourse.co.kr/post/2022-10-11-server-sent-events/
설정 - DTO - Config - Controller - Service 순서로 작성해보겠습니다.
1. 설정
spring-boot-starter-webflux의 SSE를 사용하여 stream으로 받아올겁니다.
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
</dependencies>
build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-webflux'
}
2. DTO
@Getter
@NoArgsConstructor
//Front단에서 요청하는 DTO
public class QuestionRequest implements Serializable {
private String question;
}
@Getter
@NoArgsConstructor
//chatGPT에 요청할 DTO Format
public class ChatGptRequest implements Serializable {
private String model;
@JsonProperty("max_tokens")
private Integer maxTokens;
private Double temperature;
private Boolean stream;
private List<ChatGptMessage> messages;
//@JsonProperty("top_p")
//private Double topP;
@Builder
public ChatGptRequest(String model, Integer maxTokens, Double temperature,
Boolean stream, List<ChatGptMessage> messages
/*,Double topP*/) {
this.model = model;
this.maxTokens = maxTokens;
this.temperature = temperature;
this.stream = stream;
this.messages = messages;
//this.topP = topP;
}
}
3. Config 작성하기
@Configuration
public class ChatGptConfig {
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 Boolean STREAM = true;
public static final String ROLE = "user";
public static final Double TEMPERATURE = 0.6;
//public static final Double TOP_P = 1.0;
public static final String MEDIA_TYPE = "application/json; charset=UTF-8";
public static final String CHAT_URL = "https://api.openai.com/v1/chat/completions";
}
4. Controller 작성하기
@PostMapping(value="ask-stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> ask(Locale locale,
HttpServletRequest request,
HttpServletResponse response,
@RequestBody QuestionRequest questionRequest){
try {
return chatGptService.ask(questionRequest);
}catch (JsonProcessingException je){
log.error(je.getMessage());
return Flux.empty();
}
}
5. Service 작성하기
private final ObjectMapper objectMapper = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE );
public Flux<String> ask(QuestionRequest questionRequest) throws JsonProcessingException {
client = WebClient.builder()
.baseUrl(ChatGptConfig.CHAT_URL)
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.defaultHeader(ChatGptConfig.AUTHORIZATION,ChatGptConfig.BEARER + apiKey)
.build();
List<ChatGptMessage> messages = new ArrayList<>();
messages.add(ChatGptMessage.builder()
.role(ChatGptConfig.ROLE)
.content(questionRequest.getQuestion())
.build());
ChatGptRequest chatGptRequest = new ChatGptRequest(
ChatGptConfig.CHAT_MODEL,
ChatGptConfig.MAX_TOKEN,
ChatGptConfig.TEMPERATURE,
ChatGptConfig.STREAM,
messages
//ChatGptConfig.TOP_P
);
String requestValue = objectMapper.writeValueAsString(chatGptRequest);
Flux<String> eventStream = client.post()
.bodyValue(requestValue)
.accept(MediaType.TEXT_EVENT_STREAM)
.retrieve()
.bodyToFlux(String.class);
return eventStream;
}
실행 결과
테스트상 최소한의 parameter를 사용하였으며, 적용 가능한 parameter가 다양하므로 아래 공식문서를 참조해주세요.
ref : https://platform.openai.com/docs/api-reference/completions/create
'Spring & Spring Boot' 카테고리의 다른 글
[Spring&SpringBoot] OpenAI 이미지 생성 API 사용하기 (0) | 2023.05.31 |
---|---|
[Spring&SpringBoot] ChatGPT Spring에서 사용하기 (11) | 2023.05.30 |
[Spring&Spring Boot] @Transaction, rollback이 안될 때가 있다?? (0) | 2023.03.28 |
[SpringBoot] 엑셀 값 가져오기(.xls & .xlsx) (0) | 2023.03.06 |
[SpringBoot] LocalDateTime 받기(클라이언트Json→서버) (0) | 2023.01.18 |