byteforce

CPN 한국어 자습서 · 러닝패스 2 / 4 — Building with the Claude API

도구 사용

메시지 블록 다루기

Handling message blocks

스키마를 요청에 담아 Claude를 호출하면, 처음 보는 구조의 응답이 옵니다. 지금까지는 contenttext 블록 하나뿐이었지만, 도구를 쓰면 contenttext 블록 + tool_use 블록의 리스트가 됩니다. 그리고 대화 기록은 우리가 직접 관리해야 합니다.

전체 내레이션영상 나레이션 한국어 번역 (전체)

Stephen Grider · Anthropic 기술 스태프

3단계입니다. 이제 JSON 스키마와 사용자 메시지를 담아 Claude를 호출합니다. 서버에서 평소처럼 요청을 보내되, 이번엔 이 도구 스키마를 함께 포함합니다. 그러면 Claude는 자신에게 사용할 수 있는 도구가 있다는 걸 알게 됩니다. 노트북으로 돌아가, 이전에 만든 헬퍼 함수(chat 같은)를 쓰지 않고 손으로 직접 요청해 봅니다.

새 셀을 만들어 빈 메시지 리스트를 두고, 거기에 사용자 메시지를 직접 추가합니다. role은 user, content는 “What is the exact time, formatted as HH:MM:SS?”입니다.

그 아래에서 client.messages.create를 호출합니다. 모델, max_tokens, 메시지 리스트를 지정하고, 이번엔 Claude에 도구가 있음을 알리는 tools 키워드 인자를 더합니다. 이건 리스트이고, 우리가 만든 모든 JSON 스키마가 들어갑니다. 지금은 하나뿐 — get_current_datetime_schema입니다. 맨 아래에서 response를 출력해 실행합니다.

그러면 지금까지 본 적 없는 구조의 응답이 돌아옵니다. 이전의 모든 메시지는 content가 리스트였고 그 안에 text 블록 하나가 있었습니다. text 블록 안에는 사용자에게 보여 줄 텍스트가 들어 있었죠. 그런데 도구를 쓰니 이 content 리스트가 조금 다릅니다. 리스트 안에 두 번째 블록 — tool_use 블록 — 이 생깁니다.

이게 우리의 첫 멀티 블록 메시지입니다. 메시지는 assistant 메시지이거나 user 메시지입니다. 보통은 메시지 안에 약간의 텍스트가 들어 있고, 지금까지 본 건 그게 전부였습니다. 하지만 텍스트 외에도 다른 종류의 데이터가 메시지에 담길 수 있습니다. Claude가 도구를 쓰기로 하면, 아주 흔히 text 블록과 tool_use 블록을 둘 다 담은 assistant 메시지를 보내옵니다.

text 블록은 사용자에게 보여 줘 무슨 일이 일어나는지 알려 주는 텍스트입니다 — 예: “현재 시각을 찾아드릴게요. 정보를 가져오겠습니다.” 그리고 tool_use 블록은, 우리 개발자에게 Claude가 도구를 쓰고 싶어 한다는 신호입니다. 이 블록은 호출하려는 도구 함수의 name을 적고(여기선 get_current_datetime), 그 함수에 넘길 input(인자들)도 함께 줍니다.

다음 단계는 알맞은 도구를 찾아 실제로 실행하는 것입니다. 하지만 그 전에, content 리스트에 여러 블록이 들어 있다는 점과 관련해 꼭 처리해야 할 중요한 게 있습니다. 다시 떠올려 봅시다 — 우리는 서버에서 Claude로 요청을 보냈고, 그 요청엔 도구 스키마를 포함한 사용자 메시지 하나가 있었습니다. 이제 응답을 받았고, 그 안엔 text 블록과 tool_use 블록을 담은 assistant 메시지가 있습니다.

여기서 Claude에 대해 기억할 게 있습니다. Claude는 메시지 기록이나 대화에 관한 어떤 것도 저장하지 않습니다. 대화나 기록을 유지하고 싶다면 직접 관리해야 합니다. 즉, 나중에 이 tool_use 블록을 받아 실제 함수를 호출하고 Claude에 다시 응답할 때, 결정적으로 전체 대화 기록을 포함해야 합니다 — 코스 내내 해 온 것처럼요. 이번엔 한 가지만 다릅니다. 메시지가 여러 블록을 담을 수 있다는 점입니다.

이 메시지들을 관리하기 위해, 응답을 받는 맨 아래 셀로 가서 response를 리스트에 새 assistant 메시지로 추가합니다. response를 지우고, messages.append로 role은 assistant, content는 방금 받은 응답의 content 블록 리스트 그대로 — 즉 response.content — 를 넣습니다.

이제 messages를 출력해 셀을 다시 실행하면, 처음의 user 메시지가 있고, 그다음 assistant 메시지가 있으며, 그 안에 text 블록과 tool_use 블록이 들어 있습니다. 이렇게 우리는 여러 메시지의 모든 블록을 포함해 대화 기록을 올바르게 쌓아 갑니다. (참고: 나중에 add_user_message·add_assistant_message 두 헬퍼를, 이렇게 여러 블록을 다룰 수 있게 갱신할 것입니다. 지금은 단일 text 블록만 지원하거든요.)

이 장에서 배우는 것What you'll learn

약 6분
1

도구 사용 3단계 — 스키마를 tools로 포함해 Claude 호출

2

client.messages.create(..., tools=[...])를 손으로 직접

3

응답 contenttext 블록 + tool_use 블록의 리스트로 옴

4

tool_use 블록 = 도구를 쓰겠다는 신호 — name·input 포함

5

Claude는 기록을 저장하지 않음 — 대화 기록은 직접 관리

6

messages.append({"role":"assistant", "content": response.content})

먼저 짚고 갈 용어
블록(block / part)
메시지 content 리스트의 한 항목. text·tool_use 등 종류가 있다. ‘part’라고도 부른다.
text 블록
사용자에게 보여 줄 텍스트를 담는 블록. 지금까지 본 응답은 모두 이 한 종류였다.
tool_use 블록
Claude가 도구를 쓰겠다는 신호. 호출할 도구 name과 넘길 input(인자)을 담는다.
stop_reason
응답이 멈춘 이유. 도구를 쓰려 하면 "tool_use"가 된다 — 멀티턴 루프의 핵심 신호.
대화 기록 관리
Claude는 상태를 저장하지 않음. 다음 요청에 전체 messages를 매번 다시 보내야 한다.

스키마를 담아 호출하기

Call with tools

3단계입니다. 평소처럼 요청을 보내되, 이번엔 tools 키워드 인자로 스키마를 포함합니다. 헬퍼 없이 손으로 직접 호출해 봅니다.

001_tools.ipynb · tools를 포함한 요청
messages = []

messages.append({
    "role": "user",
    "content": "What is the exact time, formatted as HH:MM:SS?",
})

response = client.messages.create(
    model=model,
    max_tokens=1000,
    messages=messages,
    tools=[get_current_datetime_schema],   # ← 도구가 있음을 알림
)
response
tools는 리스트

tools에는 우리가 만든 모든 스키마가 들어갑니다. 지금은 하나 — get_current_datetime_schema — 뿐입니다. 이걸로 Claude는 “쓸 수 있는 도구가 있다”는 걸 알게 됩니다.

처음 보는 응답 구조

A multi-block message

돌아온 응답은 지금까지와 다릅니다. content 리스트 안에 text 블록뿐 아니라 tool_use 블록이 함께 들어 있습니다 — 우리의 첫 멀티 블록 메시지입니다.

출력 · 멀티 블록 응답
Message(
    id='msg_01YMMjWw5TFYK1bUc3afhKLM',
    content=[
        TextBlock(
            text="I'll get the current time for you in the HH:MM:SS format.",
            type='text',
        ),
        ToolUseBlock(
            id='toolu_01NJdk5KQk3CxTr9EkcQxKpG',
            input={'date_format': '%H:%M:%S'},
            name='get_current_datetime',
            type='tool_use',
        ),
    ],
    stop_reason='tool_use',   # ← 도구를 쓰려 함
    type='message',
)
Assistant 메시지의
content 리스트
text 블록
“현재 시각을 찾아드릴게요. 정보를 가져오겠습니다.” — 사용자에게 보여 줄 텍스트입니다.
tool_use 블록
“도구를 쓰겠다”는 신호. 호출할 name(get_current_datetime)과 넘길 input({date_format: "%H:%M:%S"})을 담습니다.
tool_use 블록

text 블록은 사용자에게 보여 줄 텍스트, tool_use 블록은 “도구를 쓰겠다”는 신호입니다. 후자는 호출할 도구 name과 넘길 input(인자)을 담고, stop_reason"tool_use"가 됩니다.

대화 기록에 응답 쌓기

Append to history

Claude는 대화 상태를 저장하지 않습니다. 기록은 우리가 직접 관리해야 합니다 — 다음 요청에 전체 messages를 다시 보내야 하죠. 받은 응답을 assistant 메시지로 추가합니다.

응답을 기록에 추가 · response.content 통째로
messages.append({
    "role": "assistant",
    "content": response.content,   # ← 블록 리스트를 통째로
})

messages

이제 messages를 출력하면 user 메시지에 이어 assistant 메시지가 있고, 그 안에 두 블록이 모두 들어 있습니다.

출력 · 블록을 포함한 대화 기록
[
    {'role': 'user', 'content': 'What is the exact time, formatted as HH:MM:SS?'},
    {
        'role': 'assistant',
        'content': [
            TextBlock(text="I'll get the current time for you...", type='text'),
            ToolUseBlock(id='toolu_01NJ...', input={'date_format': '%H:%M:%S'},
                         name='get_current_datetime', type='tool_use'),
        ],
    },
]
핵심

차이는 하나뿐입니다 — 메시지가 여러 블록을 담을 수 있다는 것. response.content(블록 리스트)를 그대로 content에 넣어 기록을 올바르게 쌓습니다. (헬퍼 add_assistant_message 등은 나중에 멀티 블록을 지원하도록 갱신합니다.)

인스펙터로 확인 + 점검

Inspect & check

아래 인스펙터로 블록을 눌러 역할을 확인하고, 도구 응답과 일반 응답을 비교해 보세요. 그다음 퀴즈로 정리합니다.

메시지 블록 인스펙터 · 블록을 눌러 역할을 확인하세요
role: assistant

도구를 쓰면 content여러 블록의 리스트가 되고 stop_reasontool_use가 됩니다. 일반 응답은 text 블록 하나stop_reasonend_turn입니다.

핵심 정리
  • 스키마를 tools로 포함해 client.messages.create 호출.
  • 도구를 쓰면 contenttext 블록 + tool_use 블록의 리스트가 된다.
  • tool_use 블록은 도구 nameinput을 담고, stop_reasontool_use.
  • Claude는 기록을 저장하지 않음 → response.content를 assistant 메시지로 직접 추가.

Q1도구를 쓰는 응답에서 content 리스트에 들어 있는 것은?

Q2tool_use 블록이 담는 정보는?

Q3응답을 받은 뒤 대화 기록에 무엇을 추가하나요?

MEMBER SESSION REQUIRED · REGISTRATION IS FREE

여기부터는 등록한 분에게 열립니다.

전 코스는 계속 무료입니다. 등록하면 이 코스의 남은 76개 레슨을 끝까지 읽을 수 있습니다.

등록하고 이어서 읽기

이미 등록하셨다면 그때 쓰신 이메일을 넣어 주세요.