Izradite integraciju alata (API)

Integracija alata višekratno je upotrebljiva HTTP krajnja točka koju agent može pozvati tijekom poziva. ThunderPhoneu dajete opis alata u JSON shemi i URL krajnje točke; agent na temelju razgovora odlučuje kada će je pozvati, a ThunderPhone sa svojih poslužitelja šalje odlazni HTTP zahtjev i vraća odgovor agentu.

Ovaj vodič prikazuje izradu alata za dohvaćanje vremenske prognoze od početka do kraja.

Anatomija alata

Dva dijela:

  1. Shema — definicija funkcije u stilu OpenAI-ja ({type: "function", function: {name, description, parameters}}) koja LLM-u govori što alat radi i koje argumente prima.
  2. Krajnja točka — URL koji poslužitelji ThunderPhonea pozivaju kada LLM odluči upotrijebiti alat. Zahtjev je JSON POST sa argumentima koje je LLM odabrao u tijelu zahtjeva.

1. Odaberite strategiju pohrane

Ugrađeno u agenta

Priložite jednokratni alat polju tools agenta. Jednostavno, ali nije višekratno upotrebljivo.

Spremljena integracija

Spremite alat kao višekratno upotrebljivu integraciju i povežite ga s više agenata. Preporučeno za sve što se upotrebljava više od jednom.

Ovaj vodič koristi put spremljene integracije.

2. Izradite integraciju

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

Spremite vraćeni id (UUID).

3. Testirajte krajnju točku u izoliranom okruženju

Prije nego što integraciju povežete s agentom, pošaljite potpisani zahtjev s poslužitelja ThunderPhonea kako biste potvrdili povezivost:

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

Ovaj test također jača ThunderPhoneove SSRF zaštite — zahtjevi prema localhostu ili privatnim IP rasponima vraćaju 400 code=url_not_allowed.

4. Povežite integraciju s agentom

Priložite je putem integration_ids kada stvarate ili ažurirate agenta:

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

S jednim agentom možete povezati više integracija. Prompt agenta može upućivati na njih po nazivu — "upotrijebi get_weather kada pozivatelj pita o vremenskim uvjetima" — ili ih može implicitno otkriti iz opisa sheme.

5. Implementirajte krajnju točku

Kada agent pozove alat, ThunderPhone šalje potpisani POST na vaš 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"}

Vaš poslužitelj odgovara JSON-om koji se vraća LLM-u:

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

LLM prima taj odgovor i pozivatelju glasovno iznosi sažetak prirodnim jezikom.

6. Testirajte ciklus

Pokrenite sesiju mikrofona s agentom i postavite pitanje koje vaš alat obrađuje ("Kakvo je vrijeme u 94110?"). Transkript poziva prikazuje cijeli tijek zahtjeva i odgovora:

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

Ovo možete dohvatiti putem GET /v1/calls/{call_id}/transcript; neobrađeni tok događaja (s vremenom za svaki unos i pomacima zvuka) nalazi se na GET /v1/calls/{call_id}/history.

Česte zamke

Agent nikada ne poziva alat

LLM odlučuje na temelju opisa alata. Ako pitanje pozivatelja ne odgovara opisu, model neće pozvati alat. Precizirajte opis (dodajte uobičajene sinonime i formulacije) ili ga izričito navedite u promptu agenta ("Kada pozivatelj pita o vremenu, upotrijebite get_weather.").

Alat vraća previše podataka

Odgovori veći od 6 kB skraćuju se u pregledu transkripta. Vratite samo polja koja LLM treba — ne cijeli zapis.

Vremenska ograničenja

Krajnje točke alata imaju zadano vremensko ograničenje od 10 sekundi. Ako trebate više vremena, obradite zahtjev asinkrono: vratite {"status": "pending", "request_id": "..."} i prikažite rezultat putem zasebnog poziva alata.

Verzioniranje

Svaki PATCH integracije stvara novu reviziju. Pregledajte GET /v1/integrations/{id}/versions da biste vidjeli tko je što promijenio. Ako pokvarite shemu alata, možete ručno vratiti prethodnu verziju primjenom PATCH zahtjeva sa starijom snimkom stanja.


Sljedeći koraci