ThunderPhone 2.0 est disponible.En libre-service, à partir de 2 ¢/min.Découvrir l’annonce

Developer cookbook

Créer une intégration d

Permettez à votre agent d

Une intégration d’outil est un endpoint HTTP réutilisable qu’un agent peut invoquer pendant un appel. Vous fournissez à ThunderPhone une description JSON Schema de l’outil ainsi qu’une URL d’endpoint ; l’agent décide quand l’appeler en fonction de la conversation, et ThunderPhone effectue la requête HTTP sortante depuis ses serveurs et renvoie la réponse à l’agent.

Ce guide explique de bout en bout la création d’un outil de consultation de la météo.

Anatomie d’un outil

Deux éléments :

  1. Le schéma — une définition de fonction au format OpenAI ({type: "function", function: {name, description, parameters}}) qui indique au LLM ce que fait l’outil et quels arguments il accepte.
  2. L’endpoint — l’URL appelée par les serveurs de ThunderPhone lorsque le LLM décide d’utiliser l’outil. La requête est un POST JSON contenant dans son corps les arguments choisis par le LLM.

1. Choisir une stratégie de stockage

Intégré à l’agent

Attachez un outil ponctuel au tableau tools de l’agent. Simple, mais non réutilisable.

Intégration enregistrée

Stockez l’outil comme intégration réutilisable et associez-le à plusieurs agents. Recommandé pour tout outil utilisé plus d’une fois.

Ce guide utilise la méthode de l’intégration enregistrée.

2. Créer l’intégration

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" }
    ]
  }'

Enregistrez l’id renvoyé (un UUID).

3. Tester l’endpoint dans le sandbox

Avant d’associer l’intégration à un agent, envoyez une requête signée depuis les serveurs de ThunderPhone afin de confirmer la connectivité :

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" }
  }'
Response
{
  "ok": true,
  "status": 200,
  "elapsed_ms": 187,
  "response_headers": { "content-type": "application/json" },
  "response_preview": "{\"temperature_f\": 64, ...}"
}

Ce test renforce également les protections SSRF de ThunderPhone : les requêtes vers localhost ou des plages d’adresses IP privées renvoient 400 code=url_not_allowed.

4. Liez l’intégration à un agent

Associez-la via integration_ids lorsque vous créez ou mettez à jour un agent :

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-..."]
  }'

Vous pouvez lier plusieurs intégrations à un même agent. Le prompt de l’agent peut les référencer par nom — « utilisez get_weather lorsque l’appelant pose une question sur les conditions météo » — ou les découvrir implicitement à partir des descriptions du schéma.

5. Implémentez le point de terminaison

Lorsque l’agent appelle l’outil, ThunderPhone envoie une requête POST signée à votre endpoint_url :

POST /weather HTTP/1.1
Host: api.example.com
X-Api-Key: your-provider-key
X-ThunderPhone-Signature: <HMAC-SHA256 hex>
X-ThunderPhone-Call-ID: 987654321
Content-Type: application/json

{"zip": "94110"}

Votre serveur répond avec du JSON qui est renvoyé au LLM :

{"temperature_f": 64, "condition": "Partly cloudy", "wind_mph": 8}

Le LLM ingère cette réponse et en communique un résumé naturel à l’appelant.

6. Testez la boucle

Lancez une session micro avec l’agent et posez la question traitée par votre outil (« Quel temps fait-il à 94110 ? »). La transcription de l’appel affiche le cycle complet :

{
  "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." }
  ]
}

Vous pouvez récupérer cela via GET /v1/calls/{call_id}/transcript ; le flux d’événements brut (avec le minutage de chaque entrée et les décalages audio) est disponible dans GET /v1/calls/{call_id}/history.

Pièges courants

L’agent n’appelle jamais l’outil

Le LLM décide en fonction de la description de l’outil. Si la question de l’appelant ne correspond pas à la description, le modèle n’appellera pas l’outil. Précisez la description (ajoutez des synonymes et des formulations fréquentes) ou mentionnez-le explicitement dans le prompt de l’agent (« Lorsque l’ appelant pose une question sur la météo, utilisez get_weather. »).

L’outil renvoie trop de données

Les réponses de plus de 6 kB sont tronquées dans l’aperçu de la transcription. Renvoyez uniquement les champs dont le LLM a besoin — pas l’intégralité de votre enregistrement.

Délais d’expiration

Les points de terminaison d’outils ont un délai d’expiration par défaut de 10 secondes. Si vous avez besoin de plus de temps, gérez cela de manière asynchrone : renvoyez {"status": "pending", "request_id": "..."} et exposez le résultat via un appel d’outil distinct.

Gestion des versions

Chaque PATCH d’intégration crée une nouvelle révision. Consultez GET /v1/integrations/{id}/versions pour voir qui a modifié quoi. Si vous cassez le schéma d’un outil, vous pouvez revenir manuellement en arrière en appliquant par PATCH un ancien instantané.


Prochaines étapes