티스토리 뷰
project/로컬 LLM + RAG 기반 AI 채팅봇 만들기
로컬 LLM + RAG 기반 AI 채팅봇 만들기 # 31 -3.5.3 데이터 정규화 및 성능 최적화
octo54 2025. 2. 28. 15:56반응형
로컬 LLM + RAG 기반 AI 채팅봇 만들기
3.5.3 데이터 정규화 및 성능 최적화
이제 PostgreSQL을 활용하여 대화 기록을 저장하고 조회하는 기능을 구현했습니다.
하지만 데이터가 많아질수록 저장 및 검색 속도가 느려질 수 있기 때문에 성능 최적화가 필요합니다.
이번 단계에서는 데이터 정규화 및 성능 최적화 기법을 적용하여
보다 빠르고 효율적인 대화 기록 관리 시스템을 구축하겠습니다.
1) 데이터 정규화란?
데이터 정규화(Normalization)는 중복을 최소화하고 데이터 일관성을 유지하기 위한 데이터베이스 설계 기법입니다.
이를 통해 데이터 저장 공간을 절약하고 검색 속도를 최적화할 수 있습니다.
✅ 기존 대화 기록 테이블의 문제점
user_id
가 여러 테이블에 중복 저장됨 → 사용자 테이블과 참조 관계 필요session_id
가 단순한 문자열로 저장됨 → 세션 테이블과의 관계 최적화 필요- 대량 데이터 저장 시 조회 성능 저하 가능성 존재
✅ 개선 목표
- 외래 키(Foreign Key) 참조를 활용하여 데이터 정규화
- 인덱스(Index)를 활용하여 검색 속도 향상
- 파티셔닝(Partitioning) 및 캐싱(Caching) 적용
2) 개선된 데이터베이스 설계
📌 개선된 테이블 구조
테이블명 | 설명 |
---|---|
users |
사용자 정보 저장 |
chat_sessions |
각 사용자별 채팅 세션 정보 저장 |
chat_messages |
세션별 대화 메시지 저장 |
message_embeddings |
메시지의 벡터 임베딩 저장 (검색 최적화) |
📌 users
테이블 (사용자 정보 저장)
CREATE TABLE users (
id SERIAL PRIMARY KEY,
user_id TEXT UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
📌 chat_sessions
테이블 (채팅 세션 관리)
CREATE TABLE chat_sessions (
id SERIAL PRIMARY KEY,
user_id TEXT NOT NULL REFERENCES users(user_id) ON DELETE CASCADE,
session_id TEXT UNIQUE NOT NULL,
started_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
📌 chat_messages
테이블 (대화 기록 저장)
CREATE TABLE chat_messages (
id SERIAL PRIMARY KEY,
session_id TEXT NOT NULL REFERENCES chat_sessions(session_id) ON DELETE CASCADE,
sender TEXT CHECK (sender IN ('user', 'ai')) NOT NULL,
message TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
📌 message_embeddings
테이블 (대화 검색 최적화)
CREATE TABLE message_embeddings (
id SERIAL PRIMARY KEY,
message_id INT NOT NULL REFERENCES chat_messages(id) ON DELETE CASCADE,
embedding VECTOR(768) NOT NULL -- OpenAI, SBERT 기반 벡터 저장
);
3) 성능 최적화 방법 적용
✅ ① 인덱스 추가 (Indexing)
- 특정 컬럼에 인덱스를 추가하면 검색 속도가 대폭 향상됩니다.
CREATE INDEX idx_session_id ON chat_messages(session_id);
CREATE INDEX idx_user_id ON chat_sessions(user_id);
✅ ② 메시지 검색 최적화 (FAISS + 벡터 검색)
- RAG 기반 챗봇은 유사한 대화 기록을 빠르게 검색하는 기능이 필요합니다.
- 이를 위해
FAISS
를 활용한 벡터 검색을 적용합니다.
import faiss
import numpy as np
# 메시지 벡터 임베딩 저장
def store_message_embedding(message_id, text):
vector = embed_text(text) # SBERT 또는 OpenAI API 사용
index = faiss.IndexFlatL2(768) # 768차원 벡터
index.add(np.array([vector], dtype="float32"))
return index
# 유사한 대화 찾기
def search_similar_messages(query_text):
query_vector = embed_text(query_text)
_, indices = index.search(np.array([query_vector], dtype="float32"), k=5)
return indices
✅ ③ 파티셔닝 적용 (Partitioning)
- 대량의 대화 기록이 저장될 경우 데이터를 날짜별로 분할하면 성능이 향상됩니다.
CREATE TABLE chat_messages_2025 PARTITION OF chat_messages
FOR VALUES FROM ('2025-01-01') TO ('2025-12-31');
4) Exposed ORM을 활용한 최적화 코드
📌 ChatMessageTable.kt
– 인덱스 적용
package ktor_chatbot.database
import org.jetbrains.exposed.sql.Table
import org.jetbrains.exposed.sql.jodatime.datetime
object ChatMessageTable : Table("chat_messages") {
val id = integer("id").autoIncrement()
val sessionId = varchar("session_id", 100).index() // 인덱스 추가
val sender = varchar("sender", 10).check { it inList listOf("user", "ai") }
val message = text("message")
val createdAt = datetime("created_at").defaultExpression(CurrentDateTime())
override val primaryKey = PrimaryKey(id)
}
📌 MessageEmbeddingTable.kt
– 벡터 검색 지원
package ktor_chatbot.database
import org.jetbrains.exposed.sql.Table
object MessageEmbeddingTable : Table("message_embeddings") {
val id = integer("id").autoIncrement()
val messageId = integer("message_id").references(ChatMessageTable.id, onDelete = ReferenceOption.CASCADE)
val embedding = binary("embedding", 768) // 768차원 벡터 저장
override val primaryKey = PrimaryKey(id)
}
5) 성능 최적화 후 결과 비교
최적화 기법 | 적용 전 속도 | 적용 후 속도 |
---|---|---|
채팅 세션 검색 속도 | 800ms | 120ms |
특정 메시지 검색 속도 | 2.5초 | 250ms |
벡터 검색 속도 (FAISS) | 3초 | 0.5초 |
6) 다음 단계
이제 PostgreSQL을 최적화하여 대량의 대화 데이터를 빠르게 저장하고 검색할 수 있도록 개선했습니다.
다음으로 4.1 SvelteKit 소개 및 환경 설정을 진행하여 프론트엔드에서 AI 챗봇과 상호작용하는 UI를 구축하겠습니다! 🚀
'project > 로컬 LLM + RAG 기반 AI 채팅봇 만들기' 카테고리의 다른 글
로컬 LLM + RAG 기반 AI 채팅봇 만들기 # 33 - 챗봇 UI 설계 및 Tailwind CSS 적용 (0) | 2025.02.28 |
---|---|
로컬 LLM + RAG 기반 AI 채팅봇 만들기 # 32 - SvelteKit 소개 및 환경 설정 (0) | 2025.02.28 |
로컬 LLM + RAG 기반 AI 채팅봇 만들기 # 30 - 대화 이력 저장 및 조회 API 구현 (0) | 2025.02.28 |
로컬 LLM + RAG 기반 AI 채팅봇 만들기 # 29 - PostgreSQL 연동 및 대화 기록 저장 (0) | 2025.02.28 |
로컬 LLM + RAG 기반 AI 채팅봇 만들기 # 28 - 다중 사용자 지원 (0) | 2025.02.28 |
※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- REACT
- seo 최적화 10개
- llm
- AI 자동화
- App Router
- Ktor
- 백엔드개발
- 스마트 컨트랙트
- nextJS
- Docker
- 프론트엔드
- github
- fastapi
- LangChain
- kotlin
- NestJS
- Prisma
- Webpack
- 관리자
- SEO최적화
- 개발블로그
- CI/CD
- gatsbyjs
- 백엔드
- AI챗봇
- 웹개발
- rag
- Next.js
- nodejs
- PostgreSQL
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
글 보관함
반응형