Skip to content

[PIPELINE] Vision, RAG 파트와 통합 및 예외 처리 보완 이전 Pull Request#17

Merged
s0ooo0k merged 12 commits into
PETTY-HUB:mainfrom
Juyoung8563:main
Apr 22, 2025
Merged

[PIPELINE] Vision, RAG 파트와 통합 및 예외 처리 보완 이전 Pull Request#17
s0ooo0k merged 12 commits into
PETTY-HUB:mainfrom
Juyoung8563:main

Conversation

@Juyoung8563
Copy link
Copy Markdown
Contributor

📜 PR 내용 요약

  • 반려동물 필수 정보와 대한민국 행정 구역명 기반 사용자 위치 정보의 문자열을 하나의 JSON으로 반환하도록 수정하였습니다.

⚒️ 작업 및 변경 내용

  • Together API의 프롬프트를 수정하여 중괄호{ }를 제외한 JSON을 제작하도록 변경하였습니다.
  • 최종 반환할 JSON에 사용자의 위치 정보를 필수 정보가 담긴 JSON 내부의 "location"에 주입하였습니다.
  • 아래는 최종 JSON을 View로 출력한 결과입니다.
  • Controller에서 관리하던 프롬프트를 포함한 로직을 다른 Service로 구현하였습니다. PromptAssemblyService

스크린샷 2025-04-22 173648

📚 기타 참고 사항

  • 금일 기준(04/22)에 merge한 코드를 pull하지 않은 상태로 작성하였습니다.
  • build.gradle 및 yml 파일에 변경사항은 없습니다.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 22, 2025

Important

Review skipped

Auto reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Summary by CodeRabbit

  • 신규 기능

    • 위치 입력란에 한국 행정구역 전체를 포함한 자동완성 드롭다운 기능이 추가되었습니다.
  • UI 개선

    • 폼 제목이 "여행지 추천 요청"에서 "프롬프트 제작소"로 변경되었습니다.
    • 버튼 문구가 "추천 요청"에서 "제작하기"로 변경되었습니다.
    • 결과 영역 제목이 "추천 결과"에서 "제작 결과"로 변경되었습니다.
    • 추출된 반려동물 정보 JSON 표시가 제거되었습니다.
  • 리팩터링

    • 내부 추천 처리 로직이 단순화되어, 여러 단계의 서비스 호출이 하나의 프롬프트 생성 서비스 호출로 통합되었습니다.

Walkthrough

이 변경 사항은 기존의 파이프라인 컨트롤러에서 TogetherService와 GeminiService를 연속적으로 호출하던 방식을 단일 PromptAssemblyService 호출로 대체하는 리팩터링을 수행합니다. Gemini 관련 DTO, 서비스 인터페이스 및 구현체가 모두 삭제되고, 프롬프트 조립과 생성을 담당하는 새로운 서비스 계층(PromptAssemblyService, PromptGeneratorService)이 도입되었습니다. 프론트엔드 템플릿에서는 입력 폼이 자동완성 드롭다운으로 교체되고, UI 텍스트와 결과 표시 방식이 변경되었습니다.

Changes

파일/경로 요약 변경 요약
src/main/java/io/github/petty/pipeline/controller/PipelineController.java TogetherService, GeminiService 제거 및 PromptAssemblyService 도입. 프로세스 메서드가 프롬프트 조립 서비스만 호출하도록 변경.
src/main/java/io/github/petty/pipeline/model/dto/GeminiRequestDTO.java,
src/main/java/io/github/petty/pipeline/model/dto/GeminiResponseDTO.java
Gemini API 통신용 DTO 전체 삭제.
src/main/java/io/github/petty/pipeline/service/GeminiService.java,
src/main/java/io/github/petty/pipeline/service/GeminiServiceImpl.java
GeminiService 인터페이스 및 구현체 전체 삭제.
src/main/java/io/github/petty/pipeline/service/PromptAssemblyService.java,
src/main/java/io/github/petty/pipeline/service/PromptAssemblyServiceImpl.java
PromptAssemblyService 인터페이스 및 구현체 신규 추가. TogetherService와 PromptGeneratorService를 조합하여 프롬프트 생성.
src/main/java/io/github/petty/pipeline/service/PromptGeneratorService.java,
src/main/java/io/github/petty/pipeline/service/PromptGeneratorServiceImpl.java
PromptGeneratorService 인터페이스 및 구현체 신규 추가. 추출된 반려동물 정보와 위치를 받아 프롬프트 JSON 생성.
src/main/resources/templates/pipeline.html 입력 폼 텍스트와 버튼 라벨 변경, 위치 입력에 자동완성 드롭다운 도입, 결과 표시 텍스트 변경 및 JSON 표시 블록 삭제, 관련 JS/CSS 추가.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant PipelineController
    participant PromptAssemblyService
    participant TogetherService
    participant PromptGeneratorService

    User->>PipelineController: visionReport, location 입력 제출
    PipelineController->>PromptAssemblyService: assemblePrompt(visionReport, location)
    PromptAssemblyService->>TogetherService: answer(반려동물 정보 추출 프롬프트)
    TogetherService-->>PromptAssemblyService: 추출된 반려동물 정보(JSON)
    PromptAssemblyService->>PromptGeneratorService: generatePrompt(반려동물정보, location)
    PromptGeneratorService-->>PromptAssemblyService: 최종 프롬프트 문자열
    PromptAssemblyService-->>PipelineController: 프롬프트 문자열
    PipelineController-->>User: 제작 결과(프롬프트) 반환
Loading

Possibly related PRs

Poem

🐇
프롬프트 조립소 문을 열었네,
예전엔 서비스 두 번 불렀지만
이제는 한 번에 뚝딱 완성!
자동완성 드롭다운, 위치 입력도 편해졌지.
코드도, 화면도 깔끔하게 변신—
토끼는 오늘도 리팩터링에 신이 났다네!
🥕✨


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@Juyoung8563
Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 22, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (7)
src/main/java/io/github/petty/pipeline/service/PromptAssemblyService.java (1)

3-5: 명확한 인터페이스지만 예외 처리 개선 가능

인터페이스는 간결하고 목적이 명확합니다. 다만, 일반적인 Exception을 던지는 것보다 구체적인 예외 유형을 명시하는 것이 호출하는 쪽에 더 명확한 정보를 제공할 수 있습니다.

- String assemblePrompt(String visionReport, String location) throws Exception;
+ String assemblePrompt(String visionReport, String location) throws IllegalArgumentException, ServiceException;
src/main/java/io/github/petty/pipeline/service/PromptGeneratorServiceImpl.java (1)

10-15: JSON 형식에 대한 주석 추가 필요

extractedPetInfoJson이 중괄호({})를 포함하지 않는다는 가정하에 코드가 작성되어 있습니다. 이 가정을 명확히 하는 주석이 있으면 코드의 의도가 더 명확해질 것입니다.

@Override
public String generatePrompt(String extractedPetInfoJson, String location) {
+    // extractedPetInfoJson은 중괄호({})가 없는 JSON 내부 콘텐츠만 포함해야 함
+    // TogetherService에서 반환된 결과에 이미 중괄호가 제거되어 있음
    return String.format("""
            {
            %s
            "location": "%s"
            }
            """, extractedPetInfoJson, location);
}
src/main/java/io/github/petty/pipeline/service/PromptAssemblyServiceImpl.java (2)

14-18: 프롬프트 문자열 연결 방식 개선

현재 코드에서는 문자열 연결을 위해 + 연산자를 여러 번 사용하고 있습니다. 이는 가독성을 저하시키고 잠재적인 버그의 원인이 될 수 있습니다. 특히, "no markdown, only JSON"과 "최종 결과에 {}는 제거" 사이에 공백이 없어 의도하지 않은 결과가 나올 수 있습니다.

- String extractedPetInfoJson = togetherService.answer(
-         visionReport + " -> 이 문장에서 반려동물의 이름(name), 종(species), 무게(weight), 맹수 여부(is_danger(only true or false))를 JSON 형식으로 작성 + " +
-                 "만약 반려동물의 종과 무게를 보았을 때, 입마개가 필요할 것 같다면 맹수 여부를 'true'로 작성 + " +
-                 "무게는 kg 단위를 반드시 포함" + "no markdown, only JSON" + "최종 결과에 {}는 제거"
- );
+ String extractedPetInfoJson = togetherService.answer(String.format(
+         "%s -> 이 문장에서 반려동물의 이름(name), 종(species), 무게(weight), 맹수 여부(is_danger(only true or false))를 JSON 형식으로 작성 + " +
+         "만약 반려동물의 종과 무게를 보았을 때, 입마개가 필요할 것 같다면 맹수 여부를 'true'로 작성 + " +
+         "무게는 kg 단위를 반드시 포함 + no markdown, only JSON + 최종 결과에 {}는 제거",
+         visionReport
+ ));

1-22: ServiceException 클래스 추가 필요

위의 개선 제안에서 ServiceException 클래스를 사용했습니다. 이 클래스가 아직 정의되지 않았다면 추가해야 합니다.

package io.github.petty.pipeline.exception;

public class ServiceException extends Exception {
    public ServiceException(String message) {
        super(message);
    }
    
    public ServiceException(String message, Throwable cause) {
        super(message, cause);
    }
}

이 예외 클래스를 추가하시겠습니까? 아니면 기존에 있는 다른 예외 클래스를 사용하시겠습니까?

src/main/java/io/github/petty/pipeline/controller/PipelineController.java (1)

34-43: 예외 처리 개선 가능성이 있습니다.

현재 모든 예외를 catch하고 있지만, 특정 예외 유형에 따라 다른 오류 메시지를 제공하는 것이 사용자 경험을 향상시킬 수 있습니다.

try {
    String prompt = promptAssemblyService.assemblePrompt(visionReport, location);
    model.addAttribute("recommendation", prompt);
    return "pipeline";
-} catch (Exception e) {
-    log.error("프롬프트 제작 중 오류 발생", e);
-    model.addAttribute("error", "결과를 받아오지 못했습니다.");
+} catch (IllegalArgumentException e) {
+    log.error("입력 데이터 처리 중 오류 발생", e);
+    model.addAttribute("error", "입력 정보가 올바르지 않습니다: " + e.getMessage());
+    return "pipeline";
+} catch (Exception e) {
+    log.error("프롬프트 제작 중 오류 발생", e);
+    model.addAttribute("error", "결과를 받아오지 못했습니다.");
    return "pipeline";
}
src/main/resources/templates/pipeline.html (2)

171-201: 드롭다운 필터링 성능 최적화 가능성이 있습니다.

현재 구현은 모든 필터링을 클라이언트 측에서 수행합니다. 지역 목록이 매우 큰 경우 성능에 영향을 줄 수 있습니다. 대규모 데이터셋의 경우 디바운싱 기법을 적용하는 것이 좋습니다.

+        // 입력 디바운싱을 위한 타이머 변수 추가
+        let debounceTimer;
+        
         locationInput.addEventListener('input', function () {
+            // 기존 타이머 취소
+            clearTimeout(debounceTimer);
+            
+            // 타이머 설정: 300ms 후에 필터링 실행
+            debounceTimer = setTimeout(() => {
             const query = this.value.trim().toLowerCase();
             dropdownList.innerHTML = '';

             if (!query) {
                 dropdownList.style.display = 'none';
                 return;
             }

             const filtered = regions.filter(region =>
                 region.toLowerCase().includes(query)
             );

             if (filtered.length === 0) {
                 dropdownList.style.display = 'none';
                 return;
             }

             filtered.forEach(region => {
                 const li = document.createElement('li');
                 li.textContent = region;
                 li.addEventListener('click', () => {
                     locationInput.value = region;
                     dropdownList.style.display = 'none';
                 });
                 dropdownList.appendChild(li);
             });

             dropdownList.style.display = 'block';
+            }, 300);
         });

82-86: 접근성 개선을 위한 ARIA 속성 추가가 필요합니다.

현재 자동완성 드롭다운은 WAI-ARIA 표준을 따르지 않아 스크린 리더와 같은 보조 기술을 사용하는 사용자가 어려움을 겪을 수 있습니다.

 <label for="locationInput">여행 희망 지역 (예: 강릉, 부평 등)</label>
-<div class="dropdown">
-    <input type="text" name="location" id="locationInput" placeholder="지역 키워드 검색" autocomplete="off" required>
-    <ul id="dropdownList" class="dropdown-list"></ul>
+<div class="dropdown" role="combobox" aria-haspopup="listbox" aria-expanded="false">
+    <input type="text" name="location" id="locationInput" placeholder="지역 키워드 검색" autocomplete="off" required aria-autocomplete="list" aria-controls="dropdownList">
+    <ul id="dropdownList" class="dropdown-list" role="listbox"></ul>
 </div>

JavaScript에서도 ARIA 상태를 업데이트하도록 변경:

 dropdownList.style.display = 'block';
+document.querySelector('.dropdown').setAttribute('aria-expanded', 'true');
 dropdownList.style.display = 'none';
+document.querySelector('.dropdown').setAttribute('aria-expanded', 'false');
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8f8419b and 5594874.

📒 Files selected for processing (10)
  • src/main/java/io/github/petty/pipeline/controller/PipelineController.java (3 hunks)
  • src/main/java/io/github/petty/pipeline/model/dto/GeminiRequestDTO.java (0 hunks)
  • src/main/java/io/github/petty/pipeline/model/dto/GeminiResponseDTO.java (0 hunks)
  • src/main/java/io/github/petty/pipeline/service/GeminiService.java (0 hunks)
  • src/main/java/io/github/petty/pipeline/service/GeminiServiceImpl.java (0 hunks)
  • src/main/java/io/github/petty/pipeline/service/PromptAssemblyService.java (1 hunks)
  • src/main/java/io/github/petty/pipeline/service/PromptAssemblyServiceImpl.java (1 hunks)
  • src/main/java/io/github/petty/pipeline/service/PromptGeneratorService.java (1 hunks)
  • src/main/java/io/github/petty/pipeline/service/PromptGeneratorServiceImpl.java (1 hunks)
  • src/main/resources/templates/pipeline.html (1 hunks)
💤 Files with no reviewable changes (4)
  • src/main/java/io/github/petty/pipeline/service/GeminiService.java
  • src/main/java/io/github/petty/pipeline/model/dto/GeminiRequestDTO.java
  • src/main/java/io/github/petty/pipeline/model/dto/GeminiResponseDTO.java
  • src/main/java/io/github/petty/pipeline/service/GeminiServiceImpl.java
🔇 Additional comments (14)
src/main/java/io/github/petty/pipeline/service/PromptGeneratorService.java (1)

3-5: 인터페이스 설계가 깔끔합니다.

간결하고 목적이 명확한 인터페이스 설계입니다. 매개변수와 반환 타입이 명확히 정의되어 있습니다.

src/main/java/io/github/petty/pipeline/controller/PipelineController.java (5)

3-5: import 문이 리팩토링을 정확히 반영합니다.

import 문이 기존 서비스들(GeminiService 등)에서 새로운 PromptAssemblyService와 PromptGeneratorService로 적절하게 변경되었습니다. 여전히 TogetherService는 유지되고 있는 것으로 보입니다.


19-19: 의존성 주입이 올바르게 구현되었습니다.

PromptAssemblyService를 필드로 선언하고 @requiredargsconstructor를 통해 자동 주입하는 방식이 Spring 권장 패턴에 일치합니다.


28-31: 한글 주석이 명확하게 처리되었습니다.

주석이 한글로 작성되어 있고, 각 매개변수의 용도를 명확하게 설명하고 있습니다.


35-36: 프롬프트 생성 로직이 적절히 서비스로 이동되었습니다.

여러 단계의 처리 로직을 PromptAssemblyService로 위임하여 컨트롤러 코드가 간결해졌습니다. 이는 단일 책임 원칙(SRP)을 잘 따르고 있습니다.


40-41: 오류 메시지가 새 기능에 맞게 업데이트되었습니다.

오류 로깅 메시지가 "프롬프트 제작 중 오류 발생"으로 변경되어 애플리케이션의 새로운 목적에 맞게 조정되었습니다.

src/main/resources/templates/pipeline.html (8)

51-73: 드롭다운 UI의 CSS 구현이 잘 되어 있습니다.

위치 입력을 위한 드롭다운 기능의 CSS가 명확하게 구현되어 있습니다. 요소의 위치 지정, 최대 높이 제한, 스크롤 기능 등이 사용자 경험을 개선하는 데 적절히 사용되었습니다.


77-77: UI 텍스트가 새로운 기능에 맞게 변경되었습니다.

"여행지 추천 요청"에서 "프롬프트 제작소"로 헤딩이 변경되어 새로운 기능에 맞게 적절히 조정되었습니다.


82-86: 자동완성 드롭다운 UI 구현이 잘 되어 있습니다.

기존의 단순 입력 필드가 자동완성 드롭다운으로 대체되어 사용자 경험이 크게 향상되었습니다. 입력 필드와 드롭다운 목록의 구조가 잘 구성되어 있습니다.


88-88: 버튼 텍스트가 새로운 기능에 맞게 변경되었습니다.

"추천 요청"에서 "제작하기"로 버튼 텍스트가 변경되어 새로운 기능에 맞게 적절히 조정되었습니다.


92-92: 결과 표시 섹션의 제목이 적절히 변경되었습니다.

"추천 결과"에서 "제작 결과"로 헤딩이 변경되어 새로운 기능에 맞게 적절히 조정되었습니다.


101-169: 한국 행정구역 데이터의 광범위한 목록이 포함되어 있습니다.

한국의 행정구역(특별시, 광역시, 도, 시, 군, 구)이 포함된 상세한 목록이 제공되어 있습니다. 사용자에게 정확한 위치 입력을 도울 수 있는 데이터가 잘 구성되어 있습니다.


172-201: 드롭다운 필터링 기능이 효율적으로 구현되어 있습니다.

사용자 입력에 따라 지역 목록을 필터링하는 로직이 잘 구현되어 있습니다. 빈 검색어 처리, 일치하는 항목이 없는 경우의 처리 등이 포함되어 있습니다.


203-207: 외부 클릭 처리가 적절히 구현되어 있습니다.

드롭다운 영역 외부를 클릭할 때 드롭다운이 닫히는 기능이 구현되어 있어 사용자 경험이 개선되었습니다.

Comment on lines +9 to +16
public String generatePrompt(String extractedPetInfoJson, String location) {
return String.format("""
{
%s
"location": "%s"
}
""", extractedPetInfoJson, location);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

입력 매개변수 검증 및 예외 처리 필요

현재 구현은 입력 파라미터에 대한 검증이 없습니다. null이나 빈 문자열이 입력될 경우 처리 방법이 없으며, 특수 문자가 포함된 location 값이 JSON에 직접 삽입되면 JSON 파싱 오류가 발생할 수 있습니다.

@Override
public String generatePrompt(String extractedPetInfoJson, String location) {
+    if (extractedPetInfoJson == null || extractedPetInfoJson.trim().isEmpty()) {
+        throw new IllegalArgumentException("추출된 반려동물 정보가 비어 있습니다.");
+    }
+    if (location == null || location.trim().isEmpty()) {
+        throw new IllegalArgumentException("위치 정보가 비어 있습니다.");
+    }
+    
+    // 특수 문자 이스케이핑 처리
+    String escapedLocation = location.replace("\"", "\\\"");
+    
    return String.format("""
            {
            %s
-            "location": "%s"
+            "location": "%s"
            }
            """, extractedPetInfoJson, escapedLocation);
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public String generatePrompt(String extractedPetInfoJson, String location) {
return String.format("""
{
%s
"location": "%s"
}
""", extractedPetInfoJson, location);
}
@Override
public String generatePrompt(String extractedPetInfoJson, String location) {
if (extractedPetInfoJson == null || extractedPetInfoJson.trim().isEmpty()) {
throw new IllegalArgumentException("추출된 반려동물 정보가 비어 있습니다.");
}
if (location == null || location.trim().isEmpty()) {
throw new IllegalArgumentException("위치 정보가 비어 있습니다.");
}
// 특수 문자 이스케이핑 처리
String escapedLocation = location.replace("\"", "\\\"");
return String.format("""
{
%s
"location": "%s"
}
""", extractedPetInfoJson, escapedLocation);
}

Comment on lines +13 to +21
public String assemblePrompt(String visionReport, String location) throws Exception {
String extractedPetInfoJson = togetherService.answer(
visionReport + " -> 이 문장에서 반려동물의 이름(name), 종(species), 무게(weight), 맹수 여부(is_danger(only true or false))를 JSON 형식으로 작성 + " +
"만약 반려동물의 종과 무게를 보았을 때, 입마개가 필요할 것 같다면 맹수 여부를 'true'로 작성 + " +
"무게는 kg 단위를 반드시 포함" + "no markdown, only JSON" + "최종 결과에 {}는 제거"
);

return promptGeneratorService.generatePrompt(extractedPetInfoJson, location);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

프롬프트 하드코딩 및 에러 처리 개선 필요

다음과 같은 개선이 필요합니다:

  1. 긴 프롬프트 문자열이 코드에 직접 하드코딩되어 있어 유지보수가 어렵습니다.
  2. 일반 Exception을 던지는 것은 좋은 관행이 아닙니다.
  3. TogetherService 응답이나 입력 매개변수에 대한 검증이 없습니다.
+ private static final String PET_INFO_EXTRACTION_PROMPT = 
+     "%s -> 이 문장에서 반려동물의 이름(name), 종(species), 무게(weight), 맹수 여부(is_danger(only true or false))를 JSON 형식으로 작성 + " +
+     "만약 반려동물의 종과 무게를 보았을 때, 입마개가 필요할 것 같다면 맹수 여부를 'true'로 작성 + " +
+     "무게는 kg 단위를 반드시 포함" + "no markdown, only JSON" + "최종 결과에 {}는 제거";

- public String assemblePrompt(String visionReport, String location) throws Exception {
+ public String assemblePrompt(String visionReport, String location) throws IllegalArgumentException, ServiceException {
+     // 입력 파라미터 검증
+     if (visionReport == null || visionReport.trim().isEmpty()) {
+         throw new IllegalArgumentException("비전 리포트가 비어 있습니다.");
+     }
+     if (location == null || location.trim().isEmpty()) {
+         throw new IllegalArgumentException("위치 정보가 비어 있습니다.");
+     }
+
+     try {
-         String extractedPetInfoJson = togetherService.answer(
-                 visionReport + " -> 이 문장에서 반려동물의 이름(name), 종(species), 무게(weight), 맹수 여부(is_danger(only true or false))를 JSON 형식으로 작성 + " +
-                         "만약 반려동물의 종과 무게를 보았을 때, 입마개가 필요할 것 같다면 맹수 여부를 'true'로 작성 + " +
-                         "무게는 kg 단위를 반드시 포함" + "no markdown, only JSON" + "최종 결과에 {}는 제거"
-         );
+         String extractedPetInfoJson = togetherService.answer(String.format(PET_INFO_EXTRACTION_PROMPT, visionReport));
+
+         // 응답 검증
+         if (extractedPetInfoJson == null || extractedPetInfoJson.trim().isEmpty()) {
+             throw new ServiceException("반려동물 정보 추출에 실패했습니다.");
+         }

          return promptGeneratorService.generatePrompt(extractedPetInfoJson, location);
+     } catch (Exception e) {
+         throw new ServiceException("프롬프트 조립 중 오류가 발생했습니다.", e);
+     }
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public String assemblePrompt(String visionReport, String location) throws Exception {
String extractedPetInfoJson = togetherService.answer(
visionReport + " -> 이 문장에서 반려동물의 이름(name), 종(species), 무게(weight), 맹수 여부(is_danger(only true or false))를 JSON 형식으로 작성 + " +
"만약 반려동물의 종과 무게를 보았을 때, 입마개가 필요할 것 같다면 맹수 여부를 'true'로 작성 + " +
"무게는 kg 단위를 반드시 포함" + "no markdown, only JSON" + "최종 결과에 {}는 제거"
);
return promptGeneratorService.generatePrompt(extractedPetInfoJson, location);
}
// 프롬프트 하드코딩 방지를 위한 상수 분리
private static final String PET_INFO_EXTRACTION_PROMPT =
"%s -> 이 문장에서 반려동물의 이름(name), 종(species), 무게(weight), 맹수 여부(is_danger(only true or false))를 JSON 형식으로 작성 + " +
"만약 반려동물의 종과 무게를 보았을 때, 입마개가 필요할 것 같다면 맹수 여부를 'true'로 작성 + " +
"무게는 kg 단위를 반드시 포함" + "no markdown, only JSON" + "최종 결과에 {}는 제거";
public String assemblePrompt(String visionReport, String location)
throws IllegalArgumentException, ServiceException {
// 입력 파라미터 검증
if (visionReport == null || visionReport.trim().isEmpty()) {
throw new IllegalArgumentException("비전 리포트가 비어 있습니다.");
}
if (location == null || location.trim().isEmpty()) {
throw new IllegalArgumentException("위치 정보가 비어 있습니다.");
}
try {
String extractedPetInfoJson =
togetherService.answer(String.format(PET_INFO_EXTRACTION_PROMPT, visionReport));
// 응답 검증
if (extractedPetInfoJson == null || extractedPetInfoJson.trim().isEmpty()) {
throw new ServiceException("반려동물 정보 추출에 실패했습니다.");
}
return promptGeneratorService.generatePrompt(extractedPetInfoJson, location);
} catch (Exception e) {
throw new ServiceException("프롬프트 조립 중 오류가 발생했습니다.", e);
}
}

@Juyoung8563 Juyoung8563 changed the title [PIPELINE] Vision, RAG 파트와 통합 및 예외 처리 보완 전 Pull Request [PIPELINE] Vision, RAG 파트와 통합 및 예외 처리 보완 이전 Pull Request Apr 22, 2025
@usn757
Copy link
Copy Markdown
Contributor

usn757 commented Apr 22, 2025

리뷰

  • 파이프라인 로직을 리팩토링하고 PromptAssemblyService 등으로 책임을 분리하여 코드 구조를 개선하신 점 정말 인상 깊었습니다.

  • 덕분에 Controller의 역할이 더 명확해지고 서비스 로직을 이해하기 쉬워진 것 같습니다.

  • 수고 많으셨습니다!

제안

  • 서비스로 전달되는 visionReport나 location 같은 입력값들이 null일 가능성도 고려되어 현재 코드가 안전하게 처리 가능한 상태인지 궁금합니다. 만약 아니라면, NullPointerException 등을 방지하기 위해 null 또는 비어있는 값에 대한 체크 로직 추가를 고려해야 할 것 같습니다.

  • Controller나 각 Service 단계에서 발생 가능한 예외(예: IllegalArgumentException, JsonProcessingException, 외부 API 호출 실패 등)를 명확히 구분하여 잡고, 로그에 충분한 컨텍스트(어떤 데이터로, 어떤 작업 중 발생했는지)를 남겨주시면 디버깅에 큰 도움이 될 것입니다.

@s0ooo0k
Copy link
Copy Markdown
Member

s0ooo0k commented Apr 22, 2025

✅ 리뷰

  • 우선, VISION 과 LLM 중간 파트여서, 전체 로직 구현 이후에도 프롬프트 수정이나 데이터 입출력 관련하여 계속 변경 요청이 있음에도 불구하고 빠르게 작업해 주신 점 너무 감사합니다!
  • 행정구역 드롭다운 기반 입력을 통해 필터 검색의 정확도가 향상될 것 같습니다. 아이디어가 좋았습니다. 고생하셨습니다

🔧 제안 및 아이디어

  • VISION 보고서 > PIPELINE 통합하였을 때도 JSON 결과가 잘 나오는지가 중요할 것 같습니다. 다양한 상황에서 테스트를 해보면 좋을 것 같습니다.
  • RAG 파트와 연결 시 수정사항이나 이슈가 있으면 공유드리겠습니다.

@s0ooo0k s0ooo0k merged commit 5f40d3c into PETTY-HUB:main Apr 22, 2025
2 checks passed
23MinL pushed a commit to 23MinL/PETTY-BACK-VISION that referenced this pull request Apr 23, 2025
[PIPELINE] Vision, RAG 파트와 통합 및 예외 처리 보완 이전 Pull Request
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.

3 participants