2장. 개발 환경 준비
OpenAI 라이브러리로 첫 호출
거래처 창구에 주문할 때는 정해진 주문서를 씁니다. 가게 이름(출입증)을 대고, 주문서에 무엇을 원하는지 적어 내면, 창구가 쟁반에 물건과 영수증을 담아 돌려줍니다. 쟁반에서 물건을 꺼내고, 영수증으로 얼마를 썼는지 봅니다. OpenAI 의 파이썬 SDK(openai 패키지)로 모델을 부르는 순서도 이와 같습니다.
첫 상자에서 OpenAI() 가 환경 변수의 키를 읽어 클라이언트를 만들고, 둘째 상자에서 1장에서 본 역할(role)과 내용(content)의 사전 목록을 쓰고, 셋째 상자에서 create() 로 모델 이름과 함께 보냅니다. 넷째 상자에서 돌아온 응답의 choices[0].message.content 가 답의 글입니다. 여기서 창구가 클라이언트, 주문서가 메시지 목록, 쟁반이 응답 객체, 영수증이 usage 입니다. 비유와 다른 점은, 창구는 주문을 받아 두지만 API 는 1장에서 본 것처럼 앞의 주문을 기억하지 않는다는 것입니다.
부르는 코드의 생김새
아래는 실습 3에서 실제로 쓰는 코드의 핵심만 옮긴 것입니다. 키가 있어야 돌아가므로 여기서는 실행하지 않고 꼴만 봅니다.
client = OpenAI()
response = client.chat.completions.create(
model=MODEL,
messages=[{"role": "user", "content": "제주도를 한 문장으로 소개해 줘."}],
)
print(response.choices[0].message.content)| 코드 | 원래 말 | 뜻 |
|---|---|---|
OpenAI() | client | 키를 환경 변수 OPENAI_API_KEY 에서 스스로 찾아 읽는 클라이언트 |
chat.completions.create | chat(대화), completion(마저 채운 것), create(만들다) | 대화를 이어 쓴 답을 만들어 달라는 요청 |
model= | model | 쓸 모델 이름. 이 교안은 MODEL 변수로 넘긴다 |
messages= | messages | 역할과 내용을 담은 사전의 목록 |
response.choices[0] | choices(고를 거리) | 답 후보 목록의 첫째. 보통 하나만 온다 |
.message.content | message, content | 모델이 쓴 답의 글 |
response.usage | usage(사용량) | 보낸 토큰(prompt_tokens), 받은 토큰(completion_tokens), 합(total_tokens) |
짧은 예시
키 없이도 응답 객체를 읽는 연습은 할 수 있습니다. 응답과 같은 꼴의 사전을 직접 만들어 ChatCompletion 객체로 바꾼 뒤, 실제 응답을 읽을 때와 같은 코드로 꺼냅니다. 답의 글과 토큰 수는 연습용으로 지어낸 것입니다.
from openai import OpenAI
from openai.types.chat import ChatCompletion
# 클라이언트는 만들기만 하고 부르지 않는다. 만드는 것만으로는 서버에 아무것도 보내지 않는다
client = OpenAI(api_key="발급받은_인증키")
print("보낼 곳:", client.base_url)
# model_validate: 사전의 꼴을 검사해 응답 객체로 만든다. 답과 숫자는 지어낸 연습용이다
response = ChatCompletion.model_validate({
"id": "chatcmpl-연습", "object": "chat.completion", "created": 0, "model": "gpt-4.1-mini",
"choices": [{"index": 0, "finish_reason": "stop",
"message": {"role": "assistant", "content": "제주도는 바다와 오름이 어우러진 섬입니다."}}],
"usage": {"prompt_tokens": 20, "completion_tokens": 20, "total_tokens": 40},
})
print(response.choices[0].message.content)
print("보낸 토큰:", response.usage.prompt_tokens, "/ 받은 토큰:", response.usage.completion_tokens)보낼 곳: https://api.openai.com/v1/
제주도는 바다와 오름이 어우러진 섬입니다.
보낸 토큰: 20 / 받은 토큰: 20client.base_url 은 요청을 보낼 서버의 주소입니다. 클라이언트를 만드는 것만으로는 이 주소에 아무것도 보내지 않으므로, 자리표시 키로도 오류가 나지 않습니다. 키가 맞는지는 create() 로 실제로 보낼 때 알 수 있습니다.
코드가 의미하는 것
이 코드는 창구에 주문서를 내지 않고, 돌려받을 쟁반과 같은 모양의 견본 쟁반을 만들어 물건과 영수증을 꺼내 보는 연습입니다. 클라이언트 만들기, 응답 꼴 만들기, 답과 토큰 꺼내기의 세 동작입니다.
| 코드 | 하는 일 | 챗봇에서 뜻하는 것 |
|---|---|---|
OpenAI(api_key="발급받은_인증키") | 클라이언트를 만든다 | 창구 앞에 서기만 한 것입니다. 만드는 것만으로는 서버에 아무것도 보내지 않아 자리표시 키로도 오류가 나지 않습니다 |
client.base_url | 요청을 보낼 주소를 알려 준다 | 챗봇의 질문이 가는 곳입니다. 출력의 https://api.openai.com/v1/ 이 그 주소입니다 |
ChatCompletion.model_validate({...}) | 사전의 꼴을 검사해 응답 객체로 만든다 | 실제 create() 가 돌려주는 것과 같은 종류의 객체입니다. 키 없이 응답을 읽는 코드를 미리 써 볼 수 있습니다 |
response.choices[0].message.content | 답의 글을 꺼낸다 | 챗봇 화면에 보여 줄 글입니다 |
response.usage.prompt_tokens | 보낸 토큰 수를 꺼낸다 | 요금과 길이 제한을 따질 때 보는 숫자입니다 |
결과에서 읽을 것은 두 가지입니다.
- 보낼 곳은 정해졌지만 보내지는 않았습니다. 주소가 찍혔어도 요청은 나가지 않았습니다. 키가 맞는지는 실습 3에서
create()로 보낼 때 알게 됩니다. - 꺼내는 코드는 진짜 응답에도 그대로 씁니다. 답의 글과 토큰 20 / 20 은 지어낸 값이지만,
choices[0].message.content와usage를 읽는 줄은 실습 3과 같습니다.
주의할 점
OpenAI()를 키 없이 만들면 그 자리에서OpenAIError("Missing credentials", 자격 정보가 없다)가 납니다. 이때는load_dotenv()를 먼저 불렀는지,.env가 제자리에 있는지 봅니다.- 인터넷의 옛 예제에 나오는
openai.ChatCompletion.create(...)는 옛 판의 꼴이라 지금 판에서는 돌지 않습니다. 이 교안은 openai 3.42.1 에서client.chat.completions.create(...)꼴로 확인했습니다.