Open in
Crea una integración de herramientas (API)
Permite que tu agente llame a tus API durante una conversación: busca en una base de datos, crea un ticket, consulta un pedido.
Una integración de herramientas es un endpoint HTTP reutilizable que un agente puede invocar durante una llamada. Le proporcionas a ThunderPhone una descripción en esquema JSON de la herramienta junto con una URL de endpoint; el agente decide cuándo llamarla según la conversación, y ThunderPhone realiza la solicitud HTTP saliente desde sus servidores y devuelve la respuesta al agente.
Esta guía explica cómo crear una herramienta de consulta del clima de principio a fin.
Anatomía de una herramienta
Dos elementos:
- El esquema — una definición de función al estilo de OpenAI
(
{type: "function", function: {name, description, parameters}}) que le indica al LLM qué hace la herramienta y qué argumentos acepta. - El endpoint — la URL que llaman los servidores de ThunderPhone cuando el LLM decide usar la herramienta. La solicitud es un POST JSON con los argumentos elegidos por el LLM como cuerpo.
1. Elige un editor
Abre Conexiones → APIs, crea o edita la conexión de API, cambia el editor de parámetros a JSON y agrega allí el formato.
Crea la especificación con POST /v1/integrations o actualízala con
PATCH /v1/integrations/{id}.
Ambas opciones crean una integración guardada. Adjunta esa integración al
agente después de guardarla. La API de agentes no tiene un campo tools
en línea que se pueda modificar. Esta guía usa la ruta de la API de integraciones.
2. Crea la integración
curl -X POST https://api.thunderphone.com/v1/integrations \
-H "Authorization: Bearer sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"display_name": "Weather API",
"spec": {
"type": "function",
"function": {
"name": "get_weather",
"description": "Return the current weather for a zip code.",
"parameters": {
"type": "object",
"properties": {
"zip": { "type": "string", "description": "5-digit US ZIP code" }
},
"required": ["zip"]
}
}
},
"endpoint_url": "https://api.example.com/weather",
"endpoint_method": "GET",
"headers": [
{ "key": "X-Api-Key", "value": "your-provider-key" }
]
}'Guarda el id devuelto (un UUID). Los valores de los encabezados son de solo escritura: las respuestas solo enumeran los nombres de los encabezados, y un PATCH posterior puede enviar un encabezado sin un value para conservar el valor almacenado.
Declara format: "email" en los parámetros de dirección
Un parámetro que recibe una dirección de correo electrónico debe indicarlo en su esquema:
"email": { "type": "string", "format": "email", "description": "The caller's email address" }format es más que una sugerencia. Para un esquema de correo electrónico resuelto, antes de llamar a tu
endpoint, ThunderPhone recorta el valor, convierte el dominio a minúsculas,
convierte las palabras inglesas independientes at, dot, underscore,
dash y hyphen en sus caracteres, y elimina los espacios en blanco
directamente alrededor de @, ., _ y -. Las palabras tienen el mismo significado
tanto si la transcripción ya contiene un @ literal como si no:
"john dot smith at gmail dot com" se convierte en
john.smith@gmail.com.
Cualquier otro espacio en blanco interno se rechaza en lugar de unirse silenciosamente.
Las palabras de separadores hablados solo son compatibles con inglés; las formas con espacios
que no estén en inglés o que no se reconozcan fallan de forma segura. Se aceptan dominios internacionalizados válidos y partes locales SMTPUTF8.
La entrada en Punycode permanece en Punycode y la entrada de dominio Unicode permanece en Unicode
después de la normalización del analizador, por lo que tu API recibe la representación
convencional proporcionada por quien llama. Si el valor final no es válido, la herramienta no se llama. El agente recibe
invalid_email_argument, que le indica
que confirme la ortografía con quien llama y reenvíe la dirección literal.
Un correo electrónico opcional omitido no se modifica. null, una cadena vacía o una
cadena que solo contiene espacios en blanco tampoco se modifican cuando la propiedad es opcional
o admite valores nulos; los mismos valores se rechazan para un correo electrónico obligatorio que no admite valores nulos.
Las referencias de esquema locales como #/$defs/email y
#/definitions/email, además de anyOf, oneOf y allOf, se inspeccionan
con límites de ciclos y profundidad. Un $ref no local o que no se puede resolver es un
límite de aplicación conocido y se transmite sin cambios, al igual que una llamada
cuya instantánea de herramienta no tiene un esquema utilizable. Mantén los esquemas de correo electrónico locales cuando
necesites que se aplique la validación.
Los parámetros sin un formato de correo electrónico aplicado se transmiten exactamente como los produjo el modelo.
Los formatos compatibles son date-time, time, date, duration,
email, hostname, ipv4, ipv6 y uuid; actualmente solo email se
normaliza y aplica.
3. Prueba el endpoint en el entorno aislado
Antes de vincular la integración a un agente, envía una solicitud firmada desde los servidores de ThunderPhone para confirmar la conectividad:
curl -X POST https://api.thunderphone.com/v1/integrations/test-request \
-H "Authorization: Bearer sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://api.example.com/weather?zip=94110",
"method": "GET",
"headers": { "X-Api-Key": "your-provider-key" }
}'{
"ok": true,
"status": 200,
"elapsed_ms": 187,
"response_headers": { "content-type": "application/json" },
"response_preview": "{\"temperature_f\": 64, ...}"
}Esta prueba también refuerza las protecciones SSRF de ThunderPhone: las solicitudes a
localhost o a rangos de IP privados devuelven 400 code=url_not_allowed.
4. Vincula la integración a un agente
Adjúntala mediante integration_ids cuando crees o actualices un agente:
curl -X PATCH https://api.thunderphone.com/v1/agents/12 \
-H "Authorization: Bearer sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"integration_ids": ["f9b5a1a4-..."]
}'Puedes vincular varias integraciones a un agente. El prompt del agente puede
hacer referencia a ellas por nombre — "usa get_weather cuando quien llama
pregunte sobre las condiciones" — o puede descubrirlas implícitamente a partir de las
descripciones del esquema.
5. Implementa el endpoint
Cuando el agente invoca la herramienta, ThunderPhone envía un POST firmado a
tu endpoint_url:
POST /weather HTTP/1.1
Host: api.example.com
X-Api-Key: your-provider-key
X-ThunderPhone-Signature-V2: t=<unix seconds>,v1=<HMAC-SHA256 hex>
X-ThunderPhone-Signature: <HMAC-SHA256 hex>
X-ThunderPhone-Call-ID: 987654321
Content-Type: application/json
{"zip": "94110"}
Tu servidor responde con JSON que se devuelve al LLM:
{"temperature_f": 64, "condition": "Partly cloudy", "wind_mph": 8}El LLM procesa esa respuesta y le comunica un resumen comprensible a quien llama.
6. Prueba el ciclo
Inicia una sesión de micrófono con el agente y haz la pregunta que gestiona tu herramienta ("¿Cómo está el clima en 94110?"). La transcripción de la llamada muestra el ciclo completo:
{
"call_id": 987654321,
"transcripts": [
{ "role": "user",
"content": "What's the weather in 94110?" },
{ "role": "tool_call",
"content": "{\"tool_call\": \"get_weather\", \"arguments\": {\"zip\": \"94110\"}}" },
{ "role": "tool_response",
"content": "{\"tool_name\": \"get_weather\", \"response\": {\"temperature_f\": 64, \"condition\": \"Partly cloudy\"}}" },
{ "role": "agent",
"content": "It's 64 degrees and partly cloudy." }
]
}Puedes obtenerla mediante
GET /v1/calls/{call_id}/transcript;
el flujo de eventos sin procesar (con tiempos por entrada y desplazamientos de audio) está en
GET /v1/calls/{call_id}/history.
En las vistas de lista de llamadas y analíticas, ThunderPhone ahora informa las llamadas de prueba por separado del tráfico real. Las pruebas y simulaciones de Browser Talk pueden reutilizar un número de teléfono real y parecer entrantes, pero no cuentan para los totales de llamadas de producción, las calificaciones ni las métricas de incidencias.
Problemas comunes
El agente nunca llama a la herramienta
El LLM decide según la descripción de la herramienta. Si la pregunta de quien llama
no coincide con la descripción, el modelo no invocará la herramienta. Haz la
descripción más precisa (agrega sinónimos y frases comunes) o menciónala
explícitamente en el prompt del agente ("Cuando quien llama pregunte sobre el
clima, usa get_weather.").
La herramienta devuelve demasiados datos
Las respuestas de más de 6 kB se truncan en la vista previa de la transcripción. Devuelve solo los campos que el LLM necesita, no toda la fila.
Tiempos de espera
Los endpoints de herramientas tienen un tiempo de espera predeterminado de 10 segundos. Si necesitas más tiempo,
manéjalo de forma asíncrona: devuelve {"status": "pending", "request_id": "..."}
y muestra el resultado mediante una llamada de herramienta independiente.
Control de versiones
Cada PATCH de integración crea una nueva revisión. Consulta
GET /v1/integrations/{id}/versions
para ver quién cambió qué. Si dañas el esquema de una herramienta, puedes
revertirlo manualmente aplicando PATCH a una instantánea anterior.
Próximos pasos
CRUD, transferencia, historial de versiones.
Gramática completa del esquema JSON y el contrato de endpoint firmado.
Aplica el patrón de firma de webhook a los endpoints de herramientas.
Inspecciona el ciclo completo de una llamada de herramienta.