All is Well은 방대한 패널 데이터베이스에서 사용자의 자연어 질의를 지능적으로 처리하여 최적의 패널을 추출하는 차세대 검색 시스템입니다. "캠핑을 좋아하는 30대 서울 거주 여성"과 같은 자연어 질의만으로 데이터베이스에 저장된 패널과 패널의 설문 응답 데이터를 검색하고, AI가 생성한 페르소나 및 통계 시각화를 통해 즉각적인 인사이트를 제공합니다.
- 키워드 기반 검색으로 추상적 질의 처리 불가
- 효율성과 정확성의 트레이드오프 문제
- 검색 결과의 제한적 활용 (단순 목록만 제공)
- 비연속적 검색 경험 (매번 새로 검색)
- 새 데이터 추가 시 긴 전처리 시간
- 적응형 하이브리드 검색: 질의 난이도 자동 분류 (SQL/임베딩 동적 선택)
- 지능형 그룹 분석: LLM 기반 페르소나 생성 및 AI 이미지 시각화
- 대화형 연속 검색: LangGraph 세션 관리로 드릴다운 지원
- 실시간 통계 시각화: Chart.js 인터랙티브 차트
- BGE 기반 리랭킹: 전처리 없이 질문-응답 의미 유사성 계산
- 메인 검색 화면
- 검색 결과 화면
- 패널 상세 페이지
- 검색 히스토리 & 라이브러리
- 사용자 인터페이스
- 검색, 히스토리, 라이브러리 관리
- Chart.js 통계 시각화
- TanStack Query 서버 상태 관리
- 사용자 인증 (JWT)
- 검색 결과 캐시 관리
- 히스토리 & 라이브러리 CRUD
- CSV 다운로드 제공
- 프록시 패턴으로 보안 강화
- LangGraph 3-Tier 검색 워크플로우
- LLM 기반 쿼리 분석 & 결과 요약
- ChromaDB 벡터 검색
- BGE Reranker 재순위화
- 페르소나 & 이미지 생성
- SQLite: 구조화 데이터 (패널 정보, 정형 질의 응답 데이터)
- ChromaDB: 벡터 검색 (비정형 질문 + 응답)
사용자 쿼리: "서울 20대 여성 중 ChatGPT 사용하는 사람"
↓
┌─────────────────────────────────────────────────────────────┐
│ Step 1: LLM 쿼리 분석 (gpt-4o-mini) │
│ { │
│ demographics: {region: "서울", age: [20-29], gender: "여성"}│
│ structured_keywords: [] │
│ semantic_queries: ["ChatGPT 사용"] │
│ } │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Step 2: Tier 1 - Demographics SQL (인구통계 필터) │
│ WHERE region='서울' AND gender='여성' AND age BETWEEN 20-29│
│ → 1,234명 후보 추출 │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Step 3: Tier 2 - Structured SQL (구조화 키워드) │
│ SKIP (해당 없음) │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Step 4: Tier 3 - Semantic Vector Search + BGE Reranker │
│ [1] Question-First: 44개 질문 검색 → AI 관련 5개 질문 선정 │
│ [2] Answer Search: 1,234명 후보 중 5개 질문 답변만 검색 │
│ [3] BGE Reranker: Cross-encoder로 재순위화 │
│ → Top 100명 선정 (match_score: 0.85~0.95) │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Step 5: LLM 결과 요약 & 페르소나 생성 │
│ "서울 거주 20대 여성 100명 (ChatGPT 사용자)" │
└─────────────────────────────────────────────────────────────┘- Tier 1-2만 사용: ~100ms ⚡
- Full Pipeline (GPU): ~17초
- Full Pipeline (CPU): ~2.5분
그룹 페르소나 (LLM 생성)
{
"text": "30대 초반의 액티브한 아웃도어 애호가로, 주말마다 등산이나 캠핑을 즐기며...",
"hashtags": ["#아웃도어", "#30대", "#액티브", "#캠핑"],
"image_url": "data:image/png;base64,iVBORw0KG..."
}-
텍스트: GPT-4o-mini가 그룹 특성 요약
-
해시태그: 핵심 키워드 추출
-
이미지: Nano Banana 모델로 시각화
-
개별 페르소나 (36,113개 사전 생성)
-
각 패널의 성향, 관심사, 라이프스타일 요약
-
검색 시 유사도 점수와 함께 제공
-
Chart.js 기반 차트
-
연령대별 분포 (막대 그래프)
-
성별 분포 (원형 차트)
-
지역별 분포 (막대 그래프)
-
직업별 분포 (가로 막대)
-
소득별 분포 (선 그래프)
클릭 한 번으로 차트 전환
// 사용자가 "연령대" 클릭 → BarChart 렌더링
<BarChart
data={{
labels: ["20대", "30대", "40대"],
values: [50, 300, 100]
}}
title="연령대별 분포"
/>연속 질문 시나리오:
1차 검색: "캠핑 좋아하는 사람" → 450명
↓ session_id 유지
2차 검색: "이 중에서 서울 거주자" → 120명
↓ session_id 유지
3차 검색: "이 중에서 30대만" → 80명LangGraph 상태 관리:
- 이전 결과 집합 내에서만 추가 필터링
- 전체 재검색 불필요 → 효율성 극대화
CSV 다운로드
패널ID,나이,성별,지역,구역,직업,요약,유사도
PANEL_001,32,남성,서울,강남구,IT 개발자,주말마다 캠핑을...,0.95- UTF-8 BOM으로 한글 깨짐 방지
- 타임스탬프 파일명:
panel_results_20241128_143022.csv
검색 히스토리
- 최근 검색 자동 저장
- 클릭으로 이전 결과 즉시 복원
라이브러리
- 자주 사용하는 검색 저장
- 사용자 지정 제목 관리
React 18.x UI 라이브러리
TypeScript 타입 안전성
Vite 빌드 도구 (빠른 HMR)
TanStack Query 서버 상태 관리 & 캐싱
Zustand 클라이언트 전역 상태
React Router v6 라우팅
Axios HTTP 클라이언트
Tailwind CSS 유틸리티 기반 스타일링
Chart.js 데이터 시각화
Lucide React 아이콘
FastAPI 0.115+ 비동기 REST API 프레임워크
Python 3.10+ 프로그래밍 언어
Uvicorn ASGI 서버
SQLite 3 로컬 데이터베이스
Pydantic 2.x 데이터 검증 & 직렬화
httpx 비동기 HTTP 클라이언트
python-jose JWT 토큰
FastAPI 0.115+ 비동기 API 서버
Python 3.13 BGE Reranker 의존성
LangGraph StateGraph 워크플로우
LangChain LLM Chains
OpenAI gpt-4o-mini 쿼리 분석 & 결과 요약
ChromaDB 벡터 데이터베이스
OpenAI text-embedding 임베딩 (1536-dim)
BGE Reranker v2-m3 재순위화 (로컬, 무료)
sentence-transformers BGE 모델 로더
SQLite 구조화 데이터 (111MB)
- 36,113명 패널 정보
- 636,248건 설문 응답
- 검색 캐시 & 히스토리
ChromaDB 벡터 검색 (~1.5GB)
- 44개 질문 임베딩
- ~202K개 답변 임베딩
AllIsWell/
├── Frontend/ # React 프론트엔드
│ ├── src/
│ │ ├── api/ # API 통신 레이어
│ │ │ ├── auth.js
│ │ │ ├── search.js
│ │ │ ├── history.js
│ │ │ └── library.js
│ │ ├── components/ # 재사용 컴포넌트
│ │ │ ├── common/
│ │ │ ├── SearchResult/
│ │ │ ├── panelDetail/
│ │ │ └── ...
│ │ ├── pages/ # 페이지
│ │ │ ├── Login/
│ │ │ ├── Main/
│ │ │ ├── SearchResult/
│ │ │ └── History/
│ │ ├── hooks/ # 커스텀 훅
│ │ └── utils/ # 유틸리티
│ ├── package.json
│ └── vite.config.js
│
├── Backend/ # FastAPI API 서버
│ ├── src/
│ │ └── app/
│ │ ├── db/ # 데이터베이스
│ │ ├── routers/ # API 라우터
│ │ │ ├── auth.py
│ │ │ ├── search.py
│ │ │ ├── history_api.py
│ │ │ └── library_api.py
│ │ └── schemas/ # Pydantic 스키마
│ ├── databases/
│ │ └── main.db
│ ├── main.py
│ └── requirements.txt
│
└── DataPipeline/ # FastAPI + LangGraph
├── src/
│ ├── pipeline_v4/ # 메인 파이프라인
│ │ ├── pipeline.py
│ │ ├── graph.py # LangGraph StateGraph
│ │ ├── nodes.py # 6개 노드
│ │ ├── chains.py # LLM Chains
│ │ ├── retrievers.py # 3-Tier 검색
│ │ └── config.py
│ ├── api/
│ │ └── question_first_search.py
│ ├── database/
│ ├── embeddings/
│ │ ├── embedding_service.py
│ │ ├── vector_db.py
│ │ └── reranker.py # BGE Reranker
│ └── extractors/
├── databases/
│ ├── PersonaSurveyData.db # SQLite (111MB)
│ ├── chroma_db_questions/ # 질문 벡터
│ └── chroma_db_answers/ # 답변 벡터
├── scripts/ # DB 생성 스크립트
└── requirements.txt
사전 요구사항
Node.js 18.x 이상 Python 3.10 이상 (파이프라인은 3.13 권장) OpenAI API Key Gemini API Key
1️⃣ Frontend 설정 및 실행
cd Frontend
# 의존성 설치
npm install
# 환경 변수 설정
echo "VITE_API_URL=http://localhost:5001" > .env
# 개발 서버 실행
npm run dev
# → http://localhost:5173
2️⃣ Backend (API Server) 설정 및 실행
cd Backend
# 가상환경 생성 및 활성화
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
# 의존성 설치
pip install -r requirements.txt
# 데이터베이스 초기화
python create_db_tables.py
# 서버 실행
python main.py
# → http://localhost:5001
# Swagger UI: http://localhost:5001/docs
3️⃣ Data Pipeline 설정 및 실행
cd DataPipeline
# Python 3.13 가상환경 (BGE Reranker 필요)
python3.13 -m venv .venv313
source .venv313/bin/activate
# 의존성 설치
pip install -r requirements.txt
# OpenAI API 키 설정
export OPENAI_API_KEY='your-api-key'
# 데이터 전처리 (일회성)
cd scripts/
python preprocess_only.py
python create_question_embeddings.py
python create_answer_embeddings.py
cd ..
# 파이프라인 서버 실행
python run_pipeline.py
# → http://localhost:8000
4️⃣ 전체 시스템 실행 순서
# Terminal 1: Data Pipeline
cd DataPipeline
source .venv313/bin/activate
python run_pipeline.py
# Terminal 2: API Server
cd Backend
source venv/bin/activate
python main.py
# Terminal 3: Frontend
cd Frontend
npm run dev
데이터 규모
- 패널: ~3만 7천명
- 질문: ~60개
- 응답: ~64만건
- 페르소나: ~3만 7천개
- 데이터베이스: 111MB (SQLite) + ~1.5GB (ChromaDB)
검색 성능
| 검색 유형 | 사용 Tier | 처리 시간 | 설명 |
|---|---|---|---|
| 인구통계 검색 | Tier 1 | ~50ms ⚡ | SQL WHERE (성별, 나이, 지역) |
| 구조화 키워드 | Tier 1+2 | ~100ms ⚡ | SQL + LIKE (직업, 학력, 소득) |
| 의미론적 검색 (GPU) | Full Pipeline | ~17초 | 벡터 검색 + BGE Reranker |
| 의미론적 검색 (CPU) | Full Pipeline | ~2.5분 | 벡터 검색 + BGE Reranker |
참고: 대부분의 쿼리는 Tier 1-2만 사용하여 1초 이내 응답
비용 (OpenAI API) 초기 설정 (일회성)
질문 임베딩 : ~$0.0001 답변 임베딩 : ~$0.003 총: ~$0.003 (1원 미만)
검색 비용 (쿼리당)
LLM 쿼리 분석: ~$0.0005 쿼리 임베딩: ~$0.00002 LLM 결과 요약: ~$0.0005 BGE Reranker: $0 (로컬 모델) 총: ~$0.001/검색
월간 사용 예상
1,000회 검색/월: ~$1 10,000회 검색/월: ~$10
- 복잡한 SQL 작성 불필요 → 데이터 분석 인력 시간 절감
- 신속한 인사이트 도출 → 시장 대응 속도 향상
- 반복 작업 자동화 → IT 자원 소모 최소화
- 타겟 마케팅 정확도 향상 → 마케팅 ROI 극대화
- 개인화된 금융/의료 서비스 → 고객 만족도 & 객단가 상승
- 고품질 의사결정 지원 → 사업 성공률 향상
- 연구 생산성 제고 (논문, 특허, 임상 대상자 모집)
- 범용 플랫폼 확장 (마케팅, 금융, 의료, 공공)
- 정확한 정책 수립 지원
- 시스템 신뢰도 & 사용자 만족도 향상
- SQL 지식 없이 자연어로 데이터 탐색
- 조직 전반의 데이터 기반 문화 확산
- 이 프로젝트는 한성대학교 기업연계 SW캡스톤디자인 수업에서 진행되었습니다. [GitHub]







