Claude API 시작하기
pip install anthropic
import anthropic
client = anthropic.Anthropic(api_key="sk-ant-...") # 또는 ANTHROPIC_API_KEY 환경변수
message = client.messages.create(
model="claude-sonnet-4-6-20251001",
max_tokens=1024,
messages=[{"role": "user", "content": "안녕하세요!"}]
)
print(message.content[0].text)
모델 선택 가이드
| 모델 | 특징 | 입력 비용 | 출력 비용 |
|---|---|---|---|
| claude-opus-4-6 | 최고 성능, 복잡한 추론 | $15/M | $75/M |
| claude-sonnet-4-6 | 균형 잡힌 성능 (권장) | $3/M | $15/M |
| claude-haiku-4-5 | 빠르고 저렴 | $0.80/M | $4/M |
System Prompt 활용
response = client.messages.create(
model="claude-sonnet-4-6-20251001",
max_tokens=2048,
system='''당신은 시니어 백엔드 엔지니어입니다.
- 코드는 항상 타입 힌트 포함
- 예외 처리 필수
- 한국어로 설명
- 보안 취약점이 있으면 반드시 지적''',
messages=[{
"role": "user",
"content": "사용자 로그인 API를 FastAPI로 구현해줘"
}]
)
멀티턴 대화
conversation_history = []
def chat(user_message: str) -> str:
conversation_history.append({
"role": "user",
"content": user_message
})
response = client.messages.create(
model="claude-sonnet-4-6-20251001",
max_tokens=1024,
system="당신은 친절한 Python 튜터입니다.",
messages=conversation_history
)
assistant_message = response.content[0].text
conversation_history.append({
"role": "assistant",
"content": assistant_message
})
return assistant_message
# 사용
print(chat("파이썬의 리스트 컴프리헨션을 설명해줘"))
print(chat("그럼 딕셔너리 컴프리헨션은?"))
print(chat("둘의 차이점을 예제로 보여줘"))
Vision: 이미지 분석
import base64
from pathlib import Path
# 파일에서 이미지 읽기
def encode_image(image_path: str) -> str:
with open(image_path, "rb") as f:
return base64.standard_b64encode(f.read()).decode("utf-8")
# 이미지 + 텍스트 질문
response = client.messages.create(
model="claude-sonnet-4-6-20251001",
max_tokens=1024,
messages=[{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/jpeg",
"data": encode_image("screenshot.jpg"),
},
},
{
"type": "text",
"text": "이 스크린샷에서 UI 개선점을 3가지 알려줘"
}
],
}]
)
print(response.content[0].text)
# URL로 이미지 전달
response = client.messages.create(
model="claude-sonnet-4-6-20251001",
max_tokens=512,
messages=[{
"role": "user",
"content": [
{"type": "image", "source": {"type": "url", "url": "https://example.com/chart.png"}},
{"type": "text", "text": "이 차트를 분석해줘"}
]
}]
)
Tool Use (함수 호출)
import json
tools = [
{
"name": "get_weather",
"description": "특정 도시의 현재 날씨를 가져옵니다",
"input_schema": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "도시 이름 (예: Seoul, Tokyo)"},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"], "default": "celsius"}
},
"required": ["city"]
}
},
{
"name": "search_products",
"description": "상품 데이터베이스에서 검색합니다",
"input_schema": {
"type": "object",
"properties": {
"query": {"type": "string"},
"max_price": {"type": "number"}
},
"required": ["query"]
}
}
]
def process_tool_call(tool_name: str, tool_input: dict) -> str:
if tool_name == "get_weather":
# 실제 날씨 API 호출
return json.dumps({"city": tool_input["city"], "temp": 22, "condition": "맑음"})
elif tool_name == "search_products":
return json.dumps([{"name": "노트북", "price": 1200000}])
# 에이전트 루프
def run_agent(user_message: str):
messages = [{"role": "user", "content": user_message}]
while True:
response = client.messages.create(
model="claude-sonnet-4-6-20251001",
max_tokens=1024,
tools=tools,
messages=messages
)
if response.stop_reason == "end_turn":
return response.content[0].text
# 도구 호출 처리
tool_use_block = next(b for b in response.content if b.type == "tool_use")
tool_result = process_tool_call(tool_use_block.name, tool_use_block.input)
# 대화에 추가
messages.append({"role": "assistant", "content": response.content})
messages.append({
"role": "user",
"content": [{
"type": "tool_result",
"tool_use_id": tool_use_block.id,
"content": tool_result
}]
})
result = run_agent("서울 날씨 알려줘")
print(result)
스트리밍 응답
# 동기 스트리밍
with client.messages.stream(
model="claude-sonnet-4-6-20251001",
max_tokens=1024,
messages=[{"role": "user", "content": "긴 소설의 첫 장을 써줘"}]
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
# 비동기 스트리밍 (FastAPI/웹 서버)
import asyncio
import anthropic
async def stream_response(prompt: str):
async_client = anthropic.AsyncAnthropic()
async with async_client.messages.stream(
model="claude-sonnet-4-6-20251001",
max_tokens=1024,
messages=[{"role": "user", "content": prompt}]
) as stream:
async for text in stream.text_stream:
yield text
구조화된 출력 (JSON 강제)
import json
response = client.messages.create(
model="claude-sonnet-4-6-20251001",
max_tokens=1024,
tools=[{
"name": "extract_info",
"description": "텍스트에서 정보를 추출합니다",
"input_schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"company": {"type": "string"},
"email": {"type": "string"},
"phone": {"type": "string"}
},
"required": ["name", "company"]
}
}],
tool_choice={"type": "tool", "name": "extract_info"},
messages=[{
"role": "user",
"content": "김철수 씨는 네이버 개발팀에 근무하며 이메일은 [email protected]입니다."
}]
)
info = response.content[0].input
print(json.dumps(info, ensure_ascii=False, indent=2))
비용 최적화 팁
- 캐싱 활용: 동일 시스템 프롬프트는 Prompt Caching으로 90% 비용 절감
- Haiku 우선: 단순 분류/추출 작업은 claude-haiku-4-5로 충분
- max_tokens 조절: 불필요하게 높게 설정하지 않기
- 배치 처리: Batch API로 비동기 처리 시 50% 할인
# Prompt Caching (반복 사용되는 긴 시스템 프롬프트)
response = client.messages.create(
model="claude-sonnet-4-6-20251001",
max_tokens=1024,
system=[{
"type": "text",
"text": "매우 긴 시스템 프롬프트...",
"cache_control": {"type": "ephemeral"} # 캐시 적용
}],
messages=[{"role": "user", "content": user_input}]
)
Anthropic 콘솔(console.anthropic.com)에서 API 키 발급 후 바로 시작할 수 있습니다.





