Commit ·
255beb5
1
Parent(s): 0e45e6b
generator 코드수정
Browse files- src/generator/generator.py +47 -5
src/generator/generator.py
CHANGED
|
@@ -9,6 +9,7 @@ from typing import List, Dict
|
|
| 9 |
|
| 10 |
from src.utils.config import RAGConfig
|
| 11 |
from src.retriever.retriever import RAGRetriever
|
|
|
|
| 12 |
|
| 13 |
|
| 14 |
class RAGPipeline:
|
|
@@ -32,8 +33,14 @@ class RAGPipeline:
|
|
| 32 |
max_retries=3
|
| 33 |
)
|
| 34 |
|
| 35 |
-
# Retriever 초기화
|
| 36 |
self.retriever = RAGRetriever(config=self.config)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
|
| 38 |
# 대화 히스토리
|
| 39 |
self.chat_history: List[Dict] = []
|
|
@@ -48,10 +55,10 @@ class RAGPipeline:
|
|
| 48 |
# 규칙
|
| 49 |
- 답변은 한국어로 작성합니다.
|
| 50 |
- 컨텍스트 밖 내용을 추측하지 않습니다.
|
| 51 |
-
-
|
| 52 |
- 여러 문서를 비교할 때는 문서별 차이를 표 또는 목록으로 정리합니다.
|
| 53 |
- 숫자에는 가능한 단위를 포함합니다.
|
| 54 |
-
- 직전 대화 맥락을 반영
|
| 55 |
|
| 56 |
# 답변 형식
|
| 57 |
1. 한 줄 요약: 질문 핵심을 한두 문장으로 작성합니다.
|
|
@@ -182,7 +189,36 @@ class RAGPipeline:
|
|
| 182 |
"""
|
| 183 |
try:
|
| 184 |
start_time = time.time()
|
| 185 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 186 |
# 파라미터 설정
|
| 187 |
if top_k is not None:
|
| 188 |
self.top_k = top_k
|
|
@@ -194,6 +230,11 @@ class RAGPipeline:
|
|
| 194 |
# Chain 실행
|
| 195 |
answer = self.chain.invoke(query)
|
| 196 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 197 |
elapsed_time = time.time() - start_time
|
| 198 |
|
| 199 |
# 대화 히스토리에 추가
|
|
@@ -212,7 +253,8 @@ class RAGPipeline:
|
|
| 212 |
'total_tokens': estimated_tokens,
|
| 213 |
'prompt_tokens': 0,
|
| 214 |
'completion_tokens': 0
|
| 215 |
-
}
|
|
|
|
| 216 |
}
|
| 217 |
|
| 218 |
except Exception as e:
|
|
|
|
| 9 |
|
| 10 |
from src.utils.config import RAGConfig
|
| 11 |
from src.retriever.retriever import RAGRetriever
|
| 12 |
+
from src.router.query_router import QueryRouter
|
| 13 |
|
| 14 |
|
| 15 |
class RAGPipeline:
|
|
|
|
| 33 |
max_retries=3
|
| 34 |
)
|
| 35 |
|
| 36 |
+
# Retriever 및 라우터 초기화
|
| 37 |
self.retriever = RAGRetriever(config=self.config)
|
| 38 |
+
self.router = QueryRouter()
|
| 39 |
+
self._direct_responses = {
|
| 40 |
+
'greeting': "안녕하세요! 공공입찰 RFP 관련 궁금한 사항을 알려주시면 자료를 찾아 드릴게요.",
|
| 41 |
+
'thanks': "도움이 되었다니 다행입니다. 추가로 궁금한 점이 있으면 언제든지 말씀해 주세요!",
|
| 42 |
+
'out_of_scope': "해당 질문은 현재 보유한 입찰·사업 문서에서 다루지 않습니다. 다른 질문을 시도해 주세요."
|
| 43 |
+
}
|
| 44 |
|
| 45 |
# 대화 히스토리
|
| 46 |
self.chat_history: List[Dict] = []
|
|
|
|
| 55 |
# 규칙
|
| 56 |
- 답변은 한국어로 작성합니다.
|
| 57 |
- 컨텍스트 밖 내용을 추측하지 않습니다.
|
| 58 |
+
- 컨텍스트가 비어있거나 질문과 직접 관련된 사실이 없으면 "문서에서 해당 정보를 찾을 수 없습니다." 한 문장으로만 답합니다.
|
| 59 |
- 여러 문서를 비교할 때는 문서별 차이를 표 또는 목록으로 정리합니다.
|
| 60 |
- 숫자에는 가능한 단위를 포함합니다.
|
| 61 |
+
- 직전 대화 맥락을 반영하되, 확인되지 않은 내용을 추론해 추가하지 않습니다.
|
| 62 |
|
| 63 |
# 답변 형식
|
| 64 |
1. 한 줄 요약: 질문 핵심을 한두 문장으로 작성합니다.
|
|
|
|
| 189 |
"""
|
| 190 |
try:
|
| 191 |
start_time = time.time()
|
| 192 |
+
|
| 193 |
+
classification = self.router.classify(query)
|
| 194 |
+
query_type = classification.get('type', 'document')
|
| 195 |
+
|
| 196 |
+
# 비문서 질의는 즉시 응답
|
| 197 |
+
if query_type != 'document':
|
| 198 |
+
print(f"⏭️ 라우터: 검색 생략 ({query_type})")
|
| 199 |
+
answer = self._direct_responses.get(
|
| 200 |
+
query_type,
|
| 201 |
+
self._direct_responses['out_of_scope']
|
| 202 |
+
)
|
| 203 |
+
elapsed_time = time.time() - start_time
|
| 204 |
+
self._last_retrieved_docs = []
|
| 205 |
+
|
| 206 |
+
self.chat_history.append({"role": "user", "content": query})
|
| 207 |
+
self.chat_history.append({"role": "assistant", "content": answer})
|
| 208 |
+
|
| 209 |
+
return {
|
| 210 |
+
'answer': answer,
|
| 211 |
+
'sources': [],
|
| 212 |
+
'search_mode': 'none',
|
| 213 |
+
'elapsed_time': elapsed_time,
|
| 214 |
+
'usage': {
|
| 215 |
+
'total_tokens': 0,
|
| 216 |
+
'prompt_tokens': 0,
|
| 217 |
+
'completion_tokens': 0
|
| 218 |
+
},
|
| 219 |
+
'routing': classification
|
| 220 |
+
}
|
| 221 |
+
|
| 222 |
# 파라미터 설정
|
| 223 |
if top_k is not None:
|
| 224 |
self.top_k = top_k
|
|
|
|
| 230 |
# Chain 실행
|
| 231 |
answer = self.chain.invoke(query)
|
| 232 |
|
| 233 |
+
# 검색 결과가 없으면 안전 응답으로 대체
|
| 234 |
+
if not self._last_retrieved_docs:
|
| 235 |
+
answer = "문서에서 관련 정보를 찾을 수 없습니다. 다른 질문을 입력해 주세요."
|
| 236 |
+
print("⚠️ 검색 결과 없음 - 안전 응답 반환")
|
| 237 |
+
|
| 238 |
elapsed_time = time.time() - start_time
|
| 239 |
|
| 240 |
# 대화 히스토리에 추가
|
|
|
|
| 253 |
'total_tokens': estimated_tokens,
|
| 254 |
'prompt_tokens': 0,
|
| 255 |
'completion_tokens': 0
|
| 256 |
+
},
|
| 257 |
+
'routing': classification
|
| 258 |
}
|
| 259 |
|
| 260 |
except Exception as e:
|