66import com .ai .lawyer .domain .chatbot .dto .ChatDto .ChatResponse ;
77import com .ai .lawyer .domain .chatbot .entity .History ;
88import com .ai .lawyer .domain .chatbot .repository .HistoryRepository ;
9+ import com .ai .lawyer .global .qdrant .service .QdrantService ;
910import com .ai .lawyer .infrastructure .kafka .dto .ChatPostProcessEvent ;
1011import com .ai .lawyer .infrastructure .kafka .dto .DocumentDto ;
11- import com .ai .lawyer .domain .member .entity .Member ;
12- import com .ai .lawyer .domain .member .repositories .MemberRepository ;
13- import com .ai .lawyer .global .qdrant .service .QdrantService ;
1412import lombok .RequiredArgsConstructor ;
1513import lombok .extern .slf4j .Slf4j ;
1614import org .springframework .ai .chat .client .ChatClient ;
2826import org .springframework .stereotype .Service ;
2927import org .springframework .transaction .annotation .Transactional ;
3028import reactor .core .publisher .Flux ;
31- import reactor .core .publisher .Mono ;
32- import reactor .core .scheduler .Schedulers ;
3329
3430import java .util .HashMap ;
3531import java .util .List ;
@@ -44,7 +40,6 @@ public class ChatBotService {
4440 private final ChatClient chatClient ;
4541 private final QdrantService qdrantService ;
4642 private final HistoryService historyService ;
47- private final MemberRepository memberRepository ;
4843 private final HistoryRepository historyRepository ;
4944 private final ChatMemoryRepository chatMemoryRepository ;
5045
@@ -61,44 +56,40 @@ public class ChatBotService {
6156 // 멤버 조회 -> 벡터 검색 -> 프롬프트 생성 -> LLM 호출 (스트림) -> Kafka 이벤트 발행 -> 응답 반환
6257 @ Transactional
6358 public Flux <ChatResponse > sendMessage (Long memberId , ChatRequest chatRequestDto , Long roomId ) {
64- return Mono .fromCallable (() -> {
6559
66- // 벡터 검색 (판례, 법령) (블로킹)
67- List <Document > similarCaseDocuments = qdrantService .searchDocument (chatRequestDto .getMessage (), "type" , "판례" );
68- List <Document > similarLawDocuments = qdrantService .searchDocument (chatRequestDto .getMessage (), "type" , "법령" );
60+ // 벡터 검색 (판례, 법령) (블로킹)
61+ List <Document > similarCaseDocuments = qdrantService .searchDocument (chatRequestDto .getMessage (), "type" , "판례" );
62+ List <Document > similarLawDocuments = qdrantService .searchDocument (chatRequestDto .getMessage (), "type" , "법령" );
6963
70- String caseContext = formatting (similarCaseDocuments );
71- String lawContext = formatting (similarLawDocuments );
64+ String caseContext = formatting (similarCaseDocuments );
65+ String lawContext = formatting (similarLawDocuments );
7266
73- // 채팅방 조회 또는 생성 (블로킹)
74- History history = getOrCreateRoom (memberId , roomId );
67+ // 채팅방 조회 또는 생성 (블로킹)
68+ History history = getOrCreateRoom (memberId , roomId );
7569
76- // 메시지 기억 관리 (User 메시지 추가)
77- ChatMemory chatMemory = saveChatMemory (chatRequestDto , history );
70+ // 메시지 기억 관리 (User 메시지 추가)
71+ ChatMemory chatMemory = saveChatMemory (chatRequestDto , history );
7872
79- // 프롬프트 생성
80- Prompt prompt = getPrompt (caseContext , lawContext , chatMemory , history );
73+ // 프롬프트 생성
74+ Prompt prompt = getPrompt (caseContext , lawContext , chatMemory , history );
8175
82- // 준비된 데이터를 담은 컨텍스트 객체 반환
83- return new PreparedChatContext (prompt , history , similarCaseDocuments , similarLawDocuments );
84- })
85- .subscribeOn (Schedulers .boundedElastic ()) // 블로킹 작업을 별도 스레드에서 실행
86- .flatMapMany (context -> {
87- // LLM 스트리밍 호출 및 클라이언트에게 즉시 응답
88- return chatClient .prompt (context .prompt )
76+ // 준비된 데이터를 담은 컨텍스트 객체 반환
77+ //return new PreparedChatContext(prompt, history, similarCaseDocuments, similarLawDocuments);
78+
79+ return chatClient .prompt (prompt )
8980 .stream ()
9081 .content ()
9182 .collectList ()
9283 .map (fullResponseList -> String .join ("" , fullResponseList ))
9384 .doOnNext (fullResponse -> {
9485
9586 // Document를 DTO로 변환
96- List <DocumentDto > caseDtos = context . similarCaseDocuments .stream ().map (DocumentDto ::from ).collect (Collectors .toList ());
97- List <DocumentDto > lawDtos = context . similarLawDocuments .stream ().map (DocumentDto ::from ).collect (Collectors .toList ());
87+ List <DocumentDto > caseDtos = similarCaseDocuments .stream ().map (DocumentDto ::from ).collect (Collectors .toList ());
88+ List <DocumentDto > lawDtos = similarLawDocuments .stream ().map (DocumentDto ::from ).collect (Collectors .toList ());
9889
9990 // Kafka로 보낼 이벤트 객체
10091 ChatPostProcessEvent event = new ChatPostProcessEvent (
101- context . history .getHistoryId (),
92+ history .getHistoryId (),
10293 chatRequestDto .getMessage (),
10394 fullResponse ,
10495 caseDtos ,
@@ -109,13 +100,13 @@ public Flux<ChatResponse> sendMessage(Long memberId, ChatRequest chatRequestDto,
109100 kafkaTemplate .send (POST_PROCESSING_TOPIC , event );
110101
111102 })
112- .map (fullResponse -> createChatResponse (context . history , fullResponse , context . similarCaseDocuments , context . similarLawDocuments ))
103+ .map (fullResponse -> createChatResponse (history , fullResponse , similarCaseDocuments , similarLawDocuments ))
113104 .flux ()
114105 .onErrorResume (throwable -> {
115- log .error ("스트리밍 처리 중 에러 발생 (historyId: {})" , context . history .getHistoryId (), throwable );
116- return Flux .just (handleError (context . history ));
106+ log .error ("스트리밍 처리 중 에러 발생 (historyId: {})" , history .getHistoryId (), throwable );
107+ return Flux .just (handleError (history ));
117108 });
118- });
109+
119110 }
120111
121112 private ChatResponse createChatResponse (History history , String fullResponse , List <Document > cases , List <Document > laws ) {
@@ -196,8 +187,8 @@ private static class PreparedChatContext {
196187 final List <Document > similarLawDocuments ;
197188
198189 PreparedChatContext (Prompt prompt , History history ,
199- List <Document > similarCaseDocuments ,
200- List <Document > similarLawDocuments ) {
190+ List <Document > similarCaseDocuments ,
191+ List <Document > similarLawDocuments ) {
201192 this .prompt = prompt ;
202193 this .history = history ;
203194 this .similarCaseDocuments = similarCaseDocuments ;
0 commit comments