

# Simulasi pengguna
<a name="user-simulation"></a>

Simulasi pengguna menggunakan LLM-backed aktor untuk memainkan peran pengguna akhir yang berinteraksi dengan agen Anda. Anda menentukan profil dan tujuan aktor, dan aktor mendorong percakapan multi-putaran dengan agen Anda sampai tujuan tercapai atau batas belokan tercapai.

**catatan**  
Simulasi pengguna memanggil model Amazon Bedrock di sisi SDK untuk menghasilkan respons aktor. Biaya pemanggilan model Amazon Bedrock standar berlaku untuk panggilan ini. Untuk detailnya, lihat [halaman AgentCore harga](https://aws.amazon.com/bedrock/agentcore/pricing/).

Ini berguna ketika Anda ingin:
+  **Tes dengan variasi realistis:** Aktor menghasilkan frasa yang berbeda, pertanyaan tindak lanjut, dan jalur percakapan setiap lari, mengekspos kasus tepi yang terlewatkan oleh skenario yang ditulis tangan.
+  **Evaluasi percakapan terbuka:** Untuk agen yang menangani dialog bentuk bebas (dukungan pelanggan, bimbingan belajar, penasihat), skenario simulasi lebih mencerminkan perilaku pengguna nyata daripada urutan giliran tetap.
+  **Cakupan skenario skala:** Alih-alih menulis lusinan skrip multi-putaran dengan tangan, tentukan profil aktor dengan persona dan tujuan yang berbeda dan biarkan aktor menghasilkan percakapan.
+  **Uji regresi dengan keragaman:** Jalankan profil aktor yang sama beberapa kali untuk memeriksa apakah agen Anda menangani beragam ekspresi dengan maksud yang sama.

Simulasi pengguna bekerja dengan runner dataset [on-demand](dataset-evaluations-on-demand.md) dan [batch](dataset-evaluations-batch.md).

## Cara kerjanya
<a name="user-simulation-how-it-works"></a>

Pelari memproses setiap skenario simulasi melalui loop percakapan:

1.  **Mulai:** Pelari mengirimkan `input` bidang skenario ke agen Anda sebagai giliran pertama.

1.  **Agen merespons:** Agen Anda memproses input dan mengembalikan respons.

1.  **Aktor mengevaluasi:** LLM-backed Aktor menerima tanggapan agen dan memutuskan apa yang harus dilakukan selanjutnya berdasarkan profil dan tujuannya. Aktor menghasilkan respons terstruktur yang berisi:
   +  **Penalaran:** Alasan internal aktor untuk tanggapannya (misalnya, “Agen memberikan opsi penerbangan tetapi tidak meminta waktu pilihan saya. Saya harus menentukan bahwa saya lebih suka penerbangan pagi.”). Ini berguna untuk men-debug mengapa aktor berperilaku dengan cara tertentu.
   +  **Pesan:** Pesan berikutnya untuk dikirim ke agen.
   +  **Sinyal berhenti:** Boolean yang menunjukkan apakah aktor menganggap tujuannya tercapai.

1.  **Lanjutkan atau berhenti:** Jika aktor memberi sinyal penyelesaian tujuan (`stop: true`) atau jumlah giliran tercapai`max_turns`, percakapan berakhir. Jika tidak, pesan aktor berikutnya menjadi masukan untuk giliran berikutnya.

1.  **Evaluasi:** Setelah percakapan selesai, pelari mengevaluasi sesi menggunakan evaluator yang dikonfigurasi, sama seperti skenario yang telah ditentukan sebelumnya.

## Profil aktor
<a name="user-simulation-actor-profile"></a>

Setiap skenario simulasi membutuhkan `ActorProfile` yang mendefinisikan siapa aktor itu dan apa yang ingin dicapai:


| Bidang | Diperlukan | Deskripsi | 
| --- | --- | --- | 
|  `context`  | Ya | Informasi latar belakang tentang aktor. Menjelaskan situasi dan detail relevan yang harus diketahui aktor. | 
|  `goal`  | Ya | Apa yang ingin dicapai aktor dalam percakapan. Aktor memberi sinyal penyelesaian ketika menentukan tujuan telah tercapai. | 
|  `traits`  | Tidak | Key-value pasangan yang menggambarkan karakteristik aktor (misalnya, tingkat keahlian, gaya komunikasi, kesabaran). Default untuk kosong. | 

```
{
  "actor_profile": {
    "context": "A customer who purchased a laptop last week and it arrived with a cracked screen",
    "goal": "Get a replacement laptop shipped within 2 business days",
    "traits": {
      "expertise": "non-technical",
      "tone": "frustrated but polite",
      "patience": "low"
    }
  }
}
```

## Konfigurasi simulasi
<a name="user-simulation-config"></a>

`SimulationConfig`Kontrol perilaku aktor dan diatur pada konfigurasi evaluasi pelari:


| Bidang | Default | Deskripsi | 
| --- | --- | --- | 
|  `model_id`  | Model default | ID model Amazon Bedrock digunakan untuk aktor LLM. Pilih model yang dapat mengikuti instruksi persona yang kompleks. Jika dihilangkan, model default digunakan. | 

```
from bedrock_agentcore.evaluation import SimulationConfig

simulation_config = SimulationConfig(
    model_id="<model-id>",
)
```

## Skema kumpulan data
<a name="user-simulation-dataset-schema"></a>

Skenario simulasi menggunakan `actor_profile` dan `input` bukannya`turns`:

```
{
  "scenarios": [
    {
      "scenario_id": "geography-student",
      "scenario_description": "A curious student asks geography questions",
      "actor_profile": {
        "traits": {"expertise": "novice", "tone": "curious"},
        "context": "A student studying world geography who wants to learn about capitals",
        "goal": "Find out the capital cities of at least two different countries"
      },
      "input": "Hi! I'm studying geography. Can you help me learn about world capitals?",
      "max_turns": 5,
      "assertions": [
        "Agent provides accurate capital city information",
        "Agent is helpful and encouraging to the student"
      ]
    }
  ]
}
```


| Bidang | Diperlukan | Default | Deskripsi | 
| --- | --- | --- | --- | 
|  `scenario_id`  | Ya | — | Pengidentifikasi unik untuk skenario. | 
|  `scenario_description`  | Tidak |  `""`  | Metadata opsional yang menjelaskan skenario. Berguna untuk mengatur dan mengidentifikasi skenario dalam hasil. | 
|  `actor_profile`  | Ya | — | Identitas dan tujuan aktor. Lihat [Profil aktor](#user-simulation-actor-profile). | 
|  `input`  | Ya | — | Pesan pertama dikirim ke agen Anda untuk memulai percakapan. | 
|  `max_turns`  | Tidak | 10 | Jumlah putaran maksimum sebelum percakapan berhenti. Setidaknya bernilai 1. | 
|  `assertions`  | Tidak | — | Pernyataan bahasa alami tentang perilaku yang diharapkan. Digunakan oleh evaluator tingkat sesi seperti. `Builtin.GoalSuccessRate` | 

**catatan**  
Skenario simulasi tidak mendukung `expected_trajectory` atau per-putaran `expected_response` karena alur percakapan tidak diketahui sebelumnya. Gunakan `assertions` untuk kebenaran dasar dengan skenario simulasi.

 `FileDatasetProvider`otomatis mendeteksi jenis skenario dari struktur JSON: skenario dengan `actor_profile` bidang (dan tanpa `turns` bidang) dimuat sebagai. `SimulatedScenario`

## Menggunakan dengan runner kumpulan data batch
<a name="user-simulation-batch-example"></a>

Contoh berikut menjalankan evaluasi skenario simulasi menggunakan runner [kumpulan data batch](dataset-evaluations-batch.md). `simulation_config`Aktifkan `BatchEvaluationRunConfig` dan sertakan `SimulatedScenario` instance dalam kumpulan data:

```
import boto3
import json
from bedrock_agentcore.evaluation import (
    BatchEvaluationRunner,
    BatchEvaluationRunConfig,
    BatchEvaluatorConfig,
    CloudWatchDataSourceConfig,
    SimulationConfig,
    AgentInvokerInput,
    AgentInvokerOutput,
    Dataset,
    SimulatedScenario,
    ActorProfile,
)

AGENT_ARN = "arn:aws:bedrock-agentcore:us-west-2:123456789012:runtime/MyAgent-abc123"  # Replace with your agent runtime ARN
REGION = "us-west-2"  # Replace with your region
RUNTIME_ID = AGENT_ARN.split("/")[-1]
AGENT_NAME = RUNTIME_ID.rsplit("-", 1)[0]
ENDPOINT_NAME = "DEFAULT"
LOG_GROUP = f"/aws/bedrock-agentcore/runtimes/{RUNTIME_ID}-{ENDPOINT_NAME}"
SERVICE_NAME = f"{AGENT_NAME}.{ENDPOINT_NAME}"
ACTOR_MODEL_ID = "global.anthropic.claude-haiku-4-5-20251001-v1:0"  # Replace with your preferred model

# Define the dataset with simulated scenarios
dataset = Dataset(
    scenarios=[
        SimulatedScenario(
            scenario_id="support-frustrated-customer",
            scenario_description="A frustrated customer with a defective product",
            actor_profile=ActorProfile(
                traits={"expertise": "non-technical", "tone": "frustrated but polite"},
                context="Purchased a laptop last week that arrived with a cracked screen",
                goal="Get a replacement laptop shipped within 2 business days",
            ),
            input="I received my laptop and the screen is cracked. I need help.",
            max_turns=8,
            assertions=[
                "Agent acknowledges the issue and apologizes",
                "Agent offers a replacement or refund",
                "Agent provides a timeline for resolution",
            ],
        ),
        SimulatedScenario(
            scenario_id="support-billing-question",
            scenario_description="A customer with a billing discrepancy",
            actor_profile=ActorProfile(
                traits={"expertise": "moderate", "tone": "calm"},
                context="Noticed a double charge on the last credit card statement",
                goal="Get the duplicate charge reversed and confirmation of the refund",
            ),
            input="I see two charges for the same order on my statement. Can you look into this?",
            max_turns=6,
            assertions=[
                "Agent investigates the billing issue",
                "Agent confirms whether a duplicate charge exists",
            ],
        ),
    ]
)

# Configure the evaluation
config = BatchEvaluationRunConfig(
    batch_evaluation_name="simulated-support-eval",
    evaluator_config=BatchEvaluatorConfig(
        evaluator_ids=[
            "Builtin.GoalSuccessRate",
            "Builtin.Helpfulness",
        ],
    ),
    data_source=CloudWatchDataSourceConfig(
        service_names=[SERVICE_NAME],
        log_group_names=[LOG_GROUP],
        ingestion_delay_seconds=180,
    ),
    simulation_config=SimulationConfig(
        model_id=ACTOR_MODEL_ID,
    ),
    polling_timeout_seconds=1800,
    polling_interval_seconds=30,
)

# Define the agent invoker
agentcore_client = boto3.client("bedrock-agentcore", region_name=REGION)

def agent_invoker(inp: AgentInvokerInput) -> AgentInvokerOutput:
    payload = inp.payload
    if isinstance(payload, str):
        raw_bytes = json.dumps({"prompt": payload}).encode()
    elif isinstance(payload, dict):
        raw_bytes = json.dumps(payload).encode()
    else:
        raw_bytes = json.dumps({"prompt": str(payload)}).encode()

    print(f"[{inp.session_id}] > sending payload: {raw_bytes.decode()}")
    response = agentcore_client.invoke_agent_runtime(
        agentRuntimeArn=AGENT_ARN,
        runtimeSessionId=inp.session_id,
        payload=raw_bytes,
    )
    response_body = response["response"].read()
    print(f"[{inp.session_id}] < received response: {response_body.decode()}")
    return AgentInvokerOutput(agent_output=json.loads(response_body))

# Run the evaluation
runner = BatchEvaluationRunner(region=REGION)
result = runner.run_dataset_evaluation(
    config=config,
    dataset=dataset,
    agent_invoker=agent_invoker,
)

# Display results
print(f"Status: {result.status}")
if result.evaluation_results:
    er = result.evaluation_results
    print(f"Sessions completed: {er.number_of_sessions_completed}")
    print(f"Sessions failed:    {er.number_of_sessions_failed}")
    for summary in er.evaluator_summaries or []:
        avg = summary.statistics.average_score if summary.statistics else None
        print(f"  {summary.evaluator_id}: avg={avg}")
```

## Menggunakan dengan runner dataset sesuai permintaan
<a name="user-simulation-on-demand-example"></a>

[Pelari dataset sesuai permintaan mengikuti pola](dataset-evaluations-on-demand.md) yang sama. `simulation_config`Aktifkan `EvaluationRunConfig` dan sertakan `SimulatedScenario` instance dalam kumpulan data:

**catatan**  
On-demand evaluasi dibebankan berdasarkan konsumsi. Untuk detailnya, lihat [halaman AgentCore harga](https://aws.amazon.com/bedrock/agentcore/pricing/).

```
from bedrock_agentcore.evaluation import (
    OnDemandEvaluationDatasetRunner,
    EvaluationRunConfig,
    EvaluatorConfig,
    CloudWatchAgentSpanCollector,
    SimulationConfig,
    FileDatasetProvider,
)

AGENT_ARN = "arn:aws:bedrock-agentcore:us-west-2:123456789012:runtime/MyAgent-abc123"  # Replace with your agent runtime ARN
REGION = "us-west-2"  # Replace with your region
RUNTIME_ID = AGENT_ARN.split("/")[-1]
ENDPOINT_NAME = "DEFAULT"
LOG_GROUP = f"/aws/bedrock-agentcore/runtimes/{RUNTIME_ID}-{ENDPOINT_NAME}"
ACTOR_MODEL_ID = "global.anthropic.claude-haiku-4-5-20251001-v1:0"  # Replace with your preferred model

# Load dataset (auto-detects simulated scenarios from actor_profile field)
dataset = FileDatasetProvider("simulated_dataset.json").get_dataset()

# Create span collector
span_collector = CloudWatchAgentSpanCollector(
    log_group_name=LOG_GROUP,
    region=REGION,
)

# Configure with simulation support
config = EvaluationRunConfig(
    evaluator_config=EvaluatorConfig(
        evaluator_ids=["Builtin.GoalSuccessRate", "Builtin.Helpfulness"],
    ),
    evaluation_delay_seconds=180,
    max_concurrent_scenarios=5,
    simulation_config=SimulationConfig(
        model_id=ACTOR_MODEL_ID,
    ),
)

# Run
runner = OnDemandEvaluationDatasetRunner(region=REGION)
result = runner.run(
    agent_invoker=agent_invoker,
    dataset=dataset,
    span_collector=span_collector,
    config=config,
)

for scenario in result.scenario_results:
    print(f"Scenario: {scenario.scenario_id} ({scenario.status})")
    for evaluator in scenario.evaluator_results:
        for r in evaluator.results:
            print(f"  {evaluator.evaluator_id}: {r.get('value')} ({r.get('label')})")
```

## Hentikan kondisi
<a name="user-simulation-stop-conditions"></a>

Percakapan simulasi berakhir ketika salah satu dari kondisi berikut terpenuhi:

1.  **Tujuan selesai:** Aktor menentukan tujuannya telah tercapai dan sinyal`stop: true`. Ini adalah hasil yang diharapkan.

1.  **Giliran maksimum tercapai:** Percakapan mencapai `max_turns` batas. Ini bertindak sebagai backstop keselamatan. Jika skenario Anda sering mencapai batas belokan, pertimbangkan untuk meningkatkan `max_turns` atau menyederhanakan tujuan aktor.

1.  **Tidak ada pesan yang dihasilkan:** Aktor tidak menghasilkan pesan berikutnya tetapi tidak secara eksplisit memberi sinyal berhenti. Ini diperlakukan sebagai penyelesaian tujuan implisit.

## Kiat untuk skenario simulasi yang efektif
<a name="user-simulation-tips"></a>
+  **Jadilah spesifik dalam tujuan: Tujuan** yang tidak jelas seperti “memiliki percakapan” mengarah pada interaksi yang tidak fokus. Tujuan spesifik seperti “dapatkan pengembalian dana untuk pesanan \#12345" memberi aktor titik akhir yang jelas.
+  **Gunakan sifat untuk mengendalikan kesulitan:** Seorang aktor dengan `"expertise": "expert"` mengajukan pertanyaan yang lebih sulit daripada satu dengan`"expertise": "novice"`. Gunakan sifat untuk menguji agen Anda di segmen pengguna yang berbeda.
+  **Tetapkan batas belokan yang realistis:** Sebagian besar percakapan dukungan pelanggan diselesaikan dalam 5 hingga 10 putaran. Mengatur perhitungan limbah yang `max_turns` terlalu tinggi; mengaturnya terlalu rendah dapat memotong percakapan sebelum tujuan tercapai.
+  **Gunakan pernyataan untuk kebenaran dasar:** Karena alur percakapan dinamis, per-putaran `expected_response` tidak tersedia. Tulis pernyataan yang menggambarkan hasil yang Anda harapkan terlepas dari jalur spesifik yang diambil.
+  **Pilih model aktor yang sesuai: Model** aktor harus cukup mampu untuk mempertahankan persona yang koheren secara bergantian. Model yang lebih kecil bekerja untuk persona sederhana; persona kompleks dengan tujuan bernuansa mendapat manfaat dari model yang lebih mampu.