목표: “될 것 같다”를 증명 + 나중에 고치기 쉬운 흔적(Trace/Prompt 버전/평가 기록) 남기기
아키텍처
구현 체크리스트
코드 예제
기본 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% 이상이면 충분히 다음 단계로 진행할 수 있습니다.