ChatGPT API 완벽 가이드 | 사용법·요금·프롬프트 엔지니어링·실전 예제
이 글의 핵심
ChatGPT API를 실무에 활용하는 완벽 가이드입니다. API 키 발급부터 요금 체계, 프롬프트 엔지니어링, 스트리밍, 함수 호출까지 실전 예제로 정리했습니다.
실무 경험 공유: 실시간 채팅 모더레이션 시스템에 ChatGPT API를 도입한 경험을 바탕으로 작성했습니다. 초당 1000건 이상의 메시지를 처리하면서 얻은 실전 노하우를 공유합니다.
들어가며: “ChatGPT를 내 서비스에 넣고 싶어요”
실무 문제 시나리오
시나리오 1: 고객 문의 자동 응답
하루 100건 이상의 고객 문의를 수동으로 처리하고 있습니다. ChatGPT API로 80%를 자동화할 수 있습니다.
시나리오 2: 콘텐츠 자동 생성
블로그 글, 상품 설명, 메타 태그를 매번 작성하는 데 시간이 너무 걸립니다. API로 초안을 자동 생성할 수 있습니다.
시나리오 3: 코드 리뷰 자동화
Pull Request마다 코드 리뷰가 밀립니다. ChatGPT API로 기본 리뷰를 자동화할 수 있습니다.
flowchart LR
subgraph Before["수동 작업"]
A1[고객 문의]
A2[콘텐츠 작성]
A3[코드 리뷰]
end
subgraph After["ChatGPT API"]
B1[자동 응답]
B2[자동 생성]
B3[자동 리뷰]
end
Before --> After
1. ChatGPT API 시작하기
API 키 발급
- OpenAI 계정 생성: https://platform.openai.com/signup
- API 키 발급: https://platform.openai.com/api-keys
- 결제 수단 등록: https://platform.openai.com/account/billing
# API 키 확인
export OPENAI_API_KEY="sk-..."
echo $OPENAI_API_KEY
첫 API 호출
# Python 예제
import openai
openai.api_key = "sk-..."
response = openai.chat.completions.create(
model="gpt-4",
messages=[
{"role": "user", "content": "안녕하세요!"}
]
)
print(response.choices[0].message.content)
// Node.js 예제
import OpenAI from 'openai';
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
const response = await openai.chat.completions.create({
model: 'gpt-4',
messages: [
{ role: 'user', content: '안녕하세요!' }
],
});
console.log(response.choices[0].message.content);
2. 모델 선택 및 요금
모델 비교
| 모델 | 입력 가격 (1M 토큰) | 출력 가격 (1M 토큰) | 특징 |
|---|---|---|---|
| gpt-4-turbo | $10 | $30 | 최신, 빠름, 128K 컨텍스트 |
| gpt-4 | $30 | $60 | 가장 강력, 8K 컨텍스트 |
| gpt-3.5-turbo | $0.50 | $1.50 | 빠르고 저렴, 16K 컨텍스트 |
토큰 계산
import tiktoken
def count_tokens(text, model="gpt-4"):
encoding = tiktoken.encoding_for_model(model)
return len(encoding.encode(text))
text = "ChatGPT API를 사용하는 방법"
tokens = count_tokens(text)
print(f"토큰 수: {tokens}") # 약 10토큰
비용 계산 예시
def calculate_cost(input_tokens, output_tokens, model="gpt-4-turbo"):
prices = {
"gpt-4-turbo": {"input": 10, "output": 30},
"gpt-4": {"input": 30, "output": 60},
"gpt-3.5-turbo": {"input": 0.5, "output": 1.5},
}
price = prices[model]
cost = (input_tokens * price["input"] + output_tokens * price["output"]) / 1_000_000
return cost
# 예시: 1000 토큰 입력, 500 토큰 출력
cost = calculate_cost(1000, 500, "gpt-4-turbo")
print(f"비용: ${cost:.4f}") # $0.0250
3. 프롬프트 엔지니어링
기본 원칙
# ❌ 나쁜 프롬프트
response = openai.chat.completions.create(
model="gpt-4",
messages=[
{"role": "user", "content": "코드 짜줘"}
]
)
# ✅ 좋은 프롬프트
response = openai.chat.completions.create(
model="gpt-4",
messages=[
{"role": "system", "content": "당신은 Python 전문가입니다."},
{"role": "user", "content": """
Python으로 CSV 파일을 읽어서 데이터를 분석하는 코드를 작성해주세요.
요구사항:
1. pandas 라이브러리 사용
2. 결측치 처리
3. 기술 통계 출력
4. 주석 포함
입력: sales.csv (날짜, 상품명, 판매량, 가격 컬럼)
출력: 상품별 총 매출액
"""}
]
)
Few-Shot Learning
messages = [
{"role": "system", "content": "고객 문의를 분류하는 AI입니다."},
{"role": "user", "content": "배송이 언제 되나요?"},
{"role": "assistant", "content": "카테고리: 배송"},
{"role": "user", "content": "환불하고 싶어요"},
{"role": "assistant", "content": "카테고리: 환불"},
{"role": "user", "content": "상품이 불량이에요"},
]
response = openai.chat.completions.create(
model="gpt-4",
messages=messages
)
체인 오브 쏘트 (Chain of Thought)
prompt = """
문제: 사과 3개에 2000원, 바나나 2개에 3000원입니다.
사과 5개와 바나나 3개를 사면 총 얼마인가요?
단계별로 생각해봅시다:
1. 사과 1개 가격 계산
2. 바나나 1개 가격 계산
3. 사과 5개 가격 계산
4. 바나나 3개 가격 계산
5. 합계 계산
"""
response = openai.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}]
)
4. 스트리밍 응답
기본 스트리밍
# Python
response = openai.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "긴 이야기를 들려주세요"}],
stream=True
)
for chunk in response:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")
// Node.js
const stream = await openai.chat.completions.create({
model: 'gpt-4',
messages: [{ role: 'user', content: '긴 이야기를 들려주세요' }],
stream: true,
});
for await (const chunk of stream) {
const content = chunk.choices[0]?.delta?.content || '';
process.stdout.write(content);
}
웹 애플리케이션에서 스트리밍
// Next.js API Route
import OpenAI from 'openai';
import { OpenAIStream, StreamingTextResponse } from 'ai';
export async function POST(req: Request) {
const { messages } = await req.json();
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
const response = await openai.chat.completions.create({
model: 'gpt-4',
messages,
stream: true,
});
const stream = OpenAIStream(response);
return new StreamingTextResponse(stream);
}
// 클라이언트
'use client';
import { useChat } from 'ai/react';
export default function ChatPage() {
const { messages, input, handleInputChange, handleSubmit } = useChat();
return (
<div>
{messages.map(m => (
<div key={m.id}>
<strong>{m.role}:</strong> {m.content}
</div>
))}
<form onSubmit={handleSubmit}>
<input value={input} onChange={handleInputChange} />
<button type="submit">전송</button>
</form>
</div>
);
}
5. 함수 호출 (Function Calling)
기본 사용법
functions = [
{
"name": "get_weather",
"description": "특정 도시의 날씨를 가져옵니다",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "도시 이름 (예: 서울, 부산)"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["city"]
}
}
]
response = openai.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "서울 날씨 알려줘"}],
functions=functions,
function_call="auto"
)
# 함수 호출 확인
if response.choices[0].message.function_call:
function_name = response.choices[0].message.function_call.name
arguments = json.loads(response.choices[0].message.function_call.arguments)
# 실제 함수 실행
if function_name == "get_weather":
weather = get_weather(**arguments)
# 결과를 다시 GPT에 전달
messages = [
{"role": "user", "content": "서울 날씨 알려줘"},
response.choices[0].message,
{"role": "function", "name": function_name, "content": str(weather)}
]
final_response = openai.chat.completions.create(
model="gpt-4",
messages=messages
)
실전 예제: 데이터베이스 쿼리
import sqlite3
def query_database(query: str):
"""SQL 쿼리를 실행합니다"""
conn = sqlite3.connect('sales.db')
cursor = conn.cursor()
cursor.execute(query)
results = cursor.fetchall()
conn.close()
return results
functions = [
{
"name": "query_database",
"description": "판매 데이터베이스에서 정보를 조회합니다",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "실행할 SQL 쿼리"
}
},
"required": ["query"]
}
}
]
messages = [
{"role": "system", "content": "당신은 SQL 전문가입니다. 테이블: sales (date, product, quantity, price)"},
{"role": "user", "content": "지난달 가장 많이 팔린 상품은?"}
]
response = openai.chat.completions.create(
model="gpt-4",
messages=messages,
functions=functions,
function_call="auto"
)
if response.choices[0].message.function_call:
args = json.loads(response.choices[0].message.function_call.arguments)
results = query_database(args["query"])
messages.append(response.choices[0].message)
messages.append({"role": "function", "name": "query_database", "content": str(results)})
final_response = openai.chat.completions.create(
model="gpt-4",
messages=messages
)
print(final_response.choices[0].message.content)
6. 실전 예제: 고객 지원 챗봇
전체 구조
flowchart TB
User[사용자] --> Chat[챗봇 UI]
Chat --> API[ChatGPT API]
API --> Intent[의도 분류]
Intent --> FAQ[FAQ 검색]
Intent --> Ticket[티켓 생성]
Intent --> Human[상담원 연결]
FAQ --> Response[응답 생성]
Ticket --> Response
Response --> User
구현
import openai
from typing import List, Dict
class CustomerSupportBot:
def __init__(self, api_key: str):
openai.api_key = api_key
self.conversation_history: List[Dict] = []
def classify_intent(self, message: str) -> str:
"""사용자 의도 분류"""
response = openai.chat.completions.create(
model="gpt-4",
messages=[
{"role": "system", "content": """
다음 카테고리 중 하나로 분류하세요:
- 배송: 배송 관련 문의
- 환불: 환불/교환 문의
- 상품: 상품 정보 문의
- 기타: 그 외
"""},
{"role": "user", "content": message}
],
temperature=0
)
return response.choices[0].message.content.strip()
def search_faq(self, intent: str, question: str) -> str:
"""FAQ에서 답변 검색"""
faq_data = {
"배송": "일반 배송은 2-3일, 빠른 배송은 1일 소요됩니다.",
"환불": "구매일로부터 7일 이내 환불 가능합니다.",
"상품": "상품 상세 페이지에서 확인하실 수 있습니다."
}
return faq_data.get(intent, "상담원 연결이 필요합니다.")
def generate_response(self, user_message: str) -> str:
"""응답 생성"""
# 의도 분류
intent = self.classify_intent(user_message)
# FAQ 검색
faq_answer = self.search_faq(intent, user_message)
# 대화 히스토리에 추가
self.conversation_history.append(
{"role": "user", "content": user_message}
)
# 최종 응답 생성
messages = [
{"role": "system", "content": f"""
당신은 친절한 고객 지원 AI입니다.
사용자 의도: {intent}
FAQ 답변: {faq_answer}
위 정보를 바탕으로 자연스럽고 친절하게 답변하세요.
"""},
*self.conversation_history
]
response = openai.chat.completions.create(
model="gpt-4",
messages=messages,
temperature=0.7
)
assistant_message = response.choices[0].message.content
self.conversation_history.append(
{"role": "assistant", "content": assistant_message}
)
return assistant_message
# 사용 예시
bot = CustomerSupportBot(api_key="sk-...")
print(bot.generate_response("배송이 언제 되나요?"))
print(bot.generate_response("빠른 배송도 가능한가요?"))
7. 비용 최적화
1. 적절한 모델 선택
def choose_model(task_complexity: str) -> str:
"""작업 복잡도에 따라 모델 선택"""
if task_complexity == "simple":
return "gpt-3.5-turbo" # 분류, 간단한 질문
elif task_complexity == "medium":
return "gpt-4-turbo" # 복잡한 추론
else:
return "gpt-4" # 매우 복잡한 작업
2. 토큰 수 제한
response = openai.chat.completions.create(
model="gpt-4",
messages=messages,
max_tokens=500, # 출력 토큰 제한
temperature=0.7
)
3. 캐싱 활용
from functools import lru_cache
@lru_cache(maxsize=1000)
def get_cached_response(prompt: str) -> str:
"""동일한 프롬프트는 캐싱"""
response = openai.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}]
)
return response.choices[0].message.content
4. 배치 처리
def process_batch(prompts: List[str]) -> List[str]:
"""여러 요청을 한 번에 처리"""
responses = []
for prompt in prompts:
response = openai.chat.completions.create(
model="gpt-3.5-turbo", # 저렴한 모델 사용
messages=[{"role": "user", "content": prompt}],
max_tokens=100
)
responses.append(response.choices[0].message.content)
return responses
8. 에러 처리 및 재시도
기본 에러 처리
import time
from openai import OpenAIError, RateLimitError, APIError
def call_api_with_retry(messages, max_retries=3):
for attempt in range(max_retries):
try:
response = openai.chat.completions.create(
model="gpt-4",
messages=messages
)
return response
except RateLimitError:
if attempt < max_retries - 1:
wait_time = 2 ** attempt # 지수 백오프
print(f"Rate limit 도달. {wait_time}초 대기...")
time.sleep(wait_time)
else:
raise
except APIError as e:
print(f"API 에러: {e}")
if attempt < max_retries - 1:
time.sleep(1)
else:
raise
except Exception as e:
print(f"예상치 못한 에러: {e}")
raise
타임아웃 설정
import openai
openai.timeout = 30 # 30초 타임아웃
try:
response = openai.chat.completions.create(
model="gpt-4",
messages=messages,
request_timeout=30
)
except openai.Timeout:
print("요청 시간 초과")
9. 보안 및 모범 사례
API 키 보호
# ❌ 나쁜 예
openai.api_key = "sk-..." # 코드에 직접 입력
# ✅ 좋은 예
import os
from dotenv import load_dotenv
load_dotenv()
openai.api_key = os.getenv("OPENAI_API_KEY")
입력 검증
def validate_input(user_input: str) -> bool:
"""사용자 입력 검증"""
if len(user_input) > 4000:
return False
if contains_malicious_content(user_input):
return False
return True
def contains_malicious_content(text: str) -> bool:
"""악의적 콘텐츠 확인"""
blocked_patterns = ["system:", "ignore previous", "jailbreak"]
return any(pattern in text.lower() for pattern in blocked_patterns)
출력 필터링
def filter_output(response: str) -> str:
"""민감한 정보 필터링"""
import re
# 이메일 마스킹
response = re.sub(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b',
'***@***.***', response)
# 전화번호 마스킹
response = re.sub(r'\d{3}-\d{4}-\d{4}', '***-****-****', response)
return response
10. 자주 하는 실수와 해결법
문제 1: 토큰 제한 초과
# ❌ 잘못된 코드
long_text = "..." * 10000 # 너무 긴 텍스트
response = openai.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": long_text}]
)
# ✅ 올바른 코드
def truncate_text(text: str, max_tokens: int = 7000) -> str:
encoding = tiktoken.encoding_for_model("gpt-4")
tokens = encoding.encode(text)
if len(tokens) > max_tokens:
tokens = tokens[:max_tokens]
text = encoding.decode(tokens)
return text
truncated = truncate_text(long_text)
response = openai.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": truncated}]
)
문제 2: 비용 폭탄
# ❌ 잘못된 코드
for i in range(1000):
response = openai.chat.completions.create(
model="gpt-4", # 비싼 모델
messages=[{"role": "user", "content": f"항목 {i}"}]
)
# ✅ 올바른 코드
# 1. 배치로 묶기
batch_prompt = "\n".join([f"항목 {i}" for i in range(1000)])
response = openai.chat.completions.create(
model="gpt-3.5-turbo", # 저렴한 모델
messages=[{"role": "user", "content": batch_prompt}]
)
# 2. 비용 모니터링
total_cost = 0
for i in range(1000):
response = openai.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": f"항목 {i}"}]
)
cost = calculate_cost(
response.usage.prompt_tokens,
response.usage.completion_tokens,
"gpt-3.5-turbo"
)
total_cost += cost
if total_cost > 10: # $10 초과 시 중단
print("비용 한도 초과!")
break
문제 3: 일관성 없는 응답
# ❌ 잘못된 코드
response = openai.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "분류해줘"}],
temperature=1.5 # 너무 높음
)
# ✅ 올바른 코드
response = openai.chat.completions.create(
model="gpt-4",
messages=[
{"role": "system", "content": "다음 카테고리 중 하나로만 답하세요: A, B, C"},
{"role": "user", "content": "이 텍스트를 분류해주세요: ..."}
],
temperature=0, # 결정적 출력
max_tokens=10
)
정리 및 체크리스트
핵심 요약
- API 키 발급 후 환경 변수로 안전하게 관리
- 모델 선택: 작업 복잡도에 따라 gpt-3.5-turbo / gpt-4 선택
- 프롬프트 엔지니어링: 명확한 지시, Few-Shot, Chain of Thought
- 스트리밍: 실시간 응답으로 UX 향상
- 함수 호출: 외부 시스템 통합
- 비용 최적화: 토큰 제한, 캐싱, 적절한 모델 선택
실무 체크리스트
- API 키를 환경 변수로 관리
- 입력 검증 및 출력 필터링
- 에러 처리 및 재시도 로직
- 토큰 수 모니터링
- 비용 한도 설정
- 응답 캐싱
- 로깅 및 모니터링
같이 보면 좋은 글
- LangChain 실전 가이드 | 체인·메모리·에이전트·RAG
- RAG 구현 가이드 | 벡터 DB·임베딩·검색 증강 생성
- Next.js 15 완벽 가이드 | App Router·Server Actions
이 글에서 다루는 키워드
ChatGPT, OpenAI, API, GPT-4, 프롬프트 엔지니어링, AI, 자동화, 챗봇, LLM
자주 묻는 질문 (FAQ)
Q. ChatGPT API 비용은 얼마나 드나요?
A. gpt-3.5-turbo는 1M 토큰당 $0.50/$1.50, gpt-4-turbo는 $10/$30입니다. 일반적인 대화 1회는 약 $0.001-0.01 수준입니다.
Q. 무료로 사용할 수 있나요?
A. 신규 가입 시 $5 크레딧이 제공됩니다. 이후에는 사용량에 따라 과금됩니다.
Q. 한국어도 잘 되나요?
A. GPT-4는 한국어를 매우 잘 이해하고 생성합니다. gpt-3.5-turbo도 대부분의 경우 충분합니다.
Q. 개인정보를 API로 보내도 되나요?
A. OpenAI는 API 데이터를 모델 학습에 사용하지 않습니다. 하지만 민감한 정보는 마스킹 후 전송하는 것을 권장합니다.