---
title: "Testaa agentti päästä päähän (API)"
description: "Suorita kertaluonteisia simulaatioita, rinnakkaisia skenaarioeriä ja julkaisun hyväksyntätestisarjoja ThunderPhone API:n kautta, jotta agentin regressiot havaitaan ennen kuin asiakkaat kuulevat ne."
---

<Note>
  Käytätkö mieluummin hallintapaneelia? Sama toiminto löytyy kohdasta **Simulaatiot**
  (`/dashboard/simulations`), mukaan lukien tekoälyllä luotavat skenaariot — katso
  [Simuloi puhelu](/fi/guides/simulate-a-call). Tällä sivulla käsitellään
  ohjelmallista tapaa.
</Note>

Tekoälyagentin kehittäminen tarkoittaa sen kehotteen, työkalujen
ja reunatapausten käsittelytavan kehittämistä. **Simulaatioiden API** tekee todellisia
puheluja agentille antamasi skenaariokehotteen perusteella. Agentin
kohdistaminen luo botista bottiin -ajon; puhelinnumeron kohdistaminen luo
SIP-takaisinkytkentäajon. Jokainen ajo tuottaa todellisen puhelulokin, johon sisältyvät
litterointi, arviointi ja laskutus, joten näet tarkalleen, miten agentti
toimii ja mitä se maksaa.

Käytä sitä seuraaviin:

- Julkaisua edeltävät savutestit jokaisen kehote-muokkauksen jälkeen
- CI:hin liitetyt regressiotestisarjat (kytke `test-call.completed`-webhook
  → epäonnistuta build, jos pisteet laskevat)
- Samanaikaisuusrajojen kuormitustestaus

## Kerta-ajo: yksi ajo

```bash
curl -X POST https://api.thunderphone.com/v1/simulations \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "target_type":     "agent",
    "target_id":       12,
    "direction":       "outbound",
    "scenario_prompt": "You are a polite caller asking about refund policy for order 12345.",
    "consent_to_charge": true
  }'
```

Kentät:

| Kenttä | Tyyppi | Pakollinen | Kuvaus |
|-------|------|----------|-------------|
| `target_type` | merkkijono | kyllä | `agent` tai `phone_number` |
| `target_id` | kokonaisluku | kyllä | Agentin tunnus (tai puhelinnumeron tunnus) |
| `direction` | merkkijono | ei | `outbound` (oletus; testisoittaja soittaa) tai `inbound` (testisoittaja vastaa) |
| `scenario_prompt` | merkkijono | ei | Määrittää, mitä testibotti sanoo |
| `language` / `primary_language` | merkkijono | ei | Testisoittajan kieli; tukemattomat koodit hylätään |
| `simulator_product` | merkkijono | ei | `testing` (oletus) tai `spark` ihmismäisemmän simuloidun soittajan käyttöön, esimerkiksi lämpimän siirron konsultointitesteissä |
| `consent_to_charge` | totuusarvo | **kyllä** | Arvon on oltava `true`. Arvio veloittaa sekä valitun agentin että simuloidun soittajan kiinteällä minuuttihinnalla sekä mahdollisesta puheluyhteyden osuudesta |
| `target_number` | merkkijono | ei | E.164-ohitus etäpäälle; muussa tapauksessa käytetään alustan testinumeroa |

`mode` on vain luku -kenttä, ja se johdetaan arvosta `target_type`: `agent` tuottaa
`mode="bot"`, kun taas `phone_number` tuottaa `mode="sip"`.

Vastaus on [simulaatioajo-objekti](/api-reference/test-calls#test-call-run-object),
jonka tila on `status="queued"`. Kysy tilaa, kunnes `status` muuttuu arvoksi `completed` tai
`failed`; kun `call_id` on asetettu, lataa litterointi komennolla
[`GET /v1/calls/{call_id}/transcript`](/api-reference/calls#get-transcript).

## Erät: rinnakkaiset skenaariot

Aja N skenaariota samanaikaisesti — hyödyllistä regressiotestisarjoissa, jotka
käsittelevät kaikki tunnetut reunatapaukset rinnakkain:

```bash
curl -X POST https://api.thunderphone.com/v1/simulations/batches \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "target_type":     "agent",
    "target_id":       12,
    "direction":       "outbound",
    "run_count":       5,
    "stagger_seconds": 2,
    "scenario_prompts": [
      "Ask about refund policy.",
      "Ask for hours of operation.",
      "Complain about a delayed shipment.",
      "Ask to speak with a human.",
      "Ask an unrelated trivia question."
    ],
    "consent_to_charge": true
  }'
```

Vastaus sisältää `run_ids`-luettelon alisuoritusten tunnuksista. Hae erän
tila:

```bash
curl https://api.thunderphone.com/v1/simulations/batches/{batch_id} \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"
```

`run_count` on rajoitettu arvoon 20; `stagger_seconds` porrastaa käynnistykset,
jotta agenttia ei kuormiteta liikaa (0–60 s).

## Kytke se CI:hin

Luo julkaisukynnyssarja **Simulaatiot**-sivulla
(`/dashboard/simulations`) — valitse agentti, lisää skenaarioita käsin tai
luo ne agentin kehotteen pohjalta valitsemalla **Luo skenaarioita tekoälyllä**
(valinnaisella reunatapausten tarkistuksella) ja ryhmittele ne sarjaksi.
Sarja lukitsee skenaariot ja agentin sekä vähimmäisprosentin hyväksytyille
suorituksille ja valinnaisen säännön, jonka mukaan kriittisiä epäonnistumisia ei saa olla. Hyväksytyistä suorituksista tulee hyväksytty vertailutaso; myöhemmät hyväksytty→hylätty-siirtymät palautetaan regressioina.

Käytä CI:ssä [organisaation API-avainta](/api-reference/developer-api-keys).
Tämä skripti käynnistää sarjan, kyselee tilaa, kunnes arviointi ja vertailu ovat
valmiit, ja päättyy nollasta poikkeavalla paluukoodilla, ellei tulos ole `pass`:

```bash
#!/usr/bin/env bash
set -euo pipefail

: "${THUNDERPHONE_API_KEY:?Set THUNDERPHONE_API_KEY}"
: "${THUNDERPHONE_ORG_ID:?Set THUNDERPHONE_ORG_ID}"
: "${THUNDERPHONE_SUITE_ID:?Set THUNDERPHONE_SUITE_ID}"

base="https://api.thunderphone.com/v1/orgs/${THUNDERPHONE_ORG_ID}/suites/${THUNDERPHONE_SUITE_ID}"
auth="Authorization: Bearer ${THUNDERPHONE_API_KEY}"

run_id="$(curl --fail --silent --show-error -X POST "${base}/run" \
  -H "$auth" -H "Content-Type: application/json" -d '{}' | jq -r '.id')"

deadline=$((SECONDS + 1800))
while (( SECONDS < deadline )); do
  result="$(curl --fail --silent --show-error \
    "${base}/runs/${run_id}" -H "$auth")"
  status="$(jq -r '.status' <<<"$result")"
  if [[ "$status" == "completed" ]]; then
    jq . <<<"$result"
    [[ "$(jq -r '.verdict' <<<"$result")" == "pass" ]]
    exit
  fi
  sleep 10
done

echo "ThunderPhone suite timed out" >&2
exit 1
```

`POST /v1/orgs/{org_id}/suites/{suite_id}/run` palauttaa `202`-vastauksen,
jossa on suorituksen tunnus. `GET /v1/orgs/{org_id}/suites/{suite_id}/runs/{run_id}` palauttaa
arvot `status`, `verdict`, `pass_rate`, `critical_failure_count` ja
vertailutason `regressions`-luettelon. Molemmat päätepisteet sitovat URL-osoitteen organisaation
API-avaimen organisaatioon.

## Suorita sarja aikataulun mukaan

Avaa agentin **Simuloi**-välilehti, valitse **Julkaisukynnyssarjat** ja luo tai
muokkaa sarjaa. Ota käyttöön **Suorita aikataulun mukaan**, valitse **Toistuvuus** ja
**Aikavyöhyke** ja määritä sitten **Minuutti tunnin jälkeen**, **Paikallinen aika** tai **Päivä**
ohjeen mukaisesti. Valitse **Tallenna sarja**. Valinnan **Suorita aikataulun mukaan**
poistaminen poistaa hallintapaneelin aikataulun.

### API:n kautta

Lisää tai korvaa sarjan aikataulu PATCH-pyynnöllä. Katso täydellinen
sarjaobjekti ja päätepisteet kohdasta [Sarjat (julkaisukynnykset)](/api-reference/test-scenarios#suites-release-gates).

```bash
curl -X PATCH https://api.thunderphone.com/v1/suites/{suite_id} \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "schedule": {
      "enabled": true,
      "frequency": "daily",
      "timezone": "America/Chicago",
      "hour": 6,
      "minute": 30
    }
  }'
```

`frequency` voi olla `hourly`, `daily` tai `weekly`. Käytä IANA-aikavyöhykettä.
Tunnittaiset aikataulut käyttävät arvoa `minute`; päivittäiset aikataulut käyttävät arvoja `hour` ja `minute`;
viikoittaiset aikataulut käyttävät lisäksi arvoa `weekday`, jossa maanantai on `0` ja sunnuntai on `6`.
Sarjavastaus sisältää arvot `next_run_at` ja `last_run_at`.

Ajat seuraavat valitun aikavyöhykkeen kesäaikamuutoksia. Aikataulutetut suoritukset
näkyvät sarjan suoritushistoriassa ja käyttävät sen nykyistä agenttia, skenaarioita,
kriteerejä ja hyväksyttyä vertailutasoa. Jokainen luotu testipuhelu lähettää
tapahtuman `test-call.completed`; sarjatasoista valmistumiswebhookia ei ole. Aikataulutetut
puhelut laskutetaan samalla simulaatiohinnalla kuin manuaaliset sarjasuoritukset, ja ne tallentavat
sarjasuoritukseen arvon `trigger: "schedule"`.

Jos haluat keskeyttää aikataulun muuttamatta sen ajoitusta, tee PATCH-pyyntö täydellisellä olemassa olevalla
aikatauluobjektilla, jossa `"enabled": false`. `frequency` vaaditaan; pois jätetyt
aikavyöhyke- ja aika-arvot palautuvat oletusarvoihinsa, joten sisällytä nykyiset
arvot. Lähetä `"schedule": null`, jos haluat poistaa aikataulun.

## Mallit

### Kehotekohtainen regressiotestiaineisto

Ylläpidä JSON-tiedostoa, joka sisältää `{name, scenario_prompt, expected_outcome}`
-monikoita. Suorita jokaisen kehote muutoksen yhteydessä koko joukko eränä; vertaa
transkriptioita ja arvioita edelliseen suoritukseen.

### Julkaisukohtainen savutesti

Yksi viiden onnistuneen polun skenaarion erä, jonka suoritat jokaisen
julkaisun jälkeen. Viiveherkkä, joten pidä `stagger_seconds: 0`.

### Viiveen vertailumittaus

Suorita samat skenaariot eri tuotetasoja vasten (`spark`,
`bolt`, `storm-base`). Vertaa `call.graded`-pisteitä ja
`duration_seconds`-arvoa jokaisesta tuloksena syntyvästä puhelulokista.

---

## Seuraavat vaiheet

<CardGroup cols={2}>
  <Card title="Testipuheluiden viite" icon="flask" href="/api-reference/test-calls">
    Kaikki kyselyparametrit, tilakoodit ja erämuodot.
  </Card>
  <Card title="AI-arviointi" icon="chart-line" href="/api-reference/calls#ai-call-grading">
    Pisteytä jokainen testiajo automaattisesti, jotta voit seurata laatua ajan mittaan.
  </Card>
  <Card title="Ongelmaraportit" icon="triangle-exclamation" href="/api-reference/issue-reports">
    Merkitse tietyt testit ihmisen tarkistettaviksi.
  </Card>
  <Card title="test-call.completed-verkkokoukku" icon="bolt" href="/fi/webhooks/events">
    Suoratoista tulokset CI:hin / Slackiin / PagerDutyyn.
  </Card>
</CardGroup>
