API와 키 관리
모든 AI API는 같은 방식으로 동작합니다. 요청(request)을 보내고 응답(response)을 받습니다. 세부사항은 바뀌어도 패턴(pattern)은 바뀌지 않습니다.
유형: Build
언어: Python, TypeScript
선수 지식: Phase 0, Lesson 01
예상 시간: 약 30분
학습 목표
- 환경 변수(environment variable)와
.env 파일(file)을 사용해 API 키(API key)를 안전하게 저장합니다.
- Anthropic Python SDK와 원시 HTTP(raw HTTP)를 모두 사용해 LLM API 호출(API call)을 실행합니다.
- SDK 기반 요청/응답(request/response)과 raw HTTP 요청/응답 형식을 비교해 디버깅(debugging) 기준을 잡습니다.
- 인증(authentication), 사용량 제한(rate limit) 같은 흔한 API 오류(API error)를 식별하고 처리합니다.
문제
Phase 11부터는 Anthropic, OpenAI, Google 같은 LLM API를 호출하게 됩니다. Phase 13-16에서는 이런 API를 반복문(loop) 안에서 사용하는 에이전트(agent)를 만듭니다. API 키가 어떻게 동작하는지, 어디에 안전하게 저장해야 하는지, 첫 API 호출을 어떻게 만드는지 알아야 합니다.
PAI OJT에서는 키를 다루는 습관도 중요한 학습 대상입니다. API 키는 개인 비용과 회사 보안에 연결될 수 있으므로 코드에 직접 넣지 않고 환경 변수나 비공개 설정으로 분리합니다.
개념
sequenceDiagram
participant C as 내 코드
participant S as API 서버
C->>S: HTTP 요청(API 키 포함)
S->>C: HTTP 응답(JSON)
모든 API 호출에는 네 가지가 있습니다.
- 엔드포인트(endpoint): 요청을 보낼 URL
- API 키(API key): 인증(authentication) 정보
- 요청 본문(request body): 내가 원하는 작업
- 응답 본문(response body): 서버(server)가 돌려준 결과
| 구성요소 | 예시 | 확인할 것 |
|---|
| 엔드포인트(endpoint) | https://api.anthropic.com/v1/messages | 기본 URL(base URL)과 경로(path)가 맞는가 |
| API 키(API key) | ANTHROPIC_API_KEY | 환경 변수에 들어 있고 유효한가 |
| 요청 본문(request body) | model, messages, max_tokens | 필수 필드(field)와 형식(format)이 맞는가 |
| 응답 본문(response body) | JSON content, usage | 원하는 field를 제대로 읽는가 |
직접 만들기
Step 1: API 키를 안전하게 저장하기
API 키를 코드에 직접 넣지 않습니다. 환경 변수를 사용합니다.
export ANTHROPIC_API_KEY="sk-ant-..."
export OPENAI_API_KEY="sk-..."
또는 .env 파일을 사용할 수 있습니다. .env는 반드시 .gitignore에 추가합니다.
ANTHROPIC_API_KEY=sk-ant-...
OPENAI_API_KEY=sk-...
Step 2: 첫 API 호출(Python)
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=256,
messages=[{"role": "user", "content": "신경망을 한 문장으로 설명해줘."}],
)
print(response.content[0].text)
SDK는 환경 변수에서 키를 읽고, 요청 형식을 Python 객체(object)로 감싸 줍니다.
Step 3: 첫 API 호출(TypeScript)
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
const response = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 256,
messages: [{ role: "user", content: "신경망을 한 문장으로 설명해줘." }],
});
console.log(response.content[0].text);
Step 4: 원시 HTTP(raw HTTP, SDK 없이)
import json
import os
import urllib.request
url = "https://api.anthropic.com/v1/messages"
headers = {
"Content-Type": "application/json",
"x-api-key": os.environ["ANTHROPIC_API_KEY"],
"anthropic-version": "2023-06-01",
}
body = json.dumps({
"model": "claude-sonnet-4-20250514",
"max_tokens": 256,
"messages": [{"role": "user", "content": "신경망을 한 문장으로 설명해줘."}],
}).encode()
req = urllib.request.Request(url, data=body, headers=headers, method="POST")
with urllib.request.urlopen(req) as resp:
result = json.loads(resp.read())
print(result["content"][0]["text"])
SDK는 내부적으로 이런 HTTP 요청을 만들어 보냅니다. 원시 HTTP를 이해하면 인증 오류(authentication error), 요청 형식 오류(request format error), 응답 파싱 오류(response parsing error)를 더 쉽게 디버깅할 수 있습니다.
사용해보기
이 과정에서 자주 쓰게 될 API는 아래와 같습니다. 무료 크레딧(credit)이나 요금 정책은 바뀔 수 있으므로 실제 사용 전 제공자(provider) 문서를 확인합니다.
| API | 필요한 때 | 비고 |
|---|
| Anthropic (Claude) | Phase 11-16, 에이전트/도구 | SDK와 messages API 사용 |
| OpenAI | Phase 11, 제공자 비교 | 모델/API 차이를 비교할 때 사용 |
| Hugging Face | Phase 4-10, 모델/데이터셋 | 데이터셋(dataset)과 모델 허브(model hub) 사용 |
지금 당장 모든 API를 설정할 필요는 없습니다. 강의에서 요구할 때 설정합니다.
| 에러 | 흔한 원인 | 먼저 확인할 것 |
|---|
| 401 Unauthorized | 키 없음 또는 잘못된 키 | 환경 변수 이름, 키 값 |
| 403 Forbidden | 권한 없는 모델/엔드포인트 | 계정(account) 권한, 모델 접근 권한(model access) |
| 429 Too Many Requests | 사용량 제한 초과 | 재시도(retry) 간격, 요청 빈도 |
| 400 Bad Request | 본문 형식(body format) 오류 | 필수 필드(required field), 모델 이름, 메시지 형식(message format) |
| Timeout | 요청이 너무 오래 걸림 | max_tokens, 스트리밍(streaming), 네트워크(network) |
산출물 만들기
이 강의는 API 문제를 진단하는 프롬프트(prompt)를 산출합니다.
outputs/prompt-api-troubleshooter.md: 인증(authentication), 사용량 제한(rate limit), 타임아웃(timeout) 같은 API 오류를 진단하는 프롬프트
또한 code/first_api_call.py를 실행해 SDK와 원시 HTTP 호출을 비교할 수 있습니다.
python phases/00-setup-and-tooling/04-apis-and-keys/code/first_api_call.py
연습문제
- Anthropic API 키를 발급받아 첫 API 호출을 실행합니다.
- 원시 HTTP 버전을 실행하고 SDK 버전과 응답 형식(response format)을 비교합니다.
- 일부러 잘못된 API 키를 넣고 오류 메시지(error message)를 읽어 봅니다.
.env 또는 셸(shell) 환경 변수에 키를 저장하고, 키가 Git에 포함되지 않는지 확인합니다.
핵심 용어
| 용어 | 흔한 설명 | 실제 의미 |
|---|
| API 키(API key) | API 비밀번호 | 계정(account)을 식별하고 요청(request)을 승인(authorize)하는 고유 문자열 |
| 사용량 제한(Rate limit) | 속도 제한(throttling) | 남용(abuse) 방지와 공정 사용을 위해 분당/시간당 요청 수를 제한하는 기준 |
| 토큰(Token) | 단어(word) | API 과금(billing)과 컨텍스트(context) 계산에 쓰이는 텍스트 단위 |
| 스트리밍(Streaming) | 실시간 응답(real-time response) | 전체 답변을 기다리지 않고 조각(chunk) 단위로 받는 방식 |
| 환경 변수(Environment variable) | 셸 설정값 | 코드 밖에서 프로세스(process)에 전달되는 런타임 구성(runtime configuration) |
더 읽을거리