---
title: "Przetestuj agenta kompleksowo (API)"
description: "Uruchamiaj jednorazowe symulacje, równoległe partie scenariuszy i zestawy testów stanowiących bramkę wydania za pośrednictwem interfejsu API ThunderPhone, aby wykrywać regresje agenta, zanim usłyszą je klienci."
---

<Note>
  Wolisz panel? Ta sama funkcja jest dostępna w **Symulacjach**
  (`/dashboard/simulations`), w tym generowanie scenariuszy przez AI — zobacz
  [Symulowanie połączenia](/pl/guides/simulate-a-call). Ta strona opisuje
  ścieżkę programistyczną.
</Note>

Iterowanie nad agentem AI oznacza iterowanie nad jego promptem, narzędziami
i sposobem obsługi przypadków brzegowych. **API symulacji** wykonuje rzeczywiste
połączenia z agentem przy użyciu dostarczonego promptu scenariusza. Wskazanie
agenta tworzy uruchomienie bot-bot; wskazanie numeru telefonu tworzy uruchomienie
pętli zwrotnej SIP. Każde uruchomienie tworzy rzeczywisty dziennik połączenia z
transkrypcją, oceną i rozliczeniem, dzięki czemu dokładnie widzisz, jak zachowuje
się agent i ile to kosztuje.

Używaj go do:

- Testów smoke przed wdrożeniem po każdej zmianie promptu
- Zestawów regresji podłączonych do CI (podłącz webhook `test-call.completed`
  → zakończ kompilację niepowodzeniem, jeśli wynik spadnie)
- Testowania obciążeniowego limitów współbieżności

## Jednorazowo: pojedyncze uruchomienie

```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
  }'
```

Pola:

| Pole | Typ | Wymagane | Opis |
|-------|------|----------|-------------|
| `target_type` | ciąg znaków | tak | `agent` lub `phone_number` |
| `target_id` | liczba całkowita | tak | Identyfikator agenta (lub identyfikator numeru telefonu) |
| `direction` | ciąg znaków | nie | `outbound` (domyślnie; testowy rozmówca inicjuje połączenie) lub `inbound` (testowy rozmówca odbiera połączenie) |
| `scenario_prompt` | ciąg znaków | nie | Określa, co mówi bot testowy |
| `language` / `primary_language` | ciąg znaków | nie | Język testowego rozmówcy; nieobsługiwane kody są odrzucane |
| `simulator_product` | ciąg znaków | nie | `testing` (domyślnie) lub `spark` dla bardziej ludzkiego symulowanego rozmówcy, na przykład w testach konsultacji przy ciepłym przekazywaniu |
| `consent_to_charge` | wartość logiczna | **tak** | Musi mieć wartość `true`. Szacowany koszt obejmuje zarówno wybranego agenta, jak i symulowanego rozmówcę według stałej stawki za minutę, plus ewentualny segment telekomunikacyjny |
| `target_number` | ciąg znaków | nie | Zastąpienie E.164 dla strony zdalnej; w przeciwnym razie używany jest testowy numer platformy |

`mode` jest tylko do odczytu i wynika z `target_type`: `agent` tworzy
`mode="bot"`, natomiast `phone_number` tworzy `mode="sip"`.

Odpowiedź jest [obiektem uruchomienia symulacji](/api-reference/test-calls#test-call-run-object)
ze stanem `status="queued"`. Odpytuj, aż `status` zmieni się na `completed` lub
`failed`; po ustawieniu `call_id` wczytaj transkrypcję przez
[`GET /v1/calls/{call_id}/transcript`](/api-reference/calls#get-transcript).

## Partie: równoległe scenariusze

Uruchom jednocześnie N scenariuszy — przydatne w zestawach regresji, które
równolegle obejmują każdy znany przypadek brzegowy:

```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
  }'
```

Odpowiedź zawiera listę `run_ids` identyfikatorów podrzędnych uruchomień. Pobierz
stan partii:

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

Wartość `run_count` jest ograniczona do 20; `stagger_seconds` rozkłada uruchamianie
w czasie, aby uniknąć przeciążania agenta (0–60 s).

## Podłącz do CI

Utwórz pakiet bramek wydania na stronie **Symulacje**
(`/dashboard/simulations`) — wybierz agenta, dodaj scenariusze ręcznie lub
kliknij **Wygeneruj scenariusze za pomocą AI**, aby utworzyć ich wersje robocze na podstawie
promptu agenta (z opcjonalnym przebiegiem przypadków brzegowych), a następnie zgrupuj je w pakiet.
Pakiet przypina scenariusze i agenta, a także minimalny współczynnik zaliczeń oraz
opcjonalną regułę braku krytycznych niepowodzeń. Zaliczone uruchomienia stają się zaakceptowaną
bazą odniesienia; późniejsze przejścia z zaliczenia do niezaliczenia są zwracane jako regresje.

Użyj w CI [klucza API organizacji](/api-reference/developer-api-keys).
Ten skrypt uruchamia pakiet, odpytyje do momentu zakończenia oceniania i porównania,
a następnie kończy działanie z kodem różnym od zera, chyba że werdykt to `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` zwraca `202` z identyfikatorem
uruchomienia. `GET /v1/orgs/{org_id}/suites/{suite_id}/runs/{run_id}` zwraca
`status`, `verdict`, `pass_rate`, `critical_failure_count` oraz listę
regresji `regressions` z bazy odniesienia. Oba punkty końcowe wiążą organizację z adresu URL
z organizacją klucza API.

## Uruchamiaj pakiet według harmonogramu

Otwórz kartę **Symuluj** agenta, wybierz **Pakiety bramek wydania** i utwórz lub
edytuj pakiet. Włącz **Uruchamiaj według harmonogramu**, wybierz **Częstotliwość** oraz
**Strefę czasową**, a następnie ustaw **Minutę po pełnej godzinie**, **Czas lokalny** lub **Dzień**,
zgodnie z opisem. Wybierz **Zapisz pakiet**. Odznaczenie opcji **Uruchamiaj według harmonogramu** usuwa
harmonogram w panelu.

### Przez API

Wykonaj PATCH pakietu, aby dodać lub zastąpić jego harmonogram. Zobacz [Pakiety (bramki
wydania)](/api-reference/test-scenarios#suites-release-gates), aby poznać pełny
obiekt pakietu i punkty końcowe.

```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` może mieć wartość `hourly`, `daily` lub `weekly`. Użyj strefy czasowej IANA.
Harmonogramy godzinowe używają `minute`; harmonogramy dzienne używają `hour` i `minute`;
harmonogramy tygodniowe używają również `weekday`, gdzie poniedziałek to `0`, a niedziela to `6`.
Odpowiedź pakietu zawiera `next_run_at` i `last_run_at`.

Czasy uwzględniają zmiany czasu letniego w wybranej strefie czasowej. Zaplanowane uruchomienia
pojawiają się w historii uruchomień pakietu i używają jego aktualnego agenta, scenariuszy,
kryteriów oraz zaakceptowanej bazy odniesienia. Każde wygenerowane połączenie testowe emituje
`test-call.completed`; nie ma webhooka ukończenia na poziomie pakietu. Zaplanowane
połączenia są rozliczane według tej samej stawki za symulację co ręczne uruchomienia pakietu i zapisują
`trigger: "schedule"` przy uruchomieniu pakietu.

Aby wstrzymać harmonogram bez zmiany jego godzin, wykonaj PATCH pełnego istniejącego
obiektu harmonogramu z `"enabled": false`. Wymagane jest `frequency`; pominięte
pola strefy czasowej i czasu zostaną zresetowane do wartości domyślnych, dlatego uwzględnij
istniejące wartości. Wyślij `"schedule": null`, aby usunąć harmonogram.

## Wzorce

### Korpus regresji dla każdego promptu

Utrzymuj plik JSON z krotkami `{name, scenario_prompt, expected_outcome}`.
Przy każdej zmianie promptu uruchamiaj pełny zestaw wsadowo; porównuj
transkrypcje i oceny z poprzednim uruchomieniem.

### Test smoke dla każdego wydania

Pojedyncza partia pięciu scenariuszy ścieżki pozytywnej, uruchamiana po każdym
wdrożeniu. Test jest wrażliwy na opóźnienia, więc zachowaj `stagger_seconds: 0`.

### Testy porównawcze opóźnień

Uruchamiaj identyczne scenariusze dla różnych poziomów produktu (`spark`,
`bolt`, `storm-base`). Porównuj wyniki `call.graded` oraz
`duration_seconds` z każdego utworzonego dziennika połączeń.

---

## Kolejne kroki

<CardGroup cols={2}>
  <Card title="Dokumentacja połączeń testowych" icon="flask" href="/api-reference/test-calls">
    Każdy parametr zapytania, kod stanu i format partii.
  </Card>
  <Card title="Ocena AI" icon="chart-line" href="/api-reference/calls#ai-call-grading">
    Automatycznie oceniaj każde uruchomienie testowe, aby śledzić jakość w czasie.
  </Card>
  <Card title="Zgłoszenia problemów" icon="triangle-exclamation" href="/api-reference/issue-reports">
    Oznaczaj konkretne testy do weryfikacji przez człowieka.
  </Card>
  <Card title="Webhook test-call.completed" icon="bolt" href="/pl/webhooks/events">
    Przesyłaj wyniki strumieniowo do CI / Slack / PagerDuty.
  </Card>
</CardGroup>
