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)
모델 비교 및 요금
| 모델 | 컨텍스트 | 입력 ($/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 완전 가이드 | Anthropic SDK 실전 사용법·요금·함수 호출」입니다. 앞선 튜토리얼을 구현·런타임 관점에서 다시 압축합니다. 데이터 흐름과 실패 모드를 기준으로 “입력이 어디서 검증되고, 핵심 연산이 어디서 일어나며, 부작용(I/O·네트워크·디스크)·동시성이 어디서 터지는가”를 한 장면으로 그리면 장애 분석이 빨라집니다.
처리 파이프라인(개념도)
flowchart TD A[입력·요청·이벤트] --> B[파싱·검증·디코딩] B --> C[핵심 연산·상태 전이] C --> D[부작용: I/O·네트워크·동시성] D --> E[결과·관측·저장]
경계에서의 지연·실패(시퀀스 관점)
sequenceDiagram participant C as 클라이언트/호출자 participant B as 경계(프로세스·런타임·게이트웨이) participant D as 의존성(외부 API·DB·큐) C->>B: 요청/이벤트 B->>D: 조회·쓰기·RPC D-->>B: 지연·부분 실패·재시도 가능 B-->>C: 응답 또는 오류(코드·상관 ID)
알고리즘·프로토콜·리소스 관점 체크포인트
- 불변 조건(Invariant): 각 단계가 만족해야 하는 조건(버퍼 경계, 프로토콜 상태, 트랜잭션 격리, 파일 디스크립터 상한)을 문장으로 적어 두면 디버깅 비용이 줄어듭니다.
- 결정성: 동일 입력에 동일 출력이 보장되는 순수 층과, 시간·네트워크·스레드 스케줄에 의해 달라질 수 있는 층을 분리해야 테스트와 장애 분석이 쉬워집니다.
- 경계 비용: 직렬화/역직렬화, 문자 인코딩, syscall 횟수, 락 경합, GC·할당, 캐시 미스처럼 누적 비용을 의심 목록에 넣습니다.
- 백프레셔: 생산자가 소비자보다 빠를 때(소켓 버퍼, 큐 깊이, 스트림) 어디서 어떤 신호로 속도를 줄일지 정의합니다.
프로덕션 운영 패턴
실서비스에서는 기능과 함께 관측·배포·보안·비용·규제가 동시에 요구됩니다.
| 영역 | 운영 관점 질문 |
|---|---|
| 관측성 | 요청 단위 상관 ID, 에러율/지연 분위수(p95/p99), 의존성 타임아웃·재시도가 대시보드에 보이는가 |
| 안전성 | 입력 검증·권한·비밀·감사 로그가 코드 경로마다 일관적인가 |
| 신뢰성 | 재시도는 멱등 연산에만 적용되는가, 서킷 브레이커·백오프·DLQ가 있는가 |
| 성능 | 캐시 계층·배치 크기·커넥션 풀·인덱스·백프레셔가 데이터 규모에 맞는가 |
| 배포 | 롤백 룬북, 카나리/블루그린, 마이그레이션 호환성·플래그가 문서화되어 있는가 |
| 용량 | 피크 트래픽·디스크·파일 디스크립터·스레드 풀 상한을 주기적으로 검증하는가 |
스테이징은 데이터 양·네트워크 RTT·동시성을 가능한 한 프로덕션에 가깝게 맞추는 것이 재현율을 높입니다.
확장 예시: 엔드투엔드 미니 시나리오
「Claude API 완전 가이드 | Anthropic SDK 실전 사용법·요금·함수 호출」을 실제 배포·운영 흐름으로 옮긴 체크리스트형 시나리오입니다. 도메인에 맞게 단계 이름만 바꿔 적용할 수 있습니다.
- 입력 계약 고정: 스키마·버전·최대 페이로드·타임아웃·에러 코드 표를 API 또는 이벤트 경계에 둔다.
- 핵심 경로 계측: 요청 ID, 단계별 지연, 외부 호출 결과 코드를 한 화면(로그+메트릭+트레이스)에서 추적한다.
- 실패 주입: 의존성 타임아웃·5xx·부분 데이터·락 대기를 스테이징에서 재현한다.
- 호환·롤백: 설정/마이그레이션/클라이언트 버전을 되돌릴 수 있는지(또는 피처 플래그) 확인한다.
- 부하 후 검증: 피크 대비 p95/p99, 에러율, 리소스 상한, 알림 임계값이 기대 범위인지 본다.
의사코드 스케치(프레임워크 무관)
handle(request):
ctx = newCorrelationId()
validated = validateSchema(request) // 경계에서 거절
authorize(validated, ctx) // 권한·테넌트
result = domainCore(validated) // 순수에 가까운 규칙
persistOrEmit(result, idempotentKey) // I/O: 멱등·재시도 정책
recordMetrics(ctx, latency, outcome)
return result
문제 해결(Troubleshooting)
| 증상 | 가능 원인 | 조치 |
|---|---|---|
| 간헐적 실패 | 레이스, 타임아웃, 외부 의존성 불안정, DNS | 최소 재현 스크립트, 분산 트레이스·로그 상관관계, 재시도·서킷 설정 점검 |
| 성능 저하 | N+1, 동기 I/O, 락 경합, 과도한 직렬화, 캐시 미스 | 프로파일러·APM으로 핫스팟 확인 후 한 가지씩 제거 |
| 메모리 증가 | 캐시 무제한, 구독/리스너 누수, 대용량 버퍼, 커넥션 미반납 | 상한·TTL·힙/FD 스냅샷 비교 |
| 빌드·배포만 실패 | 환경 변수, 권한, 플랫폼 차이, lockfile | CI 로그와 로컬 diff, 런타임·이미지 버전 핀 |
| 설정이 로컬과 다름 | 프로필·시크릿·기본값, 지역 리전 | 단일 소스(예: 스키마 검증된 설정)와 배포 매트릭스 표준화 |
| 데이터 불일치 | 비멱등 재시도, 부분 쓰기, 캐시 무효화 누락 | 멱등 키·아웃박스·트랜잭션 경계 재검토 |
권장 순서: (1) 최소 재현 (2) 최근 변경 범위 축소 (3) 환경·의존성 차이 (4) 관측으로 가설 검증 (5) 수정 후 회귀·부하 테스트.
마치며
Claude API는 특히 긴 문서 처리, 코드 리뷰, 복잡한 추론 작업에서 탁월한 성능을 발휘합니다. 프롬프트 캐싱을 적극 활용하면 비용을 크게 절감할 수 있습니다.
다음 단계:
- LangChain과 Claude 통합 가이드
- RAG 구현 가이드
- ChatGPT API 가이드
자주 묻는 질문 (FAQ)
Q. 이 내용을 실무에서 언제 쓰나요?
A. Claude API(Anthropic SDK) 시작부터 실무 활용까지. API 키 발급, 메시지 API, 스트리밍, Tool Use(함수 호출), 프롬프트 캐싱, Vision, 요금 체계를 Python·TypeScr… 실무에서는 위 본문의 예제와 선택 가이드를 참고해 적용하면 됩니다.
Q. 선행으로 읽으면 좋은 글은?
A. 각 글 하단의 이전 글 또는 관련 글 링크를 따라가면 순서대로 배울 수 있습니다. C++ 시리즈 목차에서 전체 흐름을 확인할 수 있습니다.
Q. 더 깊이 공부하려면?
A. cppreference와 해당 라이브러리 공식 문서를 참고하세요. 글 말미의 참고 자료 링크도 활용하면 좋습니다.
같이 보면 좋은 글 (내부 링크)
이 주제와 연결되는 다른 글입니다.
- Emotion 완벽 가이드 | CSS-in-JS·성능·Styled·CSS Prop·실전 활용
- Cursor AI 에디터 완전 가이드 | VS Code 기반 AI 코딩 도구 실전 활용
- Framer Motion 완벽 가이드 | React 애니메이션·Variants
이 글에서 다루는 키워드 (관련 검색어)
Claude, Anthropic, AI, API, LLM, Python, TypeScript, 프롬프트 등으로 검색하시면 이 글이 도움이 됩니다.