Ferramentas de função
Forneça aos seus agentes de IA ferramentas de função que chamam APIs externas durante a conversa — buscam dados de clientes, agendam compromissos, atualizam registros — com parâmetros tipados.
As ferramentas de função permitem que seus agentes de IA invoquem APIs externas durante chamadas telefônicas. Use-as para consultar dados de clientes, verificar disponibilidade, agendar compromissos ou executar qualquer ação compatível com seu backend.
Como funciona
- Defina ferramentas com um esquema (quais argumentos a ferramenta aceita)
- Forneça uma configuração de
endpoint(onde o ThunderPhone chama sua API) — ou omita-a para receber chamadas de ferramenta no webhook da sua organização - Durante uma chamada, a IA decide quando usar uma ferramenta com base na conversa
- O ThunderPhone chama seu endpoint com os argumentos da ferramenta
- A resposta da sua API é enviada de volta para a IA continuar a conversa
Esquema da ferramenta
Cada ferramenta segue esta estrutura:
{
"type": "function",
"function": {
"name": "search_appointments",
"description": "Find available appointment slots for a given date",
"parameters": {
"type": "object",
"properties": {
"date": {
"type": "string",
"description": "Date in YYYY-MM-DD format"
},
"service": {
"type": "string",
"description": "Type of service (e.g., 'consultation', 'follow-up')"
}
},
"required": ["date"]
}
},
"endpoint": {
"url": "https://api.example.com/appointments/search",
"method": "POST",
"headers": {
"X-Api-Key": "your-api-key"
}
},
"timeout": 120
}Configuração da ferramenta
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
timeout | número | Não | Tempo máximo de execução em segundos (padrão: 20, máximo: 180) |
Definição da função
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
name | string | Sim | Identificador exclusivo da ferramenta |
description | string | Sim | Explica à IA quando usar esta ferramenta |
parameters | objeto | Sim | Esquema JSON para os argumentos da ferramenta |
Configuração do endpoint
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
url | string | Sim | URL do endpoint da sua API |
method | string | Não | Método HTTP (padrão: POST) |
headers | objeto | Não | Cabeçalhos personalizados a incluir |
Dois caminhos de invocação
A solicitação que seu servidor recebe depende de a ferramenta ter um
endpoint:
Ferramenta com endpoint | Ferramenta sem endpoint | |
|---|---|---|
| Para onde a solicitação vai | Diretamente para endpoint.url | URL de webhook legado da sua organização |
| Corpo | Argumentos da ferramenta sem encapsulamento | Envelope telephony.tool / web.tool |
| Cabeçalhos | Seus endpoint.headers + X-ThunderPhone-Call-ID + X-ThunderPhone-Signature | Content-Type + X-ThunderPhone-Signature |
| Chave de assinatura | Segredo do webhook da organização | Segredo do webhook da organização |
Ambos os caminhos são bloqueantes — a IA está aguardando o
resultado no meio da frase. O tempo limite padrão é 20 s; defina o
timeout no nível superior da ferramenta para permitir uma execução mais longa, até o
máximo da plataforma de 180 s. Mantenha os manipuladores rápidos. Uma combinação é válida:
em uma chamada cuja organização tenha uma URL de webhook, as ferramentas com um endpoint são
chamadas diretamente, e as demais recorrem ao webhook.
Chamadas diretas de endpoint
Quando a IA invoca uma ferramenta que tem um endpoint, o ThunderPhone envia
uma solicitação para sua URL:
Cabeçalhos da solicitação
POST /appointments/search HTTP/1.1
Host: api.example.com
Content-Type: application/json
X-ThunderPhone-Signature: abc123...
X-ThunderPhone-Call-ID: 987654321
X-Api-Key: your-api-keyOs cabeçalhos personalizados de endpoint.headers são sempre incluídos
literalmente, além de dois cabeçalhos no namespace do ThunderPhone:
X-ThunderPhone-Signature— HMAC-SHA256 dos bytes exatos do corpo da solicitação, usando como chave o segredo de webhook da organizaçãoX-ThunderPhone-Call-ID— O ID da chamada atual
Content-Type: application/json é definido, a menos que endpoint.headers
o substitua — um Content-Type personalizado tem prioridade.
Corpo da solicitação
Para POST / PUT / PATCH, o corpo contém apenas os argumentos da
ferramenta (sem envoltório), serializados canonicamente (chaves ordenadas,
separadores compactos):
{"date":"2025-01-02","service":"consultation"}Para GET / DELETE, os argumentos são enviados como parâmetros de
consulta e o corpo fica vazio — a assinatura é então calculada sobre a string
de bytes vazia. Consulte
Verificar assinaturas de webhook.
Resposta
Retorne uma resposta JSON com o resultado da ferramenta:
{
"available_slots": ["9:00 AM", "2:00 PM", "4:30 PM"],
"timezone": "America/Los_Angeles"
}A resposta é formatada e fornecida à IA para continuar a
conversa. Respostas que não são JSON são envolvidas como {"data": "<text>"};
tempos limite e falhas de conexão são informados à IA como erros, para que
o agente possa se desculpar e seguir em frente em vez de ficar bloqueado.
Despacho no modo webhook
Ferramentas sem um endpoint são encaminhadas para a URL de webhook legada
da sua organização como uma solicitação assinada telephony.tool (chamadas telefônicas) ou web.tool
(chamadas web). Diferentemente das notificações de auditoria
entregues aos endpoints de webhook após a execução, esta solicitação é
a execução — sua resposta HTTP é o resultado da ferramenta.
{
"type": "telephony.tool",
"data": {
"call_id": 987654321,
"tool_name": "search_appointments",
"arguments": { "date": "2026-04-21" },
"from_number": "+14155550199",
"to_number": "+15551234567"
}
}web.tool inclui origin_domain em vez de from_number /
to_number. Responda com o resultado da ferramenta em JSON — o mesmo contrato
de resposta das chamadas diretas de endpoint. A solicitação é assinada com o segredo
de webhook da organização sobre o corpo bruto, como qualquer outro webhook.
Verificação de assinatura
As chamadas diretas de ferramentas são assinadas da mesma forma que os webhooks:
- HMAC-SHA256 sobre os bytes exatos do corpo da solicitação (o JSON canônico — chaves ordenadas, sem espaços em branco extras)
- Com chave baseada no segredo de webhook da sua organização
- Ferramentas
GET/DELETEassinam a string de bytes vazia
import hmac
import hashlib
def verify_tool_call(body: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature)
@app.post("/appointments/search")
async def search_appointments(request: Request):
body = await request.body()
signature = request.headers.get("X-ThunderPhone-Signature", "")
if not verify_tool_call(body, signature, WEBHOOK_SECRET):
raise HTTPException(status_code=401)
data = json.loads(body)
date = data["date"]
# Look up availability
slots = await get_available_slots(date)
return {"available_slots": slots}app.post('/appointments/search', express.raw({type: 'application/json'}), (req, res) => {
const signature = req.headers['x-thunderphone-signature'] || '';
const expected = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(req.body)
.digest('hex');
if (!signature ||
signature.length !== expected.length ||
!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature))) {
return res.status(401).send('Invalid signature');
}
const { date, service } = JSON.parse(req.body);
// Look up availability
const slots = getAvailableSlots(date, service);
res.json({ available_slots: slots });
});As receitas completas — incluindo o caso de corpo vazio e a observação sobre não haver segredo — estão em Verificar assinaturas de webhook.
Exemplo: fluxo completo de agendamento
Veja um conjunto de ferramentas para um sistema completo de agendamento de consultas:
{
"tools": [
{
"type": "function",
"function": {
"name": "search_appointments",
"description": "Find available appointment slots",
"parameters": {
"type": "object",
"properties": {
"date": { "type": "string", "description": "YYYY-MM-DD" },
"service": { "type": "string" }
},
"required": ["date"]
}
},
"endpoint": {
"url": "https://api.example.com/appointments/search",
"method": "POST",
"headers": { "X-Api-Key": "key" }
}
},
{
"type": "function",
"function": {
"name": "book_appointment",
"description": "Book an appointment at a specific time",
"parameters": {
"type": "object",
"properties": {
"date": { "type": "string", "description": "YYYY-MM-DD" },
"time": { "type": "string", "description": "HH:MM format" },
"customer_name": { "type": "string" },
"customer_phone": { "type": "string" }
},
"required": ["date", "time", "customer_name"]
}
},
"endpoint": {
"url": "https://api.example.com/appointments/book",
"method": "POST",
"headers": { "X-Api-Key": "key" }
}
},
{
"type": "function",
"function": {
"name": "cancel_appointment",
"description": "Cancel an existing appointment",
"parameters": {
"type": "object",
"properties": {
"confirmation_number": { "type": "string" }
},
"required": ["confirmation_number"]
}
},
"endpoint": {
"url": "https://api.example.com/appointments/cancel",
"method": "POST",
"headers": { "X-Api-Key": "key" }
}
}
]
}Boas práticas
Escreva descrições claras
O campo description ajuda a IA a entender quando usar a ferramenta. Especifique o que ela faz e quando é apropriado usá-la.
Trate erros de forma adequada
Retorne mensagens de erro que a IA consiga entender: {"error": "No slots available for that date"} em vez de erros 500 genéricos.
Mantenha as respostas concisas
Retorne apenas o que a IA precisa para continuar a conversa. Payloads grandes reduzem a velocidade de resposta.
Use campos obrigatórios com critério
Marque campos como required apenas quando for realmente necessário. A IA pedirá ao usuário as informações obrigatórias antes de chamar a ferramenta.
Relacionados
Ferramentas gerenciadas pela plataforma para HubSpot, Salesforce, Slack, Google Calendar, Google Sheets e Cal.com — nenhum endpoint necessário.
Conecte um servidor MCP e permita que o agente chame suas ferramentas.
Integrações REST reutilizáveis que você pode conectar aos agentes.
Um auxiliar de verificação para webhooks e chamadas de ferramentas.