---
title: "একটি এজেন্টকে শুরু থেকে শেষ পর্যন্ত পরীক্ষা করুন (API)"
description: "ThunderPhone API-এর মাধ্যমে এককালীন সিমুলেশন, সমান্তরাল পরিস্থিতি ব্যাচ এবং রিলিজ-গেট স্যুট চালান, যাতে গ্রাহকেরা শোনার আগেই এজেন্টের রিগ্রেশন ধরা পড়ে।"
---

<Note>
  ড্যাশবোর্ড পছন্দ করেন? একই সুবিধা **সিমুলেশনসমূহ**-এ
  (`/dashboard/simulations`) রয়েছে, যার মধ্যে AI দৃশ্যপট তৈরি করাও অন্তর্ভুক্ত — দেখুন
  [একটি কল সিমুলেট করুন](/bn/guides/simulate-a-call)। এই পৃষ্ঠাটি
  প্রোগ্রাম্যাটিক পদ্ধতি নিয়ে আলোচনা করে।
</Note>

একটি AI এজেন্টে পুনরাবৃত্তি করার অর্থ এর prompt, টুল,
এবং এটি যেভাবে edge case পরিচালনা করে সেগুলোতে পুনরাবৃত্তি করা। **সিমুলেশন API**
আপনার দেওয়া একটি দৃশ্যপটের prompt ব্যবহার করে এজেন্টের বিরুদ্ধে বাস্তব
কল চালায়। একটি এজেন্টকে লক্ষ্য করলে bot-to-bot রান তৈরি হয়; একটি ফোন নম্বরকে
লক্ষ্য করলে SIP loopback রান তৈরি হয়। প্রতিটি রান transcript,
গ্রেডিং এবং বিলিংসহ একটি বাস্তব কল লগ তৈরি করে, তাই এজেন্টটি ঠিক কীভাবে
আচরণ করে এবং এর খরচ কত তা আপনি দেখতে পারেন।

এটি ব্যবহার করুন:

- প্রতিটি prompt সম্পাদনার পর ডিপ্লয়-পূর্ব smoke test-এর জন্য
- CI-এর সঙ্গে সংযুক্ত regression suite-এর জন্য (`test-call.completed` webhook
  হুক করুন → স্কোর কমে গেলে build ব্যর্থ করুন)
- concurrency সীমার stress test করার জন্য

## একবারে: একক রান

```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` | string | হ্যাঁ | `agent` অথবা `phone_number` |
| `target_id` | integer | হ্যাঁ | এজেন্ট id (অথবা ফোন নম্বর id) |
| `direction` | string | না | `outbound` (ডিফল্ট; টেস্ট কলার কল শুরু করে) অথবা `inbound` (টেস্ট কলার উত্তর দেয়) |
| `scenario_prompt` | string | না | টেস্ট বট কী বলবে তা নির্ধারণ করে |
| `language` / `primary_language` | string | না | টেস্ট কলারের ভাষা; অসমর্থিত কোড প্রত্যাখ্যান করা হয় |
| `simulator_product` | string | না | `testing` (ডিফল্ট) অথবা আরও মানবসদৃশ সিমুলেটেড কলারের জন্য `spark`, যেমন warm-transfer consult test |
| `consent_to_charge` | boolean | **হ্যাঁ** | অবশ্যই `true` হতে হবে। মূল্য নির্ধারণে নির্বাচিত এজেন্ট এবং সিমুলেটেড কলার, পাশাপাশি যেকোনো টেলিফোনি leg-এর জন্য বিল করা হয় |
| `target_number` | string | না | দূরবর্তী পক্ষের জন্য E.164 override; অন্যথায় প্ল্যাটফর্ম টেস্ট নম্বর ব্যবহার করা হয় |

`mode` শুধুমাত্র-পঠনযোগ্য এবং `target_type` থেকে নির্ধারিত: `agent` তৈরি করে
`mode="bot"`, আর `phone_number` তৈরি করে `mode="sip"`।

রেসপন্সটি `status="queued"` অবস্থায় একটি [সিমুলেশন রান অবজেক্ট](/api-reference/test-calls#test-call-run-object)
হয়। `status` `completed` বা
`failed` হওয়া পর্যন্ত poll করুন; `call_id` সেট হয়ে গেলে,
[`GET /v1/calls/{call_id}/transcript`](/api-reference/calls#get-transcript)-এর মাধ্যমে transcript লোড করুন।

## ব্যাচ: সমান্তরাল দৃশ্যপট

একসঙ্গে Nটি দৃশ্যপট চালান — প্রতিটি পরিচিত edge case-এ
সমান্তরালে আঘাত করা regression suite-এর জন্য উপযোগী:

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

রেসপন্সে child run id-গুলোর একটি `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`
spawn-গুলোর মধ্যে ব্যবধান রাখে (0–60 s)।

## এটিকে CI-এর সঙ্গে যুক্ত করুন

**Simulations** পেজে (`/dashboard/simulations`) একটি রিলিজ গেট স্যুট তৈরি করুন — এজেন্ট নির্বাচন করুন, হাতে করে সিনারিও যোগ করুন অথবা এজেন্টের prompt থেকে সেগুলোর খসড়া তৈরি করতে **AI দিয়ে সিনারিও তৈরি করুন**-এ ক্লিক করুন (ঐচ্ছিক এজ-কেস পর্যালোচনাসহ), তারপর সেগুলোকে একটি স্যুটে গ্রুপ করুন।
একটি স্যুট তার সিনারিও ও এজেন্টের সঙ্গে ন্যূনতম পাস রেট এবং ঐচ্ছিক শূন্য-ক্রিটিক্যাল-ব্যর্থতার নিয়ম স্থির করে। পাস করা রান গ্রহণযোগ্য বেসলাইন হয়ে যায়; পরবর্তী পাস→ফেল পরিবর্তনগুলো রিগ্রেশন হিসেবে ফেরত দেওয়া হয়।

CI-তে একটি [organization API key](/api-reference/developer-api-keys) ব্যবহার করুন।
এই স্ক্রিপ্টটি স্যুট ট্রিগার করে, গ্রেডিং ও তুলনা সম্পূর্ণ না হওয়া পর্যন্ত পোল করে, এবং রায় `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-এর organization-কে API key-এর organization-এর সঙ্গে সংযুক্ত করে।

## সময়সূচিতে একটি স্যুট চালান

এজেন্টের **Simulate** ট্যাব খুলুন, **Release gate suites** নির্বাচন করুন, এবং একটি স্যুট তৈরি বা সম্পাদনা করুন। **Run on a schedule** চালু করুন, **Frequency** ও **Timezone** বেছে নিন, তারপর দেখানো অনুযায়ী **Minute past the hour**, **Local time**, অথবা **Day** সেট করুন। **Save suite** নির্বাচন করুন। **Run on a schedule**-এর নির্বাচন সরালে ড্যাশবোর্ডের সময়সূচি মুছে যায়।

### API-এর মাধ্যমে

স্যুটের সময়সূচি যোগ বা প্রতিস্থাপন করতে স্যুটে PATCH করুন। সম্পূর্ণ স্যুট অবজেক্ট ও এন্ডপয়েন্টের জন্য [Suites (release gates)](/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"` রেকর্ড করে।

সময় পরিবর্তন না করে একটি সময়সূচি বিরতি দিতে, সম্পূর্ণ বিদ্যমান সময়সূচি অবজেক্টে `"enabled": false` দিয়ে PATCH করুন। `frequency` আবশ্যক; বাদ দেওয়া টাইমজোন ও সময় ফিল্ড তাদের ডিফল্টে রিসেট হয়, তাই বিদ্যমান মানগুলো অন্তর্ভুক্ত করুন। সময়সূচি সরাতে `"schedule": null` পাঠান।

## প্যাটার্ন

### প্রতি-prompt রিগ্রেশন কর্পাস

`{name, scenario_prompt, expected_outcome}` টিউপলের একটি JSON ফাইল বজায় রাখুন।
প্রতিটি prompt পরিবর্তনের সময়, সম্পূর্ণ সেটটি ব্যাচ হিসেবে চালান; আগের রানের সঙ্গে
ট্রান্সক্রিপ্ট ও গ্রেডের পার্থক্য তুলনা করুন।

### প্রতি-রিলিজ স্মোক টেস্ট

প্রতিটি ডিপ্লয়ের পরে চালানোর জন্য পাঁচটি সফল-পথের দৃশ্যপটের একটি একক ব্যাচ।
এটি লেটেন্সি-সংবেদনশীল, তাই `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="/bn/webhooks/events">
    ফলাফল আপনার CI / Slack / PagerDuty-তে স্ট্রিম করুন।
  </Card>
</CardGroup>
