Claude Sonnet 4와 Claude Opus 4 시작하기
API를 사용해 로컬 환경의 Python에서 Anthropic의 새로운 Claude 4 Sonnet과 Opus를 설정하고 실행하는 방법. 이 글은 AI 번역본입니다. 오역이 있을 수 있으니 댓글로 자유롭게 알려 주세요.
Created on September 12|Last edited on September 12
Comment
💡
Claude 4는 Anthropic의 최신 세대 대규모 언어 모델—새로운 Sonnet 4와 Opus 4 모델을 중심으로—은(는) 코딩 능력과 추론에서 새로운 기준을 세우고 있으며 에이전트 워크플로우이들 모델은 확장된 “사고”와 통합된 도구 사용을 지원합니다. 이를 통해 Claude는 단계별로 추론하고 계산기, 데이터베이스, 기타 서비스에 호출하며, 모든 과정을 투명하게 드러낼 수 있습니다.
이 빠른 시작 가이드에서는 순수한 Claude 4 API를 직접 다뤄 보며 W&B Weave 여러분의 워크플로 안에서 Claude가 어떻게 추론하고 도구를 사용하는지 정확히 추적하고, 시각화하고, 디버깅할 수 있도록 합니다.
다음 내용을 다루겠습니다:
목차
Anthropic API 키 발급 받기Claude 4 Sonnet 및 Opus 가격 안내W&B Weave Claude Sonnet 4와 Claude Opus 4 시작하기1단계: Anthropic API 키2단계: Pip으로 Anthropic과 W&B Weave 설치하기3단계: 추론 스크립트 작성하기 Claude Opus 4와 Claude Sonnet 4의 도구 사용 활용 결론관련 자료
💡
Anthropic API 키 발급 받기
Claude Sonnet 4와 Claude Opus 4를 사용하기 전에, 먼저 접근을 위한 API 키가 필요합니다. Anthropic 계정을 생성한 다음, 다음으로 이동하세요 Anthropic API 콘솔 왼쪽 하단에서 “API Keys”를 클릭하세요.

다음으로 “Create Key” 버튼을 클릭하여 키를 생성할 수 있습니다:

키 이름을 입력한 뒤 “Add” 버튼을 클릭하세요:

준비가 모두 끝났어요.
Claude 4 Sonnet 및 Opus 가격 안내
이 문서 작성 시점(2025년 5월 24일) 기준 Claude 4 Opus와 Sonnet의 가격은 다음과 같습니다(참고용으로 Sonnet 3.7 가격도 함께 제공합니다):

W&B Weave
W&B Weave 모델 출력의 추적과 평가를 간소화하는 방법을 제공해 프로젝트를 한층 강화해 줍니다. Weave를 사용하려면, 먼저 모듈을 임포트한 뒤 프로젝트 이름으로 초기화하세요.
핵심 기능은 @weave.op() 데코레이터로, 추적하려는 함수의 위에 추가합니다. 파이썬에서 데코레이터는 다른 함수에 기능을 덧붙이는 특별한 함수입니다. 이를 추가하면 @weave.op() 함수 정의 위에 해당 데코레이터를 추가하면, Weave가 그 함수의 입력과 출력을 자동으로 기록하도록 지시하게 됩니다. 이렇게 하면 함수에 어떤 데이터가 들어가고 어떤 결과가 나오는지 손쉽게 모니터링할 수 있습니다.
코드를 실행한 뒤에는 Weave 대시보드에서 이 로그를 확인할 수 있으며, 함수 호출에 대한 상세한 시각화와 트레이스를 제공합니다. 이는 디버깅과 실�� 데이터 정리에 도움이 되어, Claude와 함께하는 개발 과정을 더욱 효율적이고 통찰력 있게 만들어 줍니다.
Claude Sonnet 4와 Claude Opus 4 시작하기
시작하기 전에 몇 가지 참고사항:
- 이 튜토리얼의 스크린샷은 제가 Google Colab을 사용하는 모습을 보여줍니다.
- Google Colab의 큰 장점 중 하나는 텍스트 필드에 코멘트와 컨텍스트를 추가할 수 있다는 점입니다:

1단계: Anthropic API 키
가장 먼저 해야 할 일은 Anthropic API 키를 설정하는 것입니다.
이를 위한 코드는 다음과 같습니다:
if "ANTHROPIC_API_KEY" not in os.environ:os.environ["ANTHROPIC_API_KEY"] = "your api key"
"your api key"를 본인의 Anthropic API Key로 바꾸면 됩니다.
2단계: Pip으로 Anthropic과 W&B Weave 설치하기
Claude Sonnet 4와 Claude Opus 4를 사용하려면 Anthropic만 있으면 됩니다. 다만, W&B Weave를 이용해 입력과 출력을 손쉽게 추적하는 방법도 함께 보여드리겠습니다.
지금이 좋은 시기입니다 to Weights & Biases에 가입하기지금 해 두면 튜토리얼을 중단할 필요가 없습니다.
이를 위한 코드는 다음과 같습니다:
!pip install anthropic weave
그런 다음 셀을 실행하세요.

이제 설치는 끝났지만, 사용하려면 여전히 임포트해야 합니다.
Python이 처음이라면기본적으로 라이브러리를 설치할 때는 코드를 내려받는 것뿐입니다. 임포트하면 그 라이브러리를 실제로 사용할 수 있게 됩니다.
💡
3단계: 추론 스크립트 작성하기
이제 Anthropic의 Python SDK를 사용해 Claude Sonnet 4 또는 Claude Opus 4로 추론을 실행할 수 있는 스크립트를 작성해 보겠습니다. 출력 스트리밍 옵션과, 정답 전에 내부 추론 과정을 스트리밍하는 Claude의 extended thinking을 켜는 옵션도 함께 제공하겠습니다.
아래에는 견고한 Python 스크립트가 있습니다 (이와 함께 @weave.op 입력과 출력을 추적할 수 있는) 복사해 활용할 수 있는 스크립트입니다.
import os# Optional: default API key fallback for demo (replace/remove for production!)if "ANTHROPIC_API_KEY" not in os.environ:os.environ["ANTHROPIC_API_KEY"] = "your_claude_api_key"if "WANDB_API_KEY" not in os.environ:os.environ["WANDB_API_KEY"] = "your_wandb_api_key"import anthropicimport osimport weave; weave.init("claude_4")# === CONFIGURABLE ARGS ===streaming = True # Set to True for streaming, False for classic responseenable_thinking = True # Set to True to enable extended thinking# ==== MODEL SELECTION ====# Claude Opus 4 (highest reasoning, highest cost)model = "claude-opus-4-20250514"# Claude Sonnet 4 (fast, less expensive)# model = "claude-sonnet-4-20250514"client = anthropic.Anthropic()@weave.opdef claude_inference(prompt, model, streaming=True, enable_thinking=True):"""Run inference on given prompt with specified Claude model,printing thinking and response as they arrive,and returning the full final response text.Returns: text response as a string, or None on failure"""kwargs = dict(model=model,max_tokens=2048 if enable_thinking else 512,messages=[{"role": "user", "content": prompt}],)if enable_thinking:kwargs["thinking"] = {"type": "enabled", "budget_tokens": 1024}response_text = ""if streaming:with client.messages.stream(**kwargs) as stream:for event in stream:if event.type == "content_block_start":block_type = event.content_block.typeif block_type == "thinking":print("\n[THINKING]: ", end="", flush=True)elif block_type == "text":print("\n[RESPONSE]: ", end="", flush=True)elif event.type == "content_block_delta":d = event.deltaif getattr(d, "type", None) == "thinking_delta":print(d.thinking, end="", flush=True)elif getattr(d, "type", None) == "text_delta":print(d.text, end="", flush=True)response_text += d.textelif event.type == "content_block_stop":print() # Finish this blockelse:response = client.messages.create(**kwargs)for block in response.content:if block.type == "thinking" and block.thinking.strip():print("\n[THINKING]:", block.thinking.strip(), flush=True)elif block.type == "text" and block.text.strip():print("\n[RESPONSE]:", block.text.strip(), flush=True)response_text += block.text.strip()# return response_text if response_text else Nonereturn str(response_text)# === USAGE EXAMPLE ===prompt = ("If a train travels 60 miles per hour for 2.5 hours, how far does it go? ""Show your reasoning step by step.")final_answer = claude_inference(prompt,model=model,streaming=streaming,enable_thinking=enable_thinking)print("\n\n=== FINAL RETURNED RESPONSE ===\n", final_answer)
모델을 바꾸려면 model 변수를 변경하기만 하면 됩니다. Opus 4를 사용하려면 다음과 같이 설정하세요. model = "claude-opus-4-20250514". Sonnet 4를 사용하려면 다음과 같이 설정하세요. model = "claude-sonnet-4-20250514"토글 streaming 그리고 enable_thinking 스크립트 맨 위에서 설정하면, 추론 과정과/또는 스트리밍 출력을 생성되는 즉시 확인할 수 있습니다.
스크립트를 실행하면 Weave에서 모델 출력 결과를 시각화할 수 있는 링크가 표시됩니다!

링크를 클릭하면 모델의 입력과 출력을 확인할 수 있습니다.

Claude는 표준(“비사고”) 모드와 “확장 사고” 모드, 두 가지 방식으로 답변할 수 있습니다. 비사고 모드에서는 대부분의 챗봇처럼 최종 답만 제공합니다. 답이 어떻게 도출되었는지는 보여주지 않으므로, 최종 응답만 확인할 수 있습니다.
Claude는 먼저 내부 추론 과정을 단계별로(“생각 블록”) 보여준 뒤 최종 답을 제공합니다. 이렇게 하면 Claude가 어떤 과정을 통해 응답에 도달했는지 확인할 수 있어, 투명성 확보, 디버깅, 또는 상세한 논리를 요구하는 작업에 유용합니다.
코드에서 다음 설정으로 생각 모드를 활성화했습니다. enable_thinking = True 그리고 API 호출을 구성할 때 다음 블록을 추가합니다:
if enable_thinking:kwargs["thinking"] = {"type": "enabled", "budget_tokens": 1024}
이는 Claude에게 확장 사고를 사용하도록 지시하고, 최소값이 다음과 같은 “사고 예산”을 설정합니다. budget_tokens 는 1,024 토큰입니다. 이 숫자는 Claude가 내부 추론 과정에 사용할 수 있는 출력 토큰의 최대치를 의미합니다. 전체 max_tokens 요청에 대한 값은 다음보다 커야 합니다 budget_tokens, 최종 답변에도 사용할 토큰을 남겨 두어야 하기 때문입니다. 예를 들어 사고 예산이 1,024라면, 당신의 max_tokens 사고와 최종 답변을 모두 담을 수 있도록 2,048 정도로 설정하는 것이 좋습니다.
Claude Opus 4와 Claude Sonnet 4의 도구 사용 활용
Claude 4 Sonnet과 Opus에서 가장 흥미로운 기능 중 하나는 도구 사용입니다. 이는 Claude가 추론 과정에서 계산기나 데이터베이스 같은 사용자 정의 함수를 호출할 수 있는 능력을 뜻합니다. 덕분에 Claude는 일반적인 세계 지식에만 의존하지 않고, 실제 데이터와 로직, 서비스에 기반해 복잡한 프롬프트에 답할 수 있습니다.
예를 들어 비즈니스 분석 시나리오를 생각해 봅시다. “단가가 50달러인 제품을 150개 판매했을 때 총매출은 얼마인가요? 또 평균 월매출과 비교하면 어떤가요?”와 같은 질문이 있을 수 있습니다. Claude 4의 도구 사용을 활용하면, 모델이 곱셈 계산도 수행하고 실제 또는 샘플 매출 데이터를 조회하는 작업까지 한 번에 처리할 수 있어, 사용자가 직접 비즈니스 로직을 코딩할 필요가 없습니다.
이 기능을 사용하려면 Claude API 호출 시 계산기나 데이터 조회기 같은 도구를 등록하면 됩니다. 그런 다음 Claude가 작업을 진행하면서, 예를 들어 “단가 50달러로 150개 판매했을 때 총매출은 얼마이며, 월 평균 매출과 비교하면 어떤가요?” - 한 번의 턴에서 숫자를 계산하기 위해 당신의 함수를 호출하고, 데이터를 조회한 뒤, 그 결과를 바탕으로 추론까지 수행할 수 있습니다.
인터리브드 사고를 활성화하면, Claude는 도구 호출 사이에 일시 중지합니다 중간 분석을 공유하고, 최신 결과를 되짚어 보며, 다음에 무엇을 할지 지능적으로 결정합니다. 이러한 단계별 추론 덕분에 모델은 한 번에 사용할 모든 도구를 예측하도록 강요받는 대신, 어떤 도구를 활용할지 더 깊이 고민할 수 있습니다.
시작 방법은 간단합니다. 함수를 정의하고, 입력과 출력을 설명한 다음, tools 매개변수를 통해 Claude에 전달하세요. 더 높은 투명성과 고급 추론이 필요하다면 제공된 베타 헤더로 인터리브드 사고를 활성화하세요. 그러면 Claude가 사고 블록, 도구 호출, 결과를 번갈아가며 제시하며, 매 단계마다 명확하게 풀이를 구축합니다.
인터리브드 사고가 어떻게 작동하는지 보여주기 위해, 두 가지 모드를 모두 사용한 예시를 공유하겠습니다. 그러면 Weave 내부에서 두 응답이 각각 어떻게 보이는지 확인할 수 있습니다.
import anthropicimport astimport osimport weave; weave.init("claude_4")REVENUE_PER_MONTH = [5000, 6000, 4800, 5300, 5500, 5100, 4950, 5400, 5200, 5100, 5300, 5000]def handle_db_command(command):cmd = command.lower().strip()if cmd == "get average monthly revenue":avg = sum(REVENUE_PER_MONTH) / len(REVENUE_PER_MONTH)return f"{avg:.2f}"elif cmd == "get total yearly revenue":return str(sum(REVENUE_PER_MONTH))elif cmd == "get best month":month = REVENUE_PER_MONTH.index(max(REVENUE_PER_MONTH)) + 1val = max(REVENUE_PER_MONTH)return f"Month {month}, revenue: {val}"else:return "Error: unknown database command"def safe_eval(expr):try:node = ast.parse(expr, mode='eval')for sub in ast.walk(node):if not isinstance(sub, (ast.Expression, ast.BinOp, ast.UnaryOp, ast.Num, ast.Load, ast.operator, ast.unaryop, ast.Constant)):raise ValueError("Unsafe")return eval(expr, {"__builtins__": {}})except Exception as e:return f"Error: {e}"calculator_tool = {"name": "calculator","description": "Safely evaluates arithmetic expressions (e.g. '150 * 50')","input_schema": {"type": "object","properties": {"expression": {"type": "string", "description": "Math expression"}},"required": ["expression"]}}database_tool = {"name": "database","description": ("A company revenue database. Supported commands (use as the `command` field):\n""- 'get average monthly revenue' (Returns yearly average)\n""- 'get total yearly revenue'\n""- 'get best month' (Returns best month and its value)\n""Do NOT use SQL. Only use one of the 3 supported commands."),"input_schema": {"type": "object","properties": {"command": {"type": "string", "description": "Plain database command"}},"required": ["command"]}}PROMPT = ("What's the total revenue if we sold 150 units of product A at $50 each?\n""Also, compare this to our average monthly revenue in our database.\n\n""Instructions for the database tool:\n""- Only use one of these commands for the 'command' field:\n"" * get average monthly revenue\n"" * get total yearly revenue\n"" * get best month\n""Do not use SQL. Only use one of these simple command phrases.")client = anthropic.Anthropic()def execute_tools(blocks):"""Find all tool calls in blocks.Return tool_result dicts to send as messages back to Claude."""tool_results = []for b in blocks:if b.type == "tool_use":if b.name == "calculator":val = safe_eval(b.input['expression'])out = str(val)elif b.name == "database":out = handle_db_command(b.input['command'])else:out = "Error: unknown tool"tool_results.append({"type": "tool_result", "tool_use_id": b.id, "content": out})return tool_results# === ONE MODEL CALL (one assistant reply, may be tool call or final text) ===@weave.op()def claude_message_op(msg_history, interleaved=False):"""Runs a single Anthropic API call (one assistant step).Returns list of blocks (tool calls or text/thinking blocks)."""extra_headers = ({"anthropic-beta": "interleaved-thinking-2025-05-14"} if interleaved else None)response = client.messages.create(model="claude-sonnet-4-20250514",max_tokens=2512,tools=[calculator_tool, database_tool],thinking={"type": "enabled", "budget_tokens": 2000},extra_headers=extra_headers,messages=msg_history,)return response.content# === MAIN CHAIN ===@weave.op()def run_claude_tools_full_chain(prompt_text=PROMPT, interleaved=False, max_loops=5):"""Main loop: calls single-step Claude; if tool call, executes it and calls Claude again etc.Each step is a tracked @weave.op for graph lineage.Returns the full set of blocks and tool call/results for inspection in Weave."""all_steps = []msg_history = [{"role": "user", "content": prompt_text}]for loop in range(max_loops):assistant_blocks = claude_message_op(msg_history, interleaved=interleaved)all_steps.append({"assistant_blocks": assistant_blocks, "msg_history": list(msg_history)})tool_results = execute_tools(assistant_blocks)if not tool_results:breakmsg_history.append({"role": "assistant", "content": assistant_blocks})msg_history.append({"role": "user", "content": tool_results})all_steps[-1]["tool_results"] = tool_resultsreturn all_stepsdef print_blocks(blocks):for block in blocks:if block.type == "thinking":print(f"[THINKING BLOCK]: {block.thinking}\n{'-'*60}")elif block.type == "tool_use":print(f"[TOOL USE BLOCK]: {block.name} with input {block.input} (id={block.id}) {'-'*40}")elif block.type == "text":print(f"[RESPONSE BLOCK]:\n{block.text}\n{'-'*60}")# interleaved = Truesteps = run_claude_tools_full_chain(prompt_text=PROMPT,interleaved=True,max_loops=5)print("\n====== Full Conversation Step Trace ======")for i, step in enumerate(steps):print(f"\n----- Assistant Step {i+1} -----")print_blocks(step["assistant_blocks"])if "tool_results" in step:print(f"\nTOOL RESULTS: {step['tool_results']}")# Optionally, the "final" response blocks (which is the last 'assistant_blocks' returned)final_blocks = steps[-1]["assistant_blocks"]print("\n--- Final Assistant Response ---\n")print_blocks(final_blocks)# interleaved = Falsesteps = run_claude_tools_full_chain(prompt_text=PROMPT,interleaved=False,max_loops=5)print("\n====== Full Conversation Step Trace ======")for i, step in enumerate(steps):print(f"\n----- Assistant Step {i+1} -----")print_blocks(step["assistant_blocks"])if "tool_results" in step:print(f"\nTOOL RESULTS: {step['tool_results']}")# Optionally, the "final" response blocks (which is the last 'assistant_blocks' returned)final_blocks = steps[-1]["assistant_blocks"]print("\n--- Final Assistant Response ---\n")print_blocks(final_blocks)
다음과 함께 실행할 때 interleaved=True, Claude는 내부 추론, 도구 호출, 도구 결과, 최종 텍스트 응답을 번갈아가며 진행합니다. 모든 도구 호출을 한 번의 응답에서 계획하는 대신, 모델은 과정을 단계별로 해결합니다. 이 접근 방식은 투명성을 높일 뿐만 아니라, Claude가 추론을 이어 가면서 도구 호출 결과를 되짚어 보고 반영할 수 있게 해 주어, 답이 어떻게 구성되는지 단계별로 명확하게 보여 줍니다.
이 파이썬 코드는 먼저 사용자 정의 도구 두 개(계산기, 구현 방식: 통해)를 등록하여 이 오케스트레이션을 관리합니다. safe_eval(), 그리고 …에 의해 처리되는 시뮬레이션된 데이터베이스 쿼리 인터페이스 handle_db_command(). 각 도구는 기능뿐 아니라 명시적인 입력 스키마로도 설명되므로, Claude가 이러한 함수를 호출할 때 어떤 종류의 인수를 제공할 수 있는지 명확히 알 수 있습니다.
스크립트를 실행한 뒤에는 Weave 내부에서 결과를 확인할 수 있습니다.

Weave 내부에서 다음에 대한 상위 수준 호출과 함께 모두 시각화할 수 있습니다 run_claude_tools_full_chain—예를 들어 프롬프트, 도구 사용, 어시스턴트 결정—뿐만 아니라 Claude가 생성한 개별 추론(‘생각’), 도구 호출, 텍스트 응답 블록까지 모두 기록합니다. 이를 통해 완전한 의미적 트레이스를 확보하고, 각 단계에서 대화를 디버그하고 비교하며 감사를 수행할 수 있습니다.
결론
몇 단계만 거치면 Anthropic Python SDK로 Claude 4를 설정하고, W&B Weave와 통합하여 모델의 추론과 도구 사용 전반을 완전히 가시화할 수 있습니다. 이 워크플로는 모든 상호작용, 도구 호출, 중간 단계를 추적할 수 있게 해 주어, 디버깅과 최적화가 쉬워지고 Claude가 답에 이르는 과정을 정확히 이해할 수 있습니다.
이 기반 위에서 도구를 사용하는 대규모 언어 모델이 구동하는 복잡한 AI 워크플로를 신뢰성 있게 구축, 테스트, 모니터링할 수 있습니다. 프로젝트가 발전함에 따라 파이프라인을 지속적으로 개발하고, 분석하며, 개선하세요. 추가 팁과 고급 사용법은 아래 자료를 참고하세요.
관련 자료
Attribute-Value Extraction With GPT-3 and Weights & Biases
In this article, we learn how to fine-tune OpenAI's GPT-3 for attribute-value extraction from products, looking at the challenges and how to overcome them.
Automating Change Log Tweets with Few-Shot Learning and GPT-3
A text summarization recipe using OpenAI GPT-3's few-shot learning and Weights & Biases
o1 model Python quickstart using the OpenAI API
Getting set up and running the new o1 models in Python using the OpenAI API. We'll be working with o1-preview.
Add a comment