핵심 요약
DSPy 2.7이 안정화됐다. 핵심은 프롬프트를 코드처럼 다루고, optimizer가 학습 데이터 기반으로 자동 튜닝한다는 것. 고객 문의 분류 파이프라인에 적용한 결과 정확도 78.4%→87.6%, 사람이 1주 잡고 손튜닝한 결과를 4시간 만에 능가. 단, optimizer 실행 비용은 따로 생각해야 한다.
1. 핵심 개념 — Signature, Module
import dspy
class Classify(dspy.Signature):
"""고객 문의를 카테고리로 분류한다."""
inquiry: str = dspy.InputField()
category: str = dspy.OutputField(desc="결제/배송/환불/기술/기타 중 하나")
reason: str = dspy.OutputField(desc="한 문장 근거")
classifier = dspy.ChainOfThought(Classify)
dspy.settings.configure(lm=dspy.LM("anthropic/claude-haiku-4-5"))
out = classifier(inquiry="어제 주문한 상품이 아직 안 와요")
print(out.category) # "배송"
프롬프트 문자열을 직접 안 쓴다. Signature가 입출력 계약, Module이 실행 전략.
2. MIPROv2로 자동 최적화
from dspy.teleprompt import MIPROv2
def metric(gold, pred, trace=None):
return float(gold.category == pred.category)
optimizer = MIPROv2(
metric=metric,
auto="medium", # light/medium/heavy
num_threads=8,
)
optimized = optimizer.compile(
classifier,
trainset=trainset,
valset=devset,
requires_permission_to_run=False,
)
optimized.save("classifier_v1.json")
MIPROv2는 instruction과 few-shot 예시를 동시에 탐색한다. medium 모드 약 4시간, API 비용 $18.
3. 결과 — 사람 vs DSPy
| 방법 | 정확도 | F1(매크로) | 비용/시간 |
|---|---|---|---|
| 제로샷 | 71.2% | 0.68 | $0 |
| 사람 손튜닝(시니어 1주) | 78.4% | 0.75 | 인건비 |
| MIPROv2 light(1시간) | 82.1% | 0.79 | $4 |
| MIPROv2 medium(4시간) | 87.6% | 0.85 | $18 |
| BootstrapFinetune(Haiku 파인튜닝) | 89.3% | 0.87 | $240 |
4. 런타임 비용 — 의외의 함정
최적화된 프롬프트는 보통 few-shot 8~12개를 박는다. 토큰 수가 늘어 호출당 비용이 커진다.
| 버전 | 입력 토큰/호출 | 월 비용(100만 호출) |
|---|---|---|
| 제로샷 | 180 | $45 |
| MIPROv2 결과 | 1,420 | $355 |
| BootstrapFinetune(파인튜닝) | 180 | $70(추론) + $240(학습) |
호출량 많으면 finetune이 결국 싸진다. 호출량 적으면 MIPROv2 결과가 합리적.
5. RAG 파이프라인 최적화
class RAG(dspy.Module):
def __init__(self, k=5):
self.retrieve = dspy.Retrieve(k=k)
self.generate = dspy.ChainOfThought("context, question -> answer")
def forward(self, question):
ctx = self.retrieve(question).passages
return self.generate(context=ctx, question=question)
rag = RAG()
optimized_rag = MIPROv2(metric=em_metric, auto="medium").compile(
rag, trainset=qa_pairs, valset=val_pairs
)
6. 함정
- 학습/검증 분포 불일치: trainset에 없는 패턴은 retrieval로 못 잡음
- 모델 교체 시 재최적화: Haiku에서 튜닝한 프롬프트가 GPT-4o-mini에서 정확도 떨어짐
- 버전 관리: 최적화 결과 JSON을 git에 커밋. 코드처럼 PR 리뷰
- 비결정성: 같은 optimizer 두 번 돌리면 결과 다름
7. 도입 결정
- 좋음: 정답 라벨 있는 분류/추출/QA, 사람-튜닝에 한계 느낌
- 유보: 생성형 작업(요약, 글쓰기) — 메트릭 정의가 어려움
- 나쁨: 학습 데이터 50개 미만, 비즈니스 룰이 계속 바뀌는 도메인
참고
- dspy.ai
- github.com/stanfordnlp/dspy

댓글 0