Simular conversas com o SDK do Microsoft Foundry

Gere conversas simuladas a partir de descrições de cenário e avalie-as no nível da conversa. Use esse cenário para testar o comportamento do agente em situações controladas antes da implantação. O serviço gera conversas realistas com base em suas descrições de cenário e, em seguida, as avalia.

Pré-requisitos

Os exemplos usam o cliente SDK configurado em Configurar o cliente SDK.

Entender a simulação de conversa

Essa abordagem é útil para:

  • Teste de pré-implantação: validar o comportamento do agente em diversos cenários sem tráfego real do usuário.
  • Cobertura de casos extremos: cenários de teste que raramente ocorrem naturalmente, mas que são importantes de serem tratados adequadamente.
  • Teste de regressão: verifique se as atualizações do agente não prejudicam o desempenho em cenários conhecidos.
  • Teste em escala: gere muitas conversas rapidamente para testar sob estresse as capacidades do agente.

A simulação de conversa segue estas etapas:

  1. Você fornece descrições de cenários na forma de dados JSONL ou casos de teste embutidos com tipagem forte. Cada caso de teste descreve uma situação que o usuário simulado tenta realizar.
  2. O serviço usa um modelo de simulador para desempenhar a função do usuário, interagindo com seu agente com base no cenário.
  3. Cada cenário gera uma ou mais conversas completas.
  4. Os avaliadores de nível de conversa avaliam as conversas geradas.
  5. Seu projeto armazena os resultados da avaliação. Opcionalmente, você pode armazenar todas as conversas geradas como um conjunto de dados do Foundry com versionamento.

A execução usa a azure_ai_user_conversation_simulation fonte de dados. Coloque as configurações que se aplicam a cada caso de teste em default_simulation_configuration. Um caso de teste pode substituir configurações de conversa individuais em seu simulation_configuration; as configurações que ele não substituir continuarão usando os padrões de execução.

Preparar dados de cenário

Dica

Em vez de criar cenários manualmente, gere-os usando o tipo de tarefa Semente de simulação (multiturno). Antes de usar um conjunto de dados gerado existente com essa API, normalize id e mova desired_num_turnssimulation_configurationpara test_case_id . Consulte Gerar um conjunto de dados de sementes de simulação.

Forneça casos de teste usando um destes tipos de origem:

  • file_id ou file_content para cenários JSONL.
  • inline_user_conversation_simulation para casos de teste fortemente tipados na solicitação de execução. Inclua pelo menos um caso de teste.

Para JSONL, use os nomes de propriedade canônica mostrados no exemplo a seguir. Inclua o objetivo, o contexto e as restrições comportamentais do usuário em test_case_description. A descrição pode conter de 1 a 2.500 caracteres.

{"test_case_id":"contoso_refund_timeline","test_case_description":"Customer returned an item five days ago and wants to know when the refund will arrive.","simulation_configuration":{"desired_num_turns":10}}
{"test_case_id":"contoso_store_hours_lookup","test_case_description":"Customer wants today's closing time and might need to clarify the store location.","simulation_configuration":{"desired_num_turns":3,"conversation_repetitions":2}}

Quando os dados JSONL usam esses nomes canônicos, omita data_mapping. Se ele usar nomes diferentes, mapeie esses atributos para test_case_id, test_case_descriptione simulation_configuration. Não use data_mapping com fonte inline_user_conversation_simulation.

Cada caso de teste inline ou JSONL suporta estas propriedades:

Propriedade Descrição
test_case_id Identificador opcional. O serviço gera um identificador quando você o omite.
test_case_description Cenário, meta do usuário e restrições comportamentais que orientam a conversa simulada.
simulation_configuration Configurações opcionais que substituem os padrões de execução correspondentes para esse caso de teste.

Configurar o usuário simulado

Use o model_configuration objeto para configurar o modelo que reproduz o usuário simulado. Esse modelo é separado do target modelo ou do agente que está sendo avaliado.

Propriedade Obrigatório Descrição
model Yes Implantação do simulador no formato {connectionName}/{modelDeploymentName}. O roteador de modelos não é compatível como modelo do simulador; ele só pode ser um alvo de avaliação.
sampling_params Não Parâmetros de amostragem aplicados quando o simulador gera interações do usuário.
voice_model Não Converte o texto do usuário simulado em fala usando o endpoint Voice Live. Omita esta propriedade para simulação apenas de texto.

Para simulação de voz, voice_model.type deve ser azure-standard. Defina name como um nome de voz neural padrão Azure. Você também pode definir temperature de 0 a 1; quando omitido, o padrão do modelo de voz subjacente se aplica.

Configurar conversas

Defina valores para toda a execução em default_simulation_configuration. Os controles de conversa max_num_turns, conversation_repetitions, desired_num_turns, audio_effects e user_behavior também podem aparecer no simulation_configuration de um caso de teste para substituir os padrões de execução correspondentes. As propriedades de geração de conjunto de dados enable_conversation_dataset_generation e output_conversation_dataset_name são válidas apenas em default_simulation_configuration e não podem ser substituídas por caso de teste.

Propriedade Scope Padrão Descrição
max_num_turns Execução ou caso de teste 20 Limite rígido de turnos em cada conversa. Deve ser pelo menos 1.
conversation_repetitions Execução ou caso de teste 1 Número de conversas independentes geradas para cada caso de teste. Deve ser pelo menos 1.
desired_num_turns Execução ou caso de teste None Duração alvo da conversa. Ele não pode exceder o efetivo max_num_turns. Quando omitido, o simulador determina o comprimento do cenário.
audio_effects Execução ou caso de teste None Efeitos aplicados à simulação de voz. Ignorado para simulação apenas de texto.
user_behavior Execução ou caso de teste None Comportamento simulado do usuário, como interrupção.
enable_conversation_dataset_generation Executar somente false Salva todas as conversas geradas em um conjunto de dados versionado do Foundry.
output_conversation_dataset_name Executar somente Gerado pelo serviço Nome do conjunto de dados usado quando a geração do conjunto de dados de conversa está habilitada.

Configurar condições de voz e interrupções

Coloque audio_effects e user_behavior entre default_simulation_configuration para aplicá-los a cada caso de teste. Para substituir qualquer configuração para um caso de teste, coloque-a dentro do simulation_configuration desse caso de teste.

Use audio_effects para testar como o alvo se comporta em condições de escuta realistas. Adicione um ou mais efeitos: street_traffic, , crowd_chatter, background_tv, metro_stationou telephonic_voice. Defina volume_percentage de 1 a 100 para controlar o volume combinado. O padrão é 15. Os efeitos de áudio são ignorados em simulações somente texto.

Use user_behavior.interruption para testar como o alvo lida com um usuário falando enquanto o alvo está respondendo. Defina type como default para ativar interrupções simuladas. Omita interruption quando interrupções não fazem parte do teste.

{
  "default_simulation_configuration": {
    "audio_effects": {
      "effects": ["street_traffic", "telephonic_voice"],
      "volume_percentage": 20
    },
    "user_behavior": {
      "interruption": {
        "type": "default"
      }
    }
  }
}

Definir avaliadores

Selecione os avaliadores projetados para avaliação em nível de conversa. As conversas simuladas são mapeadas automaticamente para os avaliadores.

import os
from openai.types.eval_create_params import DataSourceConfigCustom
from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import TestingCriterionAzureAIEvaluator, PromptAgentDefinition

endpoint = os.environ["AZURE_AI_PROJECT_ENDPOINT"]
model_deployment_name = os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"]
simulator_model = os.environ["AZURE_AI_SIMULATOR_MODEL"]
agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "")

with (
    DefaultAzureCredential() as credential,
    AIProjectClient(endpoint=endpoint, credential=credential) as project_client,
    project_client.get_openai_client() as openai_client,
):
    # Simulation uses the same "custom" eval group type as dataset evaluation (S1),
    # since the generated conversations follow the same messages schema.
    data_source_config = DataSourceConfigCustom(
        type="custom",
        item_schema={
            "type": "object",
            "properties": {
                "messages": {"type": "array"},
                "tool_definitions": {"type": "array"},
            },
            "required": ["messages"],
        },
        include_sample_schema=False,
    )

    testing_criteria = [
        TestingCriterionAzureAIEvaluator(
            type="azure_ai_evaluator",
            name="output_quality",
            evaluator_name="builtin.output_quality",
            initialization_parameters={"model": model_deployment_name},
            data_mapping={
                "messages": "{{item.messages}}",
                "tool_definitions": "{{item.tool_definitions}}",
            },
        ),
        TestingCriterionAzureAIEvaluator(
            type="azure_ai_evaluator",
            name="tool_use_quality",
            evaluator_name="builtin.tool_use_quality",
            initialization_parameters={"model": model_deployment_name},
            data_mapping={
                "messages": "{{item.messages}}",
                "tool_definitions": "{{item.tool_definitions}}",
            },
        ),
        TestingCriterionAzureAIEvaluator(
            type="azure_ai_evaluator",
            name="deflection_rate",
            evaluator_name="builtin.deflection_rate",
            initialization_parameters={"model": model_deployment_name},
            data_mapping={
                "messages": "{{item.messages}}",
                "tool_definitions": "{{item.tool_definitions}}",
            },
        ),
        TestingCriterionAzureAIEvaluator(
            type="azure_ai_evaluator",
            name="customer_satisfaction",
            evaluator_name="builtin.customer_satisfaction",
            initialization_parameters={"model": model_deployment_name},
            data_mapping={"messages": "{{item.messages}}"},
        ),
        TestingCriterionAzureAIEvaluator(
            type="azure_ai_evaluator",
            name="task_completion",
            evaluator_name="builtin.task_completion",
            initialization_parameters={"model": model_deployment_name},
            data_mapping={"messages": "{{item.messages}}"},
        ),
        TestingCriterionAzureAIEvaluator(
            type="azure_ai_evaluator",
            name="coherence",
            evaluator_name="builtin.coherence",
            initialization_parameters={"model": model_deployment_name},
            data_mapping={"messages": "{{item.messages}}"},
        ),
        TestingCriterionAzureAIEvaluator(
            type="azure_ai_evaluator",
            name="groundedness",
            evaluator_name="builtin.groundedness",
            initialization_parameters={"model": model_deployment_name},
            data_mapping={"messages": "{{item.messages}}"},
        ),
    ]

Criar a avaliação e executar

Salve as linhas JSONL canônicas de Preparar dados de cenário como simulation_scenarios.jsonl.

# Create (or update) an agent to simulate against
agent = project_client.agents.create_version(
    agent_name=agent_name,
    definition=PromptAgentDefinition(
        model=model_deployment_name,
        instructions="You are a helpful customer service agent. Be empathetic and solution-oriented.",
    ),
)

# Upload scenario data
scenarios_id = project_client.datasets.upload_file(
    name="simulation-scenarios",
    version="1",
    file_path="./simulation_scenarios.jsonl",
).id

# Create the evaluation
eval_object = openai_client.evals.create(
    name="Multi-turn Conversation Simulation",
    data_source_config=data_source_config,
    testing_criteria=testing_criteria,
)

# Create a simulation run. AZURE_AI_SIMULATOR_MODEL uses the format
# {connectionName}/{modelDeploymentName}.
eval_run = openai_client.evals.runs.create(
    eval_id=eval_object.id,
    name="conversation-simulation-run",
    data_source={
        "type": "azure_ai_user_conversation_simulation",
        "source": {
            "type": "file_id",
            "id": scenarios_id,
        },
        "target": {
            "type": "azure_ai_agent",
            "name": agent.name,
            "version": agent.version,
        },
        "model_configuration": {
            "model": simulator_model,
            "sampling_params": {
                "temperature": 0.7,
                "top_p": 1.0,
                "max_completion_tokens": 800,
            },
        },
        "default_simulation_configuration": {
            "max_num_turns": 8,
            "conversation_repetitions": 2,
            "desired_num_turns": 5,
            "enable_conversation_dataset_generation": True,
            "output_conversation_dataset_name": "support-simulations",
        },
    },
    extra_body={"evaluation_level": "conversation"},
)

Usar casos de teste em linha

Para definir cenários diretamente na requisição de execução, defina data_source.source como origem inline_user_conversation_simulation. Fontes inline exigem pelo menos um caso de teste e não utilizam data_mapping.

inline_source = {
    "type": "inline_user_conversation_simulation",
    "test_cases": [
        {
            "test_case_id": "refund-delay",
            "test_case_description": "A frustrated customer wants an update on a delayed refund.",
            "simulation_configuration": {
                "desired_num_turns": 6,
            },
        }
    ],
}

# In the run request:
# data_source={..., "source": inline_source}

Buscar conversas geradas

Sondar a execução até atingir um estado terminal, conforme descrito em Obter resultados de avaliação de nuvem. Quando enable_conversation_dataset_generation estiver true, uma execução concluída inclui uma entrada output_datasets como esta:

{
  "type": "simulated_user_conversations",
  "dataset": {
    "id": "dataset_123",
    "name": "support-simulations",
    "version": "1"
  }
}

Use o conjunto de dados retornado id, name e version para recuperar ou reutilizar as conversas geradas. Se a geração do conjunto de dados estiver desabilitada, output_datasets será omitida.


Próximas Etapas