CPN 한국어 자습서 · Claude Certified Developer — Foundations Prep
2-4 · 도구 사용과 스키마 설계
Tool Schemas Claude Selects Correctly: Definition, Loop, and Calling Patterns
지금까지는 Claude가 내놓는 답의 형태를 다듬는 일을 다뤘습니다 — 요청을 어떻게 틀 짓고, 예시를 어떻게 주고, 원하는 출력에 맞는 기법을 어떻게 고르는지. 도구 사용은 결이 조금 다릅니다. 좋은 답이 나오도록 문장을 조율하는 대신, 여러 동작을 건네주고 그중 알맞은 하나를 Claude가 고르도록 맡깁니다. 그리고 그 선택은 스키마에 무엇을 적었는지에 거의 전적으로 달려 있습니다. 이 레슨에서는 도구 사용 루프(Claude와 코드가 주고받는 반복 흐름)가 작동하는 방식부터 시작해, 스키마를 어떻게 설계하면 Claude가 도구를 정확히 고르는지 살펴봅니다.
이 장에서 배우는 것What you'll learn
약 29분도구 사용 루프 — Claude가 도구를 고르고, 코드가 실행하고, 결과를 되돌리는 6단계
tool_use ↔ tool_result — 같은 ID로 짝을 맞추는 블록 짝짓기 규칙
스키마의 세 부분 — 이름 · 설명 · 입력 형식, 그리고 설명이 선택을 좌우하는 이유
스키마 설계의 다섯 가지 판단 — 순차 호출과 병렬 호출이 갈리는 지점
설명이 겹쳐 도구를 잘못 고르는 실패와 제외 조건으로 고치는 법
직접 스키마를 쓰는 대신 MCP 서버에 연결하는 선택지
도구 사용에서 가장 흔한 오해는 Claude가 직접 도구를 실행한다고 생각하는 것입니다. 실제로는 조금 다릅니다. Claude는 건네받은 도구 정의를 읽고, 상황에 맞는 도구를 고른 다음, 어떤 입력으로 무엇을 실행할지 애플리케이션에 알려 줍니다. 실제 실행은 코드가 하고, 그 결과를 다시 Claude에 돌려주면, Claude가 그 결과를 받아 이어 갑니다.
이 주고받음은 프로덕션(실서비스 환경)에서 특히 중요합니다. 애플리케이션이 결과를 제대로 되돌려 주지 않으면 Claude는 요청한 데이터를 끝내 받지 못하고, 루프가 거기서 끊깁니다. Claude가 맡는 일과 코드가 맡는 일의 경계 — 도구 사용에서 생기는 버그 대부분이 바로 이 경계에서 나옵니다.
아래 여섯 단계를 눌러 가며 각 단계에서 무슨 일이 일어나는지 확인해 보세요.
스키마 정의Define schema
이름, 설명, 입력 형식으로 도구 하나를 정의합니다. Claude는 이 정의를 읽고 도구를 부를지, 언제 부를지 판단합니다. 루프는 자동으로 진행되지 않아서, 네 번째 단계(도구 실행)는 코드가 직접 채워야 합니다. 도구 선택이 반복해서 어긋난다면 고칠 곳은 대개 이 스키마 정의 단계입니다.
메시지 전송Send message
코드가 도구 정의와 사용자 입력을 함께 담아 Claude에 메시지를 보냅니다.
tool_use 블록tool_use block
Claude가 도구 이름·고유 ID·넘길 입력값을 담은 tool_use 블록을 내보냅니다. 이때 API 응답은 stop_reason: tool_use로 돌아옵니다.
도구 실행Execute tool
코드가 그 입력값으로 도구를 실행합니다. 이 시점에 Claude의 턴은 이미 끝나 있습니다 — Claude가 연결을 붙잡고 서버를 기다리는 것이 아닙니다. 모델은 호출과 호출 사이에 상태를 기억하지 않습니다(stateless). 이어서 진행하려면 이전 메시지들에 도구 결과를 더한 새 API 요청을 보냅니다.
결과 반환Return result
원래 tool_use의 ID를 참조하는 tool_result 블록에 결과를 담아 돌려줍니다.
Claude가 이어감Claude continues
Claude는 도구 결과를 다음 응답의 맥락으로 삼아 이어 갑니다. 또 다른 tool_use 블록을 낼 수도 있고, 그대로 대화를 마칠 수도 있습니다.
Claude는 도구를 고르는 쪽이고, 도구를 실행하는 쪽은 코드입니다. 그래서 실행 결과를 다시 돌려주는 네 번째~다섯 번째 단계를 코드가 빠뜨리면, 아무리 스키마가 좋아도 루프가 이어지지 않습니다.
도구 사용 대화는 일반 텍스트가 아니라 구조화된 블록으로 이뤄집니다. 어시스턴트 턴과 사용자 턴은 각각 블록의 목록이고, 도구 사용 세션에서는 네 가지 블록이 일을 나눠 맡습니다.
API는 이 블록들 사이의 짝짓기를 강제합니다. 어시스턴트 턴의 tool_use 블록마다, 바로 다음 사용자 턴에 같은 ID를 지닌 tool_result 블록이 답으로 와야 합니다. ID가 맞지 않거나, 결과가 빠지거나, 턴 순서가 어긋나면 요청은 검증에서 실패합니다. 이건 프롬프트를 손봐서 해결할 수 있는 문제가 아니라 구조의 문제라서, 매 요청마다 코드가 이 순서를 정확히 만들어야 합니다.
BLOCK RULES — 블록별로 코드가 지켜야 할 규칙
| 블록 | 코드가 지켜야 할 규칙 |
|---|---|
| text | Claude는 같은 턴에서 text 블록과 tool_use 블록을 함께 낼 수 있습니다. 그 턴을 대화 기록에 더할 때 text 블록을 포함한 content 배열 전체를 그대로 남겨 둡니다. text 블록을 빠뜨리면 Claude가 이후 턴에서 기대는 맥락이 어긋납니다. |
| tool_use | tool_use 블록마다 바로 다음 사용자 턴에 tool_result 블록으로 답해야 합니다. 그 tool_result에는 같은 ID가 담겨야 합니다. 이 짝이 맞지 않으면 API가 다음 요청을 거부합니다. |
| tool_result | tool_use_id 값이 원래 tool_use 블록과 정확히 일치해야 합니다. Claude는 이 ID로 각 결과를 그것을 부른 호출과 연결합니다. 한 어시스턴트 턴이 여러 도구를 호출하고 결과가 다른 순서로 도착할 때 특히 중요합니다. 실패한 호출에는 is_error를 true로 표시할 수 있습니다. |
| thinking | 이후 턴에서 이 블록을 손대지 않고 그대로 다시 API에 넘겨야 합니다. 서명(signature)이 추론이 바뀌지 않았음을 확인하기 때문에, 편집하거나 요약하면 서명이 깨지고 API가 메시지를 거부합니다. 가려진(redacted) thinking 블록도 규칙은 같습니다 — 내용이 암호화되어 사람이 읽을 수 없더라도 받은 그대로 되돌려 줍니다. |
기억할 불변 규칙은 하나입니다 — 어시스턴트 턴의 모든 tool_use에는 바로 다음 사용자 턴에 ID가 일치하는 tool_result가 있어야 합니다. tool_result가 빠지거나 뒤쪽 턴에 나타나면 API 검증 오류가 납니다.
스키마는 도구 하나를 정의하는 세 부분으로 이뤄집니다 — 이름(name), 설명(description), 입력 형식(input_schema). 이 중에서 Claude가 도구를 맞게 고르는지 아닌지를 가르는 것은 설명입니다.
SCHEMA · THREE PARTS — 스키마의 세 부분
| name | 짧고 구체적인 식별자. 예를 들어 get_account_balance가 get_data보다 Claude에게 훨씬 쓸모 있습니다. |
|---|---|
| description | Claude가 이 도구가 필요한지 아닌지를 판단하며 읽는, 가장 중요한 부분. 언제 쓰는지와 언제 쓰지 않는지 두 갈래로 적는 것이 좋습니다. "use this to find information"처럼 적으면 무언가를 찾아 오는 다른 어떤 도구와도 구분되지 않아 잘못 선택됩니다. 반면 "특정 계정 ID의 현재 잔액을 조회할 때 쓰고, 거래 내역에는 쓰지 말 것"처럼 적으면 Claude에게 제외 조건이 생겨 판단 근거가 분명해집니다. |
| input_schema | 도구 함수가 받는 파라미터를 JSON Schema로 정의합니다. Claude가 도구를 제대로 부르는 데 꼭 필요한 값은 required로 표시하고, 없어도 도구가 동작하는 값은 선택(optional)으로 둡니다. 도구끼리 파라미터 형태가 겹치는 것이 잘못된 도구 호출의 가장 흔한 원인입니다. |
스키마는 Claude가 어떤 도구를 부를지, 어떤 인자를 넘길지, 답하기에 충분한 정보가 있는지를 판단하며 읽는 자료입니다. 스키마가 모호하거나 설명이 부족하거나 필수 필드가 빠져 있으면, 문법상으로는 멀쩡해 보여도 엉뚱한 도구를 고르거나 잘못된 입력을 넘기거나 불필요하게 루프를 반복하는 호출이 나옵니다. 아래 다섯 가지 판단이 실제 조건에서 구현이 예측 가능하게 동작할지를 가릅니다. 순차 호출과 병렬 호출이 갈리는 지점도 함께 적었습니다.
FIVE DECISIONS — 스키마 설계의 다섯 가지 판단
| 판단 | 다루는 법 | 왜 중요한지 |
|---|---|---|
| 하위 작업 의존성 | 한 도구의 출력이 다음 도구의 입력이 되면, 첫 결과가 돌아와야 두 번째 호출을 만들 수 있으므로 순차로 실행합니다. 서로 독립적인 작업이라면 Claude가 한 턴에서 여러 tool_use 블록을 내도록 도구 세트를 짜고, 코드가 동시에 실행할 수 있습니다. | 스키마 설계 자체를 바꾸는 유일한 판단입니다. 지금의 Claude 모델은 호출이 서로 독립적이면 병렬 호출을 기본으로 합니다. 실제 의존 관계가 있으면 별도 턴으로 나눠, 다음 호출을 만들기 전에 첫 결과가 준비되게 합니다. 필요하면 disable_parallel_tool_use로 한 턴에 도구 하나만 부르도록 강제할 수 있습니다. |
| 필수 필드 | 그 값이 없으면 호출 자체가 말이 되지 않을 때만 필수로 표시하고, 입력 형식의 required 배열에 넣습니다. | 모든 필드를 필수로 잡으면 Claude가 채울 근거가 없는 필드까지 값을 지어내게 됩니다. required 배열은 어떤 입력이 반드시 있어야 하는지 Claude에게 알려 주는 자리입니다. |
| 선택 필드 | 적당한 기본값이 있거나, 값이 없다는 사실 자체가 의미를 갖는 파라미터는 선택으로 둡니다. required 배열에서 빼고 함수 시그니처에 기본값을 줍니다. | 선택 필드는 Claude가 갖고 있지 않은 정보를 추측하는 대신 그냥 비워 둘 수 있게 합니다. 선택이어야 할 필드를 필수로 표시하면 호출마다 값을 지어내야 하고, 잘못된 입력으로 이어질 수 있습니다. |
| 설명 길이 | 도구 하나당 서너 문장으로 무엇을 하는지, Claude가 언제 이 도구를 집어야 하는지, 무엇을 돌려주는지를 적습니다. 형식이 중요하면 올바른 입력 예시도 함께 넣습니다. | 설명이 너무 짧으면 다른 도구와 구분할 신호가 부족해 Claude가 추측합니다. 너무 길면 정작 언제 부를지에 관한 조건이, Claude가 판단 시점에 참고하지 않는 세부 설명에 묻힙니다. |
| 겹치는 파라미터 형태 | 두 도구가 같은 파라미터 형태를 받으면, 각 설명에 그 도구가 맡은 영역이나 상황을 밝히는 구분 문장을 더합니다. | Claude는 이름과 설명으로 방향을 정하고, 파라미터 형태는 보조 신호로만 씁니다. 시그니처가 똑같으면 판단이 설명 하나에만 기대게 되고, 비슷한 설명끼리는 구분되지 않습니다. |
아래는 도구 사용 구현에서 흔히 나타나는 패턴을 바탕으로 만든 설명용 예시입니다. 도구 이름·설명·테스트 결과는 선택 구분 원리를 보여 주려고 구성한 것으로, 특정 실제 시스템에서 가져온 값이 아닙니다.
한 개발자가 도구 두 개를 등록합니다 — search_knowledge_base와 get_cached_result. 이름은 서로 다르지만, Claude의 도구 선택은 설명에 크게 기웁니다. 설명이 겹치면 이름만으로는 구분되지 않습니다.
두 도구 모두 설명이 "use this to find information"으로 시작했고, 제외 조건이 없다 보니 개발 중 테스트에서 애매한 입력에 대해 Claude가 자주 엉뚱한 도구를 골랐습니다. 문제는 선택을 판단하는 그 지점에서 두 설명이 Claude에게 똑같아 보인다는 데 있습니다. 해결은 각 설명에 한 문장씩을 더하는 것입니다.
각 설명에 제외 조건 한 문장을 더한 버전
search_knowledge_base: "Use this to search the knowledge base when the user asks a question that requires looking up current information. Do not use this if the result of a prior search in this session already covers the question." get_cached_result: "Use this to retrieve a result that was already fetched during this session. Only use this if search_knowledge_base was called earlier in this conversation for the same query."
제외 조건은 Claude에게 똑같아 보이던 두 선택지 대신 판단 규칙을 줍니다. 다만 이 조건은 매 요청에 대화 기록 전체가 함께 넘어온다는 전제에 기댑니다. 앞선 턴이 잘리거나 빠지면 Claude가 그 조건을 확인할 수 없고, 제외 논리도 조용히 작동하지 않게 됩니다.
등록하는 도구가 하나 늘 때마다 Claude가 따져야 할 범위도 넓어집니다. 그래서 이 방식은 도구들이 실제로 서로 다를 때에만 효과가 있습니다.
| 잘 맞는 경우 | 설명이 구체적이고 제외 조건이 분명할 때. Claude를 알맞은 도구로 안정적으로 보냅니다. |
|---|---|
| 잘 맞지 않는 경우 | 비슷한 일을 하는 두 도구를, 갈수록 긴 설명으로 억지로 떼어 놓아야 하는 상황. 이때는 둘을 type 파라미터 하나를 둔 단일 도구로 합치는 편이 낫습니다. |
앞의 내용은 전부 스키마를 직접 쓴다는 전제였습니다 — 이름, 설명, 입력 형식, 그리고 Claude가 tool_use 블록을 낼 때 실행되는 함수까지. 그런데 많은 연동에서는 그럴 필요가 없습니다. MCP(Model Context Protocol)는 도구 정의와 실행을 애플리케이션 코드 밖 전용 서버로 옮기는 표준 통신 방식입니다. 원하는 서비스의 MCP 서버가 이미 있다면, 연동을 직접 만드는 대신 그 서버에 연결하면 됩니다.
GitHub 연동을 예로 들어 보겠습니다. GitHub은 저장소, 풀 리퀘스트, 이슈, 프로젝트 등 여러 기능을 제공합니다. 이 모듈에서 배운 스키마 방식으로 전체 연동을 만들려면, 기능 하나하나에 스키마와 실행 함수를 쓰고 GitHub API가 바뀔 때마다 유지해야 합니다. GitHub용 MCP 서버는 그 일을 이미 해 두었습니다. 애플리케이션은 서버에 연결해 사용 가능한 도구 목록 전체를 받고, Claude는 지금까지 다뤄 온 것과 똑같은 설명 기반 방식으로 그중에서 도구를 고릅니다. 작동하는 방식 자체는 같습니다. 달라지는 것은 그 도구 정의의 작성자와 소유자입니다.
이 모듈 앞에서 만든 루프는 MCP를 들여도 바뀌지 않습니다. Claude는 여전히 tool_use 블록을 내고, 애플리케이션은 여전히 도구를 실행해 tool_result를 돌려주며, 블록 짝짓기 규칙도 그대로 적용됩니다. 달라지는 건 준비 단계뿐입니다. 직접 쓴 스키마를 등록하는 대신, MCP 클라이언트가 서버에 ListToolsRequest를 보내 도구 목록 전체를 받아 Claude에 전달합니다. Claude가 보기에 이 도구들은 직접 쓴 도구와 구분되지 않습니다.
MCP 서버는 지금 턴에서 쓰지 않는 도구라도 그 정의를 컨텍스트 창(context window)에 더합니다. 여러 서버를 한꺼번에 연결하면 첫 메시지가 오기도 전에 도구 정의만으로 예산을 씁니다. 실제로 쓰는 서버만 등록하고, 여러 서버를 연결한다면 컨텍스트 비용을 창 한도와 견줘 확인해 봅니다.
API MCP 커넥터를 쓴다면, 도구 배열의 mcp_toolset 객체로 로딩 비용을 조절합니다. mcp_toolset에는 서버의 모든 도구에 적용되는 default_config 블록이 있고, 도구 이름을 키로 한 설정으로 개별 도구를 덮어쓸 수 있습니다. 컨텍스트 비용과 관련해 두 가지 설정이 중요합니다.
defer_loading — default_config나 개별 도구 항목에 두는 불리언 값으로, 모델이 필요로 할 때까지 도구 정의를 미룹니다. 도구가 많은 서버를 연결할 때 처음 드는 컨텍스트 비용을 줄여 줍니다.enabled — 개별 도구를 켜고 끄는 불리언 값으로, 서버는 등록하되 모델에 보이는 도구는 원하는 것만 남길 수 있습니다.MCP 커넥터를 쓰려면 요청에 mcp-client-2025-11-20 베타 헤더를 설정해야 합니다. 이 헤더가 없으면 여기 설명한 대로 mcp_toolset 설정이 적용되지 않습니다.
이 단계에서 알아 둘 나머지 하나는, 클라이언트가 서버와 실제로 이야기를 주고받는 방식입니다. MCP는 두 가지 전송 방식(transport) 중 하나로 통신하고, 어느 쪽을 쓰는지는 서버가 어디에 있는지에 달려 있습니다.
stdio를 씁니다. 애플리케이션이 서버를 하위 프로세스로 띄우고 표준 입출력으로 주고받습니다.Streamable HTTP를 씁니다. 애플리케이션이 네트워크로 연결해, 클라이언트→서버 메시지는 POST로 보내고 서버가 먼저 보내는 메시지는 GET 기반 SSE 스트림(선택)으로 받습니다.예전의 SSE 전용 전송 방식도 있지만 지원이 종료되는 중이라, 새 연동은 Streamable HTTP를 씁니다. Anthropic의 API MCP 커넥터를 쓴다면 짚어 둘 제약이 하나 있습니다 — 커넥터로는 HTTP로 노출된 서버만 지원되고, stdio 서버는 SDK로 MCP 클라이언트 연결을 직접 관리해야 합니다. 연결이 맺어지고 도구 정의를 받고 나면, 그다음부터 애플리케이션 코드는 두 전송 방식을 똑같이 다룹니다.
WHEN TO USE WHICH — 언제 무엇을 쓸까
| MCP를 쓸 때 | 필요한 서비스에 잘 관리되는 MCP 서버가 이미 있을 때 (필요한 기능을 실제로 다루는지, 서비스의 현재 API에 맞춰 계속 관리되는지 확인). 그 스키마를 직접 쓰고 소유하는 건 추가 능력 없이 구현 부담만 늘립니다. Claude API MCP 커넥터는 원격 서버만 지원합니다. 로컬 stdio 서버는 Claude Desktop이나 Claude Code를 클라이언트로 써야 하고, API로 바로 연결할 수 없습니다. |
|---|---|
| 직접 쓸 때 | 쓰려는 경우를 다루는 MCP 서버가 없거나, 범용 서버가 주지 못하는 도구 범위·설명 품질의 정밀한 통제가 필요할 때. 다만 범위 통제 때문에 직접 작성으로 기울기 전에, API MCP 커넥터가 MCPToolset 설정으로 서버별 도구 허용·차단 목록을 지원한다는 점을 기억해 둡니다. 직접 작성은 설명 품질에는 여전히 근거가 있지만, 범위 통제만을 위해서라면 늘 그렇지는 않습니다. |
| 둘을 함께 쓸 때 | 넓은 범위는 MCP 서버로 확보하고, 실제로 자주 부르는 특정 도구에는 앞에서 다룬 설명 다듬기 규율을 적용합니다. 둘은 배타적이지 않습니다 — 서버가 범위를 주고, 설명이 필요한 곳의 정밀함을 줍니다. 먼저 MCPToolset 도구 허용 목록으로 Claude가 따질 범위를 좁힌 다음 설명을 다듬습니다. 도구 세트를 좁히는 일과 설명을 분명하게 다듬는 일은 별개라서, 둘 다 쓰는 것이 좋습니다. |
스키마가 멀쩡해 보이는데도 실패하는 경우가 있습니다. 파라미터에 타입이 잡혀 있고 정상 경로 테스트를 통과했다면 구조가 유효하다는 것까지는 알 수 있습니다. 하지만 설명이 겹치는 두 도구의 경계에 가까운 입력이 들어왔을 때, Claude가 둘 중 하나를 안정적으로 고를 수 있는지까지는 알려 주지 않습니다. 바로 이 지점이 초기 테스트에서 놓치기 쉽고, 프로덕션에서 드러날 가능성이 가장 큰 실패 유형입니다.
아래 대화는 개발자 디버깅 대화에서 흔한 패턴을 바탕으로 구성한 것입니다. 설명이 겹친다는 사실이 드러나는 진단의 순간을 보여 주려는 것으로, 특정 코드 리뷰를 그대로 옮긴 것은 아닙니다.
한 개발자가 코드 리뷰를 하던 중, 아침부터 붙들고 있던 잘못된 도구 선택 문제를 디버그 세션에 붙여 넣습니다. 시니어 개발자가 던진 한 가지 질문이 문제 전체를 다시 보게 합니다.
"Claude가 자꾸 search_docs를 부르는데, 답은 이미 맥락 안에 있거든요. 네 번을 다시 돌려 봤는데 계속 엉뚱한 도구로 갑니다."
search_docs 설명이 뭐라고 돼 있죠?
"Use this to find information about the product."
get_context_summary는요?
"Use this to retrieve relevant information from the current session."
Claude 입장에서는 두 설명이 같은 얘기예요. 둘 다 '정보를 찾는다'고 하고 있죠. 둘 중 하나는 언제 부르지 말아야 하는지를 말해 줘야 합니다.
그럼 제외 조건을 넣어야 하는 거네요?
맞아요. search_docs는 "when the user asks a question that requires looking up content not already present in this conversation. Do not call this if the answer is available in the current session context."로 해 보세요. 그러면 맥락 안에 답이 있는 경우는 get_context_summary가 맡게 됩니다. get_context_summary 설명도 같은 식으로 조여야 해요 — "Only use this if the answer is already present in the current session. Do not use this to look up new information."를 더합니다. 한쪽만이 아니라 두 도구 모두에 경계가 필요합니다.
두 문장이네요.
그렇죠. 하나는 언제 쓰는지, 하나는 언제 쓰지 않는지. 그게 수정의 전부입니다.
type 파라미터 하나를 둔 단일 도구로 합치는 편이 낫습니다.아래 세션 기록은 에이전트가 도구를 부르고, 결과를 받고, 다음 요청에서 API 검증 오류로 실패하는 과정을 보여 줍니다. 스키마는 유효하고, 도구 설명도 구체적이며, 도구 결과 내용도 맞습니다. 무엇이 문제일까요?
기록을 읽기 전에 알아 둘 규칙이 하나 있습니다. tool_result 블록은 언제나 사용자(user) 역할로 보냅니다 — 사람이 직접 입력한 것이 아니라 애플리케이션 코드가 만든 내용이더라도요. role 필드는 그 내용을 누가 작성했는지가 아니라, 누가 Claude에게 보내는지를 표시하기 때문입니다. 아래 기록에서 세 번째 턴을 "User (tool result)"로 적은 것도 그 배정을 분명히 하려는 것입니다.
SESSION TRACE — 검증 오류로 끝나는 세션 기록
Turn 1: User: [text]: "What is the current balance for account A-4471?" Turn 2: Assistant: [text]: "I'll look that up." [tool_use]: id="toolu_01", name="get_account_balance", input={"account_id": "A-4471"} Turn 3: User (tool result): [tool_result]: tool_use_id="toolu_02", content="Balance: $1,240.18" Turn 4: API response: Error: invalid_request_error "tool_result block references unknown tool_use_id"
기록을 읽고, 어떤 블록이 빠졌거나 순서가 어긋났는지 짚어 보고, 깨진 규칙이 무엇인지 이름 붙여 본 다음, 아래 보기에서 알맞은 수정을 골라 보세요. 정답을 먼저 떠올려 본 뒤 고르면 좋습니다. 맞히면 설명이 나옵니다.
Q1위 기록에서 깨진 규칙은 무엇이고, 어떻게 고쳐야 할까요?
결함은 세 번째 턴에 있습니다. 어시스턴트는 id가 toolu_01인 tool_use 블록을 냈는데, tool_result 블록은 toolu_02를 참조하고 있습니다. API는 위치가 아니라 ID로 tool_use와 tool_result를 짝지으므로, 어긋난 ID는 대화에 없는 tool_use를 가리키는 것으로 처리됩니다. 고치는 방법은 결과를 tool_use_id="toolu_01"로 돌려주는 것입니다. 메시지 블록 표에서 본 그 규칙 — 모든 tool_use에는 바로 다음 사용자 턴에 ID가 정확히 보존된 tool_result가 있어야 한다 — 그대로입니다.
Q2도구 사용 루프에 대한 설명 중 맞는 것은 무엇일까요?
가장 흔한 오해가 Claude가 도구를 직접 실행한다는 생각입니다. 실제로는 Claude가 도구를 고르고, 실행은 코드가 맡습니다. 게다가 모델은 호출과 호출 사이에 상태를 기억하지 않아서(무상태), 도구를 실행하는 동안 연결을 붙잡고 기다리지도 않습니다. 이어서 진행하려면 이전 메시지에 도구 결과를 더한 새 요청을 보냅니다.
Q3두 도구의 설명이 겹쳐 Claude가 자꾸 엉뚱한 도구를 고릅니다. 가장 적절한 조치는 무엇일까요?
Claude는 이름과 설명으로 도구를 고르고, 파라미터 형태는 보조 신호로만 씁니다. 그래서 설명이 겹칠 때의 해결은 설명을 무작정 늘리는 것이 아니라, 언제 쓰지 않는지를 밝히는 제외 조건을 더해 판단 경계를 주는 것입니다. 그래도 깨끗하게 나뉘지 않으면 두 도구를 type 파라미터 하나를 둔 단일 도구로 합치는 편이 낫습니다.
모듈 2의 다음 레슨은 응답을 완성되기 전부터 조금씩 받아 보는 스트리밍 응답(Streaming Responses)을 다룹니다. → 2-5 · 스트리밍 응답
전 코스는 계속 무료입니다. 등록하면 이 코스의 남은 38개 레슨을 끝까지 읽을 수 있습니다.
이미 등록하셨다면 그때 쓰신 이메일을 넣어 주세요.