

# Introdução à avaliação sob demanda
<a name="getting-started-on-demand"></a>

Siga estas etapas para configurar e executar sua primeira avaliação sob demanda.

**Topics**
+ [Pré-requisitos](#prerequisites-on-demand)
+ [Frameworks compatíveis](#supported-frameworks-on-demand)
+ [Etapa 1: criar e implantar seu agente](#create-deploy-agent-on-demand)
+ [Etapa 2: invocar seu agente](#invoke-agent-on-demand)
+ [Etapa 3: avaliar o agente](#evaluate-agent-on-demand)
+ [Etapa 4: resultados da avaliação](#evaluation-results-on-demand)

## Pré-requisitos
<a name="prerequisites-on-demand"></a>

Para usar os recursos de OnDemand avaliação de AgentCore avaliações, você precisa:
+  ** AWS Conta** com permissões apropriadas do IAM
+  Acesso ao **Amazon Bedrock** com permissões de invocação de modelo
+  **Pesquisa de transações** ativada em CloudWatch - consulte [Ativar pesquisa de transações](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Enable-TransactionSearch.html) 
+  **Python 3.10** ou posterior instalado
+  **A OpenTelemetry biblioteca** — Inclua `aws-opentelemetry-distro` (ADOT) em seu arquivo `requirements.txt`

## Frameworks compatíveis
<a name="supported-frameworks-on-demand"></a>

AgentCore Atualmente, as avaliações oferecem suporte às seguintes estruturas de agentes e bibliotecas de instrumentação:
+ Strands Agents
+ LangGraph configurado com uma das seguintes bibliotecas de instrumentação:
  +  `opentelemetry-instrumentation-langchain` 
  +  `openinference-instrumentation-langchain` 

## Etapa 1: criar e implantar seu agente
<a name="create-deploy-agent-on-demand"></a>

**nota**  
Se você já tiver um agente em execução no AgentCore Runtime, poderá passar diretamente para a etapa 2.

Crie e implante seu agente seguindo o [guia de introdução do AgentCore Runtime](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-getting-started.html). Você pode encontrar exemplos adicionais nas [amostras de AgentCore avaliações](https://github.com/awslabs/amazon-bedrock-agentcore-samples/tree/main/01-tutorials/07-AgentCore-evaluations).

## Etapa 2: invocar seu agente
<a name="invoke-agent-on-demand"></a>

Invoque seu agente usando o comando a seguir e visualize os rastreamentos, sessões e métricas no painel do GenAI Observability em. CloudWatch

**Topics**
+ [Exemplo invoke\_agent.py](#example-invoke-agent)

### Exemplo invoke\_agent.py
<a name="example-invoke-agent"></a>

```
import boto3
import json
import uuid

region = "region-code"
ace_demo_agent_arn = "agent-arn from step-2"

agent_core_client = boto3.client('bedrock-agentcore', region_name=region)

text_to_analyze = "Sample text to test agent for agentcore evaluations demo"

payload = json.dumps({
    "prompt": f"Can you analyze this text and tell me about its statistics: {text_to_analyze}"
})

# random session-id, you can set your own here
session_id = "test-ace-demo-session-18a1dba0-62a0-462g"

response = agent_core_client.invoke_agent_runtime(
    agentRuntimeArn=ace_demo_agent_arn,
    runtimeSessionId=session_id,
    payload=payload,
    qualifier="DEFAULT"
)

response_body = response['response'].read()
response_data = json.loads(response_body)
print("Agent Response:", response_data)
print("SessionId:", session_id)
```

## Etapa 3: avaliar o agente
<a name="evaluate-agent-on-demand"></a>

Depois de fazer algumas invocações ao seu agente, você estará pronto para avaliá-las. Para avaliações, exigimos:
+  `EvaluatorId`: isso pode ser o id de um avaliador embutido ou de um criado de forma personalizada
+  `SessionSpans`: os spans são os blocos de telemetria emitidos quando você interage com um aplicativo. O aplicativo em nosso exemplo é um agente hospedado no AgentCore Runtime.
  + Para avaliação sob demanda, precisamos baixar os intervalos dos grupos de CloudWatch registros e usá-los para avaliação.
  +  AgentCore A **CLI** faz isso automaticamente para você e é a mais fácil de começar.
  + Se você não estiver usando a AgentCore CLI, mostraremos como baixar registros usando o ID da sessão e usá-los para avaliação usando o SDK. AWS 

**Topics**
+ [Exemplos de código para AgentCore CLI e SDK AgentCore](#agentcore-cli-evaluation)
+ [AWS SDK](#aws-sdk-evaluation)

### Exemplos de código para AgentCore CLI e SDK AgentCore
<a name="agentcore-cli-evaluation"></a>

Os exemplos de código a seguir demonstram como executar avaliações sob demanda usando diferentes abordagens de desenvolvimento. Escolha o método mais adequado ao seu ambiente de desenvolvimento e às suas preferências.

**Example**  

1. 

   ```
   # Runs evaluation for the specified runtime and session.
   # It auto queries cloudwatch logs and orchestrates evaluation over multiple evaluators.
   
   RUNTIME_NAME="your_runtime_name"
   SESSION_ID="YOUR_SESSION_ID"
   agentcore run eval \
     --runtime $RUNTIME_NAME \
     --session-id $SESSION_ID \
     --evaluator "Builtin.Helpfulness" \
     --evaluator "Builtin.GoalSuccessRate"
   
   # Auto reads default runtime from current project config if available
   # Verify using ```agentcore status```
   agentcore run eval \
     --evaluator "Builtin.Helpfulness" \
     --evaluator "Builtin.GoalSuccessRate"
   ```

   Os resultados são salvos localmente e podem ser revisados posteriormente com`agentcore evals history`. No modo interativo, a CLI descobre automaticamente as sessões recentes de CloudWatch — você não precisa saber os IDs das sessões com antecedência.
**nota**  
Execute isso de dentro de um diretório de AgentCore projeto (criado com`agentcore create`). O `--agent-arn` sinalizador pode ser usado fora do diretório do projeto.

1. Executar `agentcore` para abrir a TUI, selecione **executar** e escolha **On-demand Avaliação**:

1. Selecione avaliadores para comparar os rastreamentos de agentes:  
![On-demand avaliação: selecione avaliadores](https://docs.aws.amazon.com/pt_br/bedrock-agentcore/latest/devguide/images/tui/eval-run-evaluators.png)

1. Revise a configuração e pressione Enter para confirmar:  
![On-demand avaliação: revisar a configuração](https://docs.aws.amazon.com/pt_br/bedrock-agentcore/latest/devguide/images/tui/eval-run-confirm.png)

1. 

   ```
   from bedrock_agentcore_starter_toolkit import Evaluation
   
   # Initialize the evaluation client
   eval_client = Evaluation()
   
   # Run evaluation on a specific session
   results = eval_client.run(
       agent_id="YOUR_AGENT_ID",      # Replace with your agent ID
       session_id="YOUR_SESSION_ID",  # Replace with your session ID
       evaluators=["Builtin.Helpfulness", "Builtin.GoalSuccessRate"]
   )
   
   # Display results
   successful = results.get_successful_results()
   failed = results.get_failed_results()
   
   print(f"  Successful: {len(successful)}")
   print(f"  Failed:     {len(failed)}")
   
   if successful:
       result = successful[0]
       print("\n📊 Result:")
       print(f"  Evaluator: {result.evaluator_name}")
       print(f"  Score:     {result.value:.2f}")
       print(f"  Label:     {result.label}")
       if result.explanation:
           print(f"  Explanation: {result.explanation[:150]}...")
   ```

### AWS SDK
<a name="aws-sdk-evaluation"></a>

**Topics**
+ [Baixe span-logs de CloudWatch](#download-span-logs)
+ [Avaliação de chamadas](#call-evaluate)
+ [Usando metas de avaliação](#using-evaluation-targets)

#### Baixe span-logs de CloudWatch
<a name="download-span-logs"></a>

Antes de chamar a `Evaluate` API, você precisa baixar os registros de span do CloudWatch. Você pode usar o código Python abaixo para fazer isso e, opcionalmente, salvá-los em um arquivo JSON. Isso facilita a solicitação da mesma sessão com avaliadores diferentes.

**nota**  
Demora alguns minutos para que os registros sejam preenchidos CloudWatch, então é possível que, se você tentar executar o script abaixo “imediatamente” após a invocação do agente, os registros estejam vazios ou incompletos

```
import boto3
import time
import json
from datetime import datetime, timedelta

region = "region-code"
agent_id = "agent-id-from-step-2"
session_id = "session-id-from-step-3"

def query_logs(log_group_name, query_string):
    client = boto3.client('logs', region_name=region)
    start_time = datetime.now() - timedelta(minutes=60) # past 1 hour
    end_time = datetime.now()

    query_id = client.start_query(
        logGroupName=log_group_name,
        startTime=int(start_time.timestamp()),
        endTime=int(end_time.timestamp()),
        queryString=query_string
    )['queryId']

    while (result := client.get_query_results(queryId=query_id))['status'] not in ['Complete', 'Failed']:
        time.sleep(1)

    if result['status'] == 'Failed':
        raise Exception("Query failed")
    return result['results']

def query_session_logs(log_group_name, session_id, **kwargs):
    query = f"""fields @timestamp, @message
    | filter ispresent(scope.name) and ispresent(attributes.session.id)
    | filter attributes.session.id = "{session_id}"
    | sort @timestamp asc"""
    return query_logs(log_group_name, query, **kwargs)

def query_agent_runtime_logs(agent_id, endpoint, session_id, **kwargs):
    return query_session_logs(
        f"/aws/bedrock-agentcore/runtimes/{agent_id}-{endpoint}",
        session_id, **kwargs)

def query_aws_spans_logs(session_id, **kwargs):
    return query_session_logs("aws/spans", session_id, **kwargs)

def extract_messages_as_json(query_results):
    return [json.loads(f['value']) for row in query_results
            for f in row if f['field'] == '@message'
            and f['value'].strip().startswith('{')]

def get_session_span_logs():
    agent_runtime_logs = query_agent_runtime_logs(
        agent_id=agent_id, endpoint="DEFAULT", session_id=session_id
    )
    print(f"Downloaded {len(agent_runtime_logs)} runtime-log entries")

    aws_span_logs = query_aws_spans_logs(session_id=session_id)
    print(f"Downloaded {len(aws_span_logs)} aws/span entries")

    session_span_logs = extract_messages_as_json(aws_span_logs) + extract_messages_as_json(agent_runtime_logs)
    print(f"Returning {len(aws_span_logs) + len(agent_runtime_logs)} total records")
    return session_span_logs

# get the spans from cloudwatch
session_span_logs = get_session_span_logs()

# optional (dump in a json file for reuse)
session_span_logs_file_name = "ace-demo-session.json"
with open(session_span_logs_file_name, "w") as f:
    json.dump(session_span_logs, f, indent=2)
```

#### Avaliação de chamadas
<a name="call-evaluate"></a>

Depois de ter os intervalos de entrada, você pode invocar a `Evaluate` API. Observe que as respostas podem levar alguns minutos, pois um grande modelo de linguagem está pontuando seus rastros.

```
# initialise client
ace_dp_client = boto3.client('bedrock-agentcore', region_name = region)

# call evaluate
response = ace_dp_client.evaluate(
    evaluatorId = "Builtin.Helpfulness", # can be a custom evaluator id as well
    evaluationInput = {"sessionSpans": session_span_logs})

print(response["evaluationResults"])
```

Se você usar a opção acima e despejar os períodos de sessão em um arquivo json, também poderá executar subseqüentemente a avaliação conforme abaixo

```
with open(session_span_logs_file_name, "r") as f:
    session_span_logs = json.load(f)

# initialise client
ace_dp_client = boto3.client('bedrock-agentcore', region_name = region)

# call evaluate
response = ace_dp_client.evaluate(
    evaluatorId = "Builtin.ToolSelectionAccuracy", # can be a custom evaluator id as well
    evaluationInput = {"sessionSpans": session_span_logs})

print(response["evaluationResults"])
```

#### Usando metas de avaliação
<a name="using-evaluation-targets"></a>

Para avaliar um rastreamento ou ferramenta específica em uma sessão, você pode especificar o destino usando o `evaluationTarget` parâmetro em sua solicitação.

**Topics**
+ [Session-level avaliador](#session-level-evaluator)
+ [Trace-level avaliador](#trace-level-evaluator)
+ [Avaliador do nível de chamada da ferramenta](#tool-call-level-evaluator)

##### Session-level avaliador
<a name="session-level-evaluator"></a>

Como o serviço oferece suporte a apenas uma sessão por avaliação, você não precisa definir explicitamente a meta da avaliação.

##### Trace-level avaliador
<a name="trace-level-evaluator"></a>

Para avaliadores em nível de rastreamento (como `Builtin.Helpfulness` ou`Builtin.Correctness`), defina os IDs de rastreamento no parâmetro: `evaluationTarget`

```
response = ace_dp_client.evaluate(
    evaluatorId = "Builtin.Helpfulness",
    evaluationInput = {"sessionSpans": session_span_logs},
    evaluationTarget = {"traceIds": ["trace-id-1", "trace-id-2"]}
)
```

##### Avaliador do nível de chamada da ferramenta
<a name="tool-call-level-evaluator"></a>

Para avaliadores em nível de intervalo (como`Builtin.ToolSelectionAccuracy`), defina os IDs de intervalo no parâmetro: `evaluationTarget`

```
response = ace_dp_client.evaluate(
    evaluatorId = "Builtin.ToolSelectionAccuracy",
    evaluationInput = {"sessionSpans": session_span_logs},
    evaluationTarget = {"spanIds": ["span-id-1", "span-id-2"]}
)
```

## Etapa 4: resultados da avaliação
<a name="evaluation-results-on-demand"></a>

Cada chamada de `Evaluate` API retorna uma resposta contendo uma lista dos resultados do avaliador. Como uma única sessão pode incluir vários rastreamentos e chamadas de ferramentas, esses elementos são avaliados como entidades separadas. Consequentemente, uma única chamada de API pode retornar vários resultados de avaliação.

```
{
    "evaluationResults": [ {evaluation-result-1}, {evaluation-result_2},.... ]
}
```

**Topics**
+ [Limite de resultados](#result-limit)
+ [Falhas parciais](#partial-failures)
+ [Contexto da extensão](#span-context)
+ [Exemplo de entrada de resultado bem-sucedida](#example-successful-result)
+ [Exemplo de falha na entrada de resultado](#example-failed-result)

### Limite de resultados
<a name="result-limit"></a>

O número de avaliações retornadas por chamada de API é limitado a 10 resultados. Por exemplo, se você avaliar uma sessão contendo 15 traços usando um avaliador de nível de rastreamento, a resposta incluirá no máximo 10 resultados. Por padrão, a API retorna as últimas 10 avaliações, pois elas normalmente contêm o contexto mais relevante para a qualidade da avaliação.

### Falhas parciais
<a name="partial-failures"></a>

Uma chamada de API pode processar uma avaliação enquanto minha falha. Falhas podem ocorrer devido a vários motivos, incluindo:
+ Limitação de fornecedores de modelos
+ Erros de análise
+ Tempos limite do modelo
+ Outros problemas de processamento

Em casos de falha parcial, a resposta inclui avaliações bem-sucedidas e fracassadas. Os resultados falhados incluem um código de erro e uma mensagem de erro para ajudá-lo a diagnosticar o problema.

### Contexto da extensão
<a name="span-context"></a>

Cada resultado do avaliador tem um `spanContext` campo que identifica a entidade avaliada:
+ Somente está presente para avaliadores em nível de sessão. `sessionId`
+ Para avaliadores em nível de rastreamento, `sessionId` e `traceId` estão presentes.
+ Para avaliadores em nível de ferramenta,, `sessionId``traceId`, e `spanId` estão presentes.

### Exemplo de entrada de resultado bem-sucedida
<a name="example-successful-result"></a>

Essa é apenas uma entrada. Se uma sessão tiver vários rastreamentos, você verá várias dessas entradas, uma para cada rastreamento. Da mesma forma, para avaliadores em nível de ferramenta, se houver várias chamadas de ferramentas e um avaliador de ferramenta (como`Builtin.ToolSelectionAccuracy`) for fornecido, haverá um resultado por extensão de ferramenta.

```
{
  "evaluatorArn": "arn:aws:bedrock-agentcore:::evaluator/Builtin.Helpfulness",
  "evaluatorId": "Builtin.Helpfulness",
  "evaluatorName": "Builtin.Helpfulness",
  "explanation": ".... evaluation explanation will be added here ...",
  "context": {
    "spanContext": {
      "sessionId": "test-ace-demo-session-18a1dba0-62a0-462e",
      "traceId": "....trace_id......."
    }
  },
  "value": 0.83,
  "label": "Very Helpful",
  "tokenUsage": {
    "inputTokens": 958,
    "outputTokens": 211,
    "totalTokens": 1169
  }
}
```

### Exemplo de falha na entrada de resultado
<a name="example-failed-result"></a>

```
{
    "evaluatorArn": "arn:aws:bedrock-agentcore:::evaluator/Builtin.Helpfulness",
    "evaluatorId": "Builtin.Helpfulness",
    "evaluatorName": "Builtin.Helpfulness",
    "context": {
        "spanContext": {
            "sessionId": "test-ace-demo-session-18a1dba0-62a0-462e",
            "traceId": "....trace_id......."
        }
    },
    "errorMessage": ".... details of the error....",
    "errorCode": ".... name/code of the error...."
}
```