Files
exAichatbot_agent/exAiChatBot-chatbot2.0-agent/old_docs
Macbook 4b86b2a660 Agent 2.0 exdev 서버 배포 스택
- server-dev start/stop/deploy 및 Gitea push 자동 배포
- local-dev 로컬 개발 환경

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-21 22:57:30 +09:00
..
2026-07-21 22:57:30 +09:00

RAG 기반 QA 시스템 (외부 API 버전)

🎯 개요

엑셀 파일의 질문-답변 쌍을 기반으로 동작하는 경량 RAG(Retrieval Augmented Generation) 시스템입니다.

핵심 특징

  • ⚡ 경량 버전: 180MB (기존 2.5GB 대비 93% 감소)
  • 📊 엑셀 지원: 질문-답변 엑셀 파일을 직접 변환
  • 🚀 외부 API: 모든 AI 모델을 외부 API로 사용 (GPU 불필요)
  • 🔍 고속 검색: FAISS 벡터 검색 + TEI Reranking
  • 🤖 LLM 통합: 검색 결과 기반 자연스러운 답변 생성
  • 🐳 Docker 지원: 간편한 빌드 및 배포
  • 💾 오프라인 배포: 패키징 스크립트 제공

📋 시스템 요구사항

필수

  • Docker: 20.10+
  • Docker Compose: 1.29+
  • 디스크: 2GB 이상
  • RAM: 4GB 이상

외부 API 서버 (별도 준비 필요)

다음 서버들이 실행 중이어야 합니다:

# 1. SGLang (LLM 서비스) - port 16000
docker run -d --gpus all --name sglang-80b-test \
  -p 16000:30000 \
  -v /DATA/exlink/models:/data \
  --ipc=host --restart always \
  lmsysorg/sglang:latest \
  python3 -m sglang.launch_server \
  --model-path /data/Qwen3-Next-80B-A3B-Instruct-Int4-GPTQ \
  --host 0.0.0.0 --port 30000 \
  --mem-fraction-static 0.92 --max-model-len 4096 \
  --trust-remote-code

# 2. TEI Embedding - port 16001
docker run -d --gpus all --name tei-embedding \
  -p 16001:80 \
  -v /DATA/exlink/models:/data \
  --pull never --restart always \
  ghcr.io/huggingface/text-embeddings-inference:hopper-1.8 \
  --model-id /data/Qwen3-Embedding-8B --port 80

# 3. TEI Reranker - port 16002
docker run -d --gpus all --name tei-reranker \
  -p 16002:80 \
  -v /DATA/exlink/models:/data \
  --pull never --restart always \
  ghcr.io/huggingface/text-embeddings-inference:hopper-1.8 \
  --model-id /data/Qwen3-Reranker-8B --port 80

🚀 5분 빠른 시작

⚡ 방법 1: 자동화 스크립트 (가장 쉬움!)

# 기본: 자동 컬럼 감지 또는 1-2열 사용
./run-with-excel.sh your_qa_data.xlsx

# 3열(C열), 4열(D열) 사용 시
./run-with-excel-col34.sh your_qa_data.xlsx

# 수동 지정: 특정 열 사용
python scripts/excel_to_jsonl.py data/your_file.xlsx 2 3
#                                                     ↑ ↑
#                                         3열(인덱스2) 4열(인덱스3)
# 그 후 Docker 실행
docker-compose -f docker-compose-slim.yml up

자동으로 실행:

  1. ✅ 엑셀 → JSONL 변환 (지정한 열 사용)
  2. ✅ 환경 설정 확인
  3. ✅ Docker 이미지 빌드
  4. ✅ 전처리 (LLM 요약)
  5. ✅ 임베딩 생성 (TEI API)
  6. ✅ FAISS 인덱싱
  7. ✅ API 서비스 시작

➜ 상세 가이드: DOCKER_DATA_GUIDE.md ➜ 3-4열 사용: COLUMN_GUIDE.md


📋 방법 2: 수동 단계별 실행

1️⃣ 엑셀 파일 변환

# data/ 폴더에 엑셀 파일 배치
cp your_qa_data.xlsx data/

# JSONL 변환 - 자동 감지
python scripts/excel_to_jsonl.py data/your_qa_data.xlsx

# 또는 특정 열 지정 (예: 3열=질문, 4열=답변)
python scripts/excel_to_jsonl.py data/your_qa_data.xlsx 2 3
#                                                        ↑ ↑
#                                            C열(인덱스2) D열(인덱스3)

엑셀 형식:

A B C (질문) D (답변) E
1 분류 카드 분실 시 어떻게 해야 하나요? 모바일 앱 또는 고객센터를 통해... 날짜
2 충전 충전 후 정지 해제가 안 되는 경우는? 한국도로공사 관리구간의 경우... 날짜

컬럼 인덱스: A=0, B=1, C=2, D=3, E=4, ...

➜ 상세 가이드: EXCEL_GUIDE.md ➜ 3-4열 사용: COLUMN_GUIDE.md

2️⃣ 환경 설정

cp env.template .env
vi .env

필수 설정:

# LLM 서버
LLM_HOST=192.168.1.100
LLM_PORT=16000
LLM_MODEL_NAME=default

# TEI 서버
TEI_EMBED_HOST=192.168.1.101
TEI_EMBED_PORT=16001
TEI_RERANK_HOST=192.168.1.101
TEI_RERANK_PORT=16002

# 벡터 DB (FAISS 또는 qdrant)
VECTOR_STORE=faiss

3️⃣ Docker 실행

# 전체 파이프라인 실행 (전처리 → 임베딩 → 인덱싱 → API 서비스)
docker-compose -f docker-compose-slim.yml up

자동 실행 단계:

  1. ✅ 전처리 (LLM으로 질문 요약) - data/qa_raw.jsonl 읽기 → data/qa.jsonl 생성
  2. ✅ 임베딩 생성 (TEI API) - data/qa.jsonl 읽기 → data/qa_vecs.jsonl 생성
  3. ✅ FAISS 인덱싱 - data/qa_vecs.jsonl 읽기 → data/qa.index 생성
  4. ✅ API 서비스 시작

4️⃣ 테스트

# 헬스체크
curl http://localhost:28012/health

# 질문하기
curl -X POST http://localhost:28012/ask \
  -H "Content-Type: application/json" \
  -d '{"query":"카드 분실 시 어떻게 해야 하나요?"}'

응답 예시:

{
  "answer": "카드를 분실하신 경우, 모바일 앱 또는 고객센터(1588-2504)를 통해 '카드분실신고'를 하신 후 재발급 신청 또는 환불 절차를 진행하실 수 있습니다...",
  "references": [
    {"q": "카드를 분실한 경우 어떻게 하나요?", "a": "모바일 앱 또는..."}
  ]
}

➜ 빠른 시작 가이드: QUICKSTART_EXCEL.md


📚 문서

🎯 시작하기

🚀 배포

🔧 기술


🏗️ 프로젝트 구조

rag/
├── scripts/
│   ├── excel_to_jsonl.py      # 엑셀 → JSONL 변환 (신규!)
│   ├── preprocess_qa.py        # LLM 질문 요약
│   ├── ingest_qa.py            # 임베딩 생성
│   ├── build_index_qa.py       # FAISS 인덱싱
│   ├── run_service_qa.py       # FastAPI 서비스
│   ├── api_clients.py          # 외부 API 클라이언트
│   └── vector_store.py         # 벡터 DB 추상화
├── docker/
│   ├── batch-slim.Dockerfile   # 배치 작업용 (경량)
│   └── service-slim.Dockerfile # API 서비스용 (경량)
├── data/                       # 데이터 디렉토리 ⭐ Docker 볼륨 마운트
│   ├── your_qa_data.xlsx      # [1] 엑셀 원본 (여기에 배치!)
│   ├── qa_raw.jsonl           # [2] 원본 QA (엑셀 변환 결과)
│   ├── qa.jsonl               # [3] 전처리된 QA (Docker 자동 생성)
│   ├── qa_vecs.jsonl          # [4] 벡터 데이터 (Docker 자동 생성)
│   └── qa.index               # [5] FAISS 인덱스 (Docker 자동 생성)
├── docker-compose-slim.yml    # Docker Compose (경량 버전)
├── run-with-excel.sh          # 엑셀 파일로 전체 자동 실행 ⭐
├── create-offline-package-slim.sh  # 오프라인 패키징
└── env.template               # 환경 변수 템플릿

🔄 전체 파이프라인

엑셀 파일 (your_qa_data.xlsx)
    ↓ excel_to_jsonl.py
qa_raw.jsonl (원본 QA)
    ↓ preprocess_qa.py (LLM API)
qa.jsonl (질문 요약 추가)
    ↓ ingest_qa.py (TEI Embedding API)
qa_vecs.jsonl (벡터 데이터)
    ↓ build_index_qa.py
qa.index (FAISS 인덱스)
    ↓
FastAPI 서비스 (run_service_qa.py)
    ├─ 사용자 질문 → TEI Embedding
    ├─ FAISS 검색 (상위 30개)
    ├─ TEI Reranker (상위 5개)
    └─ LLM 답변 생성

💾 오프라인 배포

패키지 생성 (개발 환경)

# 경량 패키지 생성 (180MB)
./create-offline-package-slim.sh

결과:

  • ~/rag-offline-package-slim.tar.gz (180MB)

배포 (프로덕션 환경)

# 1. 파일 전송
scp ~/rag-offline-package-slim.tar.gz user@server:/home/user/

# 2. 압축 해제
tar -xzf rag-offline-package-slim.tar.gz
cd rag-offline-package-slim

# 3. 배포 스크립트 실행
./deploy.sh

➜ 상세 가이드: OFFLINE_DEPLOYMENT.md


⚙️ 주요 설정

벡터 DB 선택

# FAISS (기본) - 단순하고 빠름
VECTOR_STORE=faiss

# Qdrant - 확장 가능, 메타데이터 필터링
VECTOR_STORE=qdrant
QDRANT_HOST=qdrant
QDRANT_PORT=6333

성능 튜닝

# 검색 설정
FAISS_TOP_K=30              # FAISS 검색 결과 수
FAISS_THRESHOLD=0.55        # 유사도 임계값
RERANK_CANDIDATES=20        # 재랭킹 대상 수
TOP_N_FOR_LLM=5             # LLM에 전달할 최종 결과 수

# API 타임아웃
API_TIMEOUT=60              # 초

🧪 API 사용 예시

Python

import requests

response = requests.post(
    "http://localhost:28012/ask",
    json={"query": "카드 분실 시 어떻게 해야 하나요?"}
)

print(response.json()["answer"])

JavaScript

const response = await fetch("http://localhost:28012/ask", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ query: "카드 분실 시 어떻게 해야 하나요?" })
});

const data = await response.json();
console.log(data.answer);

📊 용량 비교

항목 기존 (PyTorch) 경량 버전 개선도
Docker 이미지 2.5GB 180MB 93%↓
베이스 이미지 PyTorch+CUDA 9GB Python slim 200MB 98%↓
빌드 시간 10분+ 8초 99%↓
필요 공간 10GB+ 2GB 80%↓

➜ 상세 설명: SLIM_VERSION.md


❓ 문제 해결

엑셀 변환 실패

pip install pandas openpyxl
python scripts/excel_to_jsonl.py your_qa_data.xlsx

외부 API 연결 실패

# API 연결 테스트
curl http://<LLM_HOST>:<LLM_PORT>/health
curl http://<TEI_HOST>:<TEI_PORT>/health

Docker 빌드 실패

# 이미지 정리 후 재빌드
docker system prune -af
docker-compose -f docker-compose-slim.yml build

➜ 상세 가이드: TROUBLESHOOTING.md


🤝 기여

이슈 및 PR은 언제나 환영합니다!


📄 라이선스

MIT License


🎯 다음 단계

  1. 데이터 준비: EXCEL_GUIDE.md 참고
  2. 로컬 테스트: QUICKSTART_EXCEL.md 참고
  3. 프로덕션 배포: OFFLINE_DEPLOYMENT.md 참고
  4. 성능 튜닝: .env 파일에서 파라미터 조정

시작하세요! ⚡