> ## Documentation Index
> Fetch the complete documentation index at: https://docs.befailproof.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Evaluation Suite

> Documentação do AgentEye Evaluation Suite.

O AgentEye pontua sessões de agentes concluídas enviando via POST a transcrição completa de eventos para um **único serviço avaliador de propriedade do cliente**. O avaliador retorna as pontuações de forma inline ou devolvendo um `job_id` para que o AgentEye faça polling. Os resultados são armazenados e exibidos no dashboard.

Este guia cobre:

1. Como a conclusão de sessão é detectada.
2. O contrato HTTP que o avaliador deve implementar.
3. Como configurar o servidor AgentEye.
4. Como visualizar os resultados.
5. Solução de problemas.

Para o helper Python que implementa o contrato por você, consulte o
[pacote `agenteye-evaluator` no PyPI](https://pypi.org/project/agenteye-evaluator/).

***

## Como funciona

```text theme={null}
ingest /events  ──▶  AgentEye  ──── POST /evaluate ────▶  Serviço avaliador
   (agent_end)        server   ◀──── done | pending ────
                          │
                          │     GET /evaluate/{job_id} ─────▶
                          │     ◀──── done ──────────────
                          ▼
                     evaluations  (resultados terminais)
```

Quando o SDK do AgentEye emite um evento `agent_end` para uma sessão, o servidor
agenda uma avaliação. Em seguida, envia via POST a transcrição completa de eventos
para o seu serviço avaliador, que pode:

* **Retornar o resultado de forma inline** com `{"status":"done", "scores":{...}, "reasoning":{...}, "summary":"..."}`. O
  resultado é adicionado à linha do tempo de avaliações da sessão. `reasoning` e
  `summary` são opcionais.
* **Adiar** com `{"status":"pending", "job_id":"abc-123"}`. O AgentEye então
  chama `GET {EVALUATOR_ENDPOINT}/evaluate/abc-123` até que o avaliador
  retorne `{"status":"done", ...}` ou `{"status":"error", "error":"..."}`.

  A cadência de polling é por job: uma resposta `pending` pode incluir
  `next_poll_secs` para substituir o padrão; caso contrário, o AgentEye usa o
  valor `default_poll_interval_secs` de `GET /config`; caso contrário, o servidor
  usa `EVALUATOR_POLLING_INTERVAL_SECS` como fallback (padrão: 10s). Todos os valores
  são limitados ao intervalo \[1s, 1h].

Sessões que nunca emitem `agent_end` (por exemplo, um processo de agente que travou)
também podem ser processadas: o `GET /config` do avaliador pode retornar
`{"inactivity_timeout_secs": 1800}`, e o AgentEye avaliará qualquer sessão
que ficou ociosa por esse período. Defina o campo como `null` ou omita-o para
desabilitar esse fallback.

O pipeline é completamente inativo quando `EVALUATOR_ENDPOINT` não está definido.

Uma sessão pode acumular **múltiplas avaliações terminais ao longo do tempo**: cada
evento `agent_end` (e cada re-avaliação manual pelo dashboard) adiciona uma nova
linha de avaliação. Essa é a forma recomendada de avaliar uma conversa retomada:
um usuário encerra um agente, retorna mais tarde, envia mais eventos,
encerra o agente novamente, e uma segunda avaliação é executada contra a transcrição
completa e atualizada. O dashboard renderiza a avaliação mais recente como destaque
e as avaliações anteriores como uma linha do tempo recolhível. Enquanto uma
avaliação está em andamento para uma sessão, eventos `agent_end` adicionais para essa
sessão são ignorados; o próximo após a avaliação em andamento ser concluída
enfileirará uma nova avaliação normalmente.

O fallback de inatividade também é reativado em sessões retomadas: se novos eventos
chegarem após uma avaliação terminal anterior e a sessão ficar ociosa por mais tempo
que `inactivity_timeout_secs`, uma nova avaliação é enfileirada.

Falhas transientes (5xx, 429, timeouts, erros de rede) são repetidas com
backoff exponencial até `EVALUATOR_MAX_ATTEMPTS`; respostas 4xx são
terminais. O AgentEye pode ser executado com segurança em múltiplas instâncias
de servidor com escalonamento horizontal; o trabalho é particionado para que a mesma
sessão nunca seja despachada duas vezes simultaneamente.

***

## Contrato HTTP

Todas as rotas autenticadas usam **autenticação via bearer token**. O mesmo valor deve ser
configurado em ambos os lados:

* Servidor AgentEye: variável de ambiente `EVALUATOR_TOKEN`
* Serviço avaliador: configurado da mesma forma (o SDK `agenteye-evaluator`
  lê `EVALUATOR_TOKEN` por convenção)

Se `EVALUATOR_TOKEN` não estiver definido, o servidor não envia o header `Authorization`;
o avaliador pode então aceitar requisições anônimas, o que é aceitável para uma
rede interna, mas não recomendado na internet pública.

### Rotas que o avaliador deve disponibilizar

| Rota                 | Body / parâmetros  | Resposta                                                                                     |
| -------------------- | ------------------ | -------------------------------------------------------------------------------------------- |
| `GET /health`        | nenhum             | `{"status":"ok"}` (aberta, sem auth)                                                         |
| `GET /config`        | nenhum             | `{"inactivity_timeout_secs": <int> \| null, "default_poll_interval_secs": <int> \| omitted}` |
| `POST /evaluate`     | JSON `EvalRequest` | `{"status":"done", ...}` ou `{"status":"pending", "job_id":"..."}`                           |
| `GET /evaluate/{id}` | nenhum             | mesmo formato de resposta que `/evaluate`                                                    |

### Body `EvalRequest` enviado pelo servidor

```json theme={null}
{
  "schema_version": "1",
  "session_id":     "session-abc123",
  "agent_id":       "planner",
  "environment":    "production",
  "started_at":     "2026-05-10T12:00:00Z",
  "ended_at":       "2026-05-10T12:05:00Z",
  "events": [
    { "id": 1234, "ts": "...", "event_type": "agent_start", "payload": { ... } },
    ...
  ]
}
```

### Formatos de resposta

**Síncrono (done):**

```json theme={null}
{
  "status": "done",
  "scores": { "helpfulness": 0.85, "tool_efficiency": 0.6 },
  "reasoning": {
    "helpfulness": "answered the question directly with citations",
    "tool_efficiency": "called list_files three times when one would have done"
  },
  "summary": "strong answer quality, weak tool selection"
}
```

`reasoning` (um mapa de justificativa por pontuação) e `summary` (uma narrativa
geral de um parágrafo) são ambos opcionais. As chaves em `reasoning` devem
espelhar as chaves em `scores`; o dashboard renderiza cada entrada inline abaixo
de sua barra de pontuação. Avaliadores mais antigos que retornam apenas `scores` continuam
funcionando sem alterações; `reasoning` e `summary` simplesmente são lidos como null e
os elementos de interface correspondentes são omitidos.

**Assíncrono (adiado):**

```json theme={null}
{ "status": "pending", "job_id": "abc-123", "next_poll_secs": 30 }
```

`next_poll_secs` é opcional; se omitido, o servidor usa como fallback o
`default_poll_interval_secs` do avaliador via `/config`, e depois a sua própria
variável de ambiente `EVALUATOR_POLLING_INTERVAL_SECS`.

**Erro terminal no lado do avaliador:**

```json theme={null}
{ "status": "error", "error": "model service unavailable" }
```

O servidor trata qualquer outro body 2xx como erro de protocolo e registra um
`error` terminal para a sessão.

***

## Escrevendo um avaliador com o SDK

O pacote Python `agenteye-evaluator` fornece um wrapper FastAPI tipado
que implementa o contrato HTTP acima. Instale-o via PyPI:

```bash theme={null}
pip install agenteye-evaluator
```

Avaliador mínimo viável:

```python theme={null}
import os
from agenteye_evaluator import Evaluator, EvalRequest, EvalResponse

app = Evaluator(token=os.environ["EVALUATOR_TOKEN"])

@app.evaluator
def run(req: EvalRequest) -> EvalResponse:
    # Inspecione req.events (a transcrição completa da sessão) e retorne pontuações.
    tool_calls = sum(1 for e in req.events if e.event_type == "tool_use")
    return EvalResponse(
        scores={"tool_calls": float(tool_calls)},
        reasoning={"tool_calls": f"{tool_calls} tool invocations in the transcript"},
        summary="tight tool loop" if tool_calls < 5 else "agent looped on tools",
    )
```

A instância `app` é ASGI-callable, então `uvicorn module:app` a executa.

Para avaliadores que precisam adiar trabalho pesado, retorne `JobPending`
em vez disso e registre um handler `@app.job_lookup`; o servidor AgentEye
faz polling em `GET /evaluate/{job_id}` até que você retorne um status terminal ou o
limite `EVALUATOR_MAX_POLL_DURATION_SECS` (padrão: 1h) seja atingido.

Referência completa da API, padrão assíncrono e schema de eventos: o README do
`agenteye-evaluator` está incluído em cada tarball de release na
[página de releases do agenteye-enterprise](https://github.com/agenteye-enterprise/releases),
ou você pode lê-lo na página do pacote no PyPI.

***

## Executando um avaliador no Kubernetes

O avaliador é **seu serviço**: o AgentEye não inclui um container avaliador padrão.
O release inclui manifests de referência do Kubernetes
em `deploy/examples/evaluator/` que você pode aplicar diretamente
após substituir sua imagem e um bearer token compartilhado.

### 1. Containerize seu avaliador

Um Dockerfile mínimo para seu avaliador:

```dockerfile theme={null}
FROM python:3.12-slim
WORKDIR /app
RUN pip install --no-cache-dir agenteye-evaluator uvicorn
COPY my_evaluator.py .
RUN useradd --uid 10001 --create-home --shell /usr/sbin/nologin evaluator \
    && chown -R evaluator:evaluator /app
USER evaluator
EXPOSE 9000
CMD ["uvicorn", "my_evaluator:app", "--host", "0.0.0.0", "--port", "9000"]
```

`runAsNonRoot` (UID 10001) mantém o container compatível com perfis de segurança
restritos do Pod Security.

### 2. Crie o bearer token compartilhado

```bash theme={null}
kubectl -n agenteye create secret generic evaluator-token \
  --from-literal=token="$(openssl rand -hex 32)"
```

Use o mesmo valor como `EVALUATOR_TOKEN` no servidor AgentEye. O
servidor envia `Authorization: Bearer <token>` em cada requisição; o SDK
usa `hmac.compare_digest` para uma verificação em tempo constante e rejeita
incompatibilidades com HTTP 401.

### 3. Aplique os manifests de exemplo

```bash theme={null}
# Edite deploy/examples/evaluator/deployment.yaml primeiro para apontar
# `image:` para o seu registry, depois:
kubectl apply -k deploy/examples/evaluator/
```

O exemplo inclui:

* Um Deployment de 2 réplicas com `runAsNonRoot`, sistema de arquivos raiz somente leitura,
  todas as capabilities removidas, liveness + readiness em `/health`
* Um Service ClusterIP na porta 9000
* Um template `secret.example.yaml` (intencionalmente excluído da
  Kustomization; crie o secret real fora do processo para que nenhum token vá parar
  no git)

### 4. Configure o AgentEye para usá-lo

No servidor AgentEye, defina:

```bash theme={null}
EVALUATOR_ENDPOINT=http://evaluator:9000
EVALUATOR_TOKEN=<o valor gerado acima>
```

O servidor distribui `EVALUATOR_WORKERS × EVALUATOR_CLAIM_BATCH`
requisições concorrentes entre todos os pods do avaliador (padrões: `2 × 4 = 8`).
Escale `replicas` e os limites de recursos por pod em conjunto com esses
parâmetros do lado do servidor.

### Verificação

```bash theme={null}
kubectl -n agenteye port-forward svc/evaluator 9000:9000
curl -s http://localhost:9000/health   # → {"status":"ok"}
```

Após um agente executar de ponta a ponta, `GET /evaluations` no servidor AgentEye
deve retornar uma linha com `status: "done"` e as pontuações produzidas pelo seu avaliador.

***

## Configurando o servidor AgentEye

Defina no processo do servidor:

| Variável de ambiente               | Significado                                                                                                                                                                                                               |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `EVALUATOR_ENDPOINT`               | URL base do seu avaliador (`http://evaluator:9000`). Não definida = pipeline desabilitado.                                                                                                                                |
| `EVALUATOR_TOKEN`                  | Bearer token. Deve ser igual ao valor com que o serviço avaliador está configurado.                                                                                                                                       |
| `EVALUATOR_WORKERS`                | Tarefas de worker por instância do servidor (padrão: 2).                                                                                                                                                                  |
| `EVALUATOR_CLAIM_BATCH`            | Linhas processadas por tick de worker (padrão: 4). Os lotes são processados **de forma concorrente**; a concorrência efetiva no endpoint do avaliador é `EVALUATOR_WORKERS × EVALUATOR_CLAIM_BATCH`.                      |
| `EVALUATOR_POLL_IDLE_SECS`         | Quanto tempo um worker dorme entre tentativas de despacho quando nenhuma avaliação está pendente (padrão: 2s).                                                                                                            |
| `EVALUATOR_POLLING_INTERVAL_SECS`  | Fallback final para a cadência de `GET /evaluate/{id}` quando nem o `next_poll_secs` por resposta nem o `default_poll_interval_secs` do avaliador está definido (padrão: 10s).                                            |
| `EVALUATOR_REQUEST_TIMEOUT_MS`     | Timeout por requisição (padrão: 30000).                                                                                                                                                                                   |
| `EVALUATOR_MAX_ATTEMPTS`           | Após este número de falhas transientes, o resultado é registrado como `error` terminal (padrão: 5).                                                                                                                       |
| `EVALUATOR_CONFIG_REFRESH_SECS`    | Cadência de `GET /config` (padrão: 300).                                                                                                                                                                                  |
| `EVALUATOR_MAX_POLL_DURATION_SECS` | Tempo máximo em relógio de parede que uma sessão pode permanecer na fila de polling antes de ser encerrada como `timeout` (padrão: 3600s). Protege contra um avaliador que continua retornando `pending` indefinidamente. |

Para ativar a pontuação automática em toda a instância, provisione o Secret `agenteye-evaluator` com ambas as chaves definidas. Nos manifests Kubernetes incluídos, o servidor lê `EVALUATOR_ENDPOINT` e `EVALUATOR_TOKEN` desse Secret opcional. Crie-o pelo processo padrão de gerenciamento de secrets da sua organização e reinicie o Deployment do servidor para aplicar a mudança.

Os parâmetros de ajuste acima não são configurados por padrão; exponha as variáveis de ambiente correspondentes no container do servidor no seu manifest de Deployment caso precise substituir os valores padrão.

Consulte [deployment.md](/pt-br/agenteye/deployment) para a tabela completa de variáveis de ambiente.

***

## Referência da API

| Método | Caminho                             | Permissão necessária  | Finalidade                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| ------ | ----------------------------------- | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GET`  | `/evaluations`                      | `evaluations:read`    | Consulta resultados terminais. Suporta `session_id`, `agent_id`, `environment`, `status` (`done`/`error`/`timeout`), `ts_from`, `ts_to`, `cursor`, `limit`, `score_filters`, `latest_per_session`. `limit` tem padrão 50 e máximo 200 (diferente de `/events`, que tem máximo 1000). `environment` aceita uma lista separada por vírgulas (ex.: `environment=prod,staging`); valores únicos ainda funcionam. Com `latest_per_session=true`, a resposta contém no máximo uma linha por `session_id` (a mais recente por `completed_at`), usada pela página de listagem de sessões para colapsar a linha do tempo de avaliações de uma sessão ao seu destaque atual. Padrão é false (retorna o histórico completo). |
| `GET`  | `/evaluations/aggregate`            | `evaluations:read`    | Métricas agregadas de saúde de avaliação para uma fatia filtrada: contagem total, distribuição done/error/timeout, estatísticas por chave de pontuação (count/avg/min/max/p50 sobre as chaves arbitrárias de `scores`), e uma linha do tempo por intervalos de tempo. Aceita os **mesmos parâmetros de filtro que `/evaluations`** mais `featured_keys` (CSV de chaves de pontuação para tendência) e `latest_per_session`. Alimenta a funcionalidade de Dashboards; as métricas são exatas sobre todo o conjunto correspondente, sem amostragem.                                                                                                                                                                 |
| `GET`  | `/evaluations/environments`         | `evaluations:read`    | Valores distintos de environment da tabela `evaluations`. Usado para preencher dropdowns de filtro com escopo para dados legíveis por avaliações.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `GET`  | `/evaluation-jobs`                  | `evaluations:read`    | Visibilidade sobre avaliações em andamento. Filtre por `status` (`pending`/`polling`).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `GET`  | `/events`                           | `events:read`         | Transmite os eventos brutos de uma sessão. Suporta `session_id`, `agent_id`, `event_type` (CSV), `environment` (CSV), `ts_from`, `ts_to`, `cursor`, `limit` e `order`. `order` é `desc` (mais recente primeiro, padrão) ou `asc` (mais antigo primeiro); um valor não reconhecido usa `desc` como fallback. Pagine via cursor usando o `next_cursor` da resposta (um id de evento): passe-o de volta como `cursor` para obter a próxima página; com `asc` a próxima página são os eventos após esse id, com `desc` os eventos antes dele. `limit` tem padrão 50 e máximo 1000.                                                                                                                                    |
| `GET`  | `/sessions/:session_id/export`      | `events:read`         | Retorna exatamente o body JSON que o avaliador receberia para esta sessão, servido como um anexo para download chamado `session-<id>.json`. Útil para reproduzir sessões de produção através do `agenteye-evaluator` para testes offline. Os bytes são idênticos ao que o pipeline do avaliador envia.                                                                                                                                                                                                                                                                                                                                                                                                            |
| `POST` | `/sessions/:session_id/re-evaluate` | `evaluations:trigger` | Enfileira uma nova avaliação para uma sessão; executa independentemente de existir uma avaliação anterior. O novo resultado é **adicionado** à linha do tempo de avaliações da sessão em vez de sobrescrever o anterior, então as pontuações anteriores permanecem visíveis como histórico. Retorna `202` ao enfileirar, `404` para sessão desconhecida, `409` se já houver uma avaliação em andamento. Use isso após implantar um novo avaliador, ou para sessões que nunca emitiram `agent_end`.                                                                                                                                                                                                                |

### Filtrando por intervalo de pontuação: `score_filters`

`GET /evaluations` aceita um parâmetro opcional `score_filters` que
restringe os resultados por valores numéricos dentro do objeto `scores`. O
parâmetro é uma lista separada por vírgulas de entradas `key:min..max`; qualquer
um dos limites pode ser omitido. Múltiplas entradas se combinam com AND lógico. Linhas
onde a chave nomeada está ausente ou não é numérica são excluídas. Uma requisição pode
conter no máximo 20 entradas de filtro; exceder isso retorna HTTP 400.

Exemplos:

```text theme={null}
# helpfulness em [0.5, 0.8]
GET /evaluations?score_filters=helpfulness:0.5..0.8

# tool_efficiency no máximo 0.3 (sem limite inferior)
GET /evaluations?score_filters=tool_efficiency:..0.3

# helpfulness >= 0.5 E factuality >= 0.9
GET /evaluations?score_filters=helpfulness:0.5..,factuality:0.9..
```

Cada objeto de resposta de `/evaluations` tem estes campos:

| Campo           | Tipo                  | Observações                                                                                                                                                                                    |
| --------------- | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `evaluation_id` | string (UUID)         | O identificador canônico desta avaliação terminal. Cada avaliação terminal recebe um novo UUID; uma única sessão pode ter múltiplos.                                                           |
| `id`            | string (UUID)         | Alias de compatibilidade retroativa com o mesmo valor que `evaluation_id`.                                                                                                                     |
| `session_id`    | string                | A sessão contra a qual esta avaliação foi executada. Uma sessão pode ter múltiplas avaliações na linha do tempo.                                                                               |
| `agent_id`      | string                | Identifica o agente que produziu a sessão.                                                                                                                                                     |
| `environment`   | string                | Rótulo de environment copiado da sessão.                                                                                                                                                       |
| `status`        | enum                  | Um de `"done"`, `"error"`, `"timeout"`.                                                                                                                                                        |
| `scores`        | object \| null        | Pontuações retornadas pelo seu avaliador.                                                                                                                                                      |
| `reasoning`     | object \| null        | Mapa opcional de justificativa por pontuação retornado pelo seu avaliador. As chaves normalmente espelham as de `scores`. O dashboard renderiza cada entrada abaixo de sua barra de pontuação. |
| `summary`       | string \| null        | Narrativa geral opcional de um parágrafo retornada pelo seu avaliador. O dashboard a renderiza acima da distribuição por pontuação como o destaque da avaliação.                               |
| `error`         | string \| null        | Preenchido apenas em `"error"` / `"timeout"`.                                                                                                                                                  |
| `attempt_count` | integer               | Número de tentativas de despacho (≥ 1).                                                                                                                                                        |
| `duration_ms`   | integer \| null       | Duração da tentativa final.                                                                                                                                                                    |
| `completed_at`  | string (ISO 8601 UTC) | Quando o resultado terminal foi registrado. Os resultados são ordenados por `completed_at` (mais recente primeiro).                                                                            |
| `created_at`    | string (ISO 8601 UTC) | Carrega o mesmo timestamp que `completed_at` (semântica de escrita única).                                                                                                                     |

***

## Permissões

| Permissão             | Concede                                                                                                                                  |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `evaluations:read`    | Listar resultados de avaliação, visualizar pontuações no dashboard e carregar métricas de saúde do dashboard.                            |
| `evaluations:trigger` | Enfileirar manualmente uma avaliação para uma sessão via `POST /sessions/:session_id/re-evaluate` ou o botão de re-avaliar no dashboard. |
| `dashboards:read`     | Visualizar dashboards salvos (também precisa de `evaluations:read` para carregar suas métricas).                                         |
| `dashboards:write`    | Criar e editar dashboards.                                                                                                               |
| `dashboards:delete`   | Excluir dashboards.                                                                                                                      |

O admin bootstrap (`ADMIN_KEY`, `ADMIN_EMAIL`) recebe essas permissões automaticamente.

***

## Visualizando resultados

* **`/sessions/<id>`**: linha do tempo de eventos + um painel lateral direito mostrando as
  pontuações da sessão e qualquer erro da tentativa de despacho. Se sua chave tem
  `evaluations:trigger`, um botão de **re-avaliar** aparece ao lado do botão de exportar,
  útil para sessões que nunca emitiram `agent_end`, ou para
  atualizar pontuações após implantar um novo avaliador. O dashboard faz polling pelo
  novo resultado e atualiza o painel lateral quando ele chegar.
* **`/sessions`**: grade de sessões filtrável; a coluna de pontuação mostra o
  status de avaliação e as pontuações de cada sessão rapidamente.
* **`/dashboards`**: visualizações salvas de saúde de avaliação (veja [Dashboards](#dashboards) abaixo).

<img src="https://mintcdn.com/exosphere/RgxYS1UZshqb4m7m/agenteye/images/sessions-list.png?fit=max&auto=format&n=RgxYS1UZshqb4m7m&q=85&s=10de161665eef64465d3d100e80b643f" alt="Grade de sessões com pílulas de status de avaliação por sessão e emblemas de pontuação com código de cores (helpfulness, factuality, tool_efficiency, safety, coherence)" width="2880" height="1800" data-path="agenteye/images/sessions-list.png" />

*A grade de sessões mostra o status de avaliação e as pontuações de cada execução rapidamente; emblemas vermelhos/âmbar/verdes destacam pontuações baixas.*

<img src="https://mintcdn.com/exosphere/RgxYS1UZshqb4m7m/agenteye/images/session-detail.png?fit=max&auto=format&n=RgxYS1UZshqb4m7m&q=85&s=63cc2480e8124a05ea6a0a92d5f20690" alt="Visualização de detalhes de uma sessão com as pontuações de avaliação e o status de despacho no painel lateral direito" width="2880" height="1800" data-path="agenteye/images/session-detail.png" />

*Abrir uma sessão mostra sua linha do tempo completa ao lado das pontuações de avaliação e qualquer erro do dispatcher no painel lateral direito.*

***

## Dashboards

A página **Dashboards** (`/dashboards`) permite salvar uma combinação de filtros de avaliação
como uma visualização nomeada e reutilizável, e acompanhar como aquela fatia de avaliações está
se saindo rapidamente. Os Dashboards são **compartilhados por toda a sua organização**;
todos com `dashboards:read` veem o mesmo conjunto.

Cada dashboard fixa:

* **Filtros**: os mesmos controles da página de sessões: environment, status,
  agente, uma janela de tempo contínua e filtros de intervalo de pontuação (`key:min..max`).
* **Uma configuração de exibição**: quais chaves de pontuação destacar, os limites de saúde
  verde/âmbar/vermelho, quais painéis mostrar e se colapsar para a avaliação mais recente
  por sessão.

Cada card mostra o número de sessões correspondentes, uma distribuição done/error/timeout,
a média de cada pontuação destacada e um pequeno sparkline de tendência. Abrir um
dashboard mostra os painéis em tamanho completo; **"abrir em sessões"** leva você à
página de sessões pré-filtrada exatamente para aquela fatia. As métricas são calculadas
no lado do servidor sobre todo o conjunto correspondente (via `GET /evaluations/aggregate`), então
os números são exatos em vez de amostrados.

<img src="https://mintcdn.com/exosphere/RgxYS1UZshqb4m7m/agenteye/images/dashboard-quality.png?fit=max&auto=format&n=RgxYS1UZshqb4m7m&q=85&s=0cbe5452995b2ff187f72b8978716bb3" alt="Dashboard de saúde de avaliação com barras de pontuação média por dimensão do avaliador, distribuição ok vs. erro de ferramentas, principais ferramentas e tendência de eventos por hora" width="2880" height="1800" data-path="agenteye/images/dashboard-quality.png" />

**Permissões:** visualizar requer tanto `dashboards:read` quanto `evaluations:read`;
criar e editar requer `dashboards:write`; excluir requer `dashboards:delete`.
O admin bootstrap recebe todas essas permissões automaticamente.

***

## Solução de problemas

**Sessões existem mas nenhuma avaliação é criada.** Confirme que `EVALUATOR_ENDPOINT`
está definido no processo do servidor, que o servidor e o avaliador compartilham o mesmo
valor de `EVALUATOR_TOKEN`, e que o endpoint `/health` do avaliador é
acessível a partir do servidor. Com `EVALUATOR_ENDPOINT` não definido, o pipeline é inativo.

**Avaliações em andamento se acumulam.** Consulte `GET /evaluation-jobs` para ver a
fila em andamento. Inspecione `attempt_count`, `next_attempt_at` e `last_error`
em cada linha. Causas comuns: serviço avaliador inacessível ou retornando 5xx
(repetido com backoff), `EVALUATOR_TOKEN` incorreto (401 é terminal), ou um
avaliador assíncrono que retorna `pending` indefinidamente (veja abaixo).

**Sessões concluídas mas sem avaliação terminal.** Consulte
`GET /evaluation-jobs?status=polling`; o resultado pode ainda estar em andamento.
Se um job está preso em `pending`, o servidor está tendo dificuldade em acessar o
avaliador; verifique se o avaliador está em funcionamento e se `EVALUATOR_TOKEN` corresponde.

**`HTTP 401 from evaluator: invalid bearer token`.** O `EVALUATOR_TOKEN`
no servidor não corresponde ao valor com que o serviço avaliador está configurado.
Eles devem ser idênticos.

**Avaliador assíncrono retorna `pending` indefinidamente.** O servidor faz polling em
`GET /evaluate/{job_id}` até que o avaliador retorne `done` ou `error`, ou
até que `EVALUATOR_MAX_POLL_DURATION_SECS` (padrão: 1h) seja atingido. Após o limite,
a avaliação é registrada como `timeout` e removida da fila em andamento.
Aumente `EVALUATOR_MAX_POLL_DURATION_SECS` se o seu avaliador legitimamente precisar
de mais tempo que o padrão.
