chore(ai): 파싱 전과정 진단 로그(요청텍스트·모델원문·결과) 추가
Deploy / deploy (push) Failing after 14m50s

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
sb
2026-07-05 12:36:40 +09:00
parent 30cb68c003
commit d65dd88bba
@@ -51,7 +51,11 @@ public class AiEntryParser {
/** 자유 텍스트 → 파싱 결과. 실패/미설정 시 empty. */ /** 자유 텍스트 → 파싱 결과. 실패/미설정 시 empty. */
public Optional<ParsedEntryResponse> parse(String text, LocalDate today) { public Optional<ParsedEntryResponse> parse(String text, LocalDate today) {
if (!enabled() || text == null || text.isBlank()) return Optional.empty(); if (!enabled() || text == null || text.isBlank()) {
log.info("[ai-parse] 건너뜀 — enabled={}, textBlank={}", enabled(), (text == null || text.isBlank()));
return Optional.empty();
}
log.info("[ai-parse] 요청 수신 — text='{}'", text);
try { try {
String system = (""" String system = ("""
너는 한국어 가계부 입력 도우미다. 사용자가 자연어로 쓴 한 줄 지출/수입 메모를 구조화한다. 너는 한국어 가계부 입력 도우미다. 사용자가 자연어로 쓴 한 줄 지출/수입 메모를 구조화한다.
@@ -81,6 +85,7 @@ public class AiEntryParser {
.body(JsonNode.class); .body(JsonNode.class);
String out = stripFences(resp.path("content").path(0).path("text").asText("")).trim(); String out = stripFences(resp.path("content").path(0).path("text").asText("")).trim();
log.info("[ai-parse] 모델 원문='{}'", out);
JsonNode j = om.readTree(out); JsonNode j = om.readTree(out);
String type = "INCOME".equalsIgnoreCase(j.path("type").asText("EXPENSE")) ? "INCOME" : "EXPENSE"; String type = "INCOME".equalsIgnoreCase(j.path("type").asText("EXPENSE")) ? "INCOME" : "EXPENSE";
@@ -90,13 +95,16 @@ public class AiEntryParser {
} catch (Exception e) { } catch (Exception e) {
date = today; date = today;
} }
return Optional.of(ParsedEntryResponse.builder() ParsedEntryResponse result = ParsedEntryResponse.builder()
.recognized(j.path("recognized").asBoolean(false)) .recognized(j.path("recognized").asBoolean(false))
.type(type) .type(type)
.amount(Math.max(0, j.path("amount").asLong(0))) .amount(Math.max(0, j.path("amount").asLong(0)))
.merchant(j.path("merchant").asText("")) .merchant(j.path("merchant").asText(""))
.date(date) .date(date)
.build()); .build();
log.info("[ai-parse] 결과 — recognized={}, type={}, amount={}, merchant={}, date={}",
result.isRecognized(), result.getType(), result.getAmount(), result.getMerchant(), result.getDate());
return Optional.of(result);
} catch (Exception e) { } catch (Exception e) {
log.warn("[ai-parse] 실패 → 규칙기반 폴백: {}", e.toString()); log.warn("[ai-parse] 실패 → 규칙기반 폴백: {}", e.toString());
return Optional.empty(); return Optional.empty();