---
title: "ทดสอบเอเจนต์แบบครบวงจร (API)"
description: "เรียกใช้การจำลองแบบครั้งเดียว แบทช์สถานการณ์แบบขนาน และชุดทดสอบเกตการเผยแพร่ผ่าน ThunderPhone API เพื่อให้ตรวจพบการถดถอยของเอเจนต์ก่อนที่ลูกค้าจะได้ยิน"
---

<Note>
  ต้องการใช้แดชบอร์ดหรือไม่ ความสามารถเดียวกันนี้มีอยู่ใน **การจำลอง**
  (`/dashboard/simulations`) รวมถึงการสร้างสถานการณ์ด้วย AI — ดู
  [จำลองการโทร](/th/guides/simulate-a-call) หน้านี้ครอบคลุมแนวทางแบบ
  โปรแกรม
</Note>

การปรับปรุง AI เอเจนต์หมายถึงการปรับปรุงพรอมต์ เครื่องมือ
และวิธีจัดการกรณีขอบ การใช้ **simulations API** จะโทรจริง
ไปยังเอเจนต์โดยใช้พรอมต์สถานการณ์ที่คุณระบุ การกำหนดเป้าหมายเป็น
เอเจนต์จะสร้างการรันแบบบอตถึงบอต ส่วนการกำหนดเป้าหมายเป็นหมายเลขโทรศัพท์จะสร้าง
การรัน SIP แบบลูปแบ็ก ทุกการรันจะสร้างบันทึกการโทรจริงพร้อม
บทสนทนา การให้คะแนน และการเรียกเก็บเงิน เพื่อให้คุณเห็นได้อย่างชัดเจนว่าเอเจนต์
ทำงานอย่างไรและมีค่าใช้จ่ายเท่าใด

ใช้สำหรับ:

- การทดสอบ Smoke Test ก่อนปรับใช้หลังแก้ไขพรอมต์ทุกครั้ง
- ชุดทดสอบ Regression ที่เชื่อมต่อกับ 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` | จำนวนเต็ม | ใช่ | ID ของเอเจนต์ (หรือ ID ของหมายเลขโทรศัพท์) |
| `direction` | สตริง | ไม่ | `outbound` (ค่าเริ่มต้น ผู้โทรทดสอบเป็นผู้โทรออก) หรือ `inbound` (ผู้โทรทดสอบเป็นผู้รับสาย) |
| `scenario_prompt` | สตริง | ไม่ | กำหนดสิ่งที่บอตทดสอบพูด |
| `language` / `primary_language` | สตริง | ไม่ | ภาษาสำหรับผู้โทรทดสอบ ระบบจะปฏิเสธรหัสภาษาที่ไม่รองรับ |
| `simulator_product` | สตริง | ไม่ | `testing` (ค่าเริ่มต้น) หรือ `spark` สำหรับผู้โทรจำลองที่มีลักษณะเหมือนมนุษย์มากขึ้น เช่น การทดสอบปรึกษาก่อนโอนสายแบบ Warm Transfer |
| `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 รายการพร้อมกัน — เหมาะสำหรับชุดทดสอบ Regression ที่
ทดสอบกรณีขอบที่ทราบทั้งหมดแบบขนาน:

```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` ของ ID การรันย่อย ดึงสถานะแบทช์:

```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 วินาที)

## เชื่อมต่อเข้ากับ 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`
ไม่มีเว็บฮุกสำหรับการเสร็จสิ้นในระดับชุด การโทรตามกำหนดเวลาจะคิดค่าบริการในอัตรา
การจำลองเดียวกับการรันชุดด้วยตนเอง และบันทึก `trigger: "schedule"` ในการรันชุด

หากต้องการหยุดกำหนดเวลาชั่วคราวโดยไม่เปลี่ยนเวลา ให้ PATCH อ็อบเจ็กต์กำหนดเวลาปัจจุบัน
ฉบับสมบูรณ์พร้อม `"enabled": false` จำเป็นต้องระบุ `frequency`
เขตเวลาและฟิลด์เวลาที่ละไว้จะรีเซ็ตเป็นค่าเริ่มต้น ดังนั้นให้รวมค่าปัจจุบันไว้ด้วย
ส่ง `"schedule": null` เพื่อลบกำหนดเวลา

## รูปแบบ

### ชุดข้อมูลการทดสอบถดถอยรายพรอมป์ต์

ดูแลไฟล์ JSON ของทูเพิล `{name, scenario_prompt, expected_outcome}`
ทุกครั้งที่มีการเปลี่ยนพรอมป์ต์ ให้รันชุดทั้งหมดเป็นแบตช์ เปรียบเทียบความแตกต่างของ
ทรานสคริปต์และเกรดกับการรันครั้งก่อน

### การทดสอบแบบรวดเร็วรายรีลีส

แบตช์เดียวที่มีสถานการณ์เส้นทางปกติห้ารายการ ซึ่งรันหลังการ
ดีพลอยทุกครั้ง ไวต่อเวลาแฝง ดังนั้นให้คง `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="/th/webhooks/events">
    สตรีมผลลัพธ์ไปยัง CI / Slack / PagerDuty ของคุณ
  </Card>
</CardGroup>
