Skip to main content

Level 3: Advanced (검색전략 + 가드레일)

목표: 정확도 상승 + 안전한 실패 + 빠른 디버깅
Langfuse는 LLM-as-a-Judge로 출력 품질을 루브릭 기반으로 평가하고, LangSmith도 데이터셋 기반 평가/실험을 지원합니다.

아키텍처

구현 체크리스트

  • 질문 정규화 (오타 교정, 언어 감지)
  • PII 마스킹 (개인정보 필터링)
  • Query Rewriting / 확장 구현
  • Multi-query 또는 HyDE 적용 여부 결정
  • Dense + Sparse (BM25) Hybrid Search 구현
  • 메타데이터 필터 (ACL, 기간, 카테고리) 적용
  • MMR (Maximum Marginal Relevance) 다양성 확보
  • 검색 전략별 성능 비교 테스트
  • Cross-encoder 또는 LLM Rerank 적용 여부 결정
  • Rerank 전/후 성능 비교 (Recall, 지연)
  • top-k → rerank → top-n 파이프라인 구성
  • 답변 생성 정책 수립 (출처 필수, “모르면 모름” 규칙)
  • 가드레일 구현 (유해 콘텐츠 필터, 도메인 외 질문 처리)
  • 폴백 전략 (검색 실패 시 → 티켓 생성 또는 사람 연결)
  • 컨텍스트 압축/요약 옵션 적용
  • 스텝별 Span 분리 (Retrieval / Rerank / Generation)
  • LLM-as-Judge 자동 평가 + Human 평가 병행
  • Prompt/모델 A/B 실험으로 개선 수치 증명
  • 비용·지연 모니터링 (모델별, 스텝별)

코드 예제

Hybrid Search + Reranking 파이프라인

from langchain.chat_models import init_chat_model
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings
from langchain_classic.retrievers import EnsembleRetriever
from langchain_community.retrievers import BM25Retriever
from langchain_classic.retrievers.document_compressors import CrossEncoderReranker
from langchain_classic.retrievers.contextual_compression import ContextualCompressionRetriever
from langchain_community.cross_encoders import HuggingFaceCrossEncoder

# Dense Retriever
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = Chroma(embedding_function=embeddings, persist_directory="./chroma_db")
dense_retriever = vectorstore.as_retriever(search_kwargs={"k": 20})

# Sparse Retriever (BM25)
bm25_retriever = BM25Retriever.from_documents(documents)
bm25_retriever.k = 20

# Hybrid (Ensemble)
hybrid_retriever = EnsembleRetriever(
    retrievers=[dense_retriever, bm25_retriever],
    weights=[0.6, 0.4],
)

# Reranking
model = HuggingFaceCrossEncoder(model_name="BAAI/bge-reranker-v2-m3")
compressor = CrossEncoderReranker(model=model, top_n=5)
reranking_retriever = ContextualCompressionRetriever(
    base_compressor=compressor,
    base_retriever=hybrid_retriever,
)

# 검색 실행
docs = reranking_retriever.invoke("검색 전략 비교")

가드레일 구현

from langchain_core.prompts import ChatPromptTemplate
from langchain.chat_models import init_chat_model
from langchain_core.output_parsers import StrOutputParser

llm = init_chat_model("gpt-4o-mini", model_provider="openai")

# 답변 생성 정책이 포함된 프롬프트
prompt = ChatPromptTemplate.from_template("""
당신은 사내 문서 기반 Q&A 시스템입니다.

## 규칙
1. 반드시 아래 컨텍스트에 근거하여 답변하세요.
2. 컨텍스트에 없는 내용은 절대 추측하지 마세요.
3. 답변할 수 없으면 "해당 내용은 제공된 문서에서 확인할 수 없습니다."라고 답하세요.
4. 답변 끝에 반드시 [출처: 문서명] 형태로 근거를 표시하세요.

## 컨텍스트
{context}

## 질문
{question}

## 답변
""")

chain = prompt | llm | StrOutputParser()

Gate 3 통과 기준

품질/안전/성능

기준목표
정답률 (대표 100문항)75%
출처 포함 비율90%
p95 지연목표 이하 (예: 5초)
치명적 환각5~10%

LLMOps

기준목표
자동 평가LLM Judge 또는 규칙/휴먼으로 품질 점수 누적
A/B 실험Prompt/모델 버전 비교로 개선이 수치로 증명
Span 분리Retrieval/Rerank/Generation 스텝별로 병목/실패 위치 식별 가능
도메인 리스크가 높은 경우(법무, 의료, 금융) Gate 기준을 더 엄격하게 설정하세요. 예: 치명적 환각 ≤ 1%, 정답률 ≥ 90%.