도구 및 멀티턴 워크플로에서의 사고
사고 블록을 올바르게 보존하는 완전한 2턴 도구 사용 왕복 과정을 단계별로 살펴보고, 인터리브 사고가 흐름을 어떻게 바꾸는지 확인합니다.
이 페이지는 사고가 활성화된 상태에서 완전한 2턴 "tool use"(도구 사용) 왕복 과정을 단계별로 살펴봅니다. Claude가 사고하고, 도구 호출을 요청하고, 결과를 받은 뒤 답변을 마무리하며, 모든 단계에서 사고 블록이 올바르게 처리됩니다. 전체 규칙은 사고 페이지의 도구 사용과 함께하는 사고 및 사고 블록 보존에 있으며, 이 페이지는 해당 규칙을 실행 가능한 코드에 적용한 모습을 보여줍니다.
이 안내에서 적용하는 규칙
각 링크는 사고 페이지의 전체 설명으로 연결됩니다:
- 수동 모드에서는 도구 선택을
auto또는none으로 제한: 도구 사용을 강제하는tool_choice옵션은 수동 "extended thinking"(확장 사고)(thinking: {type: "enabled"})에서 오류를 반환합니다. 적응형 사고는 강제 도구 사용을 지원합니다. - 어시스턴트 턴당 하나의 사고 구성 유지: 도구 사용 루프는 하나의 어시스턴트 턴이므로, 구성은 턴 사이에서만 변경하세요.
- 사고 블록을 완전하고 수정 없이 다시 전달: 도구 결과를 반환할 때 어시스턴트 메시지의 사고 블록도 함께 돌려보내야 합니다.
- 어시스턴트 메시지를 받은 그대로 정확히 되돌려 보내기: 메시지를 재구성하거나
redacted_thinking블록을 걸러내면 400 오류가 발생합니다.
샘플은 적응형 사고를 사용합니다. 확장 사고만 지원하는 모델에서는 thinking: {type: "enabled", budget_tokens: N}으로 대체하세요. 왕복 규칙은 동일합니다.
2턴 도구 사용 왕복 과정 살펴보기
이 예제는 get_weather 도구를 정의하고, Claude가 사고한 뒤 도구 호출을 요청하게 한 다음, 사고 블록을 포함하여 받은 그대로 정확히 되돌린 어시스턴트 턴과 함께 도구 결과를 반환합니다.
도구를 사용 가능하게 하여 첫 번째 요청 보내기
적응형 사고를 활성화하고 도구를 정의한 요청을 보냅니다.
thinking파라미터를 제외하면 이는 표준 도구 사용 요청입니다:client = anthropic.Anthropic() weather_tool = { "name": "get_weather", "description": "Get current weather for a location", "input_schema": { "type": "object", "properties": {"location": {"type": "string", "description": "City name"}}, "required": ["location"], }, } # 첫 번째 요청 - Claude가 사고 과정과 도구 요청으로 응답합니다 response = client.messages.create( model="claude-opus-4-8", max_tokens=16000, thinking={"type": "adaptive"}, tools=[weather_tool], messages=[{"role": "user", "content": "What's the weather in Paris?"}], ) print(response)되돌려 보낼 content 배열 캡처하기
Claude가 사고하기로 선택한 실행에서는 응답 content에
thinking,text,tool_use블록이 표시됩니다(더 단순한 요청에서는 적응형 모드가 사고 블록을 건너뛸 수 있습니다). 이 content 배열을 그대로 유지하세요. 다음 단계에서 이를 그대로 다시 보냅니다.Output{ "content": [ { "type": "thinking", "thinking": "The user wants to know the current weather in Paris. I have access to a function `get_weather`...", "signature": "BDaL4VrbR2Oj0hO4XpJxT28J5T...." }, { "type": "text", "text": "I can help you get the current weather information for Paris. Let me check that for you" }, { "type": "tool_use", "id": "toolu_01CswdEQBMshySk6Y9DFKrfq", "name": "get_weather", "input": { "location": "Paris" } } ] }어시스턴트 턴을 그대로 되돌리며 도구 결과 반환하기
여러분 측에서 도구를 실행한 다음, 대화에 두 개의 메시지를 추가하는 두 번째 요청을 보냅니다. 첫 번째는 받은 그대로 정확히 되돌린 어시스턴트 content로, 사고 블록이
tool_use블록과 함께 변경 없이 유지됩니다. 두 번째는tool_result를 담은 사용자 메시지입니다.각 샘플은 독립적으로 실행되는 스크립트입니다. 첫 번째 요청을 반복한 다음, 방금 받은 응답을 사용하여 즉시 후속 요청을 보냅니다.
client = anthropic.Anthropic() weather_tool = { "name": "get_weather", "description": "Get current weather for a location", "input_schema": { "type": "object", "properties": {"location": {"type": "string", "description": "City name"}}, "required": ["location"], }, } response = client.messages.create( model="claude-opus-4-8", max_tokens=16000, thinking={"type": "adaptive"}, tools=[weather_tool], messages=[{"role": "user", "content": "What's the weather in Paris?"}], ) # 도구 결과에 사용할 ID를 얻기 위해 도구 사용 블록을 추출합니다 tool_use_block = next(block for block in response.content if block.type == "tool_use") # 실제 날씨 API를 호출합니다. 실제 API 호출이 들어갈 위치입니다 # 이것이 반환된 결과라고 가정합니다 weather_data = {"temperature": 88} # 두 번째 요청 - 어시스턴트 턴과 도구 결과를 포함합니다 continuation = client.messages.create( model="claude-opus-4-8", max_tokens=16000, thinking={"type": "adaptive"}, tools=[weather_tool], messages=[ {"role": "user", "content": "What's the weather in Paris?"}, # 어시스턴트 콘텐츠를 받은 그대로 다시 전달합니다. thinking # 블록이 있는 경우 반드시 tool_use 블록과 함께 포함해야 합니다. {"role": "assistant", "content": response.content}, { "role": "user", "content": [ { "type": "tool_result", "tool_use_id": tool_use_block.id, "content": f"Current temperature: {weather_data['temperature']}°F", } ], }, ], ) print(continuation)최종 응답 읽기
Claude가 텍스트로 턴을 완료하는 것을 볼 수 있습니다. 적응형 모드에서는 인터리브 사고가 자동이므로, 이어지는 응답이 최종 텍스트 앞에 새로운 사고 블록으로 시작할 수도 있습니다:
Output{ "content": [ { "type": "text", "text": "Currently in Paris, the temperature is 88°F (31°C)" } ] }
인터리브 사고가 흐름을 바꾸는 방식
"Interleaved thinking"(인터리브 사고)은 Claude가 도구 호출 사이에 사고하여, 각 도구 결과에 따라 행동하기 전에 그 결과에 대해 추론할 수 있게 합니다. 개념과 모델별 지원 여부는 사고 페이지의 인터리브 사고에서 다룹니다. 인터리빙은 사고 블록이 나타나는 위치를 바꿀 뿐, 도구 호출을 연쇄할 수 있는지 여부를 바꾸지는 않습니다. 다음 비교는 두 개의 도구를 사용하는 워크플로에서 인터리브 사고가 무엇을 바꾸는지 보여줍니다:
인터리브 사고가 없으면 Claude는 어시스턴트 턴 시작 시 한 번 사고합니다. 도구 결과 이후의 후속 응답은 새로운 사고 블록 없이 계속됩니다.
User: "What's the total revenue if we sold 150 units at $50 each,
and how does this compare to our average monthly revenue?"
Response 1: [thinking] "I need to calculate 150 * $50, then check the database..."
[tool_use: calculator] { "expression": "150 * 50" }
↓ tool result: "7500"
Response 2: [tool_use: database_query] { "query": "SELECT AVG(revenue)..." }
↑ no thinking block
↓ tool result: "5200"
Response 3: [text] "The total revenue is $7,500, which is 44% above your
average monthly revenue of $5,200."
↑ no thinking block인터리브 사고가 활성화되면 Claude는 각 도구 결과를 받은 후 사고할 수 있어, 계속 진행하기 전에 중간 결과에 대해 추론할 수 있습니다.
User: "What's the total revenue if we sold 150 units at $50 each,
and how does this compare to our average monthly revenue?"
Response 1: [thinking] "I need to calculate 150 * $50 first..."
[tool_use: calculator] { "expression": "150 * 50" }
↓ tool result: "7500"
Response 2: [thinking] "Got $7,500. Now I should query the database to compare..."
[tool_use: database_query] { "query": "SELECT AVG(revenue)..." }
↑ thinking after receiving calculator result
↓ tool result: "5200"
Response 3: [thinking] "$7,500 vs $5,200 average - that's a 44% increase..."
[text] "The total revenue is $7,500, which is 44% above your
average monthly revenue of $5,200."
↑ thinking before final answer다음 단계
Was this page helpful?