OpenAI API 프롬프트 엔지니어링 기초
요약
본 글은 OpenAI API를 활용한 LLM 애플리케이션 개발자를 위해 프롬프트 엔지니어링의 기초 원칙을 설명합니다. 단순히 질문하는 것을 넘어, JSON 모드 사용, 역할 분담, Few-shot 학습 등 체계적인 지시 설계가 안정적이고 비용 효율적인 결과를 얻는 핵심임을 강조합니다.
핵심 포인트
- LLM은 의도를 읽지 않으므로, 기대하는 바를 명확히 언어화해야 합니다.
- JSON 모드 사용과 함께 프롬프트에 'JSON만 반환'하도록 명시하는 것이 중요합니다.
- 재현성 확보를 위해 temperature=0 설정을 권장하며, 토큰량 확인으로 비용을 예측해야 합니다.
- 환각 방지를 위해 '모르는 경우 불명'이라고 답변하도록 지시하고, 사용자 입력은 데이터로 취급해야 합니다.
OpenAI API의 프롬프트 엔지니어링 기초
개요
LLM을 사용한 애플리케이션을 만들 때, 모델 자체의 성능보다 '어떻게 지시하느냐'에 따라 결과가 크게 달라집니다. 같은 GPT 모델이라도 프롬프트 설계에 따라 정확도(accuracy), 안정성(stability), 비용(cost)이 완전히 다르게 나타납니다.
본 글에서는 OpenAI API를 소재로, 초보자를 위해 프롬프트 엔지니어링의 기초를 정리합니다. API 호출 방법부터 실무에서 유용한 테크닉(역할 분담・Few-shot 학습・구조화 출력・온도 제어)까지, 작동하는 코드 예제와 함께 설명합니다.
대상 독자는 'API 키는 발급받았지만, 원하는 답변이 돌아오지 않는다'라는 단계에 있는 분입니다.
환경
- Python 3.11
openaiv1 계열 Python SDK - 모델은gpt-4o-mini(저렴하고 입문용으로 충분)을 가정합니다.
pip install openai
export OPENAI_API_KEY="(자신의 키)"
API 키는 코드에 직접 작성하지 않고, 반드시 환경 변수나 시크릿 관리 시스템에서 불러옵니다.
발생한 문제
프롬프트 엔지니어링을 모른 채 API를 사용하면, 전형적으로 다음과 같은 문제가 발생합니다.
- 답변이 불안정함(ブレる) — 같은 질문에도 매번 다른 형식이나 세밀도로 답변이 돌아옴
- 지시 사항 무시 — 'JSON으로 응답해 줘'라고 작성했음에도 서론 문장이 붙어 나옴
- 불필요하게 길거나 짧음 — 출력량을 제어할 수 없어 비용 예측 불가
- 사전 지식 임의 보완 — 제공되지 않은 정보를 '그럴듯하게' 창작함 (환각, Hallucination)
이러한 문제들 대부분은 모델 능력 부족이 아니라 지시 설계 부족이 원인입니다.
원인
LLM은 '다음 올 확률이 높은 토큰'을 생성할 뿐이며, 우리의 의도를 읽어내는 것이 아닙니다. 모호한 지시에는 모호한 출력으로 응답합니다.
즉, 우리가 암묵적으로 기대하는 '출력 형식', '대상 독자', '제약 조건' 등을 모델은 명시되지 않는 한 알지 못합니다. 프롬프트 엔지니어링이란, 이 암묵적인 기대를 언어화하여 모델에게 전달하는 작업입니다.
대응 방법
기초가 되는 4가지 원칙을 익힙니다.
1.
res = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
...
JSON 모드를 사용하면 '서두 문장이 섞여 파싱이 깨지는' 사고를 막을 수 있습니다. 프롬프트 측에서도 'JSON만 반환하고 설명문은 붙이지 않는다'고 명시하는 것이 확실합니다.
확인 방법
프롬프트를 변경했다면, 반드시 다음 사항들을 확인해야 합니다.
- 재현성 — 동일한 입력을 3~5회 전송하여 출력이 흔들리지 않는지 (분류/추출의 경우
temperature=0) - 형식 적합 — JSON이라면
json.loads가 예외 없이 통과하는지 - 경계 케이스 — 공백 입력이나 예상치 못한 입력에도 고장 나지 않고, 예상된 탈출구(예: '해당 없음' 등)를 반환하는지
- 토큰량 —
response.usage로 입/출력 토큰을 확인하여 비용을 추정합니다.
print(res.usage) # prompt_tokens / completion_tokens / total_tokens
## 주의점
- **API 키는 절대 코드나 리포지토리에 포함하지 마세요**. 환경 변수 또는 시크릿 관리 시스템에서 불러옵니다.
- **환각(Hallucination) 대책**: '모르는 경우 '불명'이라고 답한다'고 명시하여 임의적인 창작을 억제합니다.
- **프롬프트 인젝션 (Prompt Injection)**: 사용자 입력을 system 지시와 동등하게 취급하지 않습니다. 입력은 어디까지나 데이터로 간주하고 감싸야 합니다.
- **모델 업데이트에 따라 동작이 바뀔 수 있음**: 모델명을 고정하고, 업데이트 시에는 회귀 테스트(regression test)를 수행합니다.
- **비용은 출력 토큰에 크게 영향을 받음**: 불필요하게 긴 출력을 요구하지 않습니다. `max_tokens`로 상한을 설정해야 합니다.
## 요약
프롬프트 엔지니어링의 기초는 결국 '암묵적인 기대를 명시하는 것'에 달려 있습니다.
- `system`으로 역할 및 제약을 고정합니다. — 출력 형식, 세분성(granularity), 건수까지 구체적으로 작성합니다.
- 예시 제공 (Few-shot)으로 형식을 학습시킵니다.
- `temperature`로 작업에 따라 변동 폭을 제어합니다. — JSON 모드와 `usage` 확인으로 실무 품질을 완성합니다.
우선 자신이 다루는 1가지 태스크를 선택하여, '모호한 프롬프트 → 제약이 추가된 프롬프트'의 전후 출력을 비교해보세요. 효과를 체감하는 것이 숙련도의 지름길입니다.
### Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기