Skip to main content

프롬프트 설계 원칙

좋은 프롬프트는 LLM에게 명확한 지시, 충분한 맥락, 기대하는 출력 형식을 전달합니다. 프롬프트 설계는 단순히 질문을 던지는 것이 아니라, 모델이 최적의 응답을 생성하도록 입력을 구조화하는 엔지니어링 작업입니다.

학습 목표

이 문서를 완료하면 다음을 수행할 수 있습니다.
  • 프롬프트의 5대 구성 요소(RICFE)를 이해하고 활용할 수 있습니다
  • 태스크 유형에 맞는 프롬프트 구조를 설계할 수 있습니다
  • 흔한 안티 패턴을 식별하고 개선할 수 있습니다
  • 시스템 프롬프트와 사용자 프롬프트의 역할을 구분할 수 있습니다

왜 중요한가

동일한 LLM이라도 프롬프트에 따라 결과 품질이 크게 달라집니다.
❌ "이메일 써줘"
→ 모호한 지시 → 불필요한 내용 생성 → 여러 번 수정 필요

✅ "당신은 B2B SaaS 회사의 고객 성공 매니저입니다.
    3개월간 서비스를 미사용한 고객에게 리텐션 이메일을 작성하세요.
    - 톤: 따뜻하지만 전문적
    - 길이: 200자 이내
    - 포함: 신규 기능 2가지 언급, 미팅 제안
    - 제외: 할인 언급 금지"
→ 구체적 지시 → 즉시 사용 가능한 결과

핵심 개념: 프롬프트의 5대 구성 요소 (RICFE)

1. Role (역할)

모델이 어떤 전문가 역할로 응답해야 하는지를 정의합니다.
당신은 10년 경력의 시니어 데이터 엔지니어입니다.
당신은 한국어 문법 전문가입니다.
당신은 유치원 교사이며, 5세 아이에게 설명하듯 답변합니다.
역할의 효과:
  • 응답의 전문성 수준을 조절합니다
  • 용어 선택과 설명 깊이에 영향을 줍니다
  • 특정 관점에서의 분석을 유도합니다

2. Instruction (지시)

무엇을 해야 하는지를 명확하게 전달합니다. 프롬프트에서 가장 중요한 부분입니다.
# 나쁜 지시
"이 글에 대해 알려줘"

# 좋은 지시
"다음 뉴스 기사를 읽고 아래 3가지 관점에서 분석해주세요:
1. 핵심 주장 요약 (2문장 이내)
2. 근거의 타당성 평가 (강점/약점)
3. 누락된 관점이 있다면 지적"
효과적인 지시의 원칙:
  • 구체적 동사 사용: “분석하세요”, “비교하세요”, “요약하세요” (vs “알려줘”)
  • 단계 분해: 복잡한 작업을 명시적 단계로 나눕니다
  • 범위 한정: 분석 대상과 관점을 명확히 합니다
  • 부정 지시 포함: 하지 말아야 할 것도 명시합니다

3. Context (맥락)

모델이 응답에 활용할 배경 정보, 참조 데이터, 상황 설명을 제공합니다.
## 배경 정보
- 우리 회사는 B2B SaaS 스타트업 (시리즈 A, 직원 30명)
- 주요 고객: 중소기업 IT 팀
- 현재 MRR: $50K, 목표: $200K (12개월)

## 분석 대상
[여기에 분석할 데이터/텍스트 삽입]
맥락 제공의 규칙:
  • 관련 정보만 포함합니다 (불필요한 정보는 혼란 유발)
  • 구조화하여 제공합니다 (목록, 표, 섹션)
  • 모호한 용어를 정의합니다

4. Format (형식)

출력의 구조와 형태를 지정합니다.
다음 형식으로 답변하세요:

## 요약
(3줄 이내)

## 핵심 포인트
- 포인트 1: (설명)
- 포인트 2: (설명)
- 포인트 3: (설명)

## 결론
(1문단)
자주 사용하는 형식 지정:
  • 마크다운 구조: 헤딩, 목록, 표
  • JSON 출력: 프로그래밍에서 파싱 용이
  • 길이 제한: “200자 이내”, “3문장으로”
  • 언어/톤: “격식체”, “구어체”, “기술 문서 스타일”

5. Examples (예시)

기대하는 입출력 예시를 직접 보여줍니다. Few-shot 프롬프팅의 핵심이며, 형식과 품질 기대치를 전달하는 가장 효과적인 방법입니다.
아래 예시처럼 고객 리뷰의 감성을 분류하세요.

예시 1:
입력: "배송이 빨라서 좋았어요"
출력: {"감성": "긍정", "카테고리": "배송", "신뢰도": 0.95}

예시 2:
입력: "제품은 좋은데 가격이 비싸네요"
출력: {"감성": "혼합", "카테고리": "가격", "신뢰도": 0.80}

이제 다음 리뷰를 분류하세요:
입력: "포장이 훼손되어 왔어요"

시스템 프롬프트 vs 사용자 프롬프트

OpenAI API와 Claude API에서 프롬프트는 **역할(role)**에 따라 구분됩니다.
from openai import OpenAI
client = OpenAI()

response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[
        {
            "role": "system",
            # 시스템 프롬프트: 모델의 행동 방침, 역할, 제약 사항
            "content": """당신은 한국어 맞춤법 교정 전문가입니다.
규칙:
- 맞춤법 오류만 수정합니다
- 문체나 표현은 변경하지 않습니다
- 수정한 부분을 [수정 전 → 수정 후] 형식으로 표시합니다
- 오류가 없으면 "맞춤법 오류 없음"이라고 답합니다""",
        },
        {
            "role": "user",
            # 사용자 프롬프트: 실제 처리할 입력 데이터
            "content": "이번달 매출이 왠지 줄어든것 같습니다.",
        },
    ],
)
print(response.choices[0].message.content)
# [왠지 → 웬지], [줄어든것 → 줄어든 것]
구분System PromptUser Prompt
역할행동 방침, 역할, 제약처리할 데이터, 질문
변경 빈도거의 고정매 요청마다 변경
우선순위높음낮음
예시”당신은 ~ 입니다”, “규칙:""이 텍스트를 분석하세요:“

프롬프트 설계 템플릿

분석 태스크

# 역할
당신은 [분야] 전문 분석가입니다.

# 지시
다음 [데이터 유형]을 분석하고 아래 관점에서 평가해주세요:
1. [관점 1]
2. [관점 2]
3. [관점 3]

# 맥락
[배경 정보]

# 분석 대상
[데이터]

# 출력 형식
## 핵심 발견
- (최대 5개)

## 상세 분석
[관점별 분석]

## 권장 사항
- (실행 가능한 제안 3개)

변환 태스크

# 지시
다음 [입력 형식]을 [출력 형식]으로 변환하세요.

# 규칙
- [규칙 1]
- [규칙 2]
- [하지 말아야 할 것]

# 예시
입력: [예시 입력]
출력: [예시 출력]

# 변환 대상
[실제 입력 데이터]

생성 태스크

# 역할
당신은 [역할]입니다.

# 지시
[생성물 유형]을 작성하세요.

# 요구 사항
- 톤: [톤 설명]
- 길이: [길이 제한]
- 대상: [독자/사용자]
- 포함: [반드시 포함할 요소]
- 제외: [포함하지 말 요소]

# 참고 정보
[관련 데이터]

흔한 안티 패턴

1. 모호한 지시

❌ "좋은 코드 작성법 알려줘"
✅ "Python에서 함수 설계 시 지켜야 할 원칙 5가지를 설명하세요.
    각 원칙마다 잘못된 예시와 개선된 예시를 포함하세요."

2. 과도한 정보 제공

❌ [관련 없는 회사 전체 역사 + 모든 제품 목록 + 10년치 재무 데이터]
   "이걸 분석해줘"

✅ [현재 분기 매출 데이터 + 경쟁사 2곳 비교]
   "Q3 매출 감소 원인을 경쟁사 대비 분석하세요"

3. 모순되는 지시

❌ "간결하게 답변하세요. 모든 세부 사항을 빠짐없이 포함하세요."
✅ "핵심 포인트 3가지를 각 2문장으로 요약하세요."

4. 확인 없는 가정

❌ "이전에 말한 것처럼 진행해줘"  (LLM은 이전 대화를 기억하지 못할 수 있음)
✅ "[이전 논의 요약을 포함] 이를 기반으로 다음 단계를 진행하세요."
입력 토큰에 대한 비용이 발생하지만, 잘 설계된 프롬프트는 재시도 횟수를 줄여 총 비용을 낮춥니다. 모호한 프롬프트로 3~4번 반복하는 것보다, 구체적인 프롬프트로 한 번에 원하는 결과를 얻는 것이 더 경제적입니다.
연구 결과에 따르면 역할 지정은 모델의 응답 품질에 유의미한 영향을 미칩니다. 특히 전문 지식이 필요한 태스크에서 관련 전문가 역할을 부여하면, 더 정확하고 전문적인 용어를 사용한 답변이 생성됩니다. 다만 과장된 역할(“세계 최고의 전문가”)보다 구체적 역할(“5년 경력 데이터 분석가”)이 더 효과적입니다.
  1. 형식을 명시적으로 정의하세요 (JSON 스키마 제공). 2. 예시를 포함하세요 (입출력 예시로 형식 학습). 3. JSON 모드를 사용하세요 (OpenAI의 response_format={"type": "json_object"}). 4. 출력 파싱 라이브러리를 활용하세요 (Pydantic, instructor). 이는 출력 파싱 문서에서 자세히 다룹니다.
시스템 프롬프트는 사용자에 의해 우회될 수 있습니다 (Prompt Injection). 비밀 정보나 API 키를 시스템 프롬프트에 넣지 마세요. 보안이 중요한 경우 서버 사이드 검증을 추가해야 합니다. 이는 안전장치 문서에서 다룹니다.

체크리스트

학습을 마치기 전에 아래 항목을 확인하세요.
  • RICFE 5대 구성 요소를 모두 설명할 수 있는가?
  • 시스템 프롬프트와 사용자 프롬프트의 차이를 이해하는가?
  • 분석/변환/생성 태스크에 맞는 프롬프트 템플릿을 작성할 수 있는가?
  • 4가지 안티 패턴을 식별하고 개선할 수 있는가?
  • JSON 등 구조화된 출력을 요청하는 프롬프트를 작성할 수 있는가?

다음 문서