ThunderPhone 2.0 on nyt julkaistu.Ota käyttöön itse – alkaen 2 ¢/min.Lue lisää julkistuksesta

Developer cookbook

Rakenna työkalintegraatio (API)

Anna agenttisi kutsua API-rajapintojasi kesken keskustelun – hae tietoa tietokannasta, luo tukipyyntö tai etsi tilaus.

työkalintegraatio on uudelleenkäytettävä HTTP-päätepiste, jonka agentti voi kutsua puhelun aikana. Annat ThunderPhonelle työkalun JSON-skeemakuvauksen sekä päätepisteen URL-osoitteen; agentti päättää keskustelun perusteella, milloin sitä kutsutaan, ja ThunderPhone tekee lähtevän HTTP-pyynnön palvelimiltaan ja palauttaa vastauksen agentille.

Tässä oppaassa rakennetaan säähaun työkalu alusta loppuun.

Työkalun rakenne

Kaksi osaa:

  1. Skeema — OpenAI-tyylinen funktiomäärittely ({type: "function", function: {name, description, parameters}}), joka kertoo LLM:lle, mitä työkalu tekee ja mitä argumentteja se vastaanottaa.
  2. Päätepiste — URL-osoite, johon ThunderPhonen palvelimet soittavat, kun LLM päättää käyttää työkalua. Pyyntö on JSON POST, jonka runkona ovat LLM:n valitsemat argumentit.

1. Valitse editori

Hallintapaneeli

Avaa Yhteydet → API:t, luo tai muokkaa API-yhteyttä, vaihda parametrieditorin tilaksi JSON ja lisää määrittely sinne.

Integraatioiden API

Luo määrittely komennolla POST /v1/integrations tai päivitä se komennolla PATCH /v1/integrations/{id}.

Molemmilla tavoilla luodaan tallennettu integraatio. Liitä integraatio agenttiin tallennuksen jälkeen. Agenttien APIssa ei ole kirjoitettavaa sisäistä tools-kenttää. Tässä oppaassa käytetään integraatioiden API-polkuja.

2. Luo integraatio

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

Tallenna palautettu id (UUID). Otsakearvot ovat vain kirjoitettavia: vastaukset luettelevat vain otsakkeiden nimet, ja myöhempi PATCH voi lähettää otsakkeen ilman value-arvoa säilyttääkseen tallennetun arvon.

Määritä osoiteparametreille format: "email"

Sähköpostiosoitteen vastaanottavan parametrin tulee ilmoittaa se skeemassaan:

"email": { "type": "string", "format": "email", "description": "The caller's email address" }

format on enemmän kuin vihje. Ratkaistulle sähköpostiskeemalle ThunderPhone poistaa arvon alusta ja lopusta välilyönnit, muuntaa verkkotunnuksen pieniksi kirjaimiksi, muuttaa itsenäiset englanninkieliset sanat at, dot, underscore, dash ja hyphen merkeikseen sekä poistaa välilyönnit suoraan merkkien @, ., _ ja - ympäriltä ennen päätepisteesi kutsumista. Sanoilla on sama merkitys riippumatta siitä, sisältääkö transkriptio jo kirjaimellisen @-merkin: "john dot smith at gmail dot com" muuttuu muotoon john.smith@gmail.com.

Muut sisäiset välilyönnit hylätään sen sijaan, että ne yhdistettäisiin hiljaisesti. Puhutut erotinsanat ovat vain englanninkielisiä; muunkieliset tai tunnistamattomat välilyönneillä erotetut muodot hylätään. Kelvolliset kansainvälistetyt verkkotunnukset ja SMTPUTF8-paikallisosat hyväksytään. Punycode-syöte säilyy punycodena ja Unicode-verkkotunnussyöte säilyy Unicodena jäsentimen normalisoinnin jälkeen, joten API:si vastaanottaa soittajan antaman tavanomaisen esitystavan. Jos lopullinen arvo on virheellinen, työkalua ei kutsuta. Agentti vastaanottaa virheen invalid_email_argument, joka ohjaa sitä vahvistamaan kirjoitusasun soittajan kanssa ja lähettämään kirjaimellisen osoitteen uudelleen.

Pois jätettyä valinnaista sähköpostiosoitetta ei muuteta. Myös null, tyhjä merkkijono tai pelkistä välilyönneistä koostuva merkkijono jätetään muuttamatta, kun ominaisuus on valinnainen tai voi olla null; samat arvot hylätään pakolliselta sähköpostiosoitteelta, joka ei voi olla null.

Paikalliset skeemaviittaukset, kuten #/$defs/email ja #/definitions/email, sekä anyOf, oneOf ja allOf tarkastetaan sykli- ja syvyysrajoituksin. Ei-paikallinen tai ratkaisematon $ref on tunnettu valvonnan rajoitus ja välitetään muuttamattomana, samoin kuin kutsu, jonka työkalutilannekuvassa ei ole käyttökelpoista skeemaa. Pidä sähköpostiskeemat paikallisina, kun tarvitset tarkistuksen käyttöön.

Parametrit, joilla ei ole pakotettua sähköpostimuotoa, välitetään täsmälleen sellaisina kuin malli ne tuotti.

Tuetut muodot ovat date-time, time, date, duration, email, hostname, ipv4, ipv6 ja uuid; vain email normalisoidaan ja pakotetaan tällä hetkellä.

3. Testaa päätepiste hiekkalaatikossa

Ennen kuin liität integraation agenttiin, lähetä allekirjoitettu pyyntö ThunderPhonen palvelimilta yhteyden varmistamiseksi:

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, ...}"
}

Tämä testi vahvistaa myös ThunderPhonen SSRF-suojauksia — localhostiin tai yksityisiin IP-alueisiin kohdistuvat pyynnöt palauttavat virheen 400 code=url_not_allowed.

4. Liitä integraatio agenttiin

Liitä integration_ids-kentän avulla, kun luot tai päivität agentin:

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

Voit liittää yhteen agenttiin useita integraatioita. Agentin kehotteessa voi viitata niihin nimellä — "käytä get_weather-toimintoa, kun soittaja kysyy sääolosuhteista" — tai agentti voi tunnistaa ne epäsuorasti skeemakuvausten perusteella.

5. Toteuta päätepiste

Kun agentti kutsuu työkalua, ThunderPhone lähettää allekirjoitetun POST-pyynnön osoitteeseen 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"}

Palvelimesi vastaa JSONilla, joka välitetään takaisin LLM:lle:

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

LLM käsittelee vastauksen ja kertoo soittajalle selkokielisen yhteenvedon.

6. Testaa kokonaisuus

Käynnistä agenttia vastaan mikrofonisessio ja kysy kysymys, jonka työkalusi käsittelee ("Mikä sää on alueella 94110?"). Puhelun litterointi näyttää koko kierroksen:

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

Voit hakea tämän osoitteesta GET /v1/calls/{call_id}/transcript; raaka tapahtumavirta (jossa on kunkin merkinnän ajoitus- ja äänisiirtymät) on osoitteessa GET /v1/calls/{call_id}/history.

Puheluluetteloissa ja analytiikkanäkymissä ThunderPhone raportoi nyt testipuhelut erillään todellisesta liikenteestä. Browser Talk -testit ja simulaatiot voivat käyttää uudelleen oikeaa puhelinnumeroa ja näyttää saapuvilta puheluilta, mutta niitä ei lasketa mukaan tuotannon puhelumääriin, arvioihin tai ongelmamittareihin.

Yleiset sudenkuopat

Agentti ei koskaan kutsu työkalua

LLM tekee päätöksen työkalun kuvauksen perusteella. Jos soittajan kysymys ei vastaa kuvausta, malli ei kutsu työkalua. Täsmennä kuvausta (lisää yleisiä synonyymeja ja sanamuotoja) tai mainitse se suoraan agentin kehotteessa ("Kun soittaja kysyy säästä, käytä get_weather-toimintoa.").

Työkalu palauttaa liikaa dataa

Yli 6 kB:n vastaukset katkaistaan litteroinnin esikatselussa. Palauta vain kentät, joita LLM tarvitsee — älä koko tietuettasi.

Aikakatkaisut

Työkalupäätepisteiden oletusaikakatkaisu on 10 sekuntia. Jos tarvitset enemmän aikaa, käsittele pyyntö asynkronisesti: palauta {"status": "pending", "request_id": "..."} ja tuo tulos esiin erillisellä työkalukutsulla.

Versiointi

Jokainen integraation PATCH luo uuden revision. Tarkista GET /v1/integrations/{id}/versions nähdäksesi, kuka muutti mitäkin. Jos rikot työkalun skeeman, voit palauttaa sen manuaalisesti lähettämällä vanhemman tilannekuvan takaisin PATCH-pyynnöllä.


Seuraavat vaiheet