GEPA로 프롬프트 최적화하기
GEPA로 프롬프트 최적화하기 (Prompt Optimizing with GEPA)
같은 프롬프트라도 언어 모델마다 반응이 다릅니다. 이번 강의에서는 손으로 프롬프트를 튜닝하는 대신, GEPA라는 최적화기에게 지시문 개선을 맡기는 방법을 배워볼게요.
출처: 문서
본문
프롬프트를 최적화하는 이유
서로 다른 언어 모델은 같은 프롬프트에 다르게 반응해요. 한 모델에게는 깔끔한 구조화 출력을 주는 요청이, 다른 모델에게는 횡설수설로 이어질 수 있습니다. 오늘의 모델에서 잘 작동하는 표현이 다음 달 공급자가 업데이트를 배포하면 동작을 멈출 수도 있어요. 어쩌면 어떤 이유로 모델이 고블린 얘기를 멈추지 못할 수도 있고요. 각 모델의 버릇을 손으로 익히는 건 느리고, 그 노력은 이전되지 않아요.
그리고 설령 하나의 모델만 고수한다 해도, 우리의 단어 선택과 지시문의 잠재적 조합은 거의 무한합니다.
프롬프트 최적화(prompt optimization) 는 그 손 튜닝 루프를 대체합니다. DSPy에 훈련 세트와 메트릭을 주면, DSPy는 (LM을 사용해) 지시문의 변형들을 생성하고, 이 후보 지시문들로 우리 예시를 실행해 가장 점수가 높은 프롬프트를 유지합니다. 특정 모델이 어떤 프롬프트 요령에 반응하는지 우리가 알 필요가 없어요. 최적화기가 그걸 찾아내니까요.
절약 효과는 클 수 있습니다. 더 작고 값싼 모델에서 최적화된 프로그램은 종종 같은 작업에서 손으로 프롬프트한 대형 모델을 따라잡을 수 있어요. 최적화기가 메트릭이 보상하는 것을 골라내기 때문에 신뢰성도 개선됩니다.
Shopify는 단일 프롬프트 GPT-5 작업을 DSPy로 전환하고 작은 Qwen 모델로 옮긴 뒤 GEPA로 최적화해, 약 75배 저렴하고 약 2배 더 신뢰할 수 있는 솔루션을 얻었어요. Dropbox는 DSPy와 프롬프트 최적화기를 사용해 작은 모델로 옮기고 프로그램 정확도를 두 배로 높이며, "같은 비용으로 10-100배 많은 데이터"라고 평했습니다.
더 좋은 점은, 다음 주에 새 모델이 출시되면 우리는 그 모델에 맞춰 최적화기를 다시 실행해 바꿔 끼울 가치가 있는지 즉시 판단할 수 있다는 거예요.
GEPA는 반성을 이용해 지시문을 개선합니다
DSPy는 여러 프롬프트 최적화기를 제공하지만, 오늘은 GEPA에 집중할 거예요.
GEPA를 좋아할 이유는 많지만, 핵심 기능은 메트릭이 텍스트 피드백을 제공할 수 있게 해 주며, LM이 그 피드백을 이후 지시문을 만드는 데 사용한다는 점이에요. 이것이 어떻게 작동하는지 보여 주기 위해 원래 메트릭을 업데이트해 볼게요:
def haiku_score_gepa(example, prediction, trace=None, pred_name=None, pred_trace=None):
"""
Penalize verbatim use of the input season string.
A haiku should evoke the season through imagery, not name it
directly.
"""
text = prediction.haiku.lower()
if example.season.strip().lower() in text:
return dspy.Prediction(
score=0.0,
feedback="Don't reference the input season verbatim."
)
return dspy.Prediction(score=1.0, feedback=None)
점수만 반환하는 대신, 지시문을 쓰는 LM에게 예측이 왜 실패했거나 성공했는지 알려 줄 수 있어요. 여기 예시는 조금 우습지만, 이 피드백 능력은 강력합니다. 학습할 데이터에 레이블을 붙일 때, 레이블러는 특정 레코드의 뉘앙스를 설명하는 메모를 적어 둘 수 있고, 그것이 GEPA에 전달되어 이후 지시문을 안내할 수 있어요. LM 심사위원으로 훈련할 때는 심사위원이 예측이 기준을 충족하지 못한 이유에 대한 상세 피드백을 제공해 줄 수 있습니다.
하이쿠 메트릭 확장하기
모델에게 더 큰 도전을 주기 위해, 우리가 하이쿠에서 기대하는 여러 조건을 검사하도록 메트릭을 확장했어요:
- 줄 수가 올바른가?
- 각 줄의 음절 수가 올바른가?
- 입력을 그대로 반복하지 않는가?
- 1인칭 목소리를 피하는가?
- 품사의 비율이 균형 잡혀 있는가?
- 형용사를 적게 쓰는가?
- 관사를 적게 쓰는가?
- 현재 시제를 쓰는가?
자연어 처리 라이브러리 spaCy를 대부분의 측정에 활용할 수 있어요.
이 모든 조건 때문에 메트릭이 이 워크스루에 넣기에는 너무 길어졌지만, 코드는 여기서 확인할 수 있습니다. 노트북 옆에 haiku_metric.py 를 놓고 from haiku_metric import haiku_metric 을 추가하면 따라올 수 있어요.
최적화 컴파일하기
메트릭이 정의됐으니 이제 최적화기를 설정할 차례입니다:
from haiku_metric import haiku_metric
reflection_lm = dspy.LM("openai/gpt-5.4")
optimizer = dspy.GEPA(
metric=haiku_metric,
reflection_lm=reflection_lm,
auto="light",
num_threads=2,
)
여기서 먼저 주목할 것은 reflection_lm 이에요. GEPA는 반성(reflection)과 지시문 작성에 별도의 LM을 선택할 수 있게 해 줍니다. 이 LM은 우리 예시와 그 점수를 살펴본 뒤, 점수를 개선하기 위해 우리 프롬프트를 다시 씁니다.
작은 모델을 최적화할 때는 더 큰 모델을 reflection_lm 으로 쓰는 게 가치 있어요. 그들은 더 나은 추론자이자 프롬프터이며, 최적화 동안 몇 번만 호출되므로 비용도 문제 되지 않습니다.
reflection_lm 외에도 메트릭과 스레드 수를 설정했어요. 지금은 둘을 쓰지만, 추론 공급자에 따라 rate limit을 피하려면 이것을 조정해야 할 수도 있어요.
auto 인자는 예산을 설정합니다. auto="light" 는 중단하기 전에 여섯 개 정도의 후보 프롬프트를 평가해요. "medium" 과 "heavy" 옵션은 더 나아가며, 우리가 설정할 수 있는 추가 장치들은 GEPA 심층 탐구에서 다룹니다.
마지막으로 최적화된 프로그램을 컴파일합니다:
optimized_haiku_bot = optimizer.compile(haiku_bot, trainset=train, valset=val)
훈련 세트와 검증 세트 고르기
GEPA는 이 두 분할을 서로 다른 작업에 사용합니다. trainset 은 반성적 프롬프트 업데이트를 위한 예시를 제공하고, valset 은 Pareto 점수를 추적하며 compile 이 반환하는 프로그램을 선택합니다. 어떤 단계에도 영향을 주지 않은 예시로 최적화된 프로그램을 평가할 수 있도록 최종 테스트 세트를 따로 남겨 두세요.
보편적인 분할 비율은 없어요. 일반화를 위해서는 가능한 한 많은 데이터를 trainset 에 두고, valset 은 하류 분포를 여전히 대표하는 가장 작은 표본으로 만드세요. 모든 후보가 검증 예시에서 점수가 매겨지므로, 불필요하게 큰 valset 은 고정된 메트릭 호출 예산 안에서 GEPA가 탐색할 수 있는 후보 프롬프트 수도 줄입니다.
valset 을 생략하면 GEPA는 선택에 trainset 을 재사용합니다. 이것은 주어진 예시에 대한 최고 출력을 찾는 것이 목표인 추론 시점(inference-time) 탐색에 유용할 수 있지만, 의도적으로 프롬프트가 그 예시들에 과적합(overfit)되도록 허용합니다. 보지 못한 데이터에서의 성능이 중요하다면 별도의 검증 세트를 전달하세요.
이제 음료를 챙겨서 기다릴 시간이에요.
뒤에서는 compile이 반복 루프를 실행합니다.
- GEPA가 student LM으로 훈련 예시에서 프로그램을 실행하고 각 결과를 우리 메트릭으로 점수 매겨요.
- 예시와 그 메트릭 결과가 reflection LM으로 보내지고, reflection LM이 새 지시문을 제안합니다.
- GEPA가 새 지시문으로 프로그램을 다시 실행하고, 다시 점수를 매긴 뒤 가장 점수가 좋은 지시문 후보를 유지합니다.
이 루프는 예산이 소진될 때까지 반복됩니다.
gpt-5.4-nano 로 최적화기를 실행하고 gpt-5.4 를 reflection LM으로 사용했을 때, 우리 점수는 전체 하이쿠 메트릭 대비 78.1%에서 90.1%로 올라갔어요. gpt-5.4 의 기준 점수 82.4%와 비교해 보세요.
GEPA로 최적화되면, 우리의 작은 모델은 더 빠르고, 더 싸고, 그리고 최적화되지 않은 프론티어 모델보다 더 낫게 됩니다.
최적화된 프로그램을 빠르게 저장하고, 우리 프롬프트가 어떻게 바뀌었는지 살펴볼게요.
optimized_haiku_bot.save("react_gpt_nano_haiku_optimized.json")
GEPA의 개선된 프롬프트
앞서 논의했듯이 ReAct 는 추론하고 어떤 도구를 호출할지 결정하는 Predict 모듈과 최종 출력을 합성하는 ChainOfThought 모듈로 구성돼요. GEPA는 이 두 모듈 모두를 프롬프트 최적화했습니다.
저장된 프로그램 상태를 담은 JSON 파일 안에서, 개선된 두 지시문을 모두 볼 수 있어요.
우리 프로그램의 합성 단계는 우리가 시그니처 docstring에 정의한 이 지시문으로 시작했어요:
Write a classical haiku given the provided inputs.
compile 이후에는 이렇게 바뀌었습니다:
Write a classical haiku from three inputs:
Inputs:
- location
- season
- mood
Output requirements:
- Return only the haiku itself.
- Exactly 3 lines.
- No title, no labels, no explanation, no reasoning, no quotation marks.
Primary success criteria, in order:
1. Exact 5-7-5 syllable counts, one line per count.
2. Exactly 3 lines.
3. A concrete seasonal image or cue appropriate to the given season.
4. Do not repeat the input season or mood words verbatim.
5. Keep diction sparse and image-heavy, with strong noun/verb focus.
Haiku style requirements:
- Use a classical haiku approach: brief, image-centered, present tense, emotionally restrained.
- Evoke the location, season, and mood indirectly through concrete imagery rather than naming them outright.
- Build the poem around one small, observable moment tied to the location.
- Prefer concrete nouns and active present-tense verbs.
- Favor lexical density: most words should carry imagery or action.
- Keep adjectives very sparse; avoid piling on descriptors.
- Avoid abstraction, explanation, commentary, and explicit emotional naming.
- Do not use first-person pronouns.
- Keep article use minimal.
Location handling:
- Anchor the poem clearly in the given location with at least one concrete object, surface, sound, or visual detail from that place.
- If the location is unusual or man-made, pair one specific man-made image from the setting with one seasonal sign.
지시문은 계속 이어져서 계절과 분위기 처리, 흔한 실패 모드, 그리고 출력 전 최종 품질 점검을 다룹니다.
흥미롭게도, 같은 프로그램도 모델에 따라 다르게 최적화됩니다.
Pareto 샘플링, 예측기별 피드백, auto 예산 변환, detailed_results 감사 추적 같은 전체 메커니즘은 GEPA 심층 탐구를 참고하세요.
다음: 저장하고 불러오기 →