Claude API 완전 가이드 | Anthropic SDK 실전 사용법·요금·함수 호출
이 글의 핵심
Claude API는 Anthropic이 제공하는 대화형 AI API입니다. OpenAI API와 유사하지만 더 긴 컨텍스트(200K 토큰), 강력한 프롬프트 캐싱, 뛰어난 코드 생성 능력이 특징입니다.
Claude API란?
Claude API는 Anthropic이 제공하는 대화형 AI API입니다. GPT-4, Gemini와 함께 2026년 현재 가장 많이 사용되는 LLM API 중 하나로, 특히 긴 문서 처리, 코드 작성, 안전성에서 강점을 보입니다.
이 글에서는 Claude API를 실무에 바로 적용할 수 있도록 API 키 발급부터 고급 기능까지 Python과 TypeScript 예제로 설명합니다.
# 30초 만에 시작하는 Claude API
import anthropic
client = anthropic.Anthropic(api_key="your-api-key")
message = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Python으로 피보나치 수열 구현해줘"}]
)
print(message.content[0].text)
목차
- 모델 비교 및 요금
- API 키 발급
- SDK 설치
- 기본 메시지 API
- 스트리밍
- 시스템 프롬프트
- 멀티턴 대화
- Tool Use (함수 호출)
- Vision (이미지 입력)
- 프롬프트 캐싱
- 실전 패턴: 오류 처리 & 재시도
모델 비교 및 요금
| 모델 | 컨텍스트 | 입력 ($/MTok) | 출력 ($/MTok) | 특징 |
|---|---|---|---|---|
| claude-haiku-4-5 | 200K | $0.80 | $4.00 | 가장 빠름, 저비용 |
| claude-sonnet-4-5 | 200K | $3.00 | $15.00 | 균형잡힌 성능 |
| claude-opus-4-5 | 200K | $15.00 | $75.00 | 최고 성능 |
| claude-sonnet-4-6 | 200K | $3.00 | $15.00 | 최신, 향상된 추론 |
실무 팁: 개발/테스트는 Haiku, 프로덕션은 Sonnet을 사용하면 비용을 크게 절감할 수 있습니다.
API 키 발급
- console.anthropic.com 접속
- 계정 생성 (Google/GitHub 로그인 가능)
- API Keys → Create Key
- 키 복사 후 안전하게 보관 (재확인 불가)
# .env 파일에 저장
ANTHROPIC_API_KEY=sk-ant-api03-...
SDK 설치
Python
pip install anthropic
TypeScript / Node.js
npm install @anthropic-ai/sdk
# 또는
pnpm add @anthropic-ai/sdk
기본 메시지 API
Python
필요한 모듈을 임포트하고 초기 설정을 진행합니다.
import anthropic
client = anthropic.Anthropic() # ANTHROPIC_API_KEY 환경변수 자동 사용
message = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
messages=[
{"role": "user", "content": "대한민국의 수도는 어디인가요?"}
]
)
# 응답 구조
print(message.content[0].text) # 서울입니다.
print(message.model) # claude-sonnet-4-5
print(message.usage) # 토큰 사용량
TypeScript
TypeScript/JavaScript 예제 코드입니다.
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
const message = await client.messages.create({
model: "claude-sonnet-4-5",
max_tokens: 1024,
messages: [{ role: "user", content: "대한민국의 수도는 어디인가요?" }],
});
console.log(message.content[0].type === "text" ? message.content[0].text : "");
응답 객체 구조
설정 파일 예시입니다.
{
"id": "msg_01XFDUDYJgAACzvnptvVoYEL",
"type": "message",
"role": "assistant",
"content": [
{
"type": "text",
"text": "서울입니다."
}
],
"model": "claude-sonnet-4-5",
"stop_reason": "end_turn",
"usage": {
"input_tokens": 14,
"output_tokens": 5
}
}
스트리밍
대화형 앱에서 실시간 응답을 표시할 때 필수입니다.
Python (동기)
필요한 모듈을 임포트하고 초기 설정을 진행합니다.
import anthropic
client = anthropic.Anthropic()
with client.messages.stream(
model="claude-sonnet-4-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Python의 GIL에 대해 설명해줘"}]
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
# 완료 후 최종 메시지 객체 접근
final_message = stream.get_final_message()
print(f"\n\n총 토큰: {final_message.usage.input_tokens + final_message.usage.output_tokens}")
Python (비동기)
아래는 stream_response 함수 구현 예제입니다. 위에서 설명한 핵심 로직을 담고 있습니다.
import asyncio
import anthropic
client = anthropic.AsyncAnthropic()
async def stream_response():
async with client.messages.stream(
model="claude-sonnet-4-5",
max_tokens=1024,
messages=[{"role": "user", "content": "비동기 프로그래밍이란?"}]
) as stream:
async for text in stream.text_stream:
print(text, end="", flush=True)
asyncio.run(stream_response())
TypeScript (스트리밍)
TypeScript/JavaScript 예제 코드입니다.
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
const stream = await client.messages.stream({
model: "claude-sonnet-4-5",
max_tokens: 1024,
messages: [{ role: "user", content: "JavaScript의 이벤트 루프를 설명해줘" }],
});
for await (const chunk of stream) {
if (
chunk.type === "content_block_delta" &&
chunk.delta.type === "text_delta"
) {
process.stdout.write(chunk.delta.text);
}
}
시스템 프롬프트
모델의 역할과 행동 방식을 정의합니다.
필요한 모듈을 임포트하고 초기 설정을 진행합니다.
import anthropic
client = anthropic.Anthropic()
message = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
system="""당신은 10년 경력의 시니어 백엔드 개발자입니다.
- Python, Go, Rust에 능숙합니다
- 성능 최적화와 시스템 설계를 중시합니다
- 코드 리뷰 시 실용적이고 구체적인 피드백을 제공합니다
- 한국어로 답변합니다""",
messages=[
{"role": "user", "content": "이 Django 코드의 N+1 쿼리 문제를 해결해줘:\n\n```python\ndef get_posts():\n posts = Post.objects.all()\n return [(p.title, p.author.name) for p in posts]\n```"}
]
)
print(message.content[0].text)
멀티턴 대화
대화 히스토리를 관리하여 맥락 있는 대화를 구현합니다.
import anthropic
client = anthropic.Anthropic()
conversation_history = []
def chat(user_message: str) -> str:
conversation_history.append({
"role": "user",
"content": user_message
})
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=2048,
system="당신은 친절한 프로그래밍 튜터입니다.",
messages=conversation_history
)
assistant_message = response.content[0].text
conversation_history.append({
"role": "assistant",
"content": assistant_message
})
return assistant_message
# 대화 예시
print(chat("Python이란 무엇인가요?"))
print(chat("방금 설명한 Python으로 Hello World를 출력해줘"))
print(chat("거기서 변수를 추가해줘"))
Tool Use (함수 호출)
Claude가 외부 함수를 호출하여 실시간 정보를 처리할 수 있게 합니다.
import anthropic
import json
from datetime import datetime
client = anthropic.Anthropic()
# 도구 정의
tools = [
{
"name": "get_weather",
"description": "특정 도시의 현재 날씨 정보를 가져옵니다",
"input_schema": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "날씨를 조회할 도시 이름 (예: Seoul, Tokyo)"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "온도 단위"
}
},
"required": ["city"]
}
},
{
"name": "get_stock_price",
"description": "주식 가격을 조회합니다",
"input_schema": {
"type": "object",
"properties": {
"ticker": {
"type": "string",
"description": "주식 티커 심볼 (예: AAPL, TSLA)"
}
},
"required": ["ticker"]
}
}
]
# 실제 함수 구현
def get_weather(city: str, unit: str = "celsius") -> dict:
# 실제로는 날씨 API 호출
return {"city": city, "temperature": 22, "unit": unit, "condition": "맑음"}
def get_stock_price(ticker: str) -> dict:
# 실제로는 주식 API 호출
return {"ticker": ticker, "price": 180.50, "currency": "USD"}
def process_tool_call(tool_name: str, tool_input: dict) -> str:
if tool_name == "get_weather":
result = get_weather(**tool_input)
elif tool_name == "get_stock_price":
result = get_stock_price(**tool_input)
else:
result = {"error": f"Unknown tool: {tool_name}"}
return json.dumps(result, ensure_ascii=False)
def chat_with_tools(user_message: str) -> str:
messages = [{"role": "user", "content": user_message}]
while True:
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
tools=tools,
messages=messages
)
# 도구 호출이 없으면 최종 응답
if response.stop_reason == "end_turn":
return response.content[0].text
# 도구 호출 처리
if response.stop_reason == "tool_use":
messages.append({"role": "assistant", "content": response.content})
tool_results = []
for block in response.content:
if block.type == "tool_use":
result = process_tool_call(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": result
})
messages.append({"role": "user", "content": tool_results})
# 실행
print(chat_with_tools("서울 날씨와 애플 주가를 알려줘"))
Vision (이미지 입력)
Claude는 이미지를 이해하고 분석할 수 있습니다.
import anthropic
import base64
from pathlib import Path
client = anthropic.Anthropic()
# 방법 1: Base64 인코딩
def analyze_image_file(image_path: str, question: str) -> str:
image_data = Path(image_path).read_bytes()
base64_image = base64.standard_b64encode(image_data).decode("utf-8")
# 확장자로 media type 결정
ext = Path(image_path).suffix.lower()
media_types = {".jpg": "image/jpeg", ".png": "image/png",
".gif": "image/gif", ".webp": "image/webp"}
media_type = media_types.get(ext, "image/jpeg")
message = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
messages=[
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": media_type,
"data": base64_image,
},
},
{"type": "text", "text": question}
],
}
],
)
return message.content[0].text
# 방법 2: URL (공개 이미지)
def analyze_image_url(image_url: str, question: str) -> str:
message = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
messages=[
{
"role": "user",
"content": [
{
"type": "image",
"source": {"type": "url", "url": image_url},
},
{"type": "text", "text": question}
],
}
],
)
return message.content[0].text
# 사용 예
result = analyze_image_file("screenshot.png", "이 에러 메시지가 무엇을 의미하나요?")
print(result)
프롬프트 캐싱
반복적으로 사용되는 긴 컨텍스트의 비용을 최대 90% 절감합니다.
import anthropic
client = anthropic.Anthropic()
# 긴 시스템 프롬프트나 문서를 캐싱
LARGE_DOCUMENT = """
[매우 긴 기술 문서 내용 - 5000+ 토큰...]
""" # 실제로는 수천 토큰의 문서
def ask_about_document(question: str) -> str:
message = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
system=[
{
"type": "text",
"text": "당신은 기술 문서 전문가입니다. 다음 문서를 바탕으로 질문에 답변하세요.",
},
{
"type": "text",
"text": LARGE_DOCUMENT,
"cache_control": {"type": "ephemeral"} # 캐싱 활성화 (5분)
}
],
messages=[{"role": "user", "content": question}]
)
# 캐시 히트 여부 확인
usage = message.usage
print(f"입력 토큰: {usage.input_tokens}")
print(f"캐시 생성: {getattr(usage, 'cache_creation_input_tokens', 0)}")
print(f"캐시 읽기: {getattr(usage, 'cache_read_input_tokens', 0)}")
return message.content[0].text
# 첫 번째 호출: 캐시 생성
print(ask_about_document("이 문서의 주요 내용을 요약해줘"))
# 두 번째 호출: 캐시 히트 (비용 90% 절감)
print(ask_about_document("이 문서에서 성능 최적화 방법은?"))
실전 패턴: 오류 처리 & 재시도
import anthropic
import time
from typing import Optional
client = anthropic.Anthropic()
def create_message_with_retry(
messages: list,
model: str = "claude-sonnet-4-5",
max_tokens: int = 1024,
system: Optional[str] = None,
max_retries: int = 3,
base_delay: float = 1.0,
) -> str:
"""재시도 로직이 포함된 안정적인 API 호출"""
for attempt in range(max_retries):
try:
kwargs = {
"model": model,
"max_tokens": max_tokens,
"messages": messages,
}
if system:
kwargs["system"] = system
response = client.messages.create(**kwargs)
return response.content[0].text
except anthropic.RateLimitError as e:
# 요청 한도 초과 - 지수 백오프
if attempt < max_retries - 1:
delay = base_delay * (2 ** attempt)
print(f"요청 한도 초과. {delay}초 후 재시도 ({attempt + 1}/{max_retries})")
time.sleep(delay)
else:
raise
except anthropic.APIStatusError as e:
if e.status_code == 529: # 과부하
if attempt < max_retries - 1:
delay = base_delay * (2 ** attempt)
print(f"서버 과부하. {delay}초 후 재시도")
time.sleep(delay)
else:
raise
else:
raise # 다른 오류는 즉시 전파
except anthropic.APIConnectionError:
if attempt < max_retries - 1:
time.sleep(base_delay)
else:
raise
# 사용
result = create_message_with_retry(
messages=[{"role": "user", "content": "안녕하세요!"}],
system="You are a helpful assistant.",
)
print(result)
ChatGPT API vs Claude API 비교
| 항목 | Claude API | ChatGPT API |
|---|---|---|
| 최대 컨텍스트 | 200K 토큰 | 128K 토큰 |
| 프롬프트 캐싱 | ✅ 지원 (90% 절감) | ❌ 미지원 |
| 코드 생성 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| 문서 분석 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| JSON 모드 | ✅ | ✅ |
| Vision | ✅ | ✅ |
| 생태계 | 성장 중 | 매우 넓음 |
| 가격 (Sonnet 수준) | $3/$15 | $5/$15 |
마치며
Claude API는 특히 긴 문서 처리, 코드 리뷰, 복잡한 추론 작업에서 탁월한 성능을 발휘합니다. 프롬프트 캐싱을 적극 활용하면 비용을 크게 절감할 수 있습니다.
다음 단계: