Definición de esquemas de herramientas con name, description e input_schema
Una definición de herramienta es la única información que Claude tiene sobre lo que hace tu función y cuándo usarla. Si el esquema es correcto, Claude la llama correctamente; si es vago, Claude la omite o la rellena con suposiciones.
Resumen
Cada herramienta que le proporcionas a Claude es un objeto JSON con tres campos obligatorios: name, description e input_schema. Claude nunca ejecuta tu código directamente; lee esta definición y decide si emitir un bloque tool_use y, en caso afirmativo, qué argumentos incluir en él.
El campo description tiene la mayor importancia. Claude lo utiliza para decidir si llamar a la herramienta y cómo rellenar sus parámetros, por lo que una descripción de una sola línea que solo repite el nombre de la función no es suficiente.
input_schema es JSON Schema estándar, limitado a las propiedades que esta herramienta acepta realmente. Cada propiedad debe llevar su propia description, y cualquier parámetro con un conjunto pequeño y fijo de valores legales debe usar enum en lugar de texto libre.
Para herramientas de producción, añade "strict": true en el nivel superior de la definición de la herramienta. Esto fuerza a que el esquema sea exacto (additionalProperties: false junto con una lista required explícita) y garantiza que lo que Claude devuelva en tool_use.input valide contra tu esquema, sin necesidad de comprobaciones posteriores.
Receta
Tarjeta de referencia rápida - lista para copiar y pegar.
from anthropic import Anthropic
client = Anthropic()
tools = [
{
"name": "get_weather",
"description": (
"Obtiene el clima actual para una ubicación. Llama a esta herramienta cuando el usuario "
"pregunte sobre las condiciones actuales, la temperatura o el pronóstico para "
"un lugar específico."
),
"input_schema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "Ciudad y estado, ej. San Francisco, CA",
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "Unidad de temperatura",
},
},
"required": ["location"],
},
}
]Cuándo usar esto:
- Al definir cualquier herramienta nueva que Claude pueda llamar.
- Cuando una herramienta tiene parámetros opcionales y necesitas que Claude sepa cuáles son realmente importantes.
- Cuando un parámetro solo acepta un conjunto pequeño y conocido de valores (estados, categorías, unidades).
- Cuando depuras por qué Claude llama a una herramienta con argumentos incorrectos o la omite por completo.
- Cuando quieres que la salida de Claude sea segura para máquinas sin escribir tu propia capa de validación (usa
strict: true).
Ejemplo de trabajo
from anthropic import Anthropic
client = Anthropic()
search_database_tool = {
"name": "search_database",
"description": (
"Busca en el catálogo de productos interno por palabra clave y filtro de categoría opcional. "
"Llama a esta herramienta cuando el usuario pida encontrar, buscar o comparar productos; "
"no la llames para preguntas generales de conocimiento de productos que no necesiten una consulta en vivo."
),
"input_schema": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Palabras clave de búsqueda de texto libre, ej. 'ratón inalámbrico'",
},
"category": {
"type": "string",
"enum": ["electronics", "home", "outdoor", "apparel"],
"description": "Restringe los resultados a una categoría de producto",
},
"max_results": {
"type": "integer",
"description": "Número máximo de resultados a devolver",
},
},
"required": ["query"],
},
}
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
tools=[search_database_tool],
messages=[
{"role": "user", "content": "Encuéntrame un ratón inalámbrico de la electrónica del hogar"}
],
)
for block in response.content:
if block.type == "tool_use":
print(f"Herramienta llamada: {block.name}")
print(f"Argumentos: {block.input}")Lo que esto demuestra:
- Una
descriptionque indica tanto lo que hace la herramienta como cuándo llamarla, no solo su función. categoryrestringido a un conjunto cerrado de valores legales conenum, en lugar de texto libre que Claude podría interpretar mal.max_resultsdejado opcional (ausente derequired) porque la herramienta tiene un valor predeterminado sensato sin él.- Lectura de
response.contentpara un bloquetool_usee inspección deblock.name/block.input, los argumentos que Claude generó según tu esquema.
Profundización
Cómo funciona
- Claude recibe tu array
toolsjunto con la conversación y trata cadadescriptioncomo documentación que lee antes de decidir actuar. - Cuando una solicitud coincide con el propósito declarado de una herramienta, Claude emite un bloque de contenido
tool_useque contiene elnamede la herramienta y un objetoinputque generó para cumplir con tuinput_schema. - Los campos
descriptiona nivel de propiedad dan forma a cómo Claude rellena los argumentos: un campo de ubicación descrito como "Ciudad y estado, ej. San Francisco, CA" produce un formato más consistente que un simple"type": "string". requiredindica a Claude qué campos debe rellenar antes de llamar a la herramienta; todo lo demás lo rellena solo cuando la conversación le proporciona un valor.- Los modelos más nuevos, como Claude Sonnet 5, son más conservadores a la hora de utilizar herramientas que los anteriores, por lo que una cláusula explícita "llama a esto cuando..." en la descripción mejora mediblemente la precisión de cuándo llamar; no es solo una decoración de prosa.
Campos obligatorios de un vistazo
| Campo | Tipo | Propósito |
|---|---|---|
name | string | Identificador único y descriptivo que Claude repite en tool_use.name |
description | string | Qué hace la herramienta y, de forma prescriptiva, cuándo llamarla |
input_schema | object (JSON Schema) | Define la forma de los argumentos que Claude debe producir |
Modo Estricto (Strict Mode)
Establece "strict": true como un campo de nivel superior en la definición de la herramienta (junto con name, description, input_schema) para forzar que tool_use.input valide exactamente contra tu esquema, sin necesidad de encabezado beta.
strict_tool = {
"name": "create_ticket",
"description": "Crea un ticket de soporte. Llama a esto cuando el usuario informe de un error o solicite ayuda que deba ser rastreada.",
"strict": True,
"input_schema": {
"type": "object",
"properties": {
"title": {"type": "string", "description": "Título corto del ticket"},
"priority": {
"type": "string",
"enum": ["low", "medium", "high", "urgent"],
"description": "Prioridad del ticket",
},
},
"required": ["title", "priority"],
"additionalProperties": False,
},
}El modo estricto requiere additionalProperties: false y una lista required explícita en el esquema. Admite tipos básicos (object, array, string, integer, number, boolean, null), enum, const, anyOf, allOf, $ref/$def, y formatos de cadena (date-time, date, email, uri, uuid y similares). No admite esquemas recursivos, restricciones numéricas (minimum, maximum, multipleOf), restricciones de longitud de cadena (minLength, maxLength), restricciones complejas de arrays, ni additionalProperties configurado en algo que no sea false.
Notas de Python
# input_schema es un diccionario simple; constrúyelo con ayudantes si crece mucho,
# pero mantenlo en línea para herramientas pequeñas para que name/description/schema
# se puedan revisar juntos.
def weather_tool(units: list[str]) -> dict:
return {
"name": "get_weather",
"description": (
"Obtiene el clima actual para una ubicación. Llama a esta herramienta cuando el usuario "
"pregunte sobre las condiciones actuales."
),
"input_schema": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "Ciudad y estado"},
"unit": {"type": "string", "enum": units, "description": "Unidad de temperatura"},
},
"required": ["location"],
},
}Parámetros y Valores de Retorno
| Parámetro | Tipo | Descripción |
|---|---|---|
name | str | Identificador único de la herramienta; Claude lo devuelve en tool_use.name |
description | str | Explica qué hace la herramienta y, de forma prescriptiva, cuándo llamarla |
input_schema | dict | Objeto JSON Schema que describe los argumentos aceptados |
input_schema.properties | dict | Definiciones por parámetro, cada una con su propia description |
input_schema.required | list[str] | Nombres de los parámetros que Claude debe suministrar siempre |
strict | bool (opcional) | Cuando es True, garantiza que tool_use.input coincide exactamente con el esquema |
Errores comunes
- Nombres vagos como
helperow. Claude no tiene nada para desambiguar entre herramientas cuando los nombres no describen su propósito. Solución: usa nombres específicos y orientados a la acción comoget_weatherosearch_database. - Una descripción que solo repite el nombre.
"description": "Obtiene el clima"no le dice nada a Claude sobre cuándo usarla en lugar de responder con conocimiento general. Solución: indica el propósito y añade una cláusula explícita "Llama a esto cuando...". - Descripciones de propiedades faltantes. Un simple
{"type": "string"}no da a Claude ninguna pista sobre el formato esperado, por lo que adivina el formato (ej."NYC"vs"New York, NY"). Solución: añade unadescriptioncon un ejemplo a cada propiedad. - Cadenas de texto libre para campos de opción fija. Sin
enum, un campounitpuede devolverse como"F","Fahrenheit"o"fahrenheit"dependiendo de la redacción. Solución: restringe los parámetros de opción fija conenum. - Marcar todo como
required. Obligar a Claude a inventar valores para parámetros que la conversación nunca mencionó produce argumentos de baja calidad y fabricados. Solución: solo lista los parámetros enrequiredque la herramienta realmente no puede ejecutar sin ellos. - Usar
strict: truecon restricciones no admitidas.minLength,maximumo una$refrecursiva en un esquema en modo estricto fallarán la validación, no se relajarán silenciosamente. Solución: mueve las comprobaciones de longitud/rango a tu propio código de ejecución de herramientas y mantén el esquema estricto en el subconjunto admitido. - Demasiadas herramientas superpuestas. Un conjunto de herramientas grande con descripciones vagas y similares hace que Claude elija la herramienta incorrecta o dude y no llame a ninguna. Solución: mantén el conjunto de herramientas enfocado y dale a cada herramienta una descripción lo suficientemente específica como para que no sea ambigua junto a sus vecinas.
Alternativas
| Alternativa | Usar cuando | No usar cuando |
|---|---|---|
Esquema suelto, sin strict | Prototipado, o tu propio código ya valida tool_use.input antes de usarlo | Necesitas una garantía firme de que la entrada de Claude coincide exactamente con tu esquema |
strict: true | Herramientas de producción que alimentan directamente llamadas a funciones tipadas o APIs externas | Tu esquema necesita rangos numéricos, límites de longitud de cadena o estructuras recursivas |
Una herramienta grande multipropósito con un parámetro action enum | Un puñado de operaciones estrechamente relacionadas (ej. create/update/delete en un recurso) | Las operaciones toman argumentos fundamentalmente diferentes; herramientas separadas mantienen los esquemas más limpios |
| Varias herramientas pequeñas y de un solo propósito | Cada operación tiene un nombre, descripción y forma de argumentos distintos que Claude nunca debería confundir | Tienes docenas de herramientas casi duplicadas; considera la herramienta de búsqueda de herramientas en su lugar (herramienta de búsqueda de herramientas) |
Preguntas frecuentes
¿Qué tres campos necesita toda definición de herramienta?
name- un identificador único y descriptivodescription- qué hace la herramienta y cuándo llamarlainput_schema- un objeto JSON Schema que define los argumentos aceptados
¿Por qué la descripción es tan importante?
Claude lee la description como un desarrollador lee la documentación antes de decidir si y cómo llamar a una función. Una descripción vaga lleva a llamadas perdidas (Claude no se da cuenta de que la herramienta se aplica) o a argumentos incorrectos (Claude no tiene guía de formato).
¿Debo describir cuándo llamar a la herramienta, o solo lo que hace?
Ambas cosas. Indicar una condición como "Llama a esto cuando el usuario pregunte por los precios actuales o eventos recientes" mejora mediblemente si Claude utiliza la herramienta en el momento adecuado, especialmente en los modelos más nuevos que llaman a las herramientas de forma más conservadora por defecto.
¿Necesito una descripción en cada propiedad dentro de input_schema, o solo la descripción general de la herramienta?
Ambos niveles importan. La description de nivel superior decide si/cuándo llamar a la herramienta; la description de cada propiedad da forma a cómo Claude rellena ese argumento específico (formato, unidades, ejemplos).
¿Cuándo debo usar enum en lugar de un tipo de cadena simple?
Siempre que un parámetro solo tenga un conjunto pequeño y conocido de valores legales: unidades, estados, categorías. enum evita que Claude devuelva variantes inconsistentes como "F" vs "fahrenheit".
¿Cómo decido qué incluir en required?
Solo lista los parámetros que la herramienta no puede ejecutar sin ellos. Todo lo demás debe ser opcional para que Claude no tenga que inventar un valor cuando la conversación no lo haya proporcionado.
¿Qué garantiza realmente strict: true?
Que tool_use.input valida exactamente contra tu input_schema, sin campos obligatorios faltantes ni propiedades adicionales. Requiere additionalProperties: false y una lista required explícita, y no necesita encabezado beta.
¿Dónde va strict en la definición de la herramienta?
tool = {
"name": "create_ticket",
"description": "...",
"strict": True,
"input_schema": {"type": "object", "properties": {}, "required": [], "additionalProperties": False},
}Es un campo de nivel superior junto con name/description/input_schema, no algo configurado en tool_choice.
¿Qué características de JSON Schema están prohibidas en modo estricto?
Esquemas recursivos, restricciones numéricas (minimum/maximum/multipleOf), restricciones de longitud de cadena (minLength/maxLength), restricciones complejas de arrays y cualquier valor de additionalProperties distinto de false.
¿Todavía puedo usar minLength o maximum si los necesito?
No bajo strict: true. O bien elimina el modo estricto y valida esas restricciones tú mismo después de recibir tool_use.input, o aplícalas en tu código de ejecución de herramientas en lugar del esquema.
¿Qué sucede si le doy a dos herramientas descripciones muy similares?
Claude puede elegir la incorrecta, o dudar y no llamar a ninguna, porque las descripciones no le dan suficiente señal para desambiguar. Mantén la descripción de cada herramienta lo suficientemente específica como para que no sea ambigua junto a sus vecinas.
¿input_schema debería ser alguna vez algo que no sea type: object?
No; input_schema siempre describe un objeto cuyas properties son los argumentos nombrados de la herramienta. Las propiedades individuales pueden ser de cualquier tipo JSON Schema (string, integer, array, etc.), pero la raíz del esquema es siempre object.
¿Cuántas herramientas son demasiadas para definir a la vez?
No hay un límite estricto, pero un conjunto de herramientas grande con descripciones vagas o superpuestas confunde la selección de herramientas mucho antes de alcanzar cualquier límite técnico. Mantén el conjunto de herramientas activo enfocado en lo que es relevante para la conversación.
Relacionados
- Conceptos básicos de uso de herramientas - el ciclo completo mínimo de
tool_use/tool_resultal que se conecta este esquema. - Cómo Claude decide cuándo llamar a una herramienta - cómo la redacción de la descripción afecta la precisión de cuándo llamar.
- Manejo de solicitudes de uso de herramientas y devolución de bloques de resultados de herramientas - qué hacer con
tool_use.inputque produce este esquema. - Mejores prácticas - guía más amplia para diseñar agentes fiables que utilizan herramientas.
Versiones de Stack: Escrito contra la línea de modelos Claude actual a partir de ~junio de 2026 - Claude Fable 5, Claude Opus 4.8, Claude Sonnet 5 (el predeterminado), y Claude Haiku 4.5 - y el SDK oficial de Python
anthropic(última versión 0.x). Los nombres de los modelos, las versiones del SDK y los precios cambian rápidamente; verifica los detalles actuales en platform.claude.com/docs antes de confiar en ellos.