Skip to main content

Level 1: Naive RAG (PoC)

목표: “될 것 같다”를 증명 + 나중에 고치기 쉬운 흔적(Trace/Prompt 버전/평가 기록) 남기기

아키텍처

구현 체크리스트

  • 대표 문서 20~50개 선정 (실제 사용할 데이터의 축소판)
  • 텍스트 추출 및 기본 정제 (불필요한 헤더/푸터 제거)
  • 테스트 질문 20~30개 작성 (예상 답변 포함)
  • Chunking: Fixed-size + overlap (예: 500자, overlap 100자)
  • Embedding 모델 1개 선택 (예: text-embedding-3-small)
  • Vector DB 선택 및 적재 (예: Chroma, Qdrant)
  • Dense Retrieval: top-k 설정 (예: k=5)
  • 프롬프트 템플릿 작성 (컨텍스트 + 질문 → 답변)
  • LLM 모델 1개로 답변 생성 (예: gpt-4o-mini)
  • Tracing 활성화 (요청 1건 = Trace 1개)
  • Prompt v0를 허브/레지스트리에 등록 (버전 식별 가능)
  • 스팟체크 결과를 Score/코멘트로 기록
  • 20~30개 질문으로 답변 품질 수동 평가
  • “쓸만함/아쉬움/틀림” 3단계로 라벨링
  • 결과 기록 및 개선 포인트 정리

코드 예제

기본 RAG 파이프라인

from langchain.chat_models import init_chat_model
from langchain_openai import OpenAIEmbeddings
from langchain_chroma import Chroma
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough

# 1. Embedding + Vector DB
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = Chroma.from_documents(documents=docs, embedding=embeddings)
retriever = vectorstore.as_retriever(search_kwargs={"k": 5})

# 2. 프롬프트
prompt = ChatPromptTemplate.from_template("""
다음 컨텍스트를 기반으로 질문에 답변하세요.
모르면 "모르겠습니다"라고 답변하세요.

컨텍스트: {context}
질문: {question}
답변:
""")

# 3. LLM
llm = init_chat_model("gpt-4o-mini", model_provider="openai")

# 4. 체인
chain = (
    {"context": retriever, "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)

result = chain.invoke("RAG에서 인덱싱이란?")

LLMOps 최소 세팅 (LangSmith)

import os

# LangSmith Tracing 활성화
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = "your-api-key"
os.environ["LANGCHAIN_PROJECT"] = "rag-poc"

# 이후 모든 LangChain 실행이 자동으로 추적됨

LLMOps 최소 세팅 (Langfuse)

from langfuse import Langfuse
from langfuse.langchain import CallbackHandler

# Langfuse 클라이언트 초기화 (앱 시작 시 1회)
Langfuse(
    public_key="your-public-key",
    secret_key="your-secret-key",
    host="https://cloud.langfuse.com",  # 또는 셀프호스팅 URL
)

# 콜백 핸들러 생성
langfuse_handler = CallbackHandler()

# 체인 실행 시 콜백 전달
result = chain.invoke(
    "RAG에서 인덱싱이란?",
    config={"callbacks": [langfuse_handler]},
)

Gate 1 통과 기준

Gate 기준을 충족하지 못하면 튜닝(chunk/top-k/prompt/샘플 보강)을 반복합니다.

기능/품질

기준목표
정답 “쓸만함” 휴먼 평가60% (20~30문항)
치명적 환각 (근거 없는 확답)20%

LLMOps

기준목표
Trace 커버리지80% (대부분의 요청이 트레이스로 기록)
Prompt v0허브/레지스트리에 등록 완료 (버전 식별 가능)
스팟체크 결과Score/코멘트로 기록 (회귀 비교 가능)
Gate 1은 “완벽한 답변”이 아니라 “가능성 증명”이 목표입니다. 60% 이상이면 충분히 다음 단계로 진행할 수 있습니다.