Simulação de usuário
A simulação do usuário usa um LLM-backed ator para desempenhar o papel de um usuário final interagindo com seu agente. Você define o perfil e a meta do ator, e o ator conduz uma conversa em vários turnos com seu agente até que a meta seja atingida ou o limite de turnos seja atingido.
nota
A simulação do usuário invoca os modelos do Amazon Bedrock no lado do SDK para gerar as respostas do ator. As taxas de invocação padrão do modelo Amazon Bedrock se aplicam a essas chamadas. Para obter detalhes, consulte a página AgentCore de preços
Isso é útil quando você quer:
-
Teste com variação realista: o ator gera frases, perguntas complementares e caminhos de conversação diferentes a cada execução, expondo casos extremos que cenários criados à mão perdem.
-
Avalie conversas abertas: para agentes que lidam com diálogos de formato livre (suporte ao cliente, tutoria, consultoria), os cenários simulados refletem melhor o comportamento real do usuário do que as sequências de turnos fixos.
-
Dimensione a cobertura de cenários: em vez de escrever dezenas de roteiros de vários turnos à mão, defina perfis de atores com personalidades e objetivos diferentes e deixe que o ator gere as conversas.
-
Teste de regressão com diversidade: execute o mesmo perfil de ator várias vezes para verificar se seu agente lida com expressões variadas da mesma intenção.
A simulação do usuário funciona com os executores de conjuntos de dados sob demanda e em lote.
Como funciona
O executor processa cada cenário simulado por meio de um loop de conversação:
-
Início: o corredor envia o
inputcampo do cenário para seu agente no primeiro turno. -
O agente responde: seu agente processa a entrada e retorna uma resposta.
-
O ator avalia: o LLM-backed ator recebe a resposta do agente e decide o que fazer a seguir com base em seu perfil e objetivo. O ator produz uma resposta estruturada contendo:
-
Raciocínio: O raciocínio interno do ator para sua resposta (por exemplo, “O agente forneceu opções de voo, mas não perguntou o horário de minha preferência. Devo especificar que prefiro voos matinais.”). Isso é útil para depurar por que o ator se comportou de uma determinada maneira.
-
Mensagem: a próxima mensagem a ser enviada ao agente.
-
Sinal de parada: um booleano indicando se o ator considera sua meta alcançada.
-
-
Continuar ou parar: se o ator sinalizar a conclusão da meta (
stop: true) ou a contagem de turnos chegarmax_turns, a conversa será encerrada. Caso contrário, a próxima mensagem do ator se tornará a entrada para o próximo turno. -
Avaliar: após a conclusão da conversa, o executor avalia a sessão usando os avaliadores configurados, da mesma forma que acontece com os cenários predefinidos.
Perfil do ator
Cada cenário simulado exige um ActorProfile que defina quem é o ator e o que ele deseja alcançar:
| Campo | Obrigatório | Descrição |
|---|---|---|
|
|
Sim |
Informações básicas sobre o ator. Descreve a situação e todos os detalhes relevantes que o ator deve saber. |
|
|
Sim |
O que o ator quer alcançar na conversa. O ator sinaliza a conclusão quando determina que a meta foi atingida. |
|
|
Não |
Key-value pares descrevendo as características do ator (por exemplo, nível de experiência, estilo de comunicação, paciência). O padrão é vazio. |
{ "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" } } }
Configuração de simulação
O SimulationConfig controla o comportamento do ator e é definido na configuração de avaliação do executor:
| Campo | Padrão | Description |
|---|---|---|
|
|
Modelo padrão |
O ID do modelo Amazon Bedrock usado para o ator LLM. Escolha um modelo que possa seguir instruções complexas de persona. Se omitido, o modelo padrão será usado. |
from bedrock_agentcore.evaluation import SimulationConfig simulation_config = SimulationConfig( model_id="<model-id>", )
Esquema do conjunto de dados
Um cenário simulado usa actor_profile e input em vez deturns:
{ "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" ] } ] }
| Campo | Obrigatório | Padrão | Description |
|---|---|---|---|
|
|
Sim |
— |
Identificador exclusivo para o cenário. |
|
|
Não |
|
Metadados opcionais que descrevem o cenário. Útil para organizar e identificar cenários nos resultados. |
|
|
Sim |
— |
A identidade e o objetivo do ator. Consulte Perfil do ator. |
|
|
Sim |
— |
A primeira mensagem enviada ao seu agente para iniciar a conversa. |
|
|
Não |
10 |
Número máximo de turnos antes que a conversa termine. Deve ser pelo menos 1. |
|
|
Não |
— |
Afirmações em linguagem natural sobre o comportamento esperado. Usado por avaliadores em nível de sessão, como. |
nota
Os cenários simulados não oferecem suporte expected_trajectory ou são por turno expected_response porque o fluxo da conversa não é conhecido com antecedência. Use assertions para obter a verdade básica com cenários simulados.
FileDatasetProviderdetecta automaticamente o tipo de cenário a partir da estrutura JSON: cenários com um actor_profile campo (e nenhum turns campo) são carregados como. SimulatedScenario
Usando com o executor do conjunto de dados em lote
O exemplo a seguir executa uma avaliação de cenário simulada usando o executor do conjunto de dados em lote. simulation_configDefina BatchEvaluationRunConfig e inclua SimulatedScenario instâncias no conjunto de dados:
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}")
Usando com o executor de conjunto de dados sob demanda
O executor do conjunto de dados sob demanda segue o mesmo padrão. simulation_configDefina EvaluationRunConfig e inclua SimulatedScenario instâncias no conjunto de dados:
nota
On-demand as avaliações são cobradas com base no consumo. Para obter detalhes, consulte a página AgentCore de preços
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')})")
Condições de parada
Uma conversa simulada termina quando qualquer uma das seguintes condições é atendida:
-
Meta concluída: o ator determina que sua meta foi alcançada e sinaliza
stop: true. Esse é o resultado esperado. -
Máximo de turnos atingidos: a conversa atinge o
max_turnslimite. Isso funciona como um suporte de segurança. Se seus cenários frequentemente atingem o limite de curvas, considere aumentarmax_turnsou simplificar a meta do ator. -
Nenhuma mensagem produzida: o ator não produz a próxima mensagem, mas não sinaliza explicitamente a parada. Isso é tratado como uma conclusão implícita da meta.
Dicas para cenários simulados eficazes
-
Seja específico na meta: metas vagas, como “ter uma conversa”, levam a interações desfocadas. Metas específicas, como “obter um reembolso pelo pedido #12345", fornecem ao ator um objetivo claro.
-
Use características para controlar a dificuldade: um ator
"expertise": "expert"faz perguntas mais difíceis do que um com"expertise": "novice". Use características para testar seu agente em diferentes segmentos de usuários. -
Estabeleça limites de turnos realistas: a maioria das conversas de suporte ao cliente é resolvida em 5 a 10 turnos. Definir
max_turnsmuito alto desperdiça computação; defini-lo muito baixo pode interromper as conversas antes que a meta seja atingida. -
Use afirmações como verdades básicas: como o fluxo da conversa é dinâmico, por turno não
expected_responseestá disponível. Escreva afirmações que descrevam o resultado que você espera, independentemente do caminho específico adotado. -
Escolha um modelo de ator apropriado: O modelo de ator deve ser capaz o suficiente para manter uma personalidade coerente em todos os turnos. Modelos menores funcionam para pessoas simples; personas complexas com metas diferenciadas se beneficiam de modelos mais capazes.