# RAG 기반 사내 코드 검색 챗봇

본 프로젝트는 Retrieval-Augmented Generation (RAG) 아키텍처를 기반으로, 사내 GitLab 코드 리포지토리에 대해 자연어 질의를 수행할 수 있는 챗봇입니다.

## 기술 아키텍처

프로젝트는 `docker-compose.yml`을 통해 관리되는 4개의 주요 Docker 컨테이너로 구성됩니다.

1.  **`ui` (프론트엔드)**:
    -   **프레임워크**: Streamlit
    -   **역할**: 채팅 형태의 사용자 인터페이스를 제공합니다. 사용자의 모든 질문과 상호작용은 이 서비스를 통해 이루어지며, 백엔드 `api`와 통신합니다.

2.  **`api` (백엔드)**:
    -   **프레임워크**: FastAPI
    -   **역할**: QA 로직의 핵심을 담당합니다. RAG 파이프라인을 실행하고 REST API 엔드포인트를 통해 제공합니다.
        -   `POST /query`: `ui`로부터 질문을 받아 RAG 파이프라인으로 처리한 후, 답변과 참고 문서를 반환합니다.
        -   `POST /feedback`: 성능 평가를 위해 사용자의 피드백(좋아요/싫어요)을 수집합니다.
    -   **RAG 파이프라인 (`qa.py`)**:
        -   **Retriever**: `EnsembleRetriever`를 사용하여 두 가지 검색 방식을 결합하여 검색 정확도를 극대화합니다.
            1.  **Semantic Search**: `Chroma`를 벡터 스토어로 사용하는 `SelfQueryRetriever`. LLM을 활용하여 사용자의 자연어 질문을 메타데이터 필터링(예: `project_name`, `language`)이 포함된 벡터 쿼리로 변환합니다.
            2.  **Lexical Search**: 키워드 기반 검색을 위한 `BM25Retriever`.
        -   **Generator**: `ChatOpenAI` (기본값 `gpt-4o`)를 사용하여 검색된 문서를 기반으로 답변을 생성하며, 출처를 명시하도록 설계되었습니다.

3.  **`indexing` (데이터 파이프라인)**:
    -   **프레임워크**: `apscheduler`를 사용한 Python 스크립트
    -   **역할**: 데이터 수집 및 전처리를 담당합니다.
        -   GitLab 리포지토리를 로컬 디렉토리(`cloned_repos`)에 동기화합니다.
        -   `LangChain`을 사용하여 소스 코드 파일(`.py`, `.java`, `.md` 등)을 처리합니다.
        -   OpenAI 임베딩 모델(`text-embedding-3-small`)을 사용하여 임베딩을 생성하고 `ChromaDB`에 저장합니다.
        -   키워드 검색을 위한 `BM25` 인덱스를 생성하고 저장합니다.
    -   **스케줄**: 컨테이너 시작 시 즉시 실행된 후, 매일 자정에 다시 실행되어 데이터 최신성을 유지합니다.

4.  **`chroma` (벡터 데이터베이스)**:
    -   **이미지**: `chromadb/chroma`
    -   **역할**: `indexing` 서비스가 생성한 코드 벡터 임베딩을 저장합니다. 데이터는 `./chroma_data` 볼륨에 영속적으로 저장됩니다.

## 기술 스택

-   **백엔드**: FastAPI, Uvicorn
-   **프론트엔드**: Streamlit
-   **오케스트레이션**: Docker, Docker Compose
-   **RAG/LLM 프레임워크**: LangChain, OpenAI
-   **벡터 데이터베이스**: ChromaDB
-   **검색**: BM25 (Lexical Search)
-   **의존성 관리**: Poetry
-   **작업 스케줄링**: APScheduler

## 실행 방법

### 사전 요구사항

-   Docker 및 Docker Compose
-   GitLab 서버 접근 권한
-   OpenAI API 키

### 설정

1.  **리포지토리 클론** (아직 수행하지 않은 경우).

2.  **`.env` 파일 생성**: `.env.example` 파일을 `.env`로 복사하거나 이름을 변경하고, 필요한 환경 변수를 채웁니다.
    ```env
    # OpenAI API 키
    OPENAI_API_KEY="sk-..."

    # GitLab 정보
    GITLAB_URL="https://gitlab.your-company.com"
    GITLAB_PRIVATE_TOKEN="glpat-..." # 'read_api' 권한이 있는 토큰

    # (선택) 모델 및 이름 커스터마이징
    LLM_MODEL="gpt-4o"
    EMBEDDING_MODEL="text-embedding-3-small"
    CHROMA_COLLECTION_NAME="gitlab_code_collection"

    # UI가 사용할 API 주소
    # Docker 호스트의 IP 또는 설정된 도메인 이름을 사용
    API_BASE_URL="http://localhost:8001"
    ```

### 실행

1.  **컨테이너 빌드 및 실행**:
    ```bash
    docker-compose up --build -d
    ```

2.  **초기 인덱싱**:
    최초 실행 시 `indexing` 서비스가 모든 GitLab 리포지토리를 클론하고 인덱싱을 시작합니다. 이 과정은 리포지토리의 수와 크기에 따라 상당한 시간이 소요될 수 있습니다.
    컨테이너 로그를 통해 진행 상황을 모니터링할 수 있습니다.
    ```bash
    docker-compose logs -f indexing
    ```

3.  **애플리케이션 접근**:
    -   **챗봇 UI**: 브라우저에서 `http://localhost:8501`로 접속합니다.
    -   **API (Swagger UI)**: `http://localhost:8001/docs`에서 확인할 수 있습니다.

### 중지

모든 서비스를 중지하려면 다음을 실행합니다.
```bash
docker-compose down
```

## 🎯 프로젝트 목표

- **개발 생산성 향상**: 코드베이스 이해 시간 단축 및 원하는 정보 즉시 검색
- **지식 관리 및 공유**: 시스템화된 코드 지식 기반 답변 제공
- **신규 입사자 온보딩 가속화**: 새로운 프로젝트나 레거시 코드 이해도 향상
- **코드 품질 유지**: 중복 개발 방지 및 기존 코드 재사용성 증대

## 🏗️ 시스템 아키텍처

```mermaid
graph TD
    subgraph "Indexing Pipeline"
        A[GitLab Repository] -->|Git Clone| B[로컬 코드/문서]
        B -->|데이터 로드 및 파싱| C[소스코드, Markdown 등]
        C -->|텍스트 분할| D[의미 단위 텍스트 조각]
        D -->|임베딩 생성| E[벡터]
        E -->|벡터 DB 저장| F[(ChromaDB)]
    end

    subgraph "Retrieval & Generation Pipeline"
        G[사용자 질문] -->|질문 임베딩| H[질문 벡터]
        H -->|하이브리드 검색| F
        F -->|관련 문서 검색| I[관련 코드/문서 조각]
        G & I -->|프롬프트 구성| J[LLM 프롬프트]
        J -->|답변 생성| K[GPT-4o]
        K -->|최종 답변| L[생성된 답변]
    end
```

## 🛠️ 기술 스택

### 핵심 기술
- **언어**: Python 3.10+
- **RAG 프레임워크**: LangChain
- **LLM**: OpenAI GPT-4o
- **임베딩**: OpenAI text-embedding-3-small
- **벡터 DB**: ChromaDB
- **검색**: 하이브리드 검색 (Self-Query + BM25)
- **재랭킹**: Cohere Rerank

### 웹 인터페이스
- **API 서버**: FastAPI + Uvicorn
- **웹 UI**: Streamlit
- **컨테이너화**: Docker + Docker Compose

### Git 연동
- **GitLab API**: python-gitlab
- **스케줄링**: APScheduler

## 📁 프로젝트 구조

```
사내코드검색봇/
├── api.py              # FastAPI 서버 (REST API)
├── indexing.py         # GitLab 동기화 및 인덱싱
├── qa.py              # RAG 파이프라인 및 답변 생성
├── ui.py              # Streamlit 웹 인터페이스
├── docker-compose.yml # Docker 서비스 구성
├── Dockerfile         # Docker 이미지 설정
├── pyproject.toml     # Python 의존성 관리
├── RAG_Report.md      # 상세 기술 보고서
└── README.md          # 프로젝트 문서
```

## 🚀 빠른 시작

### 1. 환경 설정

1. **환경 변수 설정**
   
   `.env` 파일을 생성하고 다음 설정을 추가하세요:
   
   ```bash
   # OpenAI API 설정 (필수)
   OPENAI_API_KEY="your_openai_api_key_here"
   
   # GitLab 설정 (필수)
   GITLAB_URL="http://gitlab.geumdo.net"
   GITLAB_PRIVATE_TOKEN="your_gitlab_private_token_here"
   
   # Cohere API 설정 (선택사항 - 검색 결과 재랭킹용)
   COHERE_API_KEY="your_cohere_api_key_here"
   
   # API 서버 설정
   API_BASE_URL="http://chat-bot.geumdo.net"
   API_HOST="0.0.0.0"
   API_PORT="8001"
   
   # ChromaDB 설정
   CHROMA_HOST="chroma"
   CHROMA_PORT="8004"
   CHROMA_COLLECTION_NAME="gitlab_code_collection"
   
   # LLM 모델 설정
   LLM_MODEL="gpt-4o"
   EMBEDDING_MODEL="text-embedding-3-small"
   
   # 파일 경로 설정
   CLONE_DIR="cloned_repos"
   BM25_INDEX_PATH="bm25_index.pkl"
   ```

   **필수 API 키 발급 방법:**
   
   - **OpenAI API 키**: [OpenAI Platform](https://platform.openai.com/api-keys)에서 발급
   - **GitLab Private Token**: GitLab → Settings → Access Tokens에서 `api` 스코프로 발급
   - **Cohere API 키** (선택): [Cohere Platform](https://cohere.ai/)에서 발급

2. **Docker Compose로 서비스 실행**
   ```bash
   docker-compose up -d
   ```

### 2. 서비스 접속

- **웹 UI**: http://localhost:8501
- **API 서버**: http://localhost:8001
- **ChromaDB**: http://localhost:8004

### 3. 초기 인덱싱

첫 실행 시 GitLab 프로젝트 동기화 및 인덱싱이 자동으로 수행됩니다:

```bash
# 수동으로 인덱싱 실행 (필요시)
docker-compose run indexing python indexing.py
```

## 🔧 주요 기능

### 1. 하이브리드 검색
- **Self-Query Retriever**: 메타데이터 기반 필터링 (프로젝트명, 언어, 파일경로)
- **BM25 Retriever**: 키워드 기반 검색
- **Ensemble Retriever**: 두 검색 결과를 가중 평균으로 결합

### 2. 고급 검색 기능
- **메타데이터 필터링**: 프로젝트별, 언어별, 파일 경로별 검색
- **재랭킹**: Cohere Rerank를 통한 검색 결과 품질 향상
- **컨텍스트 보존**: 코드 구조를 유지하는 언어별 텍스트 분할

### 3. 사용자 인터페이스
- **채팅형 인터페이스**: 자연스러운 대화형 질의응답
- **피드백 시스템**: 답변 품질 개선을 위한 사용자 피드백 수집
- **출처 표시**: 답변의 근거가 된 파일 경로 자동 표시

### 4. 자동화
- **주기적 동기화**: GitLab 프로젝트 자동 업데이트
- **증분 인덱싱**: 변경된 파일만 재인덱싱
- **컨테이너화**: Docker를 통한 일관된 배포 환경

## 📖 사용 예시

### 질문 예시
```
"my-project에서 사용자 인증 관련 코드를 찾아줘"
"데이터베이스 연결 설정은 어디에 있어?"
"API 엔드포인트 구현 방법을 보여줘"
"특정 함수의 사용법을 알려줘"
```

### 답변 형식
```