콘텐츠로 이동
Search

RAG:MLOps

MLOps 플랫폼 RAG (Retrieval-Augmented Generation) 가이드

RAG 적용 시나리오

MLOps 플랫폼에서 RAG가 적합한 사용 사례:

플랫폼 문서/ADR 검색 (가장 현실적)

  • docs/plans/ 하위에 40개 이상의 계획서, docs/reviews/, README, 계약서 등 존재
  • 예: "YOLO 학습 런타임 변경 방법은?", "테넌트 격리는 어떻게 되는가?"
  • 문서 단락을 근거와 함께 반환
  • Tool calling은 구조적 데이터(API)에는 강점이 있으나, 비정형 문서의 부분적 매칭은 RAG가 우위

Training Log/Error 지식베이스

  • 과거 실패한 학습 로그, 에러 메시지, 해결 방법 벡터 인덱싱
  • 예: "CUDA out of memory가 났는데 과거에 어떻게 해결했어?"
  • 유사한 로그 컨텍스트 + 해결 방법 반환
  • MLflow metrics는 tool calling, 로그 텍스트는 RAG

OpenAPI/Swagger 스펙 검색

  • API 엔드포인트가 많을 때 "데이터셋 삭제 관련 엔드포인트는?" 같은 질문
  • 스펙 문서에서 관련 섹션 retrieve

권장 아키텍처

Tool Calling 과 보완하는 형태:

사용자 질문
    │
    ▼
분류기 (의도 판단)
    ├── 구조적 데이터 조회 → Tool Calling (Plan 40 그대로)
    ├── 문서/지식 검색    → RAG (docs, logs, plans)
    └── 둘 다 필요       → Hybrid (RAG context + tool results 모두 주입)

FAQ: RAG 아키텍처 - LLM 모델 변경 시 RAG 재빌드가 필요한가요?

LLM 모델 변경 시 RAG 재빌드 필요 여부: 아니오.

RAG는 두 가지 독립된 모델로 구성된다:

┌─────────────────────────────────┐
│  Embedding Model (인덱싱)        │  ← 벡터 생성
│  (예: text-embedding-3-small)    │
│  문서 → 벡터 → 벡터 DB           │
└─────────────────────────────────┘
         │
         ▼  (검색된 컨텍스트)
┌─────────────────────────────────┐
│  LLM (생성)                      │  ← 답변 생성
│  (Qwen, DeepSeek, GPT, 등)      │
│  프롬프트 + 검색 결과 → 답변      │
└─────────────────────────────────┘
  • LLM만 바꿀 때: 인덱싱, 벡터 DB, 검색 로직 전부 그대로 사용
  • 다시 빌드해야 할 때: embedding model만 바꿨을 때
    • 다른 embedding model은 동일한 텍스트를 다른 벡터 공간에 매핑

구현 방법

권장 스택: PostgreSQL + pgvector

기존 PostgreSQL에 extension 추가하는 방식:

장점

새 인프라 없음 — 이미 돌아있는 Postgres에 extension 추가

Alembic 마이그레이션으로 스키마 관리 (기존 패턴 동일)

SQLAlchemy에서 직접 vector 컬럼 사용 가능

단일 DB = 백업/장애/보안 간소화

의존성: pgvector + pgvector-python 두 개만 추가

대체안 비교

옵션

적합도

이유

pgvector

⭐ 최고

기존 PG 재사용, 인프라 0추가

ChromaDB

◐ 보통

docker-compose에 별도 컨테이너 필요

Qdrant

◐ 보통

전용 벡터 DB이지만 오버킬

Cloudflare Vectorize

○ 낮음

앱이 k3s에서 돌고 Workers에서 안 돔

구현 단계

  1. 의존성 추가: pyproject.toml → "pgvector"',"pgvector-python"''
  2. '마이그레이션:
    • alembic revision -m "add rag_vector_store"
    • CREATE EXTENSION vector
    • CREATE TABLE rag_documents (id, tenant_id, chunk_text, embedding(vector), source_file, metadata(jsonb), created_at)
  3. Embedding 서비스:
    • src/geo_mlops/services/rag_embedding.py
    • OpenAI 호환 /v1/embeddings endpoint 호출
  4. '인덱싱 Job:
    • docs/, README.md, plan 문서 → chunking → embedding → DB insert
  5. '검색 서비스:
    • src/geo_mlops/services/rag_service.py
    • query embedding → vector nearest-neighbor 검색 → top-K chunk 반환
  6. 'RAG router:
    • src/geo_mlops/routers/rag.py
    • POST /api/v1/rag/query

전체 파이프라인

OpenAI API + pgvector는 전체 파이프라인 중 2개 단계만 담당.

단계

설명

추가 라이브러리

1. Document loading

docs/*.md, README, 코드 주석 읽기

langchain or unstructured or 직접 구현

2. Chunking

문서를 적절한 크기로 분할 (중복/겹침 포함)

langchain.text_splitter or 직접 구현

3. Embedding

텍스트 → 벡터

OpenAI /v1/embeddings or vLLM

4. Storage

벡터 + 메타데이터 보관

pgvector

5. Retrieval

쿼리 → 유사도 검색 + 필터(테넌트, 출처)

pgvector HNSW index

6. Context assembly

검색 결과 → prompt 조립

직접 구현

7. Generation

prompt + context → LLM → 답변

Plan 40의 llm_endpoint

8. Re-indexing

문서 변경 시 자동/수동 재인덱싱

file watcher or cron

┌──────────────┐     ┌──────────┐     ┌─────────┐     ┌──────────┐     ┌──────┐
│  원본 문서     │ ──→ │  Chunking │ ──→ │ Embedding│ ──→ │ pgvector │
│  docs/*      │     │  분할      │     │ OpenAI API│     │  저장    │
└──────────────┘     └──────────┘     └─────────┘     └──────────┘
                                                         ↑
┌──────┐     ┌───────────┐     ┌──────────┐     ┌──────────┐     │
│ LLM  │ ←── │ Prompt 조립 │ ←── │  Top-K   │ ←── │ Query   │ ────┘
│ 답변  │     │ context   │     │ 검색      │     │ Embedding│
└──────┘     └───────────┘     └──────────┘     └──────────┘
                                            (pgvector)

OpenAI API + pgvector가 담당하는 부분은 3번(Embedding)과 4번(Storage)만. 나머지 6개는 직접 구현해야 함.

단순화 방안:

  • langchain이 1~7을 대부분 커버
  • 그러나 프로젝트가 FastAPI + SQLAlchemy 패턴으로 일관되게 작성되어 있으므로 직접 구현이 기존 코드 스타일과 더 적합

FAQ: 자동화 가능성 - 사람이 개입하여 전체 자동화에 방해되는 요소가 있는가?

문서 기반 RAG는 전체 자동화 가능. 이미지 라벨링과 근본적으로 다름.

이미지 라벨링

RAG

입력

원시 이미지 (의미 없음)

문서 (의미 이미 존재)

인간 역할

"이게 결함이다" 라벨 필요

문서 작성 이미 끝난 상태

핵심 문제

의미 부여 (supervised)

의미 검색 (unstructured → vector)

자동화 파이프라인

docs/*.md, README.md, 코드
         │
         ▼  (자동)
   Chunking — 토큰 기준 분할
         │
         ▼  (자동, API 호출)
   Embedding — 텍스트 → 벡터
         │
         ▼  (자동)
   pgvector 저장
         │
         ▼  (자동)
   HNSW index 생성
         │
         ▼  (자동)
   Query → 검색 → LLM → 답변

선택적 인간 개입

다음은 선택사항이며, 설정 이후에는 완전히 자동:

  1. 답변 품질 평가: "이 대답이 맞나?" 판단 (optional)
  2. Chunk 파라미터 튜닝: chunk size, overlap 조정 (default로도 가능)
  3. 인덱싱 범위 결정: "어떤 문서를 포함할까?" (일회성 판단)

이미지 라벨링처럼 지속적으로 사람이 개입하는 작업은 없음.

See also

lastmod 2026-09-04created 2026-09-04author Zer0 sitemap