05. 일반 응답 vs 추론 기반 응답 v2
이 노트북은 일반 모델 호출과 추론 모델 호출을 비교합니다. reasoning={"effort": "low"}가 API 요청 안에 어떻게 들어가는지 확인하세요.
# Colab 또는 로컬 노트북 실행 환경을 구분하기 위해 sys를 가져옵니다.
import sys
# 패키지 설치 명령을 현재 Python 커널에서 실행하기 위해 subprocess를 가져옵니다.
import subprocess
# 패키지 설치 여부를 확인하기 위해 importlib.util을 가져옵니다.
import importlib.util
# 환경 변수에서 API 키를 읽고 설정하기 위해 os를 가져옵니다.
import os
# API 키를 화면에 노출하지 않고 입력받기 위해 getpass를 가져옵니다.
import getpass
# .env 파일 위치를 다루기 위해 pathlib의 Path를 가져옵니다.
from pathlib import Path
# google.colab 모듈이 있으면 현재 런타임이 Google Colab이라고 판단합니다.
IN_COLAB = "google.colab" in sys.modules
# 노트북에서 사용하는 import 이름과 pip 패키지 이름을 짝지어 둡니다.
REQUIRED_PACKAGES = {
"openai": "openai>=2.26.0",
"dotenv": "python-dotenv>=1.2.2",
"pydantic": "pydantic>=2.11.0",
"PIL": "pillow>=12.1.1",
"requests": "requests>=2.32.5",
"numpy": "numpy>=2.3.3",
"websockets": "websockets>=15.0.1",
"websocket": "websocket-client>=1.8.0",
"nest_asyncio": "nest-asyncio>=1.6.0",
}
# 현재 커널에서 import할 수 없는 패키지만 설치하는 함수입니다.
def ensure_package(import_name: str, package_name: str) -> None:
# 이미 import 가능한 패키지는 설치를 건너뜁니다.
if importlib.util.find_spec(import_name) is not None:
# 설치가 필요 없음을 호출자에게 조용히 알리고 돌아갑니다.
return
# Colab에서는 현재 노트북 커널의 Python에 패키지를 설치해야 합니다.
subprocess.check_call([sys.executable, "-m", "pip", "install", "-q", package_name])
# Colab 기본 런타임에는 일부 OpenAI 실습 패키지가 없을 수 있으므로 먼저 준비합니다.
if IN_COLAB:
# 실습 전체에서 필요한 패키지를 하나씩 확인하고 부족한 것만 설치합니다.
for import_name, package_name in REQUIRED_PACKAGES.items():
# 누락된 패키지를 현재 Colab 런타임에 설치합니다.
ensure_package(import_name, package_name)
# 패키지 설치 이후 .env 로딩 기능을 사용할 수 있도록 load_dotenv를 가져옵니다.
from dotenv import load_dotenv
# 현재 작업 폴더의 .env 파일이 있으면 로컬 실행처럼 환경 변수로 올립니다.
load_dotenv(Path.cwd() / ".env")
# OPENAI_API_KEY가 이미 있으면 그대로 사용하고, 없으면 Colab Secrets 또는 입력으로 보완합니다.
if not os.getenv("OPENAI_API_KEY"):
# Colab Secrets에서 OPENAI_API_KEY를 읽어 볼 변수를 준비합니다.
secret_key = None
# Colab이 아닌 로컬 환경에서는 google.colab import가 실패할 수 있으므로 예외를 허용합니다.
try:
# Colab Secrets의 userdata API를 가져옵니다.
from google.colab import userdata
# Secrets에 저장된 OPENAI_API_KEY 값을 읽습니다.
secret_key = userdata.get("OPENAI_API_KEY")
except Exception:
# Colab Secrets를 사용할 수 없으면 이후 수동 입력 단계로 넘어갑니다.
secret_key = None
# Secrets에서 키를 찾았다면 현재 런타임 환경 변수로 설정합니다.
if secret_key:
# OpenAI SDK가 자동으로 읽을 수 있도록 표준 환경 변수 이름에 저장합니다.
os.environ["OPENAI_API_KEY"] = secret_key
else:
# 키가 없으면 노트북 실행자가 직접 입력하도록 요청합니다.
entered_key = getpass.getpass("OPENAI_API_KEY를 입력하세요: ").strip()
# 빈 문자열이 아닌 값을 입력한 경우에만 환경 변수로 등록합니다.
if entered_key:
# OpenAI SDK가 자동으로 읽을 수 있도록 표준 환경 변수 이름에 저장합니다.
os.environ["OPENAI_API_KEY"] = entered_key
# API 키가 끝까지 없으면 다음 OpenAI API 호출이 실패하므로 명확한 오류를 냅니다.
if not os.getenv("OPENAI_API_KEY"):
# Colab에서는 Secrets 또는 입력, 로컬에서는 .env 또는 환경 변수를 설정해야 함을 알려 줍니다.
raise RuntimeError("OPENAI_API_KEY가 없습니다. Colab Secrets, 수동 입력, 또는 .env 파일로 설정해 주세요.")
# 이후 셀에서 Colab 여부를 참고할 수 있도록 간단히 출력합니다.
print(f"개발환경: {'Colab' if IN_COLAB else '로컬'}")
# API 키를 직접 출력하지 않고 준비 완료 여부만 알려 줍니다.
print("OPENAI_API_KEY 준비 완료")
1단계. 최소 실행 환경 준비
이 단계에서는 API 호출에 필요한 기본 준비를 합니다. import, .env 로드, OpenAI() 클라이언트 생성, output 폴더 생성을 차례대로 확인합니다.
아래 셀에서 특히 client = OpenAI() 줄을 확인하세요. 이후 모든 API 호출은 이 client 객체에서 시작됩니다.
# 운영체제 환경 변수와 .env 값을 읽기 위해 os를 사용합니다.
import os
# JSON 메타데이터를 파일로 저장하기 위해 json을 사용합니다.
import json
# 실행 시간을 비교하는 예제에서 사용할 시간 측정 모듈입니다.
import time
# 노트북 실행 위치와 output 폴더 경로를 안전하게 다루기 위한 Path입니다.
from pathlib import Path
# .env 파일에 저장된 OPENAI_API_KEY를 현재 Python 환경으로 불러옵니다.
from dotenv import load_dotenv
# OpenAI API를 직접 호출하기 위한 공식 SDK 클라이언트입니다.
from openai import OpenAI
# 현재 노트북이 워크스페이스 루트에서 실행되는지, 01.text_generation 폴더에서 실행되는지 확인합니다.
CURRENT_DIR = Path.cwd().resolve()
# 워크스페이스 루트에서 실행 중이면 01.text_generation 폴더를 실습 루트로 사용합니다.
if (CURRENT_DIR / "01.text_generation").exists():
TEXT_GENERATION_DIR = CURRENT_DIR / "01.text_generation"
# 이미 01.text_generation 폴더 안에서 실행 중이면 현재 폴더를 실습 루트로 사용합니다.
else:
TEXT_GENERATION_DIR = CURRENT_DIR
# 워크스페이스 루트는 01.text_generation 폴더의 부모 폴더입니다.
WORKSPACE_ROOT = TEXT_GENERATION_DIR.parent
# 실행 결과를 저장할 output 폴더 경로입니다.
OUTPUT_DIR = TEXT_GENERATION_DIR / "output"
# output 폴더가 없으면 새로 만들고, 이미 있으면 그대로 둡니다.
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
# 워크스페이스 루트의 .env 파일을 읽습니다.
load_dotenv(WORKSPACE_ROOT / ".env")
# OpenAI API 키가 설정되어 있는지 먼저 확인합니다.
if not os.getenv("OPENAI_API_KEY"):
raise RuntimeError("OPENAI_API_KEY가 없습니다. 워크스페이스 루트의 .env 파일을 확인해 주세요.")
# OpenAI API를 호출할 클라이언트를 생성합니다. 이 줄이 모든 API 호출의 출발점입니다.
client = OpenAI()
# 이후 셀에서 저장 경로를 확인할 수 있도록 출력합니다.
print(f"실습 폴더: {TEXT_GENERATION_DIR}")
print(f"결과 저장 폴더: {OUTPUT_DIR}")
실습 폴더: C:\Users\ai4nu\2026-ai-tech\AS.1.1_0601\01.text_generation
결과 저장 폴더: C:\Users\ai4nu\2026-ai-tech\AS.1.1_0601\01.text_generation\output
2단계. 비교할 모델과 프롬프트 준비하기
# 일반 응답 모델입니다.
GENERAL_MODEL = os.getenv("OPENAI_GENERAL_MODEL", "gpt-4.1-mini")
# 추론 응답 모델입니다.
REASONING_MODEL = os.getenv("OPENAI_REASONING_MODEL", "gpt-5-mini")
# 두 모델에 공통으로 줄 역할 지시문입니다.
INSTRUCTIONS = "당신은 학습 코치입니다. 초급자가 이해할 수 있도록 한국어로 명확히 설명하세요."
# 두 모델에 공통으로 보낼 사용자 요청입니다.
PROMPT = "다음 조건을 모두 만족하는 2주 학습 계획을 작성해 주세요. 조건: 평일 하루 1시간, 주말 하루 2시간, 기초 이론/실습/복습 비율을 제안하고 이유를 함께 설명."
print(f"일반 모델: {GENERAL_MODEL}")
print(f"추론 모델: {REASONING_MODEL}")
print(PROMPT)
일반 모델: gpt-4.1-mini
추론 모델: gpt-5-mini
다음 조건을 모두 만족하는 2주 학습 계획을 작성해 주세요. 조건: 평일 하루 1시간, 주말 하루 2시간, 기초 이론/실습/복습 비율을 제안하고 이유를 함께 설명.
3단계. 일반 모델 직접 호출하기
# 일반 모델 호출 시작 시간을 기록합니다.
general_started = time.perf_counter()
# 일반 모델에 Responses API 요청을 보냅니다.
general_response = client.responses.create(
# 일반 응답 모델입니다.
model=GENERAL_MODEL,
# 모델의 역할 지시문입니다.
instructions=INSTRUCTIONS,
# 실제 사용자 요청입니다.
input=PROMPT,
# 최대 출력 토큰 수입니다.
max_output_tokens=320,
)
# 일반 모델 실행 시간을 계산합니다.
general_elapsed = time.perf_counter() - general_started
# 일반 모델 응답 텍스트를 읽습니다.
general_text = general_response.output_text
print("[일반 모델 응답]")
print(general_text)
print(f"모델: {general_response.model}")
print(f"실행 시간: {general_elapsed:.4f}초")
print(f"사용량: {general_response.usage}")
[일반 모델 응답]
네! 2주 학습 계획과 함께 기초 이론, 실습, 복습의 비율과 그 이유를 초급자가 이해하기 쉽게 설명해 드릴게요.
---
### 1. 학습 시간 총정리
- 평일: 5일 × 1시간 = 5시간
- 주말: 2일 × 2시간 = 4시간
**총 9시간**
---
### 2. 기초 이론 / 실습 / 복습 비율 제안
**비율: 이론 30%, 실습 50%, 복습 20%**
- 이론 (약 3시간): 기초를 이해하는 시간
- 실습 (약 4.5시간): 직접 해보며 익히는 시간
- 복습 (약 1.5시간): 배운 내용을 다시 정리하고 확인하는 시간
---
### 3. 비율 이유 설명
- **이론 30%**
처음 배울 땐 기본 개념을 이해하는 것이 중요하지만, 이론만 너무 오래 하면 지루할 수 있으므로 적당한 시간만 투자합니다.
- **실습 50%**
실제로 해보는 것이 가장 효과적인 학습 방법입니다. 실습을 통해 이론을 몸에 익히고 문제 해결 능력을 키울 수 있습니다.
- **복습 20%**
학습한 내용을 잊지 않도록 정리하고, 문제점을 확인하며 보완하는 시간이
모델: gpt-4.1-mini-2025-04-14
실행 시간: 6.0253초
사용량: ResponseUsage(input_tokens=91, input_tokens_details=InputTokensDetails(cached_tokens=0), output_tokens=320, output_tokens_details=OutputTokensDetails(reasoning_tokens=0), total_tokens=411)
4단계. 추론 모델 직접 호출하기
추론 모델 요청에서는 reasoning 매개변수를 직접 넣습니다. 계정이나 모델 접근 권한에 따라 실패할 수 있으므로 오류를 출력하고 다음 셀에서 비교가 이어지도록 처리합니다.
# 추론 모델 호출 시작 시간을 기록합니다.
reasoning_started = time.perf_counter()
# 오류 메시지를 저장할 변수입니다.
reasoning_error = None
# 추론 모델은 접근 권한이 없을 수 있으므로 예외 처리를 합니다.
try:
# 추론 모델에 Responses API 요청을 보냅니다.
reasoning_response = client.responses.create(
# 추론 응답 모델입니다.
model=REASONING_MODEL,
# 모델의 역할 지시문입니다.
instructions=INSTRUCTIONS,
# 실제 사용자 요청입니다.
input=PROMPT,
# 최대 출력 토큰 수입니다.
max_output_tokens=420,
# 추론 강도를 직접 지정합니다.
reasoning={"effort": "low"},
)
# 추론 모델 응답 텍스트를 읽습니다.
reasoning_text = reasoning_response.output_text
# 호출이 실패하면 오류를 저장합니다.
except Exception as exc:
# 실패 원인을 문자열로 저장합니다.
reasoning_error = str(exc)
# 비교 파일 구조를 유지하기 위한 안내 텍스트입니다.
reasoning_text = "추론 모델 호출 실패로 결과를 생성하지 못했습니다. API 권한 또는 모델 설정을 확인해 주세요."
# 응답 객체가 없음을 표시합니다.
reasoning_response = None
# 추론 모델 실행 시간을 계산합니다.
reasoning_elapsed = time.perf_counter() - reasoning_started
print("[추론 모델 응답]")
print(reasoning_text)
print(f"실행 시간: {reasoning_elapsed:.4f}초")
print(f"오류: {reasoning_error}")
if reasoning_response:
print(f"모델: {reasoning_response.model}")
print(f"사용량: {reasoning_response.usage}")
[추론 모델 응답]
아래는 “2주(14일)” 동안 평일 하루 1시간, 주말 하루 2시간을 지키는 초급자용 학습 계획입니다. 주제는 어떤 과목·기술이든 적용할 수 있도록 일반적인 이론/실습/복습 활동으로 구성했습니다.
총시간 계산
- 평일(10일) = 10 × 1시간 = 10시간
- 주말(4일) = 4 × 2시간 = 8시간
- 총
실행 시간: 5.7230초
오류: None
모델: gpt-5-mini-2025-08-07
사용량: ResponseUsage(input_tokens=90, input_tokens_details=InputTokensDetails(cached_tokens=0), output_tokens=420, output_tokens_details=OutputTokensDetails(reasoning_tokens=256), total_tokens=510)
5단계. 비교 결과 저장하기
# 저장 경로를 정합니다.
general_path = OUTPUT_DIR / "05_general_response_v2_output.txt"
reasoning_path = OUTPUT_DIR / "05_reasoning_response_v2_output.txt"
metadata_path = OUTPUT_DIR / "05_reasoning_vs_general_response_v2_meta.json"
# 두 응답 텍스트를 각각 저장합니다.
general_path.write_text(general_text + "\\n", encoding="utf-8")
reasoning_path.write_text(reasoning_text + "\\n", encoding="utf-8")
# 일반 모델 usage를 저장 가능한 딕셔너리로 변환합니다.
general_usage = general_response.usage.model_dump() if general_response.usage else {}
# 추론 모델 usage를 저장 가능한 딕셔너리로 변환합니다.
reasoning_usage = reasoning_response.usage.model_dump() if reasoning_response and reasoning_response.usage else {}
# 비교 메타데이터를 구성합니다.
metadata = {
"example": "05.reasoning_vs_general_response_v2",
"general_model": general_response.model,
"reasoning_model": reasoning_response.model if reasoning_response else REASONING_MODEL,
"general_elapsed_seconds": round(general_elapsed, 4),
"reasoning_elapsed_seconds": round(reasoning_elapsed, 4),
"general_usage": general_usage,
"reasoning_usage": reasoning_usage,
"reasoning_error": reasoning_error,
"general_output_path": str(general_path),
"reasoning_output_path": str(reasoning_path),
}
# 메타데이터를 저장합니다.
metadata_path.write_text(json.dumps(metadata, ensure_ascii=False, indent=2) + "\\n", encoding="utf-8")
print(json.dumps(metadata, ensure_ascii=False, indent=2))
{
"example": "05.reasoning_vs_general_response_v2",
"general_model": "gpt-4.1-mini-2025-04-14",
"reasoning_model": "gpt-5-mini-2025-08-07",
"general_elapsed_seconds": 6.0253,
"reasoning_elapsed_seconds": 5.723,
"general_usage": {
"input_tokens": 91,
"input_tokens_details": {
"cached_tokens": 0
},
"output_tokens": 320,
"output_tokens_details": {
"reasoning_tokens": 0
},
"total_tokens": 411
},
"reasoning_usage": {
"input_tokens": 90,
"input_tokens_details": {
"cached_tokens": 0
},
"output_tokens": 420,
"output_tokens_details": {
"reasoning_tokens": 256
},
"total_tokens": 510
},
"reasoning_error": null,
"general_output_path": "C:\\Users\\ai4nu\\2026-ai-tech\\AS.1.1_0601\\01.text_generation\\output\\05_general_response_v2_output.txt",
"reasoning_output_path": "C:\\Users\\ai4nu\\2026-ai-tech\\AS.1.1_0601\\01.text_generation\\output\\05_reasoning_response_v2_output.txt"
}
Click to add a cell.'AI System > OpenAI API와 바이브 코딩으로 배우는 AI 서비스 개발' 카테고리의 다른 글
| d01 - 02. function calling - 02. tool loop and routing v2 (0) | 2026.06.01 |
|---|---|
| d01 - 02. function calling - 01. responses function calling basic v2 (0) | 2026.06.01 |
| d01 - 01. text_generation - 04. Streaming_v2 (1) | 2026.06.01 |
| d01 - 01. text_generation - 03. 다중 턴 문맥 비교_v2 (0) | 2026.06.01 |
| d01 - 01. text_generation - 02. chat_completions_api_v2 (0) | 2026.06.01 |