---
title: "Einen Agenten Ende-zu-Ende testen (API)"
description: "Führen Sie Einzelsimulationen, parallele Szenariobatches und Release-Gate-Suites über die ThunderPhone API aus, damit Regressionen bei Agenten erkannt werden, bevor Kunden sie hören."
---

<Note>
  Bevorzugen Sie das Dashboard? Dieselbe Funktion finden Sie unter **Simulations**
  (`/dashboard/simulations`), einschließlich der KI-gestützten Szenariogenerierung —
  siehe [Einen Anruf simulieren](/de/guides/simulate-a-call). Diese Seite behandelt den
  programmatischen Weg.
</Note>

Die Iteration eines KI-Agenten bedeutet, seinen Prompt, seine Tools
und seine Behandlung von Sonderfällen zu optimieren. Die **Simulations-API** führt echte
Anrufe mit einem Agenten anhand eines von Ihnen bereitgestellten Szenario-Prompts aus. Die Ausrichtung
auf einen Agenten erstellt einen Bot-zu-Bot-Lauf; die Ausrichtung auf eine Telefonnummer erstellt einen
SIP-Loopback-Lauf. Jeder Lauf erzeugt ein echtes Anrufprotokoll mit
Transkript, Bewertung und Abrechnung, sodass Sie genau sehen, wie sich der Agent
verhält und was er kostet.

Verwenden Sie sie für:

- Smoke-Tests vor der Bereitstellung nach jeder Prompt-Änderung
- In CI eingebundene Regressionstest-Suites (Webhook `test-call.completed`
  einbinden → Build fehlschlagen lassen, wenn die Punktzahl sinkt)
- Belastungstests von Parallelitätslimits

## Einmalig: einzelner Lauf

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

Felder:

| Feld | Typ | Erforderlich | Beschreibung |
|-------|------|----------|-------------|
| `target_type` | Zeichenfolge | ja | `agent` oder `phone_number` |
| `target_id` | Ganzzahl | ja | Die Agent-ID (oder Telefonnummer-ID) |
| `direction` | Zeichenfolge | nein | `outbound` (Standard; der Testanrufer tätigt den Anruf) oder `inbound` (der Testanrufer nimmt den Anruf entgegen) |
| `scenario_prompt` | Zeichenfolge | nein | Steuert, was der Testbot sagt |
| `language` / `primary_language` | Zeichenfolge | nein | Sprache für den Testanrufer; nicht unterstützte Codes werden abgelehnt |
| `simulator_product` | Zeichenfolge | nein | `testing` (Standard) oder `spark` für einen menschenähnlicheren simulierten Anrufer, etwa für Beratungstests bei Warm Transfers |
| `consent_to_charge` | boolesch | **ja** | Muss `true` sein. Die Schätzung berechnet sowohl für den ausgewählten Agenten als auch für den simulierten Anrufer einen Pauschaltarif pro Minute sowie eventuelle Telefonieverbindungen |
| `target_number` | Zeichenfolge | nein | E.164-Überschreibung für die Gegenseite; andernfalls wird die Plattform-Testnummer verwendet |

`mode` ist schreibgeschützt und wird aus `target_type` abgeleitet: `agent` erzeugt
`mode="bot"`, während `phone_number` `mode="sip"` erzeugt.

Die Antwort ist ein [Simulationslaufobjekt](/api-reference/test-calls#test-call-run-object)
mit `status="queued"`. Fragen Sie ab, bis `status` zu `completed` oder
`failed` wird; sobald `call_id` gesetzt ist, laden Sie das Transkript über
[`GET /v1/calls/{call_id}/transcript`](/api-reference/calls#get-transcript).

## Stapel: parallele Szenarien

Führen Sie N Szenarien gleichzeitig aus — nützlich für Regressionstest-Suites, die
jeden bekannten Sonderfall parallel abdecken:

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

Die Antwort enthält eine `run_ids`-Liste mit IDs untergeordneter Läufe. Rufen Sie den
Stapelstatus ab:

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

`run_count` ist auf 20 begrenzt; `stagger_seconds` verteilt den Startzeitpunkt,
um den Agenten nicht zu überlasten (0–60 s).

## In CI einbinden

Erstellen Sie auf der Seite **Simulationen**
(`/dashboard/simulations`) eine Release-Gate-Suite — wählen Sie den Agenten aus, fügen Sie Szenarien manuell hinzu oder
klicken Sie auf **Szenarien mit KI generieren**, um sie anhand des
Prompts des Agenten zu entwerfen (optional mit einem Durchlauf für Sonderfälle), und gruppieren Sie sie in einer Suite.
Eine Suite fixiert ihre Szenarien und den Agenten sowie eine Mindestbestehensquote und eine
optionale Regel ohne kritische Fehler. Bestandene Durchläufe werden zur akzeptierten
Baseline; spätere Übergänge von bestanden zu fehlgeschlagen werden als Regressionen zurückgegeben.

Verwenden Sie in CI einen [API-Schlüssel der Organisation](/api-reference/developer-api-keys).
Dieses Skript startet die Suite, fragt ab, bis Bewertung und Vergleich
abgeschlossen sind, und beendet sich mit einem von null abweichenden Status, sofern das Urteil nicht `pass` lautet:

```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` gibt `202` mit der
Durchlauf-ID zurück. `GET /v1/orgs/{org_id}/suites/{suite_id}/runs/{run_id}` gibt
`status`, `verdict`, `pass_rate`, `critical_failure_count` und die
Baseline-Liste `regressions` zurück. Beide Endpunkte binden die Organisation in der URL
an die Organisation des API-Schlüssels.

## Eine Suite nach Zeitplan ausführen

Öffnen Sie den Tab **Simulieren** des Agenten, wählen Sie **Release-Gate-Suiten** aus und erstellen oder
bearbeiten Sie eine Suite. Aktivieren Sie **Nach Zeitplan ausführen**, wählen Sie **Häufigkeit** und
**Zeitzone**, und legen Sie anschließend wie gezeigt **Minute nach der Stunde**, **Ortszeit** oder **Tag**
fest. Wählen Sie **Suite speichern**. Wenn Sie **Nach Zeitplan ausführen** deaktivieren, wird der
Dashboard-Zeitplan entfernt.

### Über die API

Führen Sie einen PATCH für die Suite aus, um ihren Zeitplan hinzuzufügen oder zu ersetzen. Siehe [Suiten (Release
Gates)](/api-reference/test-scenarios#suites-release-gates) für das vollständige
Suite-Objekt und die Endpunkte.

```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` kann `hourly`, `daily` oder `weekly` sein. Verwenden Sie eine IANA-Zeitzone.
Stündliche Zeitpläne verwenden `minute`; tägliche Zeitpläne verwenden `hour` und `minute`;
wöchentliche Zeitpläne verwenden zusätzlich `weekday`, wobei Montag `0` und Sonntag `6` ist.
Die Suite-Antwort enthält `next_run_at` und `last_run_at`.

Die Zeiten folgen den Sommerzeitumstellungen der ausgewählten Zeitzone. Geplante Durchläufe
erscheinen im Durchlaufverlauf der Suite und verwenden deren aktuellen Agenten, Szenarien,
Kriterien und akzeptierte Baseline. Jeder generierte Testanruf löst
`test-call.completed` aus; es gibt keinen Webhook für den Abschluss auf Suite-Ebene. Geplante
Anrufe werden zum gleichen Simulationstarif wie manuelle Suite-Durchläufe abgerechnet und zeichnen
`trigger: "schedule"` beim Suite-Durchlauf auf.

Um einen Zeitplan anzuhalten, ohne seine Zeitangaben zu ändern, führen Sie einen PATCH für das vollständige vorhandene
Zeitplanobjekt mit `"enabled": false` aus. `frequency` ist erforderlich; ausgelassene
Zeitzonen- und Zeitfelder werden auf ihre Standardwerte zurückgesetzt, daher müssen Sie die vorhandenen
Werte einschließen. Senden Sie `"schedule": null`, um den Zeitplan zu entfernen.

## Muster

### Regressionskorpus pro Prompt

Pflegen Sie eine JSON-Datei mit Tupeln aus `{name, scenario_prompt, expected_outcome}`. Führen Sie bei jeder Prompt-Änderung den vollständigen Satz als Batch aus; vergleichen Sie die Transkripte und Bewertungen mit dem vorherigen Durchlauf.

### Smoke-Test pro Release

Ein einzelner Batch mit fünf Happy-Path-Szenarien, den Sie nach jedem Deployment ausführen. Latenzempfindlich, daher `stagger_seconds: 0` beibehalten.

### Latenz-Benchmarking

Führen Sie identische Szenarien für verschiedene Produktstufen (`spark`, `bolt`, `storm-base`) aus. Vergleichen Sie die `call.graded`-Bewertungen und die `duration_seconds` aus jedem resultierenden Anrufprotokoll.

---

## Nächste Schritte

<CardGroup cols={2}>
  <Card title="Referenz für Testanrufe" icon="flask" href="/api-reference/test-calls">
    Alle Abfrageparameter, Statuscodes und Batch-Formate.
  </Card>
  <Card title="KI-Bewertung" icon="chart-line" href="/api-reference/calls#ai-call-grading">
    Bewerten Sie jeden Testlauf automatisch, um die Qualität im Zeitverlauf zu verfolgen.
  </Card>
  <Card title="Fehlerberichte" icon="triangle-exclamation" href="/api-reference/issue-reports">
    Kennzeichnen Sie bestimmte Tests zur manuellen Überprüfung.
  </Card>
  <Card title="Webhook test-call.completed" icon="bolt" href="/de/webhooks/events">
    Streamen Sie Ergebnisse in Ihre CI / Slack / PagerDuty.
  </Card>
</CardGroup>
