개요

프롬프트 엔지니어링은 LLM에서 원하는 출력을 얻기 위해 입력을 설계하는 기술입니다. 단순한 질문 작성을 넘어, Chain-of-Thought(CoT), Few-shot Learning, 구조화된 출력 등 체계적인 기법이 발전하면서 LLM의 성능을 극대화할 수 있게 되었습니다.

이 글에서는 실무에서 바로 적용할 수 있는 고급 프롬프트 엔지니어링 기법들을 코드 예제와 함께 소개합니다.

핵심 개념: 프롬프트 설계 원칙

효과적인 프롬프트는 다음 원칙을 따릅니다.

  • 명확한 역할 부여: 시스템 프롬프트로 AI의 역할, 전문성, 제약사항을 정의
  • 구조화된 지시: 단계별 지시, 포맷 지정, 제약 조건을 명시적으로 기술
  • 컨텍스트 제공: 필요한 배경 정보를 충분히 제공하되, 관련 없는 정보는 제외
  • 출력 포맷 지정: JSON, 마크다운, XML 등 원하는 출력 형식을 명시

실전 예제: 고급 프롬프트 기법들

1. Chain-of-Thought (CoT) 프롬프팅

모델에게 단계별로 사고하도록 유도하여 복잡한 추론 능력을 향상시킵니다.

from anthropic import Anthropic

client = Anthropic()

# Zero-shot CoT
response = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=2048,
    messages=[{
        "role": "user",
        "content": """다음 문제를 단계별로 사고하여 풀어주세요.

문제: 한 회사에서 서버 3대를 운영합니다.
각 서버의 평균 응답시간이 120ms, 85ms, 200ms일 때,
로드밸런서가 요청을 균등 분배한다면 전체 평균 응답시간은?
또한 가장 느린 서버를 제거하면 평균이 얼마나 개선되나요?

단계별로 풀어주세요:"""
    }]
)

# Few-shot CoT
response = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=2048,
    messages=[{
        "role": "user",
        "content": """코드 리뷰 시 보안 취약점을 분석하는 패턴입니다.

예시 1:
코드: user_input = request.GET['id']; cursor.execute(f"SELECT * FROM users WHERE id = {user_input}")
분석: SQL 인젝션 취약점. 사용자 입력이 직접 쿼리에 삽입됨.
해결: 파라미터화된 쿼리 사용. cursor.execute("SELECT * FROM users WHERE id = %s", (user_input,))

예시 2:
코드: token = request.headers.get('Authorization'); payload = jwt.decode(token, options={"verify_signature": False})
분석: JWT 서명 검증 비활성화. 토큰 위조 가능.
해결: jwt.decode(token, SECRET_KEY, algorithms=["HS256"])으로 서명 검증 활성화.

이제 다음 코드를 분석해주세요:
코드: response.set_cookie('session_id', session_id, httponly=False, secure=False, samesite='None')"""
    }]
)

2. 구조화된 출력 (Structured Output)

# JSON 출력 강제
response = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=2048,
    system="""당신은 코드 분석 전문가입니다.
분석 결과를 반드시 다음 JSON 형식으로 출력하세요:
{
  "language": "프로그래밍 언어",
  "complexity": "low|medium|high",
  "issues": [
    {"type": "카테고리", "severity": "info|warning|error", "description": "설명", "line": 줄번호}
  ],
  "suggestions": ["개선 제안 1", "개선 제안 2"]
}
JSON 외에 다른 텍스트는 출력하지 마세요.""",
    messages=[{
        "role": "user",
        "content": "다음 코드를 분석해주세요:\n\n" + code_snippet
    }]
)

3. 메타 프롬프트: 프롬프트를 생성하는 프롬프트

당신은 프롬프트 엔지니어입니다. 다음 목적에 최적화된 시스템 프롬프트를 작성해주세요.

목적: {purpose}
대상 모델: {model_name}
입력 형식: {input_format}
출력 형식: {output_format}
핵심 제약사항: {constraints}

최적화 기준:
1. 모호성 최소화
2. 일관된 출력 형식 보장
3. 엣지 케이스 처리 포함
4. 할루시네이션 방지 조항 포함

활용 팁

  • 프롬프트 버전 관리: 프롬프트도 코드처럼 Git으로 버전 관리하세요. 변경 이력 추적이 중요합니다.
  • A/B 테스트: 동일한 입력에 대해 여러 프롬프트 변형을 테스트하고 정량적으로 비교하세요.
  • 토큰 효율성: 프롬프트가 길수록 비용이 증가합니다. 핵심 정보만 간결하게 전달하세요.
  • XML 태그 활용: Claude 모델은 XML 태그로 구조를 구분하면 더 정확하게 이해합니다. <context>, <instructions>, <output_format> 등을 활용하세요.
  • 네거티브 프롬프팅: "하지 말아야 할 것"을 명시하면 원치 않는 출력을 효과적으로 방지합니다.

마무리

프롬프트 엔지니어링은 AI 활용의 핵심 역량입니다. CoT, Few-shot, 구조화된 출력 등의 기법을 체계적으로 적용하면 같은 모델에서도 훨씬 높은 품질의 결과를 얻을 수 있습니다. 프롬프트는 "작성하고 끝"이 아니라, 지속적으로 실험하고 개선해야 하는 엔지니어링 산출물입니다.