Application/Python

[Python] 21. 파이썬으로 ChatGPT API 호출하기 - AI에게 텍스트 처리 자동으로 시키기

devsalix 2026. 8. 4. 11:22
728x90

파이썬으로 ChatGPT API 호출하기 - AI에게 텍스트 처리 자동으로 시키기

지난 편에서 뉴스 봇을 만들었잖아요. 검색어를 넣으면 관련 기사를 쫙 긁어와서 카드로 정리해주는 거요.

그때 제가 살짝 아쉬운 얘기를 하나 남겼어요. "지금은 네이버가 준 설명을 그대로 붙여넣는 거지, 진짜 요약은 아니다"라고요. 기사 원문이 다섯 줄이면 그 다섯 줄이 그대로 카드에 들어가는 거였거든요. 정리는 됐는데, 요약은 아니었어요.

그럼 진짜 요약은 누가 하죠? 사람이 하나하나 읽고 세 줄로 줄이면 되긴 해요. 근데 기사가 100개면요? 그건 못 하잖아요.

그래서 오늘부터 무대가 살짝 바뀝니다. 지금까지는 "코드로 데이터를 다루는" 법을 배웠다면, 이제부터는 "코드로 AI한테 일을 시키는" 법을 배워요. 긴 글 요약하기, 말투 바꾸기, 문의 분류하기 같은, 원래는 사람이 눈으로 읽고 손으로 하던 일을요.


ChatGPT 웹 vs API, 뭐가 다를까

혹시 챗지피티 써보셨어요? 브라우저 열고, 질문 타이핑하고, 답 나오면 읽고. 대부분 이렇게 쓰시죠.

그게 바로 이에요. 사람이 직접 앉아서 하나씩 물어보는 방식.

API는 그 자리에 파이썬 코드가 앉는 거예요. 내가 타이핑하는 대신 코드가 질문을 보내고, 화면으로 답을 읽는 대신 코드가 답을 받아서 변수에 담아요.

여기서 뭐가 달라지냐면요.

웹은 한 번에 하나예요. 질문 하나 던지고, 답 하나 읽고, 또 다음 거 복붙하고. 기사 100개를 요약하려면 100번을 반복해야 해요. 사람이.

API는 반복문 한 번이면 끝이에요. 기사가 100개든 1000개든, for 문으로 쫙 돌리면 코드가 알아서 100번 물어보고 100개 답을 받아와요. 밤새 자는 동안에도요.

따지고 보면 8에서 requests로 네이버 서버에 물어봤고, 18에서도 API를 호출해봤잖아요. 이번엔 그 대화 상대가 AI라는 것만 달라요. 원리는 똑같아요. 코드가 어딘가에 요청을 보내고, 답을 받아오는 거요.


OpenAI API 키 발급하고 안전하게 보관하기

코드가 AI한테 말을 걸려면, 먼저 신분증 같은 게 하나 필요해요. 그걸 API 키라고 불러요.

발급은 platform.openai.com 에서 해요. 대략 이런 순서예요.

  1. 가입하고 로그인
  2. 결제수단(카드) 등록
  3. 사용량 한도를 낮게 걸어두기 (이건 아래에서 다시 설명할게요)
  4. API keys 메뉴에서 새 키 만들기
  5. 만들어진 키를 바로 복사해서 안전한 곳에 저장

화면은 자주 바뀌어서 여러분이 보는 것과 조금 다를 수 있어요. 그래도 "결제수단 등록 → 키 생성 → 복사" 이 흐름은 비슷해요.

여기서 진짜 중요한 거 하나. 키는 생성 직후에 딱 한 번만 전체가 보여요. 그 창을 닫으면 다시는 전체를 볼 수 없어요. 그러니까 만들자마자 바로 복사해서 메모장이든 어디든 안전하게 옮겨두세요. 저는 처음에 이걸 모르고 창을 닫아버려서, 결국 키를 다시 만든 적 있어요.


API 키는 여러분 이름이 박힌 신용카드예요

이 부분은 꼭 짚고 갈게요.

API 키는 그냥 비밀번호가 아니라, 여러분 카드가 연결된 지갑이나 마찬가지예요. 이 키만 있으면 누구든 여러분 카드로 AI를 마음껏 쓸 수 있거든요.

그래서 세 가지만 지켜주세요.

  • 코드에 키를 직접 써넣지 말고 .env 파일로 분리하기 (13, 18에서 배운 그 습관이에요)
  • 깃허브, 블로그, 단톡방에 절대 붙여넣지 않기
  • 혹시 어디 노출됐다 싶으면, 대시보드에서 그 키를 즉시 폐기(revoke)하고 새로 발급받기

신용카드를 길에 흘리면 바로 정지시키잖아요. 딱 그 마음으로 대하시면 돼요.


비용은 얼마나 나올까 (토큰과 사용량 한도)

"유료"라는 말에 벌써 긴장하신 분 계시죠. 잠깐, 여기서 진짜로 안심하고 가셔도 돼요.

먼저 요금이 어떻게 매겨지는지부터요. 요금의 단위는 토큰이에요. 토큰은 글자를 잘게 쪼갠 조각이라고 생각하시면 돼요. 대략 영어 단어 하나가 1~2토큰, 한글은 한 글자에 여러 토큰 정도예요.

요금은 이 토큰 양에 비례해요. 내가 보낸 글자 + AI가 답한 글자, 이 둘을 합친 만큼요.

토큰은 택시 미터기랑 똑같아요. 탄 거리(주고받은 글자량)만큼 요금이 올라가요. 짧게 묻고 짧게 답 받으면 얼마 안 나오고, 장문을 통째로 넣고 장문으로 답받으면 미터기가 좀 더 돌아요.

근데 이게 얼마냐면요. 저렴한 모델로 A4 몇 장짜리 글을 요약해도 커피값은커녕 몇 원 수준이에요. 정말이에요. 겁먹을 금액이 전혀 아니에요.

게다가 안심 장치가 세 개나 있어요.

  • 처음 가입하면 보통 무료 크레딧을 조금 줘요
  • 대시보드에서 사용량 한도를 낮게(예: 5달러) 걸어두면, 코드가 실수로 무한 반복을 돌아도 그 이상은 청구가 안 돼요
  • 저렴한 모델을 고르면 애초에 요금 자체가 아주 낮아요

그러니까 시작하기 전에 사용량 한도부터 낮게 걸어두세요. 안전벨트 먼저 매고 출발하는 거예요.

참, 자주 헷갈리는 게 하나 있어요. 월정액 챗지피티 플러스를 결제하고 계셔도, API는 그거랑 완전히 별개예요. 플러스는 웹에서 쓰는 상품이고, API는 코드로 쓰는 상품이라 요금이 따로 나가요. "나 플러스 쓰는데 왜 또 돈 내지?" 하실 수 있는데, 둘은 다른 물건이에요.


OpenAI API 파이썬으로 첫 호출 해보기

키를 준비했으면 이제 코드를 짜볼 차례예요.

requests로 직접 호출해도 되긴 하는데, OpenAI가 만든 전용 도구(SDK)가 훨씬 편해요. 그걸 먼저 깔게요.

# 터미널에서 먼저 실행: pip install openai python-dotenv

import os                          # 환경변수를 읽기 위한 도구
from openai import OpenAI          # OpenAI 공식 SDK
from dotenv import load_dotenv     # .env 파일을 불러오는 도구

load_dotenv()                      # .env 안에 저장해둔 값들을 읽어옴
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))  # 키는 코드에 직접 안 쓰고 .env에서 가져옴

 

client는 앞으로 AI한테 말을 거는 창구라고 보시면 돼요. 이제부터 뭔가 물어볼 땐 이 client를 통해서 해요.

그럼 진짜로 한번 물어볼게요.

long_text = "여기에 요약하고 싶은 긴 글을 넣습니다."  # 요약할 원문

response = client.chat.completions.create(   # AI에게 질문을 보내는 핵심 한 줄
    model="gpt-4o-mini",                     # 어떤 두뇌를 쓸지 (저렴하고 빠른 모델)
    messages=[                                # AI에게 건넬 대화 내용
        {"role": "user", "content": "다음 글을 3줄로 요약해줘.\n\n" + long_text}
    ]
)

print(response.choices[0].message.content)   # AI가 준 답에서 실제 글만 꺼내 출력

 

# 실행 결과 (예시)
# 1. 파이썬 API로 AI에게 요약을 시킬 수 있습니다.
# 2. 웹과 달리 대량 자동 처리가 가능합니다.
# 3. 비용은 매우 저렴한 편입니다.

 

model에 넣은 gpt-4o-mini는 예시예요. 이 이름은 몇 달 뒤엔 바뀔 수도 있어요. 그럴 땐 당황하지 마시고, 가입 화면에서 "가장 저렴한" 또는 이름에 "mini"가 붙은 모델을 고르시면 돼요.


system 프롬프트로 요약가·번역가·분류기 만들기

방금 코드 잘 돌아갔죠? 근데 매번 "다음 글을 3줄로 요약해줘"를 붙이는 게 좀 번거롭잖아요.

그럴 때 쓰는 게 system 프롬프트예요. 이게 오늘 글에서 제일 실용적인 부분이에요. 집중해서 봐주세요.

messages 안을 보면 role이라는 게 있어요. 아까는 user 하나만 썼는데, 사실 종류가 몇 개 더 있어요.

  • system: AI한테 미리 역할과 규칙을 정해주는 자리
  • user: 내가 그때그때 하는 실제 요청
  • (assistant도 있는데, 대화를 이어갈 때 쓰는 거라 지금은 몰라도 돼요)

system은 알바생 첫날에 업무를 정해주는 거랑 똑같아요. "너 오늘부터 요약 담당이야. 손님이 뭘 가져오든 무조건 3줄로 줄여서 존댓말로 돌려줘." 이렇게 한 번 정해두면, 이후에 어떤 주문(user)이 들어와도 알바생이 알아서 같은 방식으로 처리해요.

response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[
        {"role": "system", "content": "너는 긴 글을 핵심만 3줄로 줄이는 요약 비서야. 존댓말로 답해."},
        {"role": "user", "content": long_text}   # 이제 사용자는 글만 넣으면 됨
    ],
    temperature=0.2                               # 요약은 낮게 (답이 일관됨)
)
print(response.choices[0].message.content)

 

temperature는 답의 자유도예요. 0에 가까우면 딱딱하고 일관되게, 높으면 창의적이고 들쭉날쭉하게 답해요. 요약이나 번역, 분류처럼 정확해야 하는 일은 낮게(0~0.3), 아이디어 짜는 창작은 높게. 안 넣으면 기본값으로 돌아가니까 필수는 아니에요.

여기서 진짜 재밌는 건요. system만 바꾸면 같은 코드가 완전히 다른 도구가 돼요.

system을 "딱딱한 문장을 부드럽고 정중한 존댓말로 다듬는 편집자"로 바꾸면 말투 교정기가 되고요. "고객 문의를 읽고 긍정·부정·중립 중 하나로만 답하는 분류기"로 바꾸면 감정 분류기가 돼요. 알바생 한 명한테 역할만 바꿔 맡기는 거죠.

분류기가 특히 실용적이에요. 답이 항상 한 단어로만 나오니까, 자동 처리에 딱이거든요.

def classify(text):                       # 문의 하나를 분류하는 함수
    r = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "system", "content": "고객 문의를 읽고 '긍정','부정','중립' 중 한 단어로만 답해."},
            {"role": "user", "content": text}
        ],
        temperature=0                     # 분류는 흔들리면 안 되니 0
    )
    return r.choices[0].message.content.strip()  # 앞뒤 공백 제거하고 답만 반환

문의목록 = ["배송이 너무 빨라서 감동이에요", "포장이 다 찢어져서 왔어요", "그냥 평범해요"]

for 문의 in 문의목록:                      # 여러 건을 한 번에 자동으로
    print(문의, "→", classify(문의))

 

# 실행 결과 (예시)
# 배송이 너무 빨라서 감동이에요 → 긍정
# 포장이 다 찢어져서 왔어요 → 부정
# 그냥 평범해요 → 중립

 

문의가 3개든 300개든, 리스트에 넣고 for 문만 돌리면 돼요. 이게 바로 API의 힘이에요.


응답을 왜 이렇게 깊이 파고드나요

response.choices[0].message.content. 이거 처음 보면 좀 당황스러우시죠. 왜 이렇게 길게 파고들어야 하나 싶고요.

이유가 있어요. AI가 답을 여러 개 줄 수도 있거든요. 그래서 답들이 choices라는 목록에 담겨서 와요. 우리는 보통 첫 번째 답만 쓰니까 choices[0]으로 첫 번째를 꺼내고, 그 안의 실제 글자인 .message.content를 가져오는 거예요.

"목록의 첫 번째 답, 그 안의 실제 내용" 이렇게 외우시면 편해요.


지난 편 뉴스 봇, 이제 진짜로 요약해볼까요

자, 여기서 지난 편 떡밥을 회수할게요.

지난 편 뉴스 봇은 네이버가 준 긴 설명을 그대로 카드에 붙였잖아요. 이제 그 설명을 요약 함수에 한 번 통과시키면, 그게 진짜 3줄 요약이 돼요.

def summarize(text):                      # 어디서든 재사용할 수 있는 요약 함수
    r = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "system", "content": "핵심만 2~3문장으로 요약해줘. 존댓말."},
            {"role": "user", "content": text}
        ],
        temperature=0.2
    )
    return r.choices[0].message.content

# 지난 편에서 뉴스 카드 만들 때 n["desc"] 를 그대로 넣었다면,
# 이제 summarize(n["desc"]) 로 바꾸기만 하면 됩니다.
# '정리 봇'이 '진짜 요약 봇'으로 진화하는 순간이에요.

 

딱 한 군데만 바꿨는데 봇의 급이 달라지죠.

다만 주의할 게 하나 있어요. 기사가 많으면 그만큼 호출도 많아져서 요금이랑 시간이 늘어나요. 그러니까 처음엔 전부에 붙이지 말고, 관심 기사 몇 개만 요약해보세요. 긴 문서를 통째로 다루는 건 다음 편에서 제대로 할 거예요.


자주 만나는 에러들

처음 API를 쓰면 이런 에러들을 만나실 거예요. 미리 알아두면 당황 안 하세요.

AuthenticationError / "Incorrect API key"
키가 잘못됐다는 뜻이에요. 키에 오타가 났거나, 앞뒤에 공백이나 따옴표가 딸려 들어갔거나, 이미 폐기한 옛날 키를 쓰고 있거나, .env를 안 불러온(load_dotenv() 빠뜨림) 경우예요. 키를 새로 복사해서 넣고, .env가 제대로 로딩됐는지 확인해보세요.

RateLimitError / "insufficient_quota"
크레딧이 다 떨어졌거나 결제수단이 등록 안 된 경우예요. 무료 크레딧만 있고 카드를 안 넣었으면 유료 호출이 막힐 수 있어요. 대시보드에서 잔여 크레딧이랑 결제수단을 확인해보세요.

ModuleNotFoundError: No module named 'openai'
pip install openai를 안 했거나, 가상환경이 안 맞는 경우예요. 설치부터 다시 확인해보세요.

그리고 이건 에러라기보단 사고인데요. 실습 코드에 키를 직접 써넣고 그대로 깃허브에 올리는 분들이 정말 많아요. 저도 이거 실수하는 분 많이 봤어요. OpenAI가 노출된 키를 자동으로 감지해서 막아버리기도 하거든요. 그러니까 처음부터 .env + .gitignore 습관을 들이시고, 혹시 올렸다 싶으면 즉시 그 키를 폐기하고 새로 만드세요.


직접 해보세요

머리로만 읽으면 안 남아요. 세 개만 직접 돌려보세요.

  1. 본인 메일이나 회의록 하나를 복사해서 summarize()로 3줄 요약해보기
  2. system 프롬프트를 "무조건 초등학생도 알아듣게 쉽게 설명해"로 바꿔서, 결과가 어떻게 달라지는지 느껴보기
  3. 문의나 후기 문장 5개를 리스트로 만들어서, 감정 분류를 한 번에 돌려보기

힌트를 드리면, 위에 나온 classify 함수랑 문의목록 예제를 그대로 가져다가 문장만 여러분 걸로 바꾸시면 3번은 바로 돼요.

그리고 시작 전에 대시보드에서 사용량 한도를 5달러 정도로 낮게 걸어두는 것, 잊지 마세요. 안전벨트요.

오늘은 짧은 글 하나를 요약해봤죠. 근데 실제 업무에선 몇십 장짜리 PDF나 워드 문서를 통째로 요약하거나 번역하고 싶잖아요. 그렇게 긴 글은 한 번에 통째로 넣으면 안 되거든요. 그걸 어떻게 잘라서 AI한테 나눠 먹이는지, 다음 편에서 문서 요약 봇이랑 번역 봇을 제대로 만들어볼 거예요.


 


제 글이 도움이 되셨다면 댓글 & 공감 부탁드려요 😀

 

 
728x90