66import com .going .server .domain .chatbot .entity .Sender ;
77import com .going .server .domain .chatbot .repository .ChattingRepository ;
88import com .going .server .domain .graph .entity .Graph ;
9- import com .going .server .domain .graph .entity .GraphNode ;
109import com .going .server .domain .graph .exception .GraphContentNotFoundException ;
1110import com .going .server .domain .graph .repository .GraphRepository ;
1211import com .going .server .domain .graph .repository .GraphNodeRepository ;
1312import com .going .server .domain .openai .dto .ImageCreateRequestDto ;
1413import com .going .server .domain .openai .service .ImageCreateService ;
15- import com .going .server .domain .openai .service .RAGAnswerCreateService ;
1614import com .going .server .domain .openai .service .SimpleAnswerCreateService ;
1715import com .going .server .domain .openai .service .TextSummaryCreateService ;
16+ import com .going .server .domain .rag .service .GraphRAGService ;
1817import com .going .server .domain .rag .service .SimilarityFilterService ;
1918import com .going .server .domain .rag .util .PromptBuilder ;
2019import lombok .RequiredArgsConstructor ;
2423import java .time .LocalDateTime ;
2524import java .util .*;
2625
27- import java .util .stream .Collectors ;
28-
2926@ Service
3027@ RequiredArgsConstructor
3128@ Transactional
@@ -38,13 +35,15 @@ public class ChatbotServiceImpl implements ChatbotService {
3835 // openai 관련 service
3936 private final TextSummaryCreateService textSummaryCreateService ;
4037 private final SimpleAnswerCreateService simpleAnswerCreateService ;
41- private final RAGAnswerCreateService ragAnswerCreateService ;
4238 private final ImageCreateService imageCreateService ;
39+ // graphRAG
40+ private final GraphRAGService graphRAGService ;
4341
4442 // 원문 반환
4543 @ Override
4644 public CreateChatbotResponseDto getOriginalText (String graphId ) {
47- Graph graph = graphRepository .getByGraph (Long .valueOf (graphId ));
45+ Long dbId = graphRepository .findDbIdByGraphId (Long .valueOf (graphId ));
46+ Graph graph = graphRepository .getByGraph (dbId );
4847
4948 return CreateChatbotResponseDto .builder ()
5049 .chatContent (graph .getContent ()) // 원문 텍스트
@@ -56,7 +55,8 @@ public CreateChatbotResponseDto getOriginalText(String graphId) {
5655 // 요약본 생성
5756 @ Override
5857 public CreateChatbotResponseDto getSummaryText (String graphId ) {
59- Graph graph = graphRepository .getByGraph (Long .valueOf (graphId ));
58+ Long dbId = graphRepository .findDbIdByGraphId (Long .valueOf (graphId ));
59+ Graph graph = graphRepository .getByGraph (dbId );
6060
6161 String context = Optional .ofNullable (graph .getContent ())
6262 .filter (s -> !s .trim ().isEmpty ())
@@ -71,120 +71,53 @@ public CreateChatbotResponseDto getSummaryText(String graphId) {
7171 .build ();
7272 }
7373
74-
75- // RAG 챗봇 응답 생성
74+ // GraphRAG 챗봇 응답 생성
7675 @ Override
77- public CreateChatbotResponseDto createAnswerWithRAG (String graphStrId , CreateChatbotRequestDto createChatbotRequestDto ) {
78- Long graphId = Long .valueOf (graphStrId );
79-
80- // 404 : 지식그래프 찾을 수 없음
81- Graph graph = graphRepository .getByGraph (graphId );
82-
83- // RAG: 사용자 질문
84- String userQuestion = createChatbotRequestDto .getChatContent ();
85-
86- // RAG : 키워드 추출
87- List <String > keywords = extractKeywords (userQuestion );
88- System .out .println ("[RAG] 추출된 키워드: " + keywords );
89-
90- // RAG: 유사 노드 검색 및 문장 추출
91- List <GraphNode > matchedNodes = graphNodeRepository .findByGraphIdAndKeywords (graphId , keywords );
92- // List<GraphNode> matchedNodes = graphNodeRepository.findByGraphIdAndKeywordsWithEdges(graphId, keywords);
93- System .out .println ("[RAG] matchedNodes: " + matchedNodes );
94-
95- List <String > candidateSentences = matchedNodes .stream ()
96- .map (GraphNode ::getIncludeSentence )
97- .filter (Objects ::nonNull )
98- .distinct ()
99- .collect (Collectors .toList ());
100-
101- // RAG: 유사 문장 필터링
102- List <String > filteredChunks = similarityFilterService .filterRelevantSentences (userQuestion , candidateSentences );
103-
104- // RAG: 최종 프롬프트 구성
105- String finalPrompt = promptBuilder .buildPrompt (filteredChunks , userQuestion );
106- System .out .println ("finalPrompt: " + finalPrompt );
107-
108- // RAG: 메타정보 수집
109- List <String > retrievedChunks = new ArrayList <>(filteredChunks );
110- List <String > sourceNodes = new ArrayList <>(
111- matchedNodes .stream ().map (GraphNode ::getLabel ).distinct ().toList ()
112- );
113- Map <String , String > ragMeta = Map .of (
114- "chunkCount" , String .valueOf (filteredChunks .size ())
115- );
76+ public CreateChatbotResponseDto createAnswerWithRAG (String graphStrId , CreateChatbotRequestDto requestDto ) {
77+ Long dbId = graphRepository .findDbIdByGraphId (Long .valueOf (graphStrId ));
78+ Graph graph = graphRepository .getByGraph (dbId );
11679
117- // 새로운 대화인 경우 기존 채팅 삭제
118- if (createChatbotRequestDto .isNewChat ()) {
119- deletePreviousChat (graphId );
80+ if (requestDto .isNewChat ()) {
81+ deletePreviousChat (dbId );
12082 }
12183
122- // 기존 채팅 내역 조회
123- List <Chatting > chatHistory = chattingRepository .findAllByGraphId (graphId );
124-
125- // 새로운 채팅
126- String newChat = createChatbotRequestDto .getChatContent ();
127-
128- // 새로운 채팅 repository에 저장
129- Chatting chatting = Chatting .builder ()
84+ Chatting userChat = Chatting .builder ()
13085 .graph (graph )
131- .content (newChat )
86+ .content (requestDto . getChatContent () )
13287 .sender (Sender .USER )
13388 .createdAt (LocalDateTime .now ())
13489 .build ();
135- chattingRepository .save (chatting );
136-
137- // 응답 생성
138- String chatContent ;
139-
140- // RAG: 유사 문장이 있을 경우 컨텍스트 활용
141- if (retrievedChunks .isEmpty ()) {
142- System .out .println ("[INFO] RAG 미적용 - 일반 채팅 기반 응답" );
143- System .out .println ("[INFO] RAG 미적용 - 유사 문장 없음" );
144- System .out .println ("[DEBUG] matchedNodes.size(): " + matchedNodes .size ());
145- System .out .println ("[DEBUG] candidateSentences.size(): " + candidateSentences .size ());
146- System .out .println ("[DEBUG] filteredChunks.size(): " + filteredChunks .size ());
147- chatContent = ragAnswerCreateService .chat (chatHistory , newChat );
148- } else {
149- System .out .println ("[INFO] RAG 적용됨 - 유사 문장 " + retrievedChunks .size () + "개 포함" );
150- chatContent = ragAnswerCreateService .chatWithContext (chatHistory , finalPrompt );
151- }
90+ chattingRepository .save (userChat );
15291
153- // 응답 repository에 저장
154- Chatting answer = Chatting .builder ()
155- .graph (graph )
156- .content (chatContent )
157- .sender (Sender .GPT )
158- .createdAt (LocalDateTime .now ())
159- .build ();
160- chattingRepository .save (answer );
92+ List <Chatting > chatHistory = chattingRepository .findAllByGraphId (dbId );
16193
162- // 반환
163- return CreateChatbotResponseDto .builder ()
164- .chatContent (chatContent )
165- .graphId (graphStrId )
166- .createdAt (answer .getCreatedAt ())
167- .retrievedChunks (retrievedChunks )
168- .sourceNodes (sourceNodes )
169- .ragMeta (ragMeta )
170- .build ();
94+ // RAG 응답 생성 (응답 + 메타 포함)
95+ CreateChatbotResponseDto responseDto = graphRAGService .createAnswerWithGraphRAG (
96+ dbId ,
97+ requestDto .getChatContent (),
98+ chatHistory
99+ );
100+
101+ // 응답 채팅 저장
102+ Chatting gptChat = Chatting .ofGPT (graph , responseDto .getChatContent ());
103+ chattingRepository .save (gptChat );
104+
105+ return responseDto ;
171106 }
172107
173- // RAG 사용하지 않는 응답 생성
108+ // 기본 응답 생성
174109 @ Override
175110 public CreateChatbotResponseDto createSimpleAnswer (String graphStrId , CreateChatbotRequestDto createChatbotRequestDto ) {
176- Long graphId = Long .valueOf (graphStrId );
177-
178- // 404 : 지식그래프 찾을 수 없음
179- Graph graph = graphRepository .getByGraph (graphId );
111+ Long dbId = graphRepository .findDbIdByGraphId (Long .valueOf (graphStrId ));
112+ Graph graph = graphRepository .getByGraph (dbId );
180113
181114 // 새로운 대화인 경우 기존 채팅 삭제
182115 if (createChatbotRequestDto .isNewChat ()) {
183- deletePreviousChat (graphId );
116+ deletePreviousChat (dbId );
184117 }
185118
186119 // 기존 채팅 내역 조회
187- List <Chatting > chatHistory = chattingRepository .findAllByGraphId (graphId );
120+ List <Chatting > chatHistory = chattingRepository .findAllByGraphId (dbId );
188121
189122 // 사용자 입력 채팅
190123 String newChat = createChatbotRequestDto .getChatContent ();
@@ -293,17 +226,4 @@ private void deletePreviousChat(Long graphId) {
293226 chattingRepository .deleteByGraphId (graphId );
294227 }
295228
296-
297- // RAG : 키워드 추출
298- private List <String > extractKeywords (String text ) {
299- List <String > stopwords = List .of ("은" , "는" , "이" , "가" , "을" , "를" , "에" , "의" , "와" , "과" , "에서" , "하다" );
300-
301- return Arrays .stream (text .split ("[\\ s,.!?]+" ))
302- .map (word -> word .replaceAll ("(은|는|이|가|을|를|에|의|와|과|에서)$" , "" )) // ✅ 조사 제거
303- .map (String ::toLowerCase )
304- .filter (word -> word .length () > 1 && !stopwords .contains (word ))
305- .distinct ()
306- .limit (5 )
307- .collect (Collectors .toList ());
308- }
309229}
0 commit comments