프롬프트 엔지니어링 실전 가이드 - 기법, 패턴, 최적화 전략
프롬프트 엔지니어링의 핵심 기법(Zero-shot, Few-shot, CoT, Self-Consistency, ToT), 실전 패턴, 시스템 프롬프트 설계, 구조화 출력, 평가와 최적화 전략을 체계적으로 정리합니다.
AI에게 일을 잘 시키는 것도 실력입니다. 같은 LLM도 어떻게 말을 거느냐에 따라 결과물의 품질이 천차만별이거든요 — 마치 같은 재료로 요리를 해도 레시피에 따라 맛이 달라지는 것처럼요.
프롬프트 엔지니어링은 LLM에 전달하는 입력을 최적화해 원하는 결과를 얻는 기법입니다. 이 글에서는 기본 기법부터 고급 패턴, 실전 템플릿, 평가 방법까지 체계적으로 다룹니다.
이 글에서 배우는 것
- 효과적인 프롬프트의 7가지 구성 요소
- Zero-shot·Few-shot·CoT·Self-Consistency·ToT 기법과 각 적합 상황
- 시스템 프롬프트 설계 패턴과 도메인별 예시
- JSON·마크다운·XML 구조화 출력을 강제하는 방법
- 프롬프트를 평가하고 반복적으로 개선하는 프로세스
1. 프롬프트 엔지니어링 기초
프롬프트의 구성 요소
좋은 프롬프트는 좋은 업무 지시서와 똑같습니다. 누구에게(역할), 무슨 배경으로(맥락), 무엇을 하라고(지시), 어떤 데이터를 줘서(입력), 어떤 형태로 받을지(형식)까지 명확하게 담겨야 합니다. 효과적인 프롬프트는 다음 일곱 가지 요소의 조합으로 구성됩니다.
┌────────────────────────────────────────────┐
│ 프롬프트 구조 │
│ │
│ 1. 역할 (Role) — 모델의 페르소나 │
│ 2. 맥락 (Context) — 배경 정보, 제약 │
│ 3. 지시 (Instruction) — 수행할 작업 │
│ 4. 입력 (Input) — 처리할 데이터 │
│ 5. 예시 (Examples) — 원하는 입출력 쌍 │
│ 6. 출력 형식 (Format) — 응답 구조 지정 │
│ 7. 제약 (Constraints) — 하지 말아야 할 것 │
└────────────────────────────────────────────┘
실전 예시 — 모든 요소 적용:
[역할] 당신은 10년 경력의 데이터 엔지니어입니다.
[맥락] 우리 팀은 Apache Spark 기반의 ETL 파이프라인을 운영하고 있으며,
최근 야간 배치 작업의 실행 시간이 2배로 증가했습니다.
[지시] 아래 Spark 설정과 로그를 분석하여 성능 저하 원인을 진단하고
개선 방안을 제시하세요.
[입력]
spark.executor.memory=4g
spark.executor.cores=2
spark.sql.shuffle.partitions=200
에러 로그: "GC overhead limit exceeded"
[출력 형식] 다음 형식으로 답변하세요:
1. 원인 분석 (최대 3가지)
2. 개선 방안 (구체적 설정값 포함)
3. 예상 효과
[제약] 추측이 아닌 로그에 근거한 분석만 제시하세요.
프롬프트 작성 원칙
"잘 해줘"라는 지시로는 아무도, 심지어 AI도 제대로 움직이지 않습니다. 아래 표에서 나쁜 예와 좋은 예를 비교해보면 "구체성"이 얼마나 결과를 바꾸는지 바로 느껴집니다.
| 원칙 | 나쁜 예 | 좋은 예 |
|---|---|---|
| 구체적으로 | "코드 최적화해줘" | "이 Python 함수의 시간 복잡도를 O(n²)에서 O(n log n)으로 개선해줘" |
| 역할 부여 | "SQL 작성해줘" | "당신은 DBA입니다. 인덱스 활용을 고려한 최적화된 SQL을 작성하세요" |
| 형식 지정 | "장단점 알려줘" | "장단점을 표 형식(항목/장점/단점/비고)으로 정리하세요" |
| 제약 명시 | "요약해줘" | "3문장 이내로 요약하고, 기술 용어는 한국어로 번역하세요" |
| 단계 분리 | "분석하고 보고서 써줘" | "1단계: 데이터 분석, 2단계: 인사이트 도출, 3단계: 보고서 작성" |
2. 핵심 프롬프팅 기법
마치 요리 기술처럼, 프롬프트 기법도 상황에 따라 골라 씁니다. 간단한 요리는 레시피 없이 바로 만들고(Zero-shot), 복잡한 요리는 예시를 보며 따라 하고(Few-shot), 수학 문제처럼 단계별 풀이가 필요한 경우엔 과정을 명시하는 방법(CoT)을 씁니다.
Zero-shot 프롬프팅
예시 없이 지시만으로 태스크를 수행하는 기법입니다. LLM이 이미 잘 알고 있는 단순한 작업에 가장 어울립니다.
다음 고객 리뷰의 감성을 "긍정", "부정", "중립" 중 하나로 분류하세요.
리뷰: "제품 품질은 괜찮은데 배송이 너무 느렸어요. 다음에는 빨리 보내주세요."
감성:
효과적인 상황: 모델이 이미 잘 수행하는 단순 태스크 (분류, 번역, 요약)
Few-shot 프롬프팅
"이렇게 하면 돼"라는 예시 2~3개를 먼저 보여주면, 모델은 그 패턴을 보고 따라 합니다. 특히 특정 형식으로 출력해야 할 때 매우 효과적입니다.
다음 예시를 참고하여 SQL 에러 메시지를 분류하세요.
에러: "ORA-00942: table or view does not exist"
분류: 객체 접근 오류
조치: 테이블 존재 여부 확인, 권한 확인
에러: "ORA-01400: cannot insert NULL into"
분류: 데이터 무결성 오류
조치: NOT NULL 컬럼 확인, 기본값 설정
에러: "ORA-01652: unable to extend temp segment"
분류: 스토리지 오류
조치: 임시 테이블스페이스 확장, 쿼리 최적화
에러: "ORA-04031: unable to allocate shared memory"
분류:
조치:
Few-shot 설계 팁:
| 팁 | 설명 |
|---|---|
| 다양한 예시 | 각 카테고리를 골고루 포함 |
| 엣지 케이스 | 경계 사례 포함으로 정확도 향상 |
| 일관된 형식 | 모든 예시를 동일한 구조로 작성 |
| 적절한 수 | 3~5개가 적정 (너무 많으면 비용 증가) |
| 순서 | 가장 관련성 높은 예시를 마지막에 배치 |
Chain-of-Thought (CoT) 프롬프팅
수학 문제를 풀 때 "답: 8"이라고 쓰기 전에 중간 계산을 적는 것처럼, LLM에게도 풀이 과정을 먼저 쓰게 하면 정답률이 올라갑니다. 단계별 추론 과정을 명시적으로 유도하는 기법입니다.
기본 CoT (매직 문구):
Q: 서버 3대가 각각 초당 150 요청을 처리합니다. 피크 시간에 트래픽이
2.5배 증가하면, 요청 손실 없이 몇 대의 서버가 필요한가요?
A: 단계별로 풀어보겠습니다.
1. 현재 총 처리량: 3 × 150 = 450 요청/초
2. 피크 시간 트래픽: 450 × 2.5 = 1,125 요청/초
3. 필요 서버 수: 1,125 ÷ 150 = 7.5
4. 반올림 (서버는 정수): 8대
따라서 피크 시간에 최소 8대의 서버가 필요합니다.
Zero-shot CoT:
Q: 이 Spark 쿼리가 느린 이유를 분석하세요.
[쿼리 코드]
단계별로 분석해주세요. (Let's think step by step.)
참고: "단계별로 생각해보세요(Let's think step by step)" 한 줄만 추가해도 수학, 논리, 코드 분석 태스크에서 정확도가 크게 향상됩니다.
Self-Consistency
여러 사람에게 같은 질문을 던지고 다수결로 정답을 고르는 것처럼, 동일 질문에 대해 여러 번 추론한 뒤 가장 빈번한 답을 선택하는 기법입니다. 비용이 늘어나는 대신 신뢰도가 높아집니다.
[동일 질문을 Temperature 0.7로 5회 생성]
시도 1: 서버 8대 필요 (계산: 1125/150 = 7.5 → 올림)
시도 2: 서버 8대 필요
시도 3: 서버 9대 필요 (여유분 포함)
시도 4: 서버 8대 필요
시도 5: 서버 8대 필요
→ 다수결: 8대 (4/5 = 80% 일치)
import anthropic
client = anthropic.Anthropic()
def self_consistency(prompt: str, n: int = 5):
"""Self-Consistency: 다수결 기반 답변 선택"""
answers = []
for _ in range(n):
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
temperature=0.7,
messages=[{"role": "user", "content": prompt}]
)
answers.append(extract_answer(response.content[0].text))
# 가장 빈번한 답 선택
from collections import Counter
most_common = Counter(answers).most_common(1)[0]
return most_common[0], most_common[1] / n # 답, 신뢰도Tree-of-Thought (ToT) 프롬프팅
체스 선수가 "이 수를 두면 다음에 어떻게 될까?" 를 여러 경우의 수로 미리 따져보듯, 여러 추론 경로를 트리 형태로 탐색하여 최적의 답을 찾는 기법입니다. 복잡한 진단이나 의사결정 문제에 특히 유용합니다.
기법 비교 정리
한 문장으로: 태스크가 단순할수록 Zero-shot, 복잡하고 정확도가 중요할수록 CoT·ToT를 쓰면 됩니다.
| 기법 | 적합 태스크 | 비용 | 정확도 향상 |
|---|---|---|---|
| Zero-shot | 단순 분류, 번역, 요약 | 최저 | 기본 |
| Few-shot | 패턴 학습, 형식 지정 | 낮음 | 중간 |
| CoT | 수학, 논리, 코드 분석 | 중간 | 높음 |
| Self-Consistency | 정답이 명확한 문제 | 높음 (N배) | 매우 높음 |
| ToT | 복잡한 의사결정, 진단 | 높음 | 매우 높음 |
3. 시스템 프롬프트 설계
시스템 프롬프트의 역할
직원 온보딩 매뉴얼을 떠올려보세요 — "우리 회사에서는 이렇게 일해야 합니다" 라고 미리 정해두는 규칙집입니다. 시스템 프롬프트가 바로 그 역할을 합니다. 모델의 전반적인 행동 방식, 역할, 제약 조건을 정의하며, 모든 사용자 메시지에 앞서 적용됩니다.
# Claude 시스템 프롬프트
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=2048,
system="""당신은 Data Dynamics의 시니어 데이터 엔지니어 '데이터봇'입니다.
## 역할
- Apache Spark, Kafka, NiFi, Kudu 등 빅데이터 기술 전문가
- 사내 기술 표준과 모범 사례를 숙지
## 응답 규칙
1. 기술적 질문에는 코드 예시를 반드시 포함
2. 설정 변경 시 변경 전/후를 비교하여 제시
3. 확실하지 않은 정보는 "확인이 필요합니다"로 명시
4. 보안에 민감한 정보(비밀번호, 키)는 절대 출력하지 않음
## 응답 형식
- 간결하고 실용적인 답변 (불필요한 인사말 생략)
- 코드는 실행 가능한 수준으로 작성
- 핵심 포인트를 먼저 제시 (Bottom-up)
## 제한사항
- 인프라 비용이나 라이선스 관련 조언은 하지 않음
- 프로덕션 환경 직접 변경 명령은 수행하지 않음""",
messages=[{
"role": "user",
"content": "Spark executor OOM 에러가 발생합니다. 어떻게 해결하나요?"
}]
)시스템 프롬프트 설계 패턴
세 가지 검증된 패턴을 소개합니다. 처음에는 가장 단순한 ROLE-TASK-FORMAT으로 시작해서 필요에 따라 확장하면 됩니다.
패턴 1: ROLE-TASK-FORMAT
[ROLE] 당신은 {역할}입니다.
[TASK] {수행할 작업}을 합니다.
[FORMAT] 답변은 {형식}으로 작성합니다.
패턴 2: CONTEXT-OBJECTIVE-STYLE-TONE (COST)
[CONTEXT] 빅데이터 플랫폼을 운영하는 엔터프라이즈 환경
[OBJECTIVE] 기술 문제 해결 및 모범 사례 제시
[STYLE] 코드 중심, 실용적
[TONE] 전문적이면서 친근한
패턴 3: 행동 기반 (DO/DON'T)
## DO (해야 할 것)
- 코드 예시를 포함하세요
- 설정 변경의 영향도를 설명하세요
- 대안을 2가지 이상 제시하세요
## DON'T (하지 말아야 할 것)
- 비밀번호나 API 키를 출력하지 마세요
- 확실하지 않은 정보를 단정적으로 말하지 마세요
- 프로덕션 환경 변경을 직접 수행하지 마세요
도메인별 시스템 프롬프트 예시
데이터 엔지니어링 어시스턴트:
당신은 데이터 엔지니어링 전문 어시스턴트입니다.
전문 영역: Apache Spark, Kafka, Airflow, Hadoop, Hive, Kudu, NiFi
응답 언어: 한국어 (기술 용어는 영어 유지)
규칙:
1. 성능 관련 질문에는 반드시 메트릭 기반 분석 포함
2. 설정 변경 시 사이드이펙트 경고
3. 코드는 프로덕션 수준으로 작성 (에러 처리, 로깅 포함)
4. 스케일 고려사항 명시 (데이터 규모별 권장 사항)
코드 리뷰 어시스턴트:
당신은 코드 리뷰 전문가입니다.
리뷰 기준:
1. 버그 및 논리 오류
2. 보안 취약점 (SQL 인젝션, XSS 등)
3. 성능 이슈 (불필요한 루프, N+1 쿼리)
4. 코드 가독성 및 유지보수성
5. 테스트 커버리지
출력 형식:
- 심각도: 🔴 Critical / 🟡 Warning / 🟢 Suggestion
- 파일:줄번호
- 문제 설명
- 수정 제안 (코드 포함)
4. 구조화 출력 (Structured Output)
JSON 출력 강제
LLM의 답변을 코드에서 파싱하려면 형식이 예측 가능해야 합니다. "자유로운 산문" 대신 JSON이나 마크다운 테이블처럼 프로그램이 바로 읽을 수 있는 형식을 강제하는 방법을 알아봅시다.
다음 서버 로그를 분석하여 JSON 형식으로 결과를 반환하세요.
로그:
2025-03-15 14:32:01 ERROR [PaymentService] Connection timeout to payment gateway (retry 3/3)
2025-03-15 14:32:05 WARN [OrderService] Order #12345 payment pending, fallback to queue
2025-03-15 14:33:00 INFO [OrderService] Order #12345 payment retried successfully
출력 형식:
{
"incident_summary": "요약",
"severity": "critical|warning|info",
"affected_services": ["서비스명"],
"root_cause": "근본 원인",
"resolution": "해결 방법",
"timeline": [
{"time": "시간", "event": "이벤트", "level": "레벨"}
]
}
JSON만 출력하고 다른 텍스트는 포함하지 마세요.
마크다운 테이블 출력
다음 3개 데이터베이스를 비교하여 마크다운 테이블로 작성하세요.
비교 대상: PostgreSQL, MySQL, MongoDB
비교 항목: 유형, 트랜잭션, 스케일링, JSON 지원, 라이선스, 적합 용도
| 항목 | PostgreSQL | MySQL | MongoDB |
|------|-----------|-------|---------|
형식으로 작성하세요.
XML 태그 기반 구조화
Claude에서 특히 효과적인 방식입니다. XML 태그로 입력 영역과 출력 영역을 명확히 구분하면, 모델이 어디서 무엇을 읽고 어디에 무엇을 써야 하는지 혼동하지 않습니다.
다음 코드를 분석하세요.
<code>
def process_data(df):
result = df.groupBy("user_id").agg(
count("*").alias("total_orders"),
sum("amount").alias("total_amount")
)
return result.filter(col("total_amount") > 1000)
</code>
다음 태그에 맞게 분석 결과를 작성하세요:
<analysis>
<purpose>코드의 목적</purpose>
<issues>발견된 문제점 (있는 경우)</issues>
<optimization>최적화 제안</optimization>
<improved_code>개선된 코드</improved_code>
</analysis>
5. 고급 프롬프트 패턴
기본 기법을 익혔다면 이제 한 단계 위의 패턴들을 살펴봅시다. 각 패턴은 특정 상황에서 결과물의 품질을 크게 끌어올려줍니다.
역할극 (Role-Playing) 패턴
이 코드 리뷰를 세 가지 관점에서 진행하세요:
<reviewer role="보안 전문가">
보안 취약점 관점에서 코드를 검토하세요.
</reviewer>
<reviewer role="성능 엔지니어">
성능 병목 관점에서 코드를 검토하세요.
</reviewer>
<reviewer role="주니어 개발자">
코드 가독성과 이해 용이성 관점에서 검토하세요.
</reviewer>
비판적 사고 (Devil's Advocate) 패턴
다음 아키텍처 결정에 대해 반론을 제시하세요.
결정: "마이크로서비스 아키텍처로 전환한다"
당신은 이 결정에 반대하는 시니어 아키텍트입니다.
1. 이 결정의 잠재적 위험 3가지
2. 모놀리식이 더 나은 구체적 시나리오
3. 전환 시 가장 큰 실패 원인
4. 대안 접근 방식
점진적 복잡도 (Graduated Complexity) 패턴
Kafka의 Consumer Group을 세 가지 수준으로 설명하세요.
[초급] 비유를 사용하여 5줄 이내로 설명
[중급] 핵심 개념과 동작 원리를 코드 예시와 함께 설명
[고급] 리밸런싱 프로토콜, 파티션 할당 전략, 에러 처리를 상세히 설명
메타 프롬프팅 (Prompt about Prompt)
"좋은 프롬프트를 어떻게 써야 할지 모르겠다"면 LLM에게 직접 물어보세요. LLM에게 프롬프트 자체를 생성하게 하는 기법입니다.
나는 Spark 성능 튜닝에 대한 체계적인 분석을 수행하고 싶습니다.
다음 조건을 고려하여, 이 목표를 달성하기 위한 최적의 프롬프트를 작성해주세요:
- 대상: Apache Spark 3.x
- 분석 범위: 설정, 코드, 인프라
- 출력 형식: 체크리스트 + 개선 방안
- 사용 환경: Kubernetes 기반 Spark on K8s
반복적 정제 (Iterative Refinement) 패턴
[1차 요청]
Spark 성능 최적화 가이드를 작성하세요.
[2차 요청 — 깊이 추가]
메모리 관리 섹션을 더 상세하게 작성하세요.
특히 Off-heap 메모리와 Tungsten 엔진에 대해 설명을 추가하세요.
[3차 요청 — 사례 추가]
실제 장애 사례를 3가지 추가하세요.
각 사례에 원인, 진단 과정, 해결 방법을 포함하세요.
[4차 요청 — 형식 최적화]
전체 내용을 팀 위키에 올릴 형식으로 정리하세요.
목차, 코드 블록, 주의사항 박스를 포함하세요.
6. 실전 프롬프트 템플릿
코드 생성 템플릿
다음 요구사항에 맞는 {언어} 코드를 작성하세요.
## 요구사항
{상세 요구사항}
## 기술 스택
{사용할 라이브러리, 프레임워크}
## 제약 조건
- {제약 1}
- {제약 2}
## 코드 품질 기준
- 에러 처리 포함
- 타입 힌트 사용 (Python)
- 독스트링 작성
- 단위 테스트 포함
## 출력 형식
1. 메인 코드
2. 사용 예시
3. 테스트 코드
장애 분석 템플릿
다음 장애 상황을 분석하세요.
## 증상
{현재 관찰되는 문제}
## 환경
- 시스템: {시스템명}
- 버전: {버전}
- 인프라: {인프라 정보}
## 수집된 정보
{로그, 메트릭, 설정 등}
## 분석 요청
1. 가능한 원인 (확률 높은 순)
2. 원인별 진단 명령어/쿼리
3. 즉시 조치 방안 (긴급 대응)
4. 근본적 해결 방안 (재발 방지)
5. 영향 범위 평가
기술 문서 작성 템플릿
다음 주제로 기술 문서를 작성하세요.
## 주제
{문서 주제}
## 대상 독자
{독자 수준과 배경}
## 문서 구조
1. 개요 (왜 필요한가)
2. 아키텍처/구조
3. 단계별 가이드 (코드 포함)
4. 모범 사례
5. 트러블슈팅
6. FAQ
## 스타일
- 간결하고 실용적
- 코드 예시는 복사-붙여넣기로 바로 사용 가능
- 주의사항/경고는 명확히 구분
7. 프롬프트 안티패턴과 해결법
흔한 실수와 개선
처음 프롬프트를 짜다 보면 누구나 같은 실수를 반복합니다. 아래 표는 "이건 왜 잘 안 되지?" 싶을 때 바로 확인할 수 있는 체크리스트입니다.
| 안티패턴 | 문제 | 개선 |
|---|---|---|
| 모호한 지시 | "잘 작성해줘" | "3문장으로 요약하고 핵심 수치를 포함하세요" |
| 과도한 지시 | 20개 이상의 규칙 나열 | 핵심 규칙 5~7개로 압축, 우선순위 부여 |
| 부정 지시 | "하지 마세요" 나열 | "해야 할 것"을 먼저 명시 |
| 컨텍스트 부재 | 코드만 던지기 | 코드의 목적, 환경, 기대 결과 함께 제공 |
| 단일 턴 과부하 | 모든 것을 한 프롬프트에 | 단계별로 분리하여 순차 요청 |
| Temperature 미고려 | 항상 기본값 사용 | 창작: 0.7 |
Temperature와 Top-p 가이드
Temperature는 LLM의 "창의성 다이얼"입니다 — 0에 가까울수록 정확하고 예측 가능하며, 1에 가까울수록 다양하고 창의적인 답이 나옵니다. 코드를 짤 때는 0, 브레인스토밍할 때는 0.8 정도를 기억해두면 됩니다.
| 태스크 | Temperature | Top-p | 이유 |
|---|---|---|---|
| 코드 생성 | 0.0 | 1.0 | 정확성 최우선 |
| 버그 분석 | 0.0~0.2 | 1.0 | 사실 기반 분석 |
| 기술 문서 | 0.3~0.5 | 0.9 | 정확하되 자연스러운 문체 |
| 브레인스토밍 | 0.7~1.0 | 0.95 | 다양한 아이디어 |
| 창작 글쓰기 | 0.8~1.0 | 0.95 | 창의적 표현 |
# Temperature 설정 예시
import anthropic
client = anthropic.Anthropic()
# 코드 생성: 정확한 답변 (Temperature 0)
code_response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=2048,
temperature=0.0,
messages=[{"role": "user", "content": "Python으로 이진 탐색 구현"}]
)
# 브레인스토밍: 다양한 아이디어 (Temperature 0.8)
idea_response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=2048,
temperature=0.8,
messages=[{"role": "user", "content": "데이터 파이프라인 모니터링 개선 아이디어 10가지"}]
)8. 프롬프트 평가와 최적화
평가 방법
"이 프롬프트가 좋은 건지 어떻게 알 수 있죠?" — 이 질문에 제대로 답하려면 측정 방법이 있어야 합니다. 느낌이나 인상이 아니라 수치로 판단해야 지속적 개선이 가능합니다.
| 방법 | 설명 | 적합 상황 |
|---|---|---|
| 자동 평가 | 정답 비교 (Exact Match, F1) | 분류, 추출, QA |
| LLM-as-Judge | 다른 LLM이 품질 채점 | 생성형 태스크, 요약 |
| 사람 평가 | 도메인 전문가가 직접 평가 | 고품질 요구, 최종 검증 |
| A/B 테스트 | 프롬프트 변형 간 비교 | 프로덕션 최적화 |
LLM-as-Judge 구현
def evaluate_with_llm(question: str, response: str, criteria: list) -> dict:
"""LLM으로 응답 품질 평가"""
eval_prompt = f"""다음 응답의 품질을 평가하세요.
질문: {question}
응답: {response}
평가 기준 (각 1~5점):
{chr(10).join(f'- {c}' for c in criteria)}
JSON 형식으로 평가 결과를 반환하세요:
{{"scores": {{"기준명": 점수}}, "total": 평균, "feedback": "개선 사항"}}
"""
result = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
temperature=0.0,
messages=[{"role": "user", "content": eval_prompt}]
)
return json.loads(result.content[0].text)
# 사용
scores = evaluate_with_llm(
question="Spark에서 데이터 스큐를 해결하는 방법은?",
response="...(LLM 응답)...",
criteria=["정확성", "완전성", "실용성", "코드 품질"]
)프롬프트 최적화 프로세스
한 번에 완벽한 프롬프트를 만들려고 하지 마세요. 아래 흐름처럼 "작성 → 테스트 → 실패 분석 → 수정" 사이클을 반복하는 것이 핵심입니다.
참고: 프롬프트 최적화는 "한 번에 완벽하게"가 아닌 "반복적 개선"이 핵심입니다. 실패 사례를 수집하고 분석하여 점진적으로 개선하세요. 또한 모델 버전이 바뀌면 프롬프트 재검증이 필요합니다.
마치며 — 핵심 요약
- 프롬프트는 7가지 구성 요소(역할·맥락·지시·입력·예시·형식·제약)를 갖출수록 결과가 좋아집니다. 모두 필요한 건 아니지만, 부족한 항목이 있으면 거기서 오류가 납니다.
- 기법 선택의 원칙: 단순 태스크는 Zero-shot, 형식 맞추기엔 Few-shot, 추론이 필요하면 CoT, 정확도가 생명이면 Self-Consistency나 ToT.
- 시스템 프롬프트는 "직원 온보딩 가이드"입니다. 역할·규칙·금지 사항을 명확히 적어두면 매 메시지마다 반복 설명할 필요가 없습니다.
- JSON 출력이 필요하면 프롬프트에 스키마를 직접 보여주세요. "JSON만 출력하세요" 한 줄보다 실제 형식을 붙여넣는 것이 훨씬 효과적입니다.
- Temperature 0은 코드·분석, 0.7~1.0은 브레인스토밍·창작에 씁니다. 기본값(보통 1.0)이 항상 최선은 아닙니다.
- 프롬프트 개선은 반복입니다. 10~20건의 테스트 케이스로 실패 사례를 수집하고, 패턴을 분석해 개선하는 주기를 만드세요.
References
- Wei, J. et al. (2022). "Chain-of-Thought Prompting Elicits Reasoning in Large Language Models." NeurIPS
- Wang, X. et al. (2023). "Self-Consistency Improves Chain of Thought Reasoning in Language Models." ICLR
- Yao, S. et al. (2023). "Tree of Thoughts: Deliberate Problem Solving with Large Language Models." NeurIPS
- Anthropic. "Prompt Engineering Guide" — https://docs.anthropic.com/en/docs/build-with-claude/prompt-engineering
- OpenAI. "Prompt Engineering Guide" — https://platform.openai.com/docs/guides/prompt-engineering
- White, J. et al. (2023). "A Prompt Pattern Catalog to Enhance Prompt Engineering with ChatGPT." arXiv
— Data Dynamics 엔지니어링 팀