This commit is contained in:
2025-12-12 16:17:30 +09:00
parent aa59037e28
commit 90101cfb45
3 changed files with 51 additions and 10 deletions

View File

@@ -277,13 +277,14 @@ public class ChatService {
// 요청 바디 구성
Map<String, Object> requestBody = new HashMap<>();
requestBody.put("model", chatModel);
requestBody.put("temperature", 0.3);
// gpt-5 계열은 temperature 1만 지원하므로 생략 (기본값 사용)
// 모델에 따라 파라미터 다르게 설정
if (chatModel.startsWith("gpt-5") || chatModel.startsWith("o3") || chatModel.startsWith("o4")) {
requestBody.put("max_completion_tokens", 2000);
requestBody.put("max_completion_tokens", 16000); // gpt-5는 충분히 높게
} else {
requestBody.put("max_tokens", 2000);
requestBody.put("max_tokens", 4000);
requestBody.put("temperature", 0.3); // gpt-4 계열만 temperature 설정
}
// 메시지 구성
@@ -340,9 +341,48 @@ public class ChatService {
// 응답 파싱
if (response.getStatusCode() == HttpStatus.OK) {
JsonNode root = objectMapper.readTree(response.getBody());
String content = root.path("choices").get(0).path("message").path("content").asText();
log.info("[Chat] 응답 생성 완료 - 길이: {}", content.length());
String responseBody = response.getBody();
log.info("[Chat] 응답 원본 (처음 1000자): {}",
responseBody != null ? responseBody.substring(0, Math.min(1000, responseBody.length())) : "null");
JsonNode root = objectMapper.readTree(responseBody);
String content = "";
// 1. 기존 구조: choices[0].message.content
JsonNode choices = root.path("choices");
if (choices.isArray() && choices.size() > 0) {
JsonNode message = choices.get(0).path("message");
content = message.path("content").asText("");
// 2. reasoning_content 시도 (o1/gpt-5 계열)
if (content.isEmpty()) {
content = message.path("reasoning_content").asText("");
}
// 3. text 필드 시도
if (content.isEmpty()) {
content = message.path("text").asText("");
}
}
// 4. output 구조 시도
if (content.isEmpty()) {
content = root.path("output").path("content").asText("");
}
if (content.isEmpty()) {
content = root.path("output").asText("");
}
// 5. finish_reason 확인
String finishReason = choices.size() > 0 ?
choices.get(0).path("finish_reason").asText("") : "";
log.info("[Chat] finish_reason: {}, 응답 길이: {}", finishReason, content.length());
if (content.isEmpty()) {
log.error("[Chat] 응답 content가 비어있음! 전체 응답: {}", responseBody);
return "응답을 파싱할 수 없습니다. (finish_reason: " + finishReason + ")";
}
return content;
}

View File

@@ -149,13 +149,14 @@ public class SmartChunkingService {
// 요청 바디 구성
Map<String, Object> requestBody = new HashMap<>();
requestBody.put("model", chatModel);
requestBody.put("temperature", 0.3);
// gpt-5 계열은 temperature 1만 지원
// 모델에 따라 파라미터 다르게 설정
if (chatModel.startsWith("gpt-5") || chatModel.startsWith("o3") || chatModel.startsWith("o4")) {
requestBody.put("max_completion_tokens", 1000);
requestBody.put("max_completion_tokens", 2000);
} else {
requestBody.put("max_tokens", 1000);
requestBody.put("temperature", 0.3);
}
// 메시지 구성

View File

@@ -51,7 +51,7 @@ openai:
api-key: ${OPENAI_API_KEY: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}
model:
embedding: text-embedding-3-small # 임베딩 모델 (텍스트 → 벡터 변환)
chat: gpt-5-mini # 채팅 모델 - gpt-4o-mini (빠르고 저렴)
chat: gpt-5.2 # 채팅 모델 - gpt-4o-mini (빠르고 저렴)
# -----------------------------------------------------
# RAG (Retrieval-Augmented Generation) 설정
@@ -83,7 +83,7 @@ rag:
# - true: PDF 페이지를 이미지로 변환 후 분석
# - false: 텍스트만 추출
# 주의: 활성화 시 API 비용 크게 증가
model: gpt-5-mini # Vision 모델 - gpt-4o 사용
model: gpt-5.2 # Vision 모델 - gpt-4o 사용
# -----------------------------------------------------
# 파일 저장 경로