From 90101cfb458045044c83ae699261bdce7749395e Mon Sep 17 00:00:00 2001 From: Hyoseong Jo Date: Fri, 12 Dec 2025 16:17:30 +0900 Subject: [PATCH] commit --- .../kr/co/ragone/service/ChatService.java | 52 ++++++++++++++++--- .../ragone/service/SmartChunkingService.java | 5 +- src/main/resources/application.yml | 4 +- 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/src/main/java/kr/co/ragone/service/ChatService.java b/src/main/java/kr/co/ragone/service/ChatService.java index 2216632..30a2917 100644 --- a/src/main/java/kr/co/ragone/service/ChatService.java +++ b/src/main/java/kr/co/ragone/service/ChatService.java @@ -277,13 +277,14 @@ public class ChatService { // 요청 바디 구성 Map 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; } diff --git a/src/main/java/kr/co/ragone/service/SmartChunkingService.java b/src/main/java/kr/co/ragone/service/SmartChunkingService.java index b062c76..295e457 100644 --- a/src/main/java/kr/co/ragone/service/SmartChunkingService.java +++ b/src/main/java/kr/co/ragone/service/SmartChunkingService.java @@ -149,13 +149,14 @@ public class SmartChunkingService { // 요청 바디 구성 Map 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); } // 메시지 구성 diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 2bf03ef..f666b0c 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -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 사용 # ----------------------------------------------------- # 파일 저장 경로