튜토리얼: 기업 작업을 위한 구조화 정보 추출에 GEPA 사용
튜토리얼: 기업 작업을 위한 구조화 정보 추출에 GEPA 사용 (GEPA for Structured Information Extraction for Enterprise Tasks)
이 튜토리얼에서는 GEPA가 예측기(predictor) 수준의 피드백을 활용해 GPT-4.1 Nano의 성능을, 기업 환경에서 구조화 정보 추출과 분류를 위한 세 부분으로 나뉜 작업에 대해 개선하는 방법을 살펴볼게요.
출처: 문서
본문
LM 설정 (Setup the LM)
작은 모델이 GEPA로 어떻게 튜닝될 수 있는지 시연하기 위해 GPT-4.1 nano를 사용할 거예요.
api_key = input("Enter your OpenAI API key: ")
import dspy
lm = dspy.LM("openai/gpt-4.1-nano", temperature=1, api_key=api_key)
dspy.configure(lm=lm)
작업 입력의 예를 살펴볼게요. 이 작업은 시설 관리 이메일을 받아 세 가지 하위 작업 — 범주(categories), 감성(sentiment), 긴급도(urgency) — 를 분류합니다.
print("Input Message:")
print(train_set[0]['message'])
print("\n\nGold Answer:")
for k, v in json.loads(train_set[0]['answer']).items():
print(f"{k}: {v}")
Input Message:
Subject: Adjusting Bi-Weekly Cleaning Schedule for My Office
Dear ProCare Facility Solutions Support Team,
...
Best regards,
Dr. Alex Turner
Cryptography Researcher
Gold Answer:
categories: {'routine_maintenance_requests': False, 'customer_feedback_and_complaints': False, 'training_and_support_requests': False, 'quality_and_safety_concerns': False, 'sustainability_and_environmental_practices': False, 'cleaning_services_scheduling': True, 'specialized_cleaning_services': False, 'emergency_repair_services': False, 'facility_management_issues': False, 'general_inquiries': False}
sentiment: neutral
urgency: low
출력을 평가할 지표 정의 (Define the metric to evaluate the outputs)
지표는 세 작업 모두의 출력을 평가하고 집계 점수를 반환해요.
def score_urgency(gold_urgency, pred_urgency):
"""
Compute score for the urgency module.
"""
score = 1.0 if gold_urgency == pred_urgency else 0.0
return score
def score_sentiment(gold_sentiment, pred_sentiment):
"""
Compute score for the sentiment module.
"""
score = 1.0 if gold_sentiment == pred_sentiment else 0.0
return score
def score_categories(gold_categories, pred_categories):
"""
Compute score for the categories module.
Uses the same match/mismatch logic as category accuracy in the score.
"""
correct = 0
for k, v in gold_categories.items():
if v and k in pred_categories:
correct += 1
elif not v and k not in pred_categories:
correct += 1
score = correct / len(gold_categories)
return score
def metric(example, pred, trace=None, pred_name=None, pred_trace=None):
"""
Computes a score based on agreement between prediction and gold standard for categories, sentiment, and urgency.
Returns the score (float).
"""
# Parse gold standard from example
gold = json.loads(example['answer'])
# Compute scores for all modules
score_urgency_val = score_urgency(gold['urgency'], pred.urgency)
score_sentiment_val = score_sentiment(gold['sentiment'], pred.sentiment)
score_categories_val = score_categories(gold['categories'], pred.categories)
# Overall score: average of the three accuracies
total = (score_urgency_val + score_sentiment_val + score_categories_val) / 3
return total
GEPA로 최적화 (Optimizing with GEPA)
GEPA가 텍스트 피드백을 볼 수 있도록, 평가 지표를 피드백이 있는 지표(metric with feedback)로 수정해요. 이 지표는 평가 지표가 이미 비교하고 있는 내용을 명시적으로 제시해 GEPA가 각 예측기 수준에서 무엇을 개선해야 하는지 반성하게 합니다.
from dspy import GEPA
optimizer = GEPA(
metric=metric_with_feedback,
auto="light", # <-- We will use a light budget for this tutorial. However, we typically recommend using auto="heavy" for optimized performance!
num_threads=32,
track_stats=True,
use_merge=False,
reflection_lm=dspy.LM(model="gpt-5", temperature=1.0, max_tokens=32000, api_key=api_key)
)
평가 지표가 이미 텍스트 피드백을 생성하는 데 필요한 모든 정보를 포함하고 있었다는 점에 주목하세요 — 우리는 단순히 무엇이 비교되고 있는지 명시적으로 말하도록 수정했을 뿐이에요. 일반적으로 대부분의 작업에 대한 지표 함수는 이러한 피드백을 만드는 데 필요한 핵심 구성 요소를 제공하며, 어떤 요소를 GEPA 옵티마이저에 노출시켜 프로그램 성능을 반성하고 강화하게 할지 식별하는 것이 필요한 경우가 많아요.
최적화된 프롬프트 살펴보기 (Let's take a look at the optimized prompts)
for name, pred in optimized_program.named_predictors():
print("================================")
print(f"Predictor: {name}")
print("================================")
print("Prompt:")
print(pred.signature.instructions)
print("*********************************")
GEPA가 생성한 최적화된 프롬프트들은 상세하고 실행 가능한 지침을 포함합니다. 예를 들어 urgency_module.predict는 긴급도 수준(low/medium/high)과 각각에 대한 의사결정 규칙을 명확히 정의합니다:
================================
Predictor: urgency_module.predict
================================
Prompt:
Task: Read the provided message and determine the urgency.
Context/domain:
- Messages typically relate to facility management and services (e.g., facility operations, space utilization, security, sustainability, HVAC systems, maintenance, cleaning services) for a provider like ProCare Facility Solutions.
- Senders may be residential or commercial clients and may reference residents, tenants, property operations, or prior support interactions.
Output format:
- Provide exactly two fields, in this order, no extra text or formatting:
reasoning: <1–3 concise sentences explaining the key cues that determine urgency>
urgency: <one of: low | medium | high>
Urgency levels and decision rules:
- HIGH:
- Clear or implied immediate risk to safety/security or major operational impact.
- Explicit urgency signals (e.g., "Urgent," "Immediate attention required," "ASAP," "critical," "escalating").
...
- MEDIUM:
- Time-sensitive issues that affect comfort, reliability, or service quality but are not emergencies and pose no immediate safety/security risk.
...
- LOW:
- General inquiries, information requests, quotes, scheduling/options discussions, or interest in additional services with no stated or implied time pressure.
...
Key cues to weigh:
- Explicit urgency language vs. statements like "not an emergency."
- Safety/security implications and operational continuity.
- Impact scope (residents/tenants/business operations).
- Deadlines/dates or requested response times.
- Prior failed attempts and escalation tone.
- Do not inflate urgency based solely on polite phrases like "prompt assistance" if no urgent risk is present.
Tie-breakers:
- If the message explicitly says it's not an emergency and no serious risk is evident, do not classify as high.
- If unclear and no risk/time pressure is indicated, default to low.
*********************************
마찬가지로 sentiment_module.predict는 감성 분류에 대한 명확한 지침과 라벨 정의를 제공합니다.