“AI가 원하는 대로 안 해줘서 답답하다"는 말을 자주 듣습니다. 저도 처음에 그랬습니다. 그런데 프롬프트 엔지니어링을 체계적으로 공부하고 나서는 생각이 달라졌습니다. AI 모델은 무능한 게 아니라, 우리가 불완전한 지시를 주고 있는 것이었습니다. 좋은 프롬프트는 개발자가 함수 시그니처를 설계하는 것과 같습니다. 입력을 명확히 정의할수록 출력 품질이 올라갑니다.
이 가이드는 2026년 현재 주요 LLM(Claude, GPT-4o, Gemini)에 검증된 기법들을 실전 중심으로 정리한 것입니다.
You are a senior backend engineer with 15 years of experience,
specializing in Python and distributed systems.
Your task is to review the following code for security vulnerabilities,
performance bottlenecks, and adherence to SOLID principles.
Be direct and specific. Point out line numbers.
[코드 삽입]
기술 문서 작가 역할:
1
2
3
4
5
6
7
8
9
You are a technical writer who creates documentation for developers.
Your writing style is:
- Concise: one idea per sentence
- Active voice preferred
- Code examples for every concept
- No jargon without explanation
Write API documentation for the following endpoint:
[엔드포인트 정보]
주의사항: 역할 부여는 모델이 실제로 그 전문성을 갖고 있을 때 효과적입니다. 존재하지 않는 전문성을 부여하면 오히려 환각(hallucination)이 늘어납니다.
Q: 철수는 사과 5개를 갖고 있었습니다.
영희에게 2개를 주고, 마트에서 3개를 샀습니다.
남은 사과는 몇 개인가요?
A: 단계별로 생각해봅시다.
1) 시작: 5개
2) 영희에게 2개 줌: 5 - 2 = 3개
3) 마트에서 3개 구입: 3 + 3 = 6개
정답: 6개
Q: [실제 문제]
A:
텍스트: "배송이 너무 빠르고 포장도 꼼꼼해서 만족합니다"
분류: 긍정
이유: 배송 속도와 포장에 대한 명확한 만족 표현
텍스트: "기대했던 것과 달리 품질이 아쉽네요"
분류: 부정
이유: 기대 불충족, 품질 불만족 표현
텍스트: "그냥 그래요. 나쁘진 않은데 딱히 좋지도 않아요"
분류: 중립
이유: 명확한 긍정도 부정도 없는 표현
텍스트: "{{ 실제 리뷰 텍스트 }}"
분류:
이유:
<context>당신은 스타트업 기술 블로그의 편집자입니다.
독자는 주로 개발자이며, 실용적인 내용을 선호합니다.
</context><task>아래 초고를 편집해주세요.
</task><constraints>- 1,500단어 이내로 줄이기
- 전문 용어는 유지하되 처음 등장시 설명 추가
- 코드 예시는 반드시 보존
- 비유나 은유는 제거
</constraints><draft>[초고 내용]
</draft><output_format>편집된 글을 마크다운 형식으로 출력해주세요.
변경 사항은 [변경 요약] 섹션에 bullet point로 정리해주세요.
</output_format>
# 역할
당신은 Python 시니어 엔지니어입니다.
## 작업
아래 코드를 리뷰하세요.
## 리뷰 기준
1. 버그 및 오류 가능성
2. 성능 이슈
3. 보안 취약점
4. 코드 가독성
## 출력 형식
각 항목을 **[심각도: 높음/중간/낮음]** 형식으로 표시하세요.
## 코드
```python
[코드]
---
## 자기 일관성 (Self-Consistency)
동일한 질문을 여러 번 실행하고 다수결로 최종 답을 선택합니다. 특히 단일 답이 중요한 추론 문제에 효과적입니다.
```python
import anthropic
from collections import Counter
client = anthropic.Anthropic()
def self_consistent_answer(question: str, n: int = 5) -> str:
answers = []
for _ in range(n):
response = client.messages.create(
model="claude-opus-4-5",
max_tokens=500,
messages=[{
"role": "user",
"content": f"{question}\n\n단계별로 추론한 후 최종 답만 마지막 줄에 적어주세요."
}]
)
# 마지막 줄을 최종 답으로 추출
final_answer = response.content[0].text.strip().split("\n")[-1]
answers.append(final_answer)
# 다수결
most_common = Counter(answers).most_common(1)[0][0]
return most_common
result = self_consistent_answer("만약 A이면 B이고, B이면 C가 아니다. A가 참일 때 C는?")
print(result)
문제: [복잡한 설계 문제]
이 문제를 해결하기 위해 3가지 다른 접근 방법을 생각해보세요.
접근 1: [방법 설명]
- 장점:
- 단점:
- 실현 가능성 (1-10):
접근 2: [방법 설명]
- 장점:
- 단점:
- 실현 가능성 (1-10):
접근 3: [방법 설명]
- 장점:
- 단점:
- 실현 가능성 (1-10):
위 세 접근 중 가장 유망한 것을 선택하고,
그 접근법으로 구체적인 실행 계획을 세워주세요.
response = client.messages.create( model="claude-opus-4-5", max_tokens=1024, system="""당신은 한국어 기술 블로그의 편집자입니다.
항상 '~입니다/합니다' 체를 사용하세요.
코드 예시는 반드시 Python 3.11 기준으로 작성하세요.
응답은 마크다운 형식으로만 해주세요.""", messages=[{"role":"user","content":"FastAPI로 JWT 인증 미들웨어 작성하는 방법을 설명해줘."}])
시스템 프롬프트에 넣어야 할 것: 역할, 페르소나, 일관적으로 지켜야 할 규칙, 출력 형식 기본값
사용자 프롬프트에 넣어야 할 것: 구체적인 요청, 그때그때 달라지는 컨텍스트, 입력 데이터
“코드 리뷰해줘"는 너무 막연합니다. 무엇을, 어떤 기준으로, 어떤 형식으로 원하는지 구체적으로 써야 합니다.
실수 2: 부정적 지시만 있다
“~하지 마라"만 있으면 모델이 무엇을 해야 할지 모릅니다. 부정 지시와 함께 반드시 대안 행동을 제시합니다.
실수 3: 컨텍스트 창을 낭비한다
쓸모없는 배경 설명으로 컨텍스트를 채우면 핵심 내용의 영향력이 줄어듭니다. 정보는 관련성 순으로 배치합니다.
실수 4: 한 프롬프트에 여러 작업을 넣는다
요약 + 번역 + 감성 분석을 한 번에 요청하면 품질이 낮아집니다. 작업을 분리해서 순차적으로 요청하거나, 명확히 섹션을 구분합니다.
프롬프트 엔지니어링은 꾸준히 실험하고 반복하는 과정입니다. 오늘 소개한 기법들을 모두 한 번에 적용할 필요는 없습니다. 기초 원칙 4가지부터 시작해서, 결과가 부족하다고 느껴질 때마다 CoT나 Few-shot을 추가하는 방식으로 점진적으로 발전시켜 가시기 바랍니다. 모델은 여러분의 지시를 따르고 싶어합니다. 더 명확히 말할수록 더 좋은 결과가 돌아옵니다.