From e1711d917663bb46be3f6f2da5f14bf877492229 Mon Sep 17 00:00:00 2001 From: thug0bin Date: Sun, 8 Mar 2026 15:28:58 +0900 Subject: [PATCH] =?UTF-8?q?fix(animal-chat):=20=ED=94=84=EB=A1=AC=ED=94=84?= =?UTF-8?q?=ED=8A=B8=20+=20RAG=20=EC=B5=9C=EC=A0=81=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 프롬프트 개선: - 상세 요청 감지 ('자세히', '설명해줘' 등) - 상세 요청 시 10-15문장 응답 - RAG 검색 결과 적극 활용 지시 2. 벡터 검색 수정: - L2 거리 → 유사도 변환: 1/(1+distance) - 음수 유사도 문제 해결 - 임계값 0.3 적용 (30% 미만 제외) 3. 컨텍스트 주입 개선: - 상세 질문 시 n_results=5로 증가 - RAG 활용 지시 추가 --- backend/app.py | 19 ++++++++++++++++--- backend/utils/animal_rag.py | 12 +++++++++++- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/backend/app.py b/backend/app.py index bb520f1..5bbd80e 100644 --- a/backend/app.py +++ b/backend/app.py @@ -2963,7 +2963,11 @@ ANIMAL_CHAT_SYSTEM_PROMPT = """당신은 약국의 동물약 전문 상담사입 **응답 규칙:** 1. **보유 제품 정보 우선** - [대상: 개, 고양이] 표시된 제품은 개/고양이 모두 사용 가능 2. 체중별 제품은 정확한 전체 이름 사용 (안텔민킹, 안텔민뽀삐 등) -3. 짧고 명확하게 (3-5문장) +3. **응답 길이 조절:** + - 기본 질문 ("~추천해줘", "~있어?"): 짧고 명확하게 (2-4문장) + - 상세 요청 ("자세히", "상세히", "더 알려줘", "설명해줘", "왜"): 길고 자세하게 (10-15문장) + → 📚 RAG 검색 결과 적극 활용, 성분·작용기전·용량·주의사항 상세 설명 + - 용량/투약 질문: 체중별 표 형식으로 정리 4. 친근하게 🐕🐱 5. **업셀링은 자연스럽게** - 강요하지 말고 "~하면 좋아요" 식으로 부드럽게 권유 @@ -3217,12 +3221,21 @@ def api_animal_chat(): try: from utils.animal_rag import get_animal_rag if last_user_msg: + # 상세 질문 감지: 더 많은 컨텍스트 제공 + detail_keywords = ['자세히', '상세히', '더 알려', '설명해', '왜', '어떻게', '원리', '기전', '성분'] + is_detail_request = any(kw in last_user_msg for kw in detail_keywords) + n_results = 5 if is_detail_request else 3 + rag = get_animal_rag() - vector_results = rag.search(last_user_msg, n_results=3) + vector_results = rag.search(last_user_msg, n_results=n_results) log_entry.vector_results_count = len(vector_results) log_entry.vector_top_scores = [r.get('score', 0) for r in vector_results] log_entry.vector_sources = [f"{r.get('source', '')}#{r.get('section', '')}" for r in vector_results] - vector_context = rag.get_context_for_chat(last_user_msg, n_results=3) + vector_context = rag.get_context_for_chat(last_user_msg, n_results=n_results) + + # 상세 요청 시 컨텍스트 활용 지시 추가 + if is_detail_request and vector_context: + vector_context = "⚠️ 아래 RAG 검색 결과를 적극 활용하여 상세하게 답변하세요!\n\n" + vector_context except Exception as e: logging.warning(f"벡터 검색 실패 (무시): {e}") log_entry.vector_duration_ms = int((time.time() - vector_start) * 1000) diff --git a/backend/utils/animal_rag.py b/backend/utils/animal_rag.py index 6aa9568..bfb04bd 100644 --- a/backend/utils/animal_rag.py +++ b/backend/utils/animal_rag.py @@ -243,11 +243,21 @@ class AnimalDrugRAG: output = [] for r in results: + # L2 거리 (0~∞) → 유사도 (1~0) + # 거리가 작을수록 유사도 높음 + distance = r.get("_distance", 10) + score = 1 / (1 + distance) # 0~1 범위로 변환 + + # 임계값: 유사도 0.3 미만은 제외 (관련 없는 문서) + # L2 거리 2.33 이상이면 제외 + if score < 0.3: + continue + output.append({ "text": r["text"], "source": r["source"], "section": r["section"], - "score": 1 - r.get("_distance", 0) # 거리 → 유사도 + "score": score }) return output