Skip to content

Commit c91a161

Browse files
committed
fix: 채팅 에러
1 parent e58093a commit c91a161

File tree

2 files changed

+30
-36
lines changed

2 files changed

+30
-36
lines changed

backend/src/main/java/com/ai/lawyer/domain/chatbot/controller/ChatBotController.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,21 @@ public class ChatBotController {
2121
private final ChatBotService chatBotService;
2222

2323
@Operation(summary = "01. 새로운 채팅", description = "첫 메시지 전송으로 새로운 채팅방을 생성하고 챗봇과 대화를 시작")
24-
@PostMapping(value = "/message", produces = "application/stream+json")
24+
@PostMapping(value = "/message")
2525
public Flux<ChatResponse> postNewMessage(@RequestBody ChatRequest chatRequest) {
2626
// SecurityContext에서 memberId를 미리 추출 (컨트롤러 진입 시점)
2727
Long memberId = AuthUtil.getAuthenticatedMemberId();
28+
if (memberId == null) {
29+
throw new IllegalStateException("인증된 사용자가 아닙니다.");
30+
}
2831
log.info("새로운 채팅 요청: memberId={}", memberId);
2932

3033
// memberId를 Flux에 전달 (SecurityContext 전파 문제 방지)
3134
return chatBotService.sendMessage(memberId, chatRequest, null);
3235
}
3336

3437
@Operation(summary = "02. 기존 채팅", description = "기존 채팅방에 메시지를 보내고 챗봇과 대화를 이어감")
35-
@PostMapping(value = "{roomId}/message", produces = "application/stream+json")
38+
@PostMapping(value = "{roomId}/message")
3639
public Flux<ChatResponse> postMessage(
3740
@RequestBody ChatRequest chatRequest,
3841
@PathVariable(value = "roomId", required = false) Long roomId) {

backend/src/main/java/com/ai/lawyer/domain/chatbot/service/ChatBotService.java

Lines changed: 25 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,9 @@
66
import com.ai.lawyer.domain.chatbot.dto.ChatDto.ChatResponse;
77
import com.ai.lawyer.domain.chatbot.entity.History;
88
import com.ai.lawyer.domain.chatbot.repository.HistoryRepository;
9+
import com.ai.lawyer.global.qdrant.service.QdrantService;
910
import com.ai.lawyer.infrastructure.kafka.dto.ChatPostProcessEvent;
1011
import 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;
1412
import lombok.RequiredArgsConstructor;
1513
import lombok.extern.slf4j.Slf4j;
1614
import org.springframework.ai.chat.client.ChatClient;
@@ -28,8 +26,6 @@
2826
import org.springframework.stereotype.Service;
2927
import org.springframework.transaction.annotation.Transactional;
3028
import reactor.core.publisher.Flux;
31-
import reactor.core.publisher.Mono;
32-
import reactor.core.scheduler.Schedulers;
3329

3430
import java.util.HashMap;
3531
import 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

Comments
 (0)