Cargando

Construir un sistema de conversación con herramientas requiere implementar un bucle que siga llamando a Claude hasta que deje de solicitar el uso de herramientas. Cuando Claude ya no pide herramientas, eso indica que tiene una respuesta final lista para el usuario.

Detectando solicitudes de herramientas

La clave para saber si Claude quiere usar una herramienta está en el campo stop_reason del mensaje de respuesta. Cuando Claude decide que necesita llamar a una herramienta, este campo se establece en "tool_use". Esto nos da una forma clara de verificar si necesitamos continuar el bucle de conversación:

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

El bucle de conversación

La función principal de conversación sigue un patrón simple:

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

Este bucle continúa hasta que Claude proporciona una respuesta final sin solicitar ninguna herramienta.

Manejo de múltiples llamadas a herramientas

Claude puede solicitar múltiples herramientas en una sola respuesta. El contenido del mensaje contiene una lista de bloques, y necesitamos procesar cada bloque de uso de herramienta por separado:

La función run_tools maneja esto filtrando los bloques de uso de herramientas y procesando cada uno:

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:
        # Procesar cada solicitud de herramienta...

Bloques de resultado de herramienta

Cada bloque de uso de herramienta debe responderse con un bloque de resultado de herramienta correspondiente. La conexión entre ellos se mantiene mediante IDs coincidentes:

La estructura del bloque de resultado de herramienta incluye:

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

Manejo de errores

La ejecución robusta de herramientas requiere manejar posibles errores. Cuando una herramienta falla, aún necesitamos proporcionar un bloque de resultado a Claude:

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
    }

Enrutamiento escalable de herramientas

Para admitir múltiples herramientas, crea una función de enrutamiento que asigne los nombres de las herramientas a sus implementaciones:

python
def run_tool(tool_name, tool_input):
    if tool_name == "get_current_datetime":
        return get_current_datetime(**tool_input)
    elif tool_name == "another_tool":
        return another_tool(**tool_input)
    # Agrega más herramientas según sea necesario

Este enfoque facilita agregar nuevas herramientas sin modificar la lógica central de la conversación.

Flujo de trabajo completo

La conversación completa de múltiples turnos funciona así:

  • Enviar el mensaje del usuario a Claude con las herramientas disponibles
  • Claude responde con texto y/o solicitudes de herramientas
  • Ejecutar todas las herramientas solicitadas y crear bloques de resultado
  • Enviar los resultados de las herramientas de vuelta como un mensaje del usuario
  • Repetir hasta que Claude proporcione una respuesta final

Esto crea una experiencia fluida en la que Claude puede usar múltiples herramientas a lo largo de varios turnos para responder completamente a solicitudes complejas del usuario. El historial de la conversación mantiene el contexto completo, lo que permite a Claude basarse en resultados de herramientas anteriores para proporcionar respuestas integrales.