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

도구를 사용하는 대화 시스템을 구축하려면 Claude가 도구 사용 요청을 멈출 때까지 계속 호출하는 루프를 구현해야 합니다. Claude가 더 이상 도구를 요청하지 않으면, 이는 사용자에게 제공할 최종 응답이 준비되었다는 신호입니다.

도구 요청 감지하기

Claude가 도구를 사용하고자 하는지 알 수 있는 핵심은 응답 메시지의 stop_reason 필드에 있습니다. Claude가 도구를 호출해야 한다고 판단하면, 이 필드는 "tool_use"로 설정됩니다. 이를 통해 대화 루프를 계속해야 하는지 확인할 수 있는 명확한 방법을 얻을 수 있습니다:

python
if response.stop_reason != "tool_use":
    break  # Claude is done, no more tools needed

대화 루프

주요 대화 함수는 간단한 패턴을 따릅니다:

python
def run_conversation(messages):
    while True:
        response = chat(messages, tools=[get_current_datetime_schema])
        add_assistant_message(messages, response)
        print(text_from_message(response))
        
        if response.stop_reason != "tool_use":
            break
            
        tool_results = run_tools(response)
        add_user_message(messages, tool_results)
    
    return messages

이 루프는 Claude가 도구를 요청하지 않고 최종 답변을 제공할 때까지 계속됩니다.

여러 도구 호출 처리하기

Claude는 단일 응답에서 여러 도구를 요청할 수 있습니다. 메시지 콘텐츠에는 블록 목록이 포함되어 있으며, 각 도구 사용 블록을 개별적으로 처리해야 합니다:

run_tools 함수는 도구 사용 블록을 필터링하고 각각을 처리함으로써 이를 처리합니다:

python
def run_tools(message):
    tool_requests = [
        block for block in message.content if block.type == "tool_use"
    ]
    tool_result_blocks = []
    
    for tool_request in tool_requests:
        # 각 도구 요청을 처리합니다...

도구 결과 블록

각 도구 사용 블록에 대해, 이에 대응하는 도구 결과 블록을 생성해야 합니다. 이러한 블록에는 특정한 필수 필드가 있습니다:

도구 결과 블록에는 원본 도구 사용 블록과 동일한 ID가 tool_use_id 필드에 포함되어야 합니다:

python
tool_result_block = {
    "type": "tool_result",
    "tool_use_id": tool_request.id,
    "content": json.dumps(tool_output),
    "is_error": False
}

오류 처리

견고한 도구 실행을 위해서는 발생 가능한 오류를 처리해야 합니다. 도구가 실패하더라도, 여전히 도구 결과 블록을 반환해야 하지만, 오류 정보를 포함해야 합니다:

python
try:
    tool_output = run_tool(tool_request.name, tool_request.input)
    tool_result_block = {
        "type": "tool_result",
        "tool_use_id": tool_request.id,
        "content": json.dumps(tool_output),
        "is_error": False
    }
except Exception as e:
    tool_result_block = {
        "type": "tool_result", 
        "tool_use_id": tool_request.id,
        "content": f"Error: {e}",
        "is_error": True
    }

확장 가능한 도구 라우팅

여러 도구를 지원하려면, 도구 이름을 하드코딩하는 대신 별도의 라우팅 함수를 만드세요:

python
def run_tool(tool_name, tool_input):
    if tool_name == "get_current_datetime":
        return get_current_datetime(**tool_input)
    elif tool_name == "other_tool":
        return other_tool_function(**tool_input)
    # 필요에 따라 더 많은 도구를 추가하세요

이 접근 방식을 사용하면 핵심 대화 로직을 수정하지 않고도 새로운 도구를 쉽게 추가할 수 있습니다.

전체 워크플로우

전체 다중 턴 대화는 다음과 같이 작동합니다:

  • 사용 가능한 도구와 함께 사용자 메시지를 Claude에 전송합니다
  • Claude는 텍스트 및/또는 도구 사용 블록으로 응답합니다
  • 요청된 도구를 실행하고 도구 결과 블록을 생성합니다
  • 도구 결과를 사용자 메시지로 Claude에 다시 전송합니다
  • Claude가 도구 요청 없이 최종 응답을 제공할 때까지 반복합니다

이를 통해 Claude가 사용자에게 포괄적인 최종 답변을 제공하기 전에 필요한 모든 정보를 수집하기 위해 여러 대화 턴에 걸쳐 여러 도구 호출을 수행할 수 있는 원활한 경험이 만들어집니다.