Lección 4 de 9 · 11 min de lectura
Tool use / function calling: integra herramientas en Claude
Aprende a definir herramientas, gestionar el ciclo tool_use/tool_result, usar herramientas de servidor y diseñar integraciones seguras y eficientes.
Tool use / function calling: integra herramientas en Claude
Claude no es solo un modelo de lenguaje: es un agente inteligente que puede usar herramientas externas para resolver problemas. Cuando integras tool use en tu aplicación, le das a Claude la capacidad de tomar decisiones, ejecutar acciones y recuperar información en tiempo real. Es el puente entre la inteligencia del modelo y la funcionalidad del mundo real.
En esta lección aprenderás cómo definir herramientas, gestionar el ciclo de interacción tool_use/tool_result, integrar herramientas de servidor y aplicar patrones de seguridad que el examen espera que domines.
¿Qué es el tool use en Claude?
El tool use es el mecanismo mediante el cual Claude solicita ejecutar una herramienta (función) durante una conversación. A diferencia de los prompts que solo generan texto, las herramientas permiten que Claude:
- Recupere información: consultar bases de datos, APIs externas, búsquedas web.
- Ejecute acciones: crear usuarios, enviar mensajes, escribir archivos.
- Realice cálculos complejos: análisis de datos, transformaciones, validaciones.
- Tome decisiones informadas: basándose en datos reales, no en conocimiento entrenable.
Cuando defines una herramienta, le comunicas a Claude qué puede hacer, qué parámetros espera y qué tipo de resultado devuelve. Claude entonces decide cuándo usarla, cómo usarla y qué hacer con el resultado.
Anatomía de una herramienta: definición y parámetros
Toda herramienta en Claude se define mediante un objeto JSON con estructura estándar:
{
"name": "buscar_usuarios",
"description": "Busca usuarios en la base de datos por nombre o email",
"input_schema": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Nombre o email del usuario a buscar"
},
"limite": {
"type": "integer",
"description": "Número máximo de resultados (por defecto 10)"
}
},
"required": ["query"]
}
}
Los elementos clave son:
- name: identificador único, sin espacios, en snake_case.
- description: instrucción clara sobre qué hace, cuándo usarla y qué esperar.
- input_schema: esquema JSON Schema que define los parámetros esperados, sus tipos, descripciones y cuáles son obligatorios.
Un esquema bien diseñado es crítico. Si la descripción es vaga o los parámetros confusos, Claude cometerá errores al llamar la herramienta. El examen valida que entiendas esta estructura y que sepas escribir esquemas precisos.
El ciclo tool_use/tool_result
La interacción con herramientas sigue un patrón de dos turnos:
Turno 1: Claude solicita uso de herramienta
Cuando Claude decide que necesita una herramienta, devuelve un bloque tool_use en su respuesta:
{
"type": "tool_use",
"id": "toolu_01A7JpQ2XqZb9k8W",
"name": "buscar_usuarios",
"input": {
"query": "juan@example.com",
"limite": 5
}
}
Turno 2: Aplicación ejecuta y devuelve resultado
Tu código:
- Intercepta el bloque
tool_use. - Ejecuta la herramienta real (consulta a BD, llamada a API, etc.).
- Devuelve el resultado en un mensaje de rol
usercon tipotool_result:
{
"type": "tool_result",
"tool_use_id": "toolu_01A7JpQ2XqZb9k8W",
"content": "[{\"id\": 123, \"name\": \"Juan Pérez\", \"email\": \"juan@example.com\"}]"
}
Luego, Claude recibe este resultado y continúa razonando. Puede solicitar más herramientas o generar una respuesta final basada en los datos obtenidos.
Ejemplo completo en Python:
import anthropic
import json
client = anthropic.Anthropic()
tools = [
{
"name": "buscar_usuarios",
"description": "Busca usuarios por email",
"input_schema": {
"type": "object",
"properties": {
"email": {"type": "string"}
},
"required": ["email"]
}
}
]
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
tools=tools,
messages=[{"role": "user", "content": "¿Quién es juan@example.com?"}]
)
if response.stop_reason == "tool_use":
tool_use_block = next(b for b in response.content if b.type == "tool_use")
# Ejecutar herramienta real
resultado = {"id": 123, "name": "Juan Pérez", "email": "juan@example.com"}
# Enviar resultado de vuelta a Claude
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
tools=tools,
messages=[
{"role": "user", "content": "¿Quién es juan@example.com?"},
{"role": "assistant", "content": response.content},
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": tool_use_block.id,
"content": json.dumps(resultado)
}
]
}
]
)
print(response.content[0].text)
Este ciclo es fundamental. El examen valida que entiendas cuándo se activa, qué información fluye en cada dirección y cómo estructurar los mensajes.
Herramientas de servidor y patrones comunes
Algunas herramientas son tan comunes que Anthropic proporciona patrones recomendados:
Web Search (búsqueda web)
Si tu aplicación necesita que Claude acceda a información actual, puedes definir una herramienta de búsqueda:
{
"name": "buscar_web",
"description": "Busca información en internet. Usa esto cuando necesites datos actuales o verificar hechos recientes.",
"input_schema": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "Término de búsqueda"}
},
"required": ["query"]
}
}
Tu backend llamaría a un API de búsqueda real (Google Custom Search, Bing, etc.) y devolvería los resultados.
Code Execution (ejecución de código)
Para problemas analíticos o de programación, puedes permitir que Claude ejecute código:
{
"name": "ejecutar_codigo",
"description": "Ejecuta código Python en un entorno seguro. Usa para cálculos, análisis de datos o validaciones complejas.",
"input_schema": {
"type": "object",
"properties": {
"codigo": {"type": "string", "description": "Código Python a ejecutar"}
},
"required": ["codigo"]
}
}
Esto requiere un sandbox seguro. Nunca ejecutes código arbitrario sin restricciones.
Database / API Calls
Las herramientas más comunes son consultas a bases de datos o llamadas a APIs internas:
{
"name": "obtener_saldo_cuenta",
"description": "Obtiene el saldo actual de una cuenta de usuario",
"input_schema": {
"type": "object",
"properties": {
"cuenta_id": {"type": "string"},
"moneda": {"type": "string", "enum": ["USD", "EUR", "MXN"]}
},
"required": ["cuenta_id"]
}
}
Buenas prácticas de diseño y seguridad
1. Descripciones claras y precisas
Una descripción vaga lleva a uso incorrecto. Sé específico:
❌ Malo: "description": "Obtiene datos"
✅ Bueno: "description": "Obtiene el saldo actual de una cuenta de usuario. Solo funciona para cuentas del usuario autenticado. Devuelve un número con dos decimales."
2. Parámetros obligatorios vs opcionales
Haz explícito en required qué parámetros son obligatorios. Usa enum para limitar opciones:
"estado": {
"type": "string",
"enum": ["activo", "inactivo", "suspendido"],
"description": "Estado de la cuenta"
}
3. Validación en el backend
Nunca confíes en que Claude siempre llama la herramienta correctamente. Valida siempre:
def buscar_usuarios(query: str, limite: int = 10):
# Validación
if not query or len(query) < 2:
return {"error": "Query debe tener al menos 2 caracteres"}
if limite < 1 or limite > 100:
return {"error": "Límite debe estar entre 1 y 100"}
# Lógica real
return perform_search(query, limite)
4. Control de acceso y contexto
Nunca devuelvas más datos de los necesarios. Implementa validación de permisos:
def obtener_saldo(account_id: str, usuario_autenticado: str):
cuenta = db.get_account(account_id)
# Validar que el usuario tiene permiso
if cuenta.propietario != usuario_autenticado:
return {"error": "No tienes permiso para acceder a esta cuenta"}
return {"saldo": cuenta.saldo}
5. Manejo de errores informativo
Cuando algo falla, devuelve un error que Claude pueda entender y actuar:
try:
resultado = api_externa.buscar(query)
return {"exito": True, "datos": resultado}
except TimeoutError:
return {"exito": False, "error": "La búsqueda tardó demasiado. Intenta de nuevo."}
except PermissionError:
return {"exito": False, "error": "No tienes permiso para esta operación."}
6. Limitar complejidad
No definas herramientas que hagan demasiado. Una herramienta = una responsabilidad:
❌ Malo: crear_y_enviar_notificacion_y_registrar_log
✅ Bueno: crear_usuario, enviar_email, registrar_evento
Clause puede encadenar llamadas si es necesario.
Para el examen
Este tema es crítico en la certificación Developer. Debes dominar:
- Definición de herramientas: estructura JSON, propiedades del esquema, tipos de datos, parámetros obligatorios vs opcionales.
- Ciclo tool_use/tool_result: qué es cada bloque, cómo se intercambian, cuándo ocurren.
- Interpretación de respuestas: identificar cuándo Claude devuelve
tool_use, cuándo necesitas ejecutar la herramienta real y cómo devolver el resultado. - Errores y validación: cómo manejar llamadas fallidas, validar entrada, devolver errores informativos.
- Seguridad: control de acceso, validación de permisos, no confiar en entrada de Claude.
- Casos de uso reales: reconocer cuándo tool use es la solución correcta y cómo diseñar herramientas prácticas.
El examen puede presentarte fragmentos de código incompletos y pedir que identifiques problemas de seguridad, errores en la estructura del esquema o pasos faltantes en el ciclo.
Para recordar
- Tool use es un ciclo de dos turnos: Claude solicita, tu aplicación ejecuta y devuelve resultados.
- El esquema JSON Schema es el contrato: define qué puede hacer Claude, qué parámetros espera y qué devuelve; imprecisiones aquí causan errores.
- Valida siempre en el backend: nunca confíes en que Claude use la herramienta exactamente como esperas; implementa validación, control de acceso y manejo de errores.
- Diseña herramientas simples y específicas: una responsabilidad por herramienta; descripciones claras; limita el scope de datos devueltos para evitar confusiones y riesgos de seguridad.
Ponte a prueba
Tipo test
6 preguntas sobre esta lección. Responde una a una; verás las soluciones al terminar.