머신러닝&딥러닝

OpenAI API 사용법 정리 (Responses API, Chat Completions 차이, 요청 구조)

SecLogs YJ 2026. 3. 23. 21:46

1. OpenAI API란

OpenAI API는 자연어 처리, 코드 생성, 이미지 생성 등 다양한 인공지능 기능을 HTTP 기반으로 호출할 수 있도록 제공하는 인터페이스이다.
개발자는 별도의 모델 학습 없이도 API 호출만으로 GPT 계열 모델을 활용할 수 있다.

 

주요 특징은 다음과 같다.

  • 텍스트 생성: 질문 응답, 요약, 번역
  • 코드 생성 및 분석
  • 멀티턴 대화 처리
  • 함수 호출(Function Calling / Tool Calling)
  • 다양한 모델 선택 가능

즉, OpenAI API는 “AI 모델을 서비스 형태로 사용하는 방식”이다.

 

2. OpenAI 모듈 vs HTTP 직접 호출

OpenAI API는 두 가지 방식으로 사용할 수 있다.

2-1 OpenAI Python/JS SDK 사용

from openai import OpenAI
client = OpenAI()

response = client.responses.create(
model="gpt-5.4",
input="Hello"
)

print(response.output_text)

 

특징

  • 코드가 매우 간단함
  • 내부 JSON 구조 자동 처리
  • 빠른 개발에 유리
 

 

2-2 HTTP 직접 호출 (REST API)

curl https://api.openai.com/v1/responses \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-type: application/json" \
-d '{
"model": "gpt-5.4",
"input": "Hello"
}'
 
 
상황 추천 방식
빠르게 개발 SDK
서버/백엔드 개발 HTTP
구조 이해 HTTP

 

 

3. 로컬 개발 환경 설정

1) 라이브러리 설치

pip install openai python-dotenv
 
 

 

2) API Key 설정

환경 변수로 설정하는 것이 가장 안전하다.

설정 방법은 크게 두 가지가 있다.

 

방법 1. OS 환경 변수 설정

 

Mac / Linux

export OPENAI_API_KEY="your_api_key"
export 환경 변수를 설정하는 명령어 (현재 셸/세션에 적용됨)
OPENAI_API_KEY 환경 변수 이름 (OpenAI API 인증에 사용되는 표준 변수명)
= 변수에 값을 할당하는 연산자
"your_api_key" 실제 OpenAI에서 발급받은 API Key 값

 

Windows

setx OPENAI_API_KEY "your_api_key"
setx Windows에서 환경 변수를 영구적으로 설정하는 명령어
OPENAI_API_KEY 환경 변수 이름 (API 인증에 사용됨)
"your_api_key" 설정할 API Key 값
(공백 구분 방식) Windows에서는 = 없이 공백으로 변수와 값을 구분

 

 

방법 2. .env 파일 사용(추천)

프로젝트 내부에서 API Key를 관리하는 방법이다.

 

왜 .env를 쓰는가?

  • 코드에 API Key 노출 방지
  • GitHub 업로드 시 보안 유지
  • 프로젝트별 관리 가능

 

① env 파일 생성 : 프로젝트 루트에 .env 파일 생성

OPENAI_API_KEY=your_api_key
 

 

② 코드에서 불러오기

from dotenv import load_dotenv
import os

load_dotenv()

OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
 
load_dotenv() .env 파일을 읽어서 환경 변수로 등록
os.getenv() 환경 변수 값을 가져오는 함수
OPENAI_API_KEY 저장된 API Key 변수
 

 

3) 클라이언트 생성

from openai import OpenAI
client = OpenAI()

 

from openai import OpenAI OpenAI Python SDK에서 OpenAI 클래스를 가져오는 import 문
openai 설치된 Python 패키지 이름 (pip install openai)
OpenAI API 요청을 처리하는 클라이언트 클래스
client 생성된 클라이언트 객체를 담는 변수
OpenAI() 클라이언트 인스턴스를 생성 (환경 변수의 API Key 자동 사용)

 

 

4. Responses API 핵심 이해

OpenAI API를 제대로 사용하려면, 가장 먼저 Responses API 구조를 이해하는 것이 중요하다.

현재 OpenAI API에서는 기존의 Chat Completions 방식보다 Responses API를 중심으로 사용하는 것을 권장하고 있다.

 

그 이유는 Responses API가 단순히 텍스트만 처리하는 것이 아니라, 다음과 같은 다양한 입력과 기능을 하나의 통합된 구조에서 처리할 수 있기 때문이다.

  • 대화형 메시지 구조
  • 함수 호출(Function Calling)
  • 멀티모달(Multimodal) 입력(이미지, 음성 등 다양한 형태의 데이터)
  • 프롬프트 재사용

 

4-1. 가장 기본 요청

가장 단순한 방식은 문자열 하나를 바로 input에 넣는 것이다.

 

질문이 짧고 별도의 대화 맥락이나 규칙이 필요 없을 때 적합하다.

즉, “질문 → 답변”만 필요한 가장 기본적인 형태의 요청이다.

response = client.responses.create(
    model="gpt-5.4",
    input="파이썬 리스트 정렬 방법 알려줘"
)

print(response.output_text)
client.responses.create() OpenAI Responses API 호출 메서드
model 사용할 AI 모델 지정
input 모델에게 전달할 입력 텍스트
response API 응답 객체
response.output_text 모델이 생성한 텍스트 결과

 

코드는 그대로 질문 하나를 바로 보내는 가장 기본형이다.

아직 역할 구분도 없고, 시스템 규칙도 없고, 프롬프트 템플릿도 없다.
즉, 모델에게 전달되는 정보가 “질문 하나”뿐인 상태이다.

그래서 입문 예제로는 좋지만, 실제 서비스에서는 다음과 같은 요소가 추가된다.

- 응답 스타일을 제어하기 위한 메시지 구조
- 외부 기능을 연결하기 위한 도구(tools) 정의
- 대화 흐름을 유지하기 위한 이전 메시지 정보

 

 

2) 메시지 기반 입력 구조

Responses API의 input은 문자열만 받을 있는 것이 아니라, 메시지 배열도 받을 있다.
방식은 단순히 질문만 전달하는 것이 아니라, “누가 어떤 역할로 어떤 말을 했는지”를 구조적으로 표현 있다.

그래서 대화 흐름을 유지하거나, 응답 스타일을 제어해야 하는 대화형 애플리케이션에서 필수적으로 사용된다.

OpenAI 문서상 입력 메시지의 역할로 user, assistant, system, developer를 사용할 있다.

 
response = client.responses.create(
    model="gpt-5.4",
    input=[
        {"role": "developer", "content": "친절한 튜터처럼 설명해"},
        {"role": "user", "content": "리스트 정렬 방법 알려줘"}
    ]
)

print(response.output_text)
input 리스트 형태의 메시지 배열
role 메시지의 주체 (developer / user / assistant)
user 실제 사용자 질문

 

 

role 각 주체 설명

developer 모델의 동작 원칙, 말투, 정책, 비즈니스 규칙 등을 지정하는 역할
user 실제 질문이나 명령을 전달하는 역할
assistant 모델에 의해 생성된 메시지로, 이전 응답을 대화 문맥에 포함할 사용
system 일부 문맥이나 기존 방식에서 사용되며, Chat Completions에서 특히 익숙한 상위 지시 역할

 

여기서 중요한 포인트는 다음과 같다.

- developer는 “모델이 어떻게 답해야 하는지”를 정의한다.
- user는 “무엇을 물어보는지”를 전달한다.
- assistant는 “모델이 이전에 생성한 응답”을 대화에 포함하여 흐름을 유지할 때 사용된다.

즉, 메시지 구조를 사용하면 단순한 질문이 아니라 “규칙 + 질문 + 이전 응답(대화 흐름)”을 함께 전달할 수 있다.


 

3) Prompt 기반 요청

기본 요청과 메시지 기반 요청은 코드 안에 직접 프롬프트를 작성한다.

방식은 다음과 같은 문제가 있다.

- 프롬프트 수정 시 코드 수정 필요
- 버전 관리 어려움
- 여러 곳에서 재사용하기 불편함

이 문제를 해결하기 위해 사용하는 방식이 Prompt 기반 요청이다.

이 방식은 프롬프트를 코드가 아니라, OpenAI 대시보드(Playground/Prompt 관리 기능)에 미리 저장해두고 코드에서는 해당 프롬프트의 ID를 불러와 사용하는 구조이다.

, "pmpt_abc123"은 코드에서 생성하는 값이 아니라 대시보드에 저장된 프롬프트의 고유 ID이다.

response = client.responses.create(
    model="gpt-4.1",
    prompt={
        "id": "pmpt_abc123",
        "version": "2",
        "variables": {
            "customer_name": "Jane Doe"
        }
    }
)

print(response.output_text)

 

prompt 사전에 저장된 프롬프트를 불러오는 옵션
id 프롬프트 고유 식별자
version 프롬프트 버전
variables 프롬프트 내부 변수에 들어갈 값
customer_name 프롬프트에서 사용하는 변수

 

 

4) Chat Completions (기존 방식)

Chat Completions API는 대화를 구성하는 messages 목록을 기반으로 응답을 생성하는 기존 방식이다.

방식은 system, user, assistant와 같은 역할 구조를 사용하여 “대화 형태”를 그대로 모델링하는 초점이 맞춰져 있다.

과거에는 방식이 표준이었지만, 현재는 확장된 기능을 제공하는 Responses API가 권장된다.

다만 구조가 단순하고 직관적이기 때문에 여전히 많은 예제에서 사용되고 있다.

response = client.chat.completions.create(
    model="gpt-5.4",
    messages=[
        {"role": "system", "content": "친절한 튜터처럼 설명해"},
        {"role": "user", "content": "리스트 정렬 방법 알려줘"}
    ]
)

print(response.choices[0].message.content)

 

client.chat.completions.create() Chat Completions API 호출
messages 대화 메시지 배열
system 시스템 역할 (전체 동작 규칙 설정)
user 사용자 입력
response.choices 모델이 생성한 응답 리스트
choices[0].message.content 실제 텍스트 결과

 


여기서 중요한 점은 출력 구조이다.

Chat Completions API는 하나의 응답이 아니라 여러 개의 후보 응답(choices) 리스트 형태로 반환한다.
그래서 번째 결과를 사용하기 위해 choices[0].message.content 형태로 접근해야 한다.

또한 system 역할은 Responses API의 developer 역할과 유사하다.

즉, 다음과 같이 이해할 수 있다.
- Chat Completions → system 사용
- Responses API → developer 사용

 

 

5) Responses API와 Chat Completions의 차이

 

공통점

둘 다 “사용자 입력을 받아 모델 응답을 생성한다”는 점은 같다

 

차이점

구분 Responses API Chat Completions
중심 개념 통합 입력/출력 구조 대화 메시지 중심
입력 필드 input messages
출력 접근 response.output_text response.choices[0].message.content
확장성 도구 호출, 다양한 입력 구조, 재사용 구조와 잘 연결됨 전통적인 대화 처리에 익숙함
느낌 최신 통합형 기존 대화형

 

이 표에서 가장 중요한 차이는 “확장성”이다.

Chat Completions는 대화 메시지를 주고받는 구조에 최적화되어 있지만, 기능 확장(도구 호출, 프롬프트 재사용 등)을 고려하면 구조적으로 한계가 있다.

반면 Responses API는 단순한 대화를 넘어서
- 도구 호출 (Function Calling)
- 다양한 입력 형태 (텍스트, 이미지 등)
- 프롬프트 템플릿 재사용
까지 하나의 요청 구조 안에서 처리할 수 있도록 설계되어 있다.

즉, Chat Completions는 “채팅 기능”에 초점이 맞춰져 있고, Responses API는 “AI 기능 전체를 통합한 인터페이스”에 가깝다.

 

 

6) 총 정리

지금까지 나온 네 가지를 한 줄씩만 다시 구분하면 다음과 같다

항목 핵심 의미
기본 요청 형태 질문 하나를 바로 보냄
메시지 기반 입력 구조 역할과 대화 문맥까지 구조적으로 보냄
Prompt 기반 요청 저장된 프롬프트 템플릿을 재사용함
Chat Completions 기존의 대화 전용 방식

 

5. API 요청 구조 전체 이해

OpenAI API는 단순히 input만 전달하는 구조가 아니라, 입력 방식, 모델 동작 방식, 출력 길이, 외부 기능 연결 등 여러 요소를 조합하여 동작한다.

즉, 하나의 요청은 단순한 질문이 아니라

- 무엇을 물어볼지
- 어떤 방식으로 답하게 할지
- 얼마나 길게 답하게 할지
- 외부 기능을 사용할 수 있게 할지

를 함께 정의하는 과정이라고 볼 수 있다.

쉽게 말해, OpenAI API 요청은 “질문 + 규칙 + 생성 방식 + 기능 확장”을 하나로 묶은 구조이다.

 

 

예시

response = client.responses.create(
    model="gpt-5.4",
    input=[...],
    temperature=0.3,
    max_output_tokens=200
)

 

1) 입력 제어 영역

input / role / content

 

이 영역은 모델에게 전달되는 실제 데이터와 대화 구조를 정의한다.

  • input : 모델에 전달하는 입력값
  • role : 메시지의 주체나 성격
  • content : 각 메시지의 실제 내용

예를 들어, developer 역할은 모델이 따라야 할 규칙이나 응답 스타일을 지정하고, user 역할은 실제 질문을 전달한다.
즉, 단순 문자열 입력보다 더 구조적으로 대화 맥락을 표현할 수 있다.

 

instruction
instruction="간결하게 설명해"
 
 

instruction은 모델의 전체 응답 스타일이나 방향을 간단히 제어하는 옵션이다.
복잡한 메시지 구조를 쓰지 않아도 “간결하게”, “친절하게”, “전문가처럼” 같은 지시를 줄 수 있다.
일반적으로 developer 메시지보다 단순한 제어 방식으로 이해하면 된다.

 

2) 모델 동작 제어 영역

이 영역은 모델이 어떤 방식으로 답변을 생성할지를 조절한다.

temperature

 

출력의 랜덤성을 조절하는 옵션이다.

  • 값이 낮을수록 더 안정적이고 일관된 답변 생성
  • 값이 높을수록 더 창의적이고 다양한 답변 생성
top_p

 

확률 기반 샘플링 범위를 조절하는 옵션이다.
temperature와 비슷하게 출력 다양성에 영향을 주며, 일반적으로 둘 중 하나를 중심으로 조절하는 경우가 많다.

 

presence_penalty / frequency_penalty

 

반복을 줄이기 위한 옵션이다.

  • presence_penalty : 새로운 주제를 더 잘 꺼내도록 유도
  • frequency_penalty : 같은 표현의 반복을 줄이도록 유도

 

3) 출력 제어 영역

이 영역은 응답 길이와 종료 조건을 조절한다.

max_output_tokens

 

모델이 생성할 수 있는 최대 출력 길이를 제한한다.

  • 응답 길이 제어 가능
  • 비용 관리에 중요

 

stop
stop=["\n"]
 

특정 문자열이 나오면 출력을 종료하도록 지정하는 옵션이다.
정해진 형식으로 응답을 끊고 싶을 때 사용할 수 있다.

 

6. 실전 예제: tool 호출 + 메시지 append + call_id 처리

이 코드는 다음과 같은 흐름으로 동작한다.

1. 사용자 질문 전달
2. 모델이 함수 호출 필요 여부 판단
3. function_call 요청 생성
4. 개발자가 실제 함수 실행
5. 실행 결과를 function_call_output으로 전달
6. 모델이 최종 답변 생성

 

이 구조를 이해할 때 반드시 알아야 할 점은 다음과 같다.
- 모델은 함수를 직접 실행하지 않는다.
- 모델은 어떤 함수를 어떤 인자로 호출할지 “요청만 생성”한다.
- 실제 함수 실행은 개발자가 담당한다.
- 실행 결과는 다시 모델에게 전달해야 한다.

 

1) 함수 정의

def get_weather(location: str) -> str:
 
 

개발자가 실제로 실행할 함수를 정의한다.
모델은 이 함수를 직접 실행하지 못하므로, 반드시 애플리케이션 코드 안에 구현되어 있어야 한다.

 

2) tools 정의

tools = [
    {
        "type": "function",
        "name": "get_weather",
        ...
    }
]
 
 

모델에게 “이런 함수가 있고, 이런 인자를 받아 호출할 수 있다”는 정보를 알려준다.
여기서 중요한 것은 함수 이름, 설명, 매개변수 구조를 명확하게 적는 것이다.

 

3) 첫 번째 요청

 
response = client.responses.create(
    model="gpt-5.4",
    input=input_messages,
    tools=tools
)

 

사용자의 질문과 tool 정보를 함께 전달하면, 모델은 다음 두 가지 중 하나를 선택한다.

1. 일반 텍스트로 답변
2. 특정 함수를 호출해야 한다고 판단 → function_call 생성

 

 

4) function_call 확인

if item.type == "function_call":
 
 

모델이 함수 호출이 필요하다고 판단하면
response.output 안에 function_call 객체가 포함된다.

이 객체에는 다음 정보가 들어 있다.

- 어떤 함수를 호출할지 (item.name)
- 어떤 인자를 사용할지 (item.arguments)

 

 

5) 함수 실행

 
args = json.loads(item.arguments)
result = get_weather(args["location"])

 

여기서 중요한 점은 이 부분이 “AI가 아니라 개발자가 실행하는 영역”이라는 것이다.

모델이 생성한 arguments는 문자열(JSON 형태)이므로 json.loads를 사용해 Python 객체로 변환한 뒤 실제 함수를 실행한다.

 

 

 

6) 메시지 append

input_messages.append(item)
 

모델이 요청한 function_call을 그대로 대화 내역에 추가한다.
이 단계가 중요한 이유는, 다음 요청에서 모델이 “내가 어떤 함수를 요청했는지”를 기억하게 하기 위해서이다.

 

 

7) function_call_output 추가

 
input_messages.append(
    {
        "type": "function_call_output",
        "call_id": item.call_id,
        "output": str(result)
    }
)
 

 

함수 실행 결과를 모델에게 전달하는 단계이다.

여기서 call_id가 매우 중요하다.

- item.call_id → 모델이 만든 함수 호출 ID
- function_call_output.call_id → 그 호출에 대한 결과라는 연결 정보

즉, “이 결과는 이 함수 호출의 결과입니다”라고 알려주는 역할을 한다.
이 값이 맞지 않으면 모델은 결과를 제대로 이해하지 못한다.

 

 

8) 최종 응답 생성

 
final_response = client.responses.create(
    model="gpt-5.4",
    input=input_messages,
    tools=tools
)

 

이제 함수 실행 결과까지 포함된 전체 대화 내역을 다시 모델에 전달한다.

모델은 이 정보를 바탕으로 사용자에게 자연스럽고 완성된 최종 답변을 생성한다.

 


 👉 Function Calling 완전 정리 – GPT를 API·DB와 연결하는 방법