ChatGPT API 완벽 가이드 | 사용법·요금·프롬프트 엔지니어링·실전 예제

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 키 발급

  1. OpenAI 계정 생성: https://platform.openai.com/signup
  2. API 키 발급: https://platform.openai.com/api-keys
  3. 결제 수단 등록: 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 데이터를 모델 학습에 사용하지 않습니다. 하지만 민감한 정보는 마스킹 후 전송하는 것을 권장합니다.

... 996 lines not shown ... Token usage: 63706/1000000; 936294 remaining Start-Sleep -Seconds 3