Skip to content

refactor: Spring AI 응답 반환 로직 개선#31

Merged
Bumnote merged 1 commit intomainfrom
refactor/spring-ai-response
Mar 17, 2026
Merged

refactor: Spring AI 응답 반환 로직 개선#31
Bumnote merged 1 commit intomainfrom
refactor/spring-ai-response

Conversation

@Bumnote
Copy link
Copy Markdown
Member

@Bumnote Bumnote commented Mar 17, 2026

#️⃣ 연관된 이슈

#23

📝 작업 내용

  • Spring AI의 응답을 .content()이 아닌, .entity()로 변경
  • 응답 형식을 json 형식으로 즉, 객체 형태로 받을 수 있도록 강제했습니다.
  • 2회 중복호출 되고 있었던 toJson 함수를 1번만 호출될 수 있도록 수정했습니다.
  • 프롬프트 주입을 @value 어노테이션을 활용하여 Resource 타입으로 받도록 수정했습니다.

💬 리뷰 요구사항

리뷰어가 특별히 봐주었으면 하는 부분이 있다면 작성해주세요


- Spring AI의 응답을 .content()이 아닌, .entity()로 변경
- 응답 형식을 json 형식으로 즉, 객체 형태로 받을 수 있도록 강제했습니다.
@Bumnote Bumnote self-assigned this Mar 17, 2026
@Bumnote Bumnote requested a review from Copilot March 17, 2026 03:39
@Bumnote Bumnote merged commit 4df0c97 into main Mar 17, 2026
3 checks passed
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Spring AI 기반 주간 루틴 추천에서 LLM 응답을 문자열(.content) 파싱 대신 객체(.entity)로 직접 역직렬화하도록 리팩터링하여, 응답 처리 로직을 단순화하고 중복 JSON 변환을 줄이려는 PR입니다. 또한 프롬프트 로딩 방식을 Resource 주입으로 변경했습니다.

Changes:

  • LLM 응답 처리 방식을 .content() + 수동 파싱에서 .entity(WeeklyRecommendResponse.class)로 변경
  • toJson(request) 중복 호출 제거
  • 프롬프트 로딩을 파일 read 방식에서 @Value 기반 Resource 주입 방식으로 변경

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 39 to +44
stopWatch.start("1. Semaphore Acquire");
llmSemaphore.acquire();
stopWatch.stop();

stopWatch.start("2. Prompt & JSON Prep");
String systemMessage = loadPrompt("prompt/routineV4.prompt");
String userJson = toJson(request);
Comment on lines 55 to 72
stopWatch.start("3. LLM API Call (External)");
String llmResponse = chatClient
.prompt()
.system(systemMessage)
.user(userMessage)
.call()
.content();
stopWatch.stop();

stopWatch.start("4. Response Parsing");
WeeklyRecommendResponse response = objectMapper.readValue(sanitize(llmResponse), WeeklyRecommendResponse.class);
WeeklyRecommendResponse response = chatClient
.prompt()
.system(s -> s.text(systemPromptResource))
.user(userMessage)
.call()
.entity(WeeklyRecommendResponse.class);
stopWatch.stop();

log.info(stopWatch.prettyPrint());

return response;

} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new CustomException(LLM_INTERRUPT_ERROR);
} catch (JsonProcessingException e) {
log.error("JSON 파싱 실패. Raw Response: {}", e.getMessage());
throw new CustomException(INVALID_JSON_RESPONSE);
} catch (Exception e) {
log.error("LLM 호출 중 알 수 없는 에러 발생", e);
throw new CustomException(LLM_INTERRUPT_ERROR);
private final ChatClient chatClient;
private final ObjectMapper objectMapper;
private final Semaphore llmSemaphore = new Semaphore(5);
private final int MAX_CONCURRENT_LLM_CALLS = 5;
Comment on lines +32 to +33
@Value("classpath:prompt/routineV4.prompt")
private Resource systemPromptResource;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants