Sign in to save your progressYou can keep reading without an account, but completed lessons won't be saved.
Sign in

Claude가 도구 사용 요청으로 응답하면, 서버는 요청된 도구를 실제로 실행하고 결과를 다시 전송해야 합니다. 이 단계에는 Claude의 응답에서 도구 사용 부분을 추출하고, 적절한 함수를 실행하고, 결과를 올바르게 포맷하는 작업이 포함됩니다.

여러 도구 요청 처리하기

Claude는 단일 응답에 여러 도구 사용 부분을 보낼 수 있습니다. 코드는 이러한 가능성을 방어적으로 처리해야 합니다. 어시스턴트 메시지에는 텍스트 부분 뒤에 하나, 둘, 또는 그 이상의 도구 사용 부분이 포함될 수 있습니다.

흐름은 다음과 같이 작동합니다: Claude가 JSON 스키마와 함께 요청을 보내고, 도구 사용 부분을 받으면, 서버가 도구를 실행하고 도구 결과 부분을 다시 보내 Claude가 최종 응답을 제공하도록 합니다.

도구 사용 부분 추출하기

먼저, 채팅 요청에서 반환된 모든 부분을 처리하는 함수를 만듭니다:

python
def run_tools(parts):
    tool_requests = [part for part in parts if "toolUse" in part]
    tool_result_parts = []
    
    for tool_request in tool_requests:
        tool_use_id = tool_request["toolUse"]["toolUseId"]
        tool_name = tool_request["toolUse"]["name"]
        tool_input = tool_request["toolUse"]["input"]

이 컴프리헨션은 부분 목록을 필터링하여 "toolUse" 키를 포함하는 딕셔너리만 포함하고, 텍스트 부분은 무시합니다.

실제 도구 실행하기

요청된 도구를 실행하는 헬퍼 함수를 만듭니다:

python
def run_tool(tool_name, tool_input):
    if tool_name == "get_current_datetime":
        return get_current_datetime(**tool_input)
    else:
        raise Exception(f"Unknown tool name: {tool_name}")

여기서 핵심은 **tool_input을 사용하여 인수 딕셔너리를 도구 함수로 풀어 넣는 것입니다. Claude는 항상 인수를 딕셔너리 객체로 반환하므로, 이를 올바르게 언패킹해야 합니다.

도구 결과 부분 생성하기

도구를 실행한 후, 응답을 도구 결과 부분으로 포맷해야 합니다:

도구 결과 부분에는 세 가지 핵심 속성이 필요합니다:

  • toolUseId - 원래 도구 사용 부분의 ID와 일치해야 합니다
  • content - 문자열로 직렬화된 도구의 출력
  • status - "success" 또는 "error" 중 하나

도구 사용 ID 이해하기

도구 사용 ID 시스템은 Claude가 여러 도구를 병렬로 요청할 때 중요해집니다. 예를 들어, Claude가 계산기 도구를 두 번 실행하려는 경우:

각 도구 사용은 고유한 ID(예: "ab3" 및 "po9")를 받으며, 도구 결과에는 일치하는 ID가 포함되어야 Claude가 어떤 결과가 어떤 요청에 해당하는지 알 수 있습니다.

오류 처리

도구 실행을 try-catch 블록으로 감싸세요. Claude는 도구 오류에 대해 지능적으로 대응하며, 적절한 오류 정보를 반환하면 접근 방식을 조정할 수 있습니다:

python
try:
    tool_output = run_tool(tool_name, tool_input)
    tool_result_part = {
        "toolResult": {
            "toolUseId": tool_use_id,
            "content": [{"text": json.dumps(tool_output)}],
            "status": "success"
        }
    }
except Exception as e:
    tool_result_part = {
        "toolResult": {
            "toolUseId": tool_use_id,
            "content": [{"text": f"Error: {e}"}],
            "status": "error"
        }
    }

전체 구현

다음은 도구 요청을 처리하고 포맷된 결과를 반환하는 전체 함수입니다:

python
def run_tools(parts):
    tool_requests = [part for part in parts if "toolUse" in part]
    tool_result_parts = []
    
    for tool_request in tool_requests:
        tool_use_id = tool_request["toolUse"]["toolUseId"]
        tool_name = tool_request["toolUse"]["name"]
        tool_input = tool_request["toolUse"]["input"]
        
        try:
            tool_output = run_tool(tool_name, tool_input)
            tool_result_part = {
                "toolResult": {
                    "toolUseId": tool_use_id,
                    "content": [{"text": json.dumps(tool_output)}],
                    "status": "success"
                }
            }
        except Exception as e:
            tool_result_part = {
                "toolResult": {
                    "toolUseId": tool_use_id,
                    "content": [{"text": f"Error: {e}"}],
                    "status": "error"
                }
            }
        
        tool_result_parts.append(tool_result_part)
    
    return tool_result_parts

도구 결과 부분을 얻으면, 다음 채팅 요청에서 이를 Claude에게 다시 보내 도구 사용 사이클을 완료할 수 있습니다.