RAG 튜토리얼
RAG 튜토리얼 (Tutorial: Retrieval-Augmented Generation)
DSPy에서 검색 증강 생성(Retrieval-Augmented Generation, RAG) 의 유·무에 따른 기본 질의응답의 빠른 예시를 살펴봅니다. 구체적으로는 Linux나 iPhone 앱 같은 Tech 질문에 답하는 시스템을 만듭니다.
출처: 문서
본문
최신 DSPy를 pip install -U dspy 로 설치하고 따라와 주세요. 개념적 개요가 필요하다면 이 최근 강의가 좋은 출발점입니다. pip install datasets 도 실행해야 합니다. 이 튜토리얼은 dspy.Embedder 와 dspy.retrievers.Embeddings 를 쓰는데, numpy가 필요하므로 pip install dspy[numpy] 도 실행하세요.
DSPy 환경 구성
모듈에서 OpenAI gpt-4o-mini 를 사용한다고 DSPy에 알립니다. 인증은 OPENAI_API_KEY 에서 찾아봅니다. 다른 공급자나 로컬 모델로 쉽게 바꿀 수 있습니다.
권장: MLflow Tracing 설정(튜토리얼 내 네 단계 안내).
import dspy
lm = dspy.LM('openai/gpt-4o-mini')
dspy.configure(lm=lm)
가장 단순한 모듈은 dspy.Predict 입니다. DSPy Signature 즉 구조화 입출력 스키마를 받아 지정한 동작의 호출 가능한 함수를 반환합니다.
qa = dspy.Predict('question: str -> response: str')
response = qa(question="what are high memory and low memory on linux?")
print(response.response)
시그니처에서 지정한 변수 이름이 입력·출력 인자 이름과 역할을 정의한 것을 주목하세요. dspy.inspect_history(n=1) 로 DSPy가 보낸 프롬프트를 확인할 수 있습니다.
DSPy는 다양한 내장 모듈(dspy.ChainOfThought, dspy.ProgramOfThought, dspy.ReAct)을 가지며, 이들은 기본 dspy.Predict 와 상호 교환 가능합니다. 같은 시그니처를 받고 일반적인 프롬프트 기법·추론 시점 전략을 적용합니다. 예를 들어 dspy.ChainOfThought 는 시그니처가 요청한 출력 전에 LM에서 reasoning 을 이끌어내는 쉬운 방법입니다.
예시 다루기와 평가
RAG-QA Arena "Tech" 데이터셋에서 StackExchange 기반 질문과 정답 세트를 내려받습니다. 간단한 dict를 dspy.Example 리스트로 만듭니다. dspy.Example 을 만들 때 .with_inputs("field1", ...) 로 어떤 필드가 입력인지 지정하고, 나머지는 레이블·메타데이터로 취급됩니다.
data = [dspy.Example(**d).with_inputs('question') for d in data]
메트릭으로 dspy.evaluate.SemanticF1 을 씁니다. 이것은 실제로 우리가 쓰는 LM을 사용하는 매우 단순한 DSPy 모듈로 구현된 의미적 F1 메트릭입니다. dspy.Evaluate 로 병렬 평가를 실행할 수 있습니다.
evaluate = dspy.Evaluate(devset=devset, metric=metric, num_threads=24, ...)
기본 RAG
RAG 검색용 코퍼스 데이터를 내려받습니다. 더 빠르고 값싸게 돌리려고 코퍼스를 28,000 문서로 다운샘플링했습니다.
시스템의 retriever 설정
dspy.Embedder 와 임베딩을 사용해 retriever를 구성합니다.
첫 RAG 모듈 만들기
dspy.Module 로 검색과 답변 생성을 조합합니다. forward 는 질문을 받아 관련 문단을 검색해 컨텍스트를 만들고, ChainOfThought 로 답을 생성합니다.
class RAG(dspy.Module):
def __init__(self, k=3):
super().__init__()
self.retrieve = dspy.Retrieve(k=k)
self.generate_answer = dspy.ChainOfThought("context, question -> answer")
def forward(self, question):
context = self.retrieve(question).passages
return self.generate_answer(context=context, question=question)
DSPy 최적화기로 RAG 프롬프트 개선
dspy.GEPA 같은 최적화기로 메트릭에 맞춰 RAG 프로그램을 컴파일하면 더 높은 품질의 프롬프트를 얻어 점수를 더 끌어올립니다.
비용 주시
작은 LM과 최적화를 결합해 정확도를 높이면서 비용을 낮출 수 있습니다.
저장과 불러오기
최적화된 프로그램을 저장하고 다시 불러올 수 있습니다(MLflow에도 저장·로드 가능).
다음은?
Multi-Hop RAG나 RAG를 에이전트로 같은 심화 튜토리얼로 나아가세요.