Benutzersimulation
Bei der Benutzersimulation spielt ein LLM-backed Akteur die Rolle eines Endbenutzers, der mit Ihrem Agenten interagiert. Sie definieren das Profil und das Ziel des Schauspielers, und der Schauspieler führt eine mehrstufige Konversation mit Ihrem Agenten, bis das Ziel erreicht oder das Zug-Limit erreicht ist.
Anmerkung
Die Benutzersimulation ruft Amazon Bedrock-Modelle auf der SDK-Seite auf, um die Antworten des Akteurs zu generieren. Für diese Anrufe fallen die Standardgebühren des Amazon Bedrock-Modells an. Einzelheiten finden Sie auf der Seite mit den AgentCore Preisen
Dies ist nützlich, wenn Sie:
-
Testen Sie mit realistischen Variationen: Der Schauspieler generiert bei jedem Durchlauf unterschiedliche Formulierungen, Folgefragen und Gesprächspfade, wodurch Grenzfälle aufgedeckt werden, die in handgeschriebenen Szenarien übersehen werden.
-
Evaluieren Sie Konversationen mit offenem Ende: Für Agenten, die frei formale Dialoge führen (Kundensupport, Nachhilfe, Beratung), spiegeln simulierte Szenarien das tatsächliche Nutzerverhalten besser wider als feste Abbiegesequenzen.
-
Skalieren Sie die Szenarioabdeckung: Anstatt Dutzende von Drehbüchern mit mehreren Runden von Hand zu schreiben, definieren Sie Schauspielerprofile mit unterschiedlichen Personas und Zielen und lassen Sie den Schauspieler die Konversationen generieren.
-
Regressionstest mit Diversität: Führen Sie dasselbe Schauspielerprofil mehrmals durch, um zu überprüfen, ob Ihr Agent mit unterschiedlichen Ausdrücken derselben Absicht umgeht.
Die Benutzersimulation funktioniert sowohl mit On-Demand-Dataset-Runnern als auch mit Batch-Runnern.
Funktionsweise
Der Runner verarbeitet jedes simulierte Szenario über eine Konversationsschleife:
-
Start: Der Runner sendet das
inputFeld des Szenarios in der ersten Runde an Ihren Agenten. -
Der Agent antwortet: Ihr Agent verarbeitet die Eingabe und gibt eine Antwort zurück.
-
Der Schauspieler bewertet: Der LLM-backed Schauspieler erhält die Antwort des Agenten und entscheidet anhand seines Profils und Ziels, was als Nächstes zu tun ist. Der Schauspieler gibt eine strukturierte Antwort ab, die Folgendes enthält:
-
Begründung: Die interne Begründung des Schauspielers für seine Antwort (zum Beispiel: „Der Agent hat Flugoptionen angegeben, aber nicht nach meiner bevorzugten Zeit gefragt. Ich sollte angeben, dass ich Flüge am Morgen bevorzuge.“). Dies ist nützlich, um herauszufinden, warum sich der Schauspieler auf eine bestimmte Weise verhalten hat.
-
Nachricht: Die nächste Nachricht, die an den Agenten gesendet werden soll.
-
Stoppsignal: Ein boolescher Wert, der angibt, ob der Akteur sein Ziel für erreicht hält.
-
-
Weiter oder Stopp: Wenn der Schauspieler signalisiert, dass das Ziel erreicht ist (
stop: true) oder die Anzahl an Zügen erreicht istmax_turns, wird die Konversation beendet. Andernfalls wird die nächste Nachricht des Schauspielers zur Eingabe für den nächsten Zug. -
Auswerten: Nach Abschluss der Konversation bewertet der Runner die Sitzung mithilfe der konfigurierten Evaluatoren, genau wie bei vordefinierten Szenarien.
Profil des Schauspielers
Jedes simulierte Szenario erfordert einActorProfile, das definiert, wer der Akteur ist und was er erreichen möchte:
| Feld | Erforderlich | Beschreibung |
|---|---|---|
|
|
Ja |
Hintergrundinformationen über den Schauspieler. Beschreibt die Situation und alle relevanten Details, die der Schauspieler kennen sollte. |
|
|
Ja |
Was der Schauspieler im Gespräch erreichen möchte. Der Akteur signalisiert den Abschluss, wenn er feststellt, dass das Ziel erreicht wurde. |
|
|
Nein |
Key-value Paare, die die Eigenschaften des Schauspielers beschreiben (z. B. Fachwissen, Kommunikationsstil, Geduld). Die Standardeinstellung ist leer. |
{ "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" } } }
Konfiguration der Simulation
Die SimulationConfig steuert das Verhalten des Schauspielers und ist in der Evaluierungskonfiguration des Läufers festgelegt:
| Feld | Standard | Description |
|---|---|---|
|
|
Standardmodell |
Die Amazon Bedrock-Modell-ID, die für den Schauspieler LLM verwendet wurde. Wählen Sie ein Modell, das komplexen Persona-Anweisungen folgen kann. Wenn es weggelassen wird, wird das Standardmodell verwendet. |
from bedrock_agentcore.evaluation import SimulationConfig simulation_config = SimulationConfig( model_id="<model-id>", )
Datensatz-Schema
Ein simuliertes Szenario verwendet actor_profile und input anstelle vonturns:
{ "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" ] } ] }
| Feld | Erforderlich | Standard | Description |
|---|---|---|---|
|
|
Ja |
— |
Eindeutiger Bezeichner für das Szenario. |
|
|
Nein |
|
Optionale Metadaten, die das Szenario beschreiben. Nützlich für die Organisation und Identifizierung von Szenarien in Ergebnissen. |
|
|
Ja |
— |
Die Identität und das Ziel des Schauspielers. Siehe Profil des Schauspielers. |
|
|
Ja |
— |
Die erste Nachricht, die an Ihren Agenten gesendet wurde, um die Konversation zu beginnen. |
|
|
Nein |
10 |
Maximale Anzahl von Runden, bevor die Konversation beendet wird. muss mindestens 1 sein. |
|
|
Nein |
— |
Aussagen in natürlicher Sprache zum erwarteten Verhalten. Wird von Evaluatoren auf Sitzungsebene verwendet, z. B. |
Anmerkung
Simulierte Szenarien unterstützen expected_trajectory oder nicht pro Runde, expected_response da der Gesprächsablauf nicht im Voraus bekannt ist. Wird assertions für Ground Truth bei simulierten Szenarien verwendet.
FileDatasetProvidererkennt den Szenariotyp automatisch anhand der JSON-Struktur: Szenarien mit einem actor_profile Feld (und ohne turns Feld) werden als SimulatedScenario geladen.
Verwendung mit dem Batch-Dataset-Runner
Im folgenden Beispiel wird eine simulierte Szenarioauswertung mit dem Batch-Dataset-Runner ausgeführt. simulation_configAktiviert SimulatedScenario Instanzen BatchEvaluationRunConfig und schließt sie in den Datensatz ein:
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}")
Verwendung mit dem On-Demand-Dataset-Runner
Der On-Demand-Dataset-Runner folgt demselben Muster. simulation_configAktiviert SimulatedScenario Instanzen EvaluationRunConfig und schließt sie in den Datensatz ein:
Anmerkung
On-demand Bewertungen werden auf der Grundlage des Verbrauchs berechnet. Einzelheiten finden Sie auf der AgentCore Preisseite
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')})")
Beenden Sie die Bedingungen
Eine simulierte Konversation endet, wenn eine der folgenden Bedingungen erfüllt ist:
-
Ziel erreicht: Der Akteur stellt fest, dass sein Ziel erreicht wurde, und signalisiert
stop: true. Dies ist das erwartete Ergebnis. -
Maximale Anzahl an Runden erreicht: Die Konversation erreicht das
max_turnsLimit. Dies dient als Sicherheits-Backstop. Wenn Ihre Szenarien häufig das Zug-Limit erreichen, sollten Sie erwägen, das Ziel des Schauspielers zu erhöhenmax_turnsoder zu vereinfachen. -
Keine Nachricht gesendet: Der Akteur gibt keine nächste Nachricht ab, signalisiert aber nicht ausdrücklich, dass er stoppt. Dies wird als implizite Zielerreichung behandelt.
Tipps für effektive simulierte Szenarien
-
Seien Sie spezifisch beim Ziel: Vage Ziele wie „ein Gespräch führen“ führen zu unkonzentrierten Interaktionen. Spezifische Ziele wie „Erhalte eine Rückerstattung für Bestellung #12345“ geben dem Akteur einen klaren Endpunkt.
-
Nutze Eigenschaften, um den Schwierigkeitsgrad zu kontrollieren: Ein Schauspieler mit
"expertise": "expert"stellt schwierigere Fragen als einer mit"expertise": "novice". Verwenden Sie Merkmale, um Ihren Agenten in verschiedenen Benutzersegmenten zu testen. -
Setzen Sie realistische Abbiegelimits: Die meisten Kundenservice-Konversationen werden innerhalb von 5 bis 10 Runden abgeschlossen. Eine
max_turnszu hohe Einstellung verschwendet Rechenleistung; eine zu niedrige Einstellung kann dazu führen, dass Konversationen unterbrochen werden, bevor das Ziel erreicht ist. -
Verwenden Sie Behauptungen, um Ground Truth zu erhalten: Da der Konversationsfluss dynamisch ist,
expected_responseist er nicht pro Runde verfügbar. Schreiben Sie Behauptungen, die das erwartete Ergebnis beschreiben, unabhängig vom eingeschlagenen Weg. -
Wählen Sie ein geeignetes Schauspielermodell: Das Schauspielermodell sollte in der Lage sein, über Runden hinweg eine kohärente Persönlichkeit aufrechtzuerhalten. Kleinere Modelle eignen sich für einfache Personas; komplexe Personas mit nuancierten Zielen profitieren von leistungsfähigeren Modellen.