project/로컬 LLM + RAG 기반 AI 채팅봇 만들기
로컬 LLM + RAG 기반 AI 채팅봇 만들기 # 30 - 대화 이력 저장 및 조회 API 구현
octo54
2025. 2. 28. 15:53
반응형
로컬 LLM + RAG 기반 AI 채팅봇 만들기
3.5.2 대화 이력 저장 및 조회 API 구현
이제 PostgreSQL에 저장된 대화 이력을 API를 통해 관리할 수 있도록
대화 기록을 저장하고 조회하는 API를 구현하겠습니다.
1) API 설계 개요
✅ API에서 제공할 기능
1️⃣ 대화 저장하기
- 사용자가 WebSocket을 통해 메시지를 보낼 때 자동으로 DB에 저장
2️⃣ 특정 세션의 대화 이력 조회 - 사용자가 특정 세션에서 진행한 대화 목록을 조회
3️⃣ 사용자별 전체 대화 세션 목록 조회 - 사용자가 생성한 모든 대화 세션 리스트를 불러오기
2) API 엔드포인트 설계
HTTP 메서드 | 엔드포인트 | 설명 |
---|---|---|
POST |
/chat/save |
대화 메시지 저장 |
GET |
/chat/{sessionId} |
특정 대화 세션의 대화 기록 조회 |
GET |
/chat/sessions/{userId} |
사용자의 전체 대화 세션 목록 조회 |
3) 대화 저장 API 구현 (ChatService.kt
)
📌 ChatService.kt
– 대화 저장 기능
package ktor_chatbot.services
import ktor_chatbot.database.ChatMessageTable
import ktor_chatbot.database.ChatSessionTable
import ktor_chatbot.database.UserTable
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.transactions.transaction
import org.joda.time.DateTime
class ChatService {
fun saveMessage(sessionId: String, sender: String, message: String) {
transaction {
// 세션이 없으면 생성
ChatSessionTable.insertIgnore {
it[ChatSessionTable.sessionId] = sessionId
it[ChatSessionTable.userId] = "guest"
it[ChatSessionTable.startedAt] = DateTime.now()
}
// 메시지 저장
ChatMessageTable.insert {
it[ChatMessageTable.sessionId] = sessionId
it[ChatMessageTable.sender] = sender
it[ChatMessageTable.message] = message
it[ChatMessageTable.createdAt] = DateTime.now()
}
}
}
fun getMessagesBySession(sessionId: String): List<Pair<String, String>> {
return transaction {
ChatMessageTable.select { ChatMessageTable.sessionId eq sessionId }
.orderBy(ChatMessageTable.createdAt, SortOrder.ASC)
.map { it[ChatMessageTable.sender] to it[ChatMessageTable.message] }
}
}
fun getUserSessions(userId: String): List<String> {
return transaction {
ChatSessionTable.select { ChatSessionTable.userId eq userId }
.map { it[ChatSessionTable.sessionId] }
}
}
}
4) API 엔드포인트 추가 (Routing.kt
)
package ktor_chatbot.plugins
import io.ktor.server.application.*
import io.ktor.server.routing.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import ktor_chatbot.services.ChatService
import org.koin.ktor.ext.inject
fun Application.configureChatRoutes() {
val chatService: ChatService by inject()
routing {
// 대화 메시지 저장
post("/chat/save") {
val request = call.receive<Map<String, String>>()
val sessionId = request["sessionId"] ?: return@post call.respondText("세션 ID 필요", status = io.ktor.http.HttpStatusCode.BadRequest)
val sender = request["sender"] ?: return@post call.respondText("보낸 사람 필요", status = io.ktor.http.HttpStatusCode.BadRequest)
val message = request["message"] ?: return@post call.respondText("메시지 필요", status = io.ktor.http.HttpStatusCode.BadRequest)
chatService.saveMessage(sessionId, sender, message)
call.respondText("메시지 저장 완료", status = io.ktor.http.HttpStatusCode.OK)
}
// 특정 세션의 대화 이력 조회
get("/chat/{sessionId}") {
val sessionId = call.parameters["sessionId"] ?: return@get call.respondText("세션 ID 필요", status = io.ktor.http.HttpStatusCode.BadRequest)
val messages = chatService.getMessagesBySession(sessionId)
call.respond(messages)
}
// 사용자의 전체 대화 세션 조회
get("/chat/sessions/{userId}") {
val userId = call.parameters["userId"] ?: return@get call.respondText("사용자 ID 필요", status = io.ktor.http.HttpStatusCode.BadRequest)
val sessions = chatService.getUserSessions(userId)
call.respond(sessions)
}
}
}
5) Ktor 서버에서 API 활성화
📌 Application.kt
수정
package ktor_chatbot
import io.ktor.server.application.*
import ktor_chatbot.plugins.*
import ktor_chatbot.services.ChatService
import org.koin.dsl.module
import org.koin.ktor.plugin.Koin
fun Application.module() {
install(Koin) {
modules(module {
single { ChatService() }
})
}
configureChatRoutes()
configureRouting()
}
6) API 테스트
🔹 Ktor 서버 실행
./gradlew run
🔹 Postman 또는 cURL을 사용한 API 테스트
✅ 1) 대화 메시지 저장
curl -X POST "http://localhost:8080/chat/save" \
-H "Content-Type: application/json" \
-d '{"sessionId": "session123", "sender": "user", "message": "안녕하세요!"}'
📌 예상 응답
메시지 저장 완료
✅ 2) 특정 세션의 대화 조회
curl -X GET "http://localhost:8080/chat/session123"
📌 예상 응답 (JSON)
[
{ "sender": "user", "message": "안녕하세요!" },
{ "sender": "ai", "message": "안녕하세요! 무엇을 도와드릴까요?" }
]
✅ 3) 사용자의 전체 대화 세션 조회
curl -X GET "http://localhost:8080/chat/sessions/guest"
📌 예상 응답
[
"session123",
"session456"
]
7) 최적화 및 개선 방안
✅ ① 오래된 대화 자동 정리
- 일정 기간(예: 30일)이 지난 대화 기록을 자동으로 삭제하는 기능 추가 가능
DELETE FROM chat_messages WHERE created_at < NOW() - INTERVAL '30 days';
✅ ② 대화 기록 검색 기능 추가
- 특정 키워드를 포함하는 대화를 검색하는 기능 추가 가능
SELECT * FROM chat_messages WHERE message ILIKE '%AI%' AND session_id = 'session123';
8) 대화 이력 저장 기능 요약
기능 | 구현 코드 |
---|---|
대화 저장 | saveMessage(sessionId, sender, message) |
세션별 대화 조회 | getMessagesBySession(sessionId) |
사용자별 세션 목록 조회 | getUserSessions(userId) |
API 엔드포인트 추가 | post("/chat/save") , get("/chat/{sessionId}") , get("/chat/sessions/{userId}") |
9) 다음 단계
이제 PostgreSQL을 연동하여 대화 기록을 저장하고 조회할 수 있도록 구현했습니다.
다음으로 3.5.3 데이터 정규화 및 성능 최적화를 진행하여 대화 저장 및 조회 속도를 개선하는 최적화 방법을 적용하겠습니다! 🚀