---
title: "اختبر وكيلاً من البداية إلى النهاية (API)"
description: "شغّل عمليات محاكاة أحادية التنفيذ، ودفعات سيناريوهات متوازية، ومجموعات بوابة الإصدار عبر واجهة ThunderPhone API، لكي تُكتشف تراجعات الوكيل قبل أن يسمعها العملاء."
---

<Note>
  تفضّل لوحة التحكم؟ تتوفر الإمكانية نفسها في **المحاكاة**
  (`/dashboard/simulations`)، بما في ذلك إنشاء السيناريوهات بالذكاء الاصطناعي — راجع
  [محاكاة مكالمة](/ar/guides/simulate-a-call). تغطي هذه الصفحة
  المسار البرمجي.
</Note>

يعني التكرار على وكيل ذكاء اصطناعي التكرار على موجّهه وأدواته
وطريقة تعامله مع الحالات الطرفية. تُجري **واجهة برمجة تطبيقات المحاكاة** مكالمات
حقيقية مع وكيل باستخدام موجّه سيناريو تقدّمه. يؤدي استهداف
وكيل إلى تشغيل بين روبوتين؛ ويؤدي استهداف رقم هاتف إلى
تشغيل حلقة SIP راجعة. ينتج عن كل تشغيل سجل مكالمة حقيقي يتضمن
نصًا مفرغًا وتقييمًا وفوترة، بحيث ترى بدقة كيفية تصرف الوكيل
وتكلفته.

استخدمها من أجل:

- اختبارات تحقق سريعة قبل النشر بعد كل تعديل على الموجّه
- مجموعات اختبار الانحدار المتصلة بالتكامل المستمر CI (اربط خطاف الويب `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 ثانية).

## وصّلها إلى CI

أنشئ مجموعة بوابة إصدار في صفحة **المحاكاة**
(`/dashboard/simulations`) — اختر الوكيل، وأضف السيناريوهات يدويًا أو
انقر **إنشاء سيناريوهات بالذكاء الاصطناعي** لصياغتها من موجّه الوكيل
(مع تمرير اختياري للحالات الطرفية)، ثم اجمعها في مجموعة.
تثبّت المجموعة سيناريوهاتها ووكيلها، إضافة إلى حد أدنى لمعدل النجاح وقاعدة
اختيارية تمنع أي إخفاقات حرجة. تصبح عمليات التشغيل الناجحة خط الأساس
المعتمد؛ وتُرجع التحولات اللاحقة من النجاح إلى الفشل على أنها حالات تراجع.

استخدم [مفتاح 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="التقييم بالذكاء الاصطناعي" 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="/ar/webhooks/events">
    دفق النتائج إلى CI / Slack / PagerDuty لديك.
  </Card>
</CardGroup>
