---
title: "Тестирајте агента од почетка до краја (API)"
description: "Покрените једнократне симулације, паралелне пакете сценарија и скупове за контролу издања преко ThunderPhone API-ја да бисте открили регресије агента пре него што их клијенти чују."
---

<Note>
  Више Вам одговара контролна табла? Иста могућност доступна је у одељку **Симулације**
  (`/dashboard/simulations`), укључујући генерисање сценарија помоћу AI-ја — погледајте
  [Симулирајте позив](/sr/guides/simulate-a-call). Ова страница описује
  програмски приступ.
</Note>

Итерирање AI агента подразумева итерирање његовог упита, алата
и начина на који обрађује граничне случајеве. **API за симулације** покреће стварне
позиве ка агенту користећи упит сценарија који наведете. Циљање
агента креира извршавање од бота до бота; циљање броја телефона креира
SIP повратни тест. Свако извршавање производи стварни запис позива са
транскриптом, оцењивањем и обрачуном, тако да тачно видите како се агент
понаша и колико кошта.

Користите га за:

- Smoke тестове пре објављивања након сваке измене упита
- Регресионе пакете повезане са CI-јем (повежите webhook `test-call.completed`
  → неуспешно завршите изградњу ако оцена падне)
- Тестирање ограничења конкурентности под оптерећењем

## Једнократно: једно извршавање

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

Поља:

| Поље | Тип | Обавезно | Опис |
|-------|------|----------|-------------|
| `target_type` | ниска | да | `agent` или `phone_number` |
| `target_id` | цео број | да | ИД агента (или ИД броја телефона) |
| `direction` | ниска | не | `outbound` (подразумевано; тест позивалац позива) или `inbound` (тест позивалац одговара) |
| `scenario_prompt` | ниска | не | Одређује шта тест бот говори |
| `language` / `primary_language` | ниска | не | Језик тест позиваоца; неподржани кодови се одбијају |
| `simulator_product` | ниска | не | `testing` (подразумевано) или `spark` за симулираног позиваоца који више личи на човека, на пример за тестове консултација при топлом пребацивању |
| `consent_to_charge` | логичка вредност | **да** | Мора бити `true`. Процењени трошак обухвата наплату и за изабраног агента и за симулираног позиваоца, као и за било који телекомуникациони сегмент |
| `target_number` | ниска | не | E.164 замена за удаљену страну; у супротном се користи тест број платформе |

`mode` је само за читање и изведен је из `target_type`: `agent` производи
`mode="bot"`, док `phone_number` производи `mode="sip"`.

Одговор је [објекат извршавања симулације](/api-reference/test-calls#test-call-run-object)
са `status="queued"`. Проверавајте док `status` не постане `completed` или
`failed`; када је `call_id` постављен, учитајте транскрипт путем
[`GET /v1/calls/{call_id}/transcript`](/api-reference/calls#get-transcript).

## Пакети: паралелни сценарији

Покрените N сценарија истовремено — корисно за регресионе пакете који
паралелно обухватају сваки познати гранични случај:

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

Одговор садржи листу `run_ids` са ИД-јевима подређених извршавања. Преузмите статус
пакета:

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

`run_count` је ограничен на 20; `stagger_seconds` распоређује покретање
како се агент не би преоптеретио (0–60 s).

## Укључите у CI

Направите пакет контролне тачке издања на страници **Симулације**
(`/dashboard/simulations`) — изаберите агента, ручно додајте сценарије или
кликните на **Генеришите сценарије помоћу AI** да бисте их направили на основу
упита агента (уз опционалну проверу граничних случајева) и групишите их у пакет.
Пакет фиксира своје сценарије и агента, као и минималну стопу пролазности и
опционо правило без критичних неуспеха. Успешна покретања постају прихваћена
основа; каснији прелази из проласка у неуспех враћају се као регресије.

Користите [API кључ организације](/api-reference/developer-api-keys) у CI-ју.
Ова скрипта покреће пакет, проверава статус док се оцењивање и поређење не
заврше и завршава се кодом различитим од нуле осим ако је пресуда `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` враћа `202` са ИД-ом
покретања. `GET /v1/orgs/{org_id}/suites/{suite_id}/runs/{run_id}` враћа
`status`, `verdict`, `pass_rate`, `critical_failure_count` и листу
`regressions` основе. Обе крајње тачке повезују организацију из URL-а са
организацијом API кључа.

## Покрените пакет по распореду

Отворите картицу агента **Симулирајте**, изаберите **Пакети контролне тачке издања**
и направите или измените пакет. Укључите **Покрени по распореду**, изаберите
**Учесталост** и **Временска зона**, а затим подесите **Минут после пуног сата**,
**Локално време** или **Дан** како је приказано. Изаберите **Сачувајте пакет**.
Искључивањем опције **Покрени по распореду** уклањате распоред са контролне табле.

### Путем API-ја

PATCH-ујте пакет да бисте додали или заменили његов распоред. Погледајте
[Пакети (контролне тачке издања)](/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` може бити `hourly`, `daily` или `weekly`. Користите IANA временску
зону. Распореди по сату користе `minute`; дневни распореди користе `hour` и
`minute`; недељни распореди користе и `weekday`, где је понедељак `0`, а недеља
`6`. Одговор пакета садржи `next_run_at` и `last_run_at`.

Времена прате промене летњег рачунања времена у изабраној временској зони.
Заказана покретања приказују се у историји покретања пакета и користе његовог
тренутног агента, сценарије, критеријуме и прихваћену основу. Сваки генерисани
тест позив емитује `test-call.completed`; не постоји webhook за завршетак на
нивоу пакета. Заказани позиви се наплаћују по истој стопи симулације као ручна
покретања пакета и бележе `trigger: "schedule"` у покретању пакета.

Да бисте паузирали распоред без промене времена, PATCH-ујте комплетан постојећи
објекат распореда са `"enabled": false`. `frequency` је обавезан; изостављена
временска зона и временска поља враћају се на подразумеване вредности, зато
укључите постојеће вредности. Пошаљите `"schedule": null` да бисте уклонили
распоред.

## Обрасци

### Регресиони корпус по промпту

Одржавајте JSON датотеку са торкама `{name, scenario_prompt, expected_outcome}`.
При свакој измени промпта, покрените цео скуп као пакет; упоредите
транскрипте и оцене са претходним покретањем.

### Smoke тест по издању

Један пакет од пет сценарија са очекиваним током које покрећете после сваког
постављања. Осетљиво на кашњење, зато задржите `stagger_seconds: 0`.

### Мерење кашњења

Покрените идентичне сценарије за различите нивое производа (`spark`,
`bolt`, `storm-base`). Упоредите резултате `call.graded` и
`duration_seconds` из сваког добијеног евиденционог записа позива.

---

## Следећи кораци

<CardGroup cols={2}>
  <Card title="Референца за тест позиве" icon="flask" href="/api-reference/test-calls">
    Сваки параметар упита, статусни код и структура пакета.
  </Card>
  <Card title="AI оцењивање" icon="chart-line" href="/api-reference/calls#ai-call-grading">
    Аутоматски оцените свако тестирање да бисте пратили квалитет током времена.
  </Card>
  <Card title="Пријаве проблема" icon="triangle-exclamation" href="/api-reference/issue-reports">
    Означите одређене тестове за људски преглед.
  </Card>
  <Card title="Веб-хук test-call.completed" icon="bolt" href="/sr/webhooks/events">
    Прослеђујте резултате у свој CI / Slack / PagerDuty.
  </Card>
</CardGroup>
