1562 lines
34 KiB
Markdown
Executable File
1562 lines
34 KiB
Markdown
Executable File
# Agent Framework OCI Evaluator — LLM-as-a-Judge
|
|
|
|
**Idioma:** Português | [English](README.en-US.md)
|
|
|
|
## 1. Visão geral
|
|
|
|
O **Agent Framework OCI Evaluator** é o componente batch responsável por avaliar, de forma assíncrona, a qualidade das conversas produzidas pelos agentes construídos sobre o Agent Framework OCI.
|
|
|
|
O serviço lê sessões e traces do **Langfuse v3**, seleciona uma amostra determinística de sessões, calcula métricas de qualidade com um **LLM-as-a-Judge**, persiste resultados em **Oracle Autonomous Database**, gera o arquivo oficial `.TXT.GZ`, publica esse arquivo em **Google Cloud Storage (GCS)** e registra a execução do próprio job no Langfuse.
|
|
|
|
Ele foi desenhado para execução **D+1**, como um **Kubernetes CronJob**, sem endpoint HTTP/gRPC de runtime.
|
|
|
|
> **Modelo de implantação recomendado:** uma instância do evaluator por agente/squad. O código é genérico e suporta múltiplos agentes na configuração, mas em produção a recomendação é cada deployment carregar apenas o agente de sua responsabilidade. Isso mantém credenciais, ownership, scheduling e troubleshooting isolados.
|
|
|
|
---
|
|
|
|
## 2. Por que este componente existe
|
|
|
|
Avaliar respostas generativas em tempo real dentro do fluxo síncrono do agente aumenta latência, custo e acoplamento. O evaluator separa essa responsabilidade do atendimento online.
|
|
|
|
O desenho é:
|
|
|
|
```text
|
|
Atendimento online
|
|
|
|
|
v
|
|
Agent Framework
|
|
|
|
|
+--------------------> Langfuse v3
|
|
|
|
|
| traces / sessions
|
|
v
|
|
Evaluator D+1 (CronJob)
|
|
|
|
|
+------------------+------------------+
|
|
| | |
|
|
v v v
|
|
OCI GenAI ADB GCS
|
|
LLM-as-a-Judge estado/resultados .TXT.GZ oficial
|
|
|
|
|
+-----------------------> Langfuse
|
|
auditoria / scores opcionais
|
|
```
|
|
|
|
Essa separação traz alguns benefícios:
|
|
|
|
- não adiciona latência ao atendimento;
|
|
- permite reprocessamento e auditoria;
|
|
- permite amostragem configurável por agente;
|
|
- isola falhas de avaliação do agente online;
|
|
- permite utilizar modelos dedicados do OCI GenAI;
|
|
- mantém um artefato oficial para a camada analítica da TIM;
|
|
- evita acoplamento do código a nomes específicos de agentes, buckets ou credenciais.
|
|
|
|
---
|
|
|
|
## 3. Conceitos principais
|
|
|
|
### 3.1. Trace
|
|
|
|
Um **trace** representa uma interação avaliada individualmente. Para cada trace são calculadas métricas trace-level:
|
|
|
|
- `judgeScore` — qualidade global da resposta;
|
|
- `accuracyScore` — aderência/factualidade em relação ao contexto;
|
|
- `alucinationScore` — grau de afirmações não suportadas pelo contexto;
|
|
- `promptLength` — tamanho bruto, em caracteres, do `trace.input`.
|
|
|
|
### 3.2. Session
|
|
|
|
Uma **session** representa a conversa completa. Uma sessão normalmente possui vários traces.
|
|
|
|
As métricas session-level são calculadas uma vez e replicadas nas linhas dos traces daquela sessão:
|
|
|
|
- `inferredCsiScore`;
|
|
- `resolution`;
|
|
- `conversationPrecision`;
|
|
- `loop`.
|
|
|
|
### 3.3. Amostragem por sessão
|
|
|
|
A amostragem é feita sobre **sessions**, nunca sobre traces isolados.
|
|
|
|
A seed é determinística:
|
|
|
|
```text
|
|
agentId:reference_date
|
|
```
|
|
|
|
Exemplo:
|
|
|
|
```text
|
|
billing:2026-08-13
|
|
```
|
|
|
|
Com isso, duas execuções para o mesmo agente, data e percentual selecionam as mesmas sessões.
|
|
|
|
Depois que uma sessão é selecionada, **todos os traces daquela sessão** são mantidos.
|
|
|
|
### 3.4. Janela BRT
|
|
|
|
`run-agents` calcula a data de referência com base em:
|
|
|
|
```text
|
|
D - daysBack
|
|
```
|
|
|
|
usando explicitamente:
|
|
|
|
```text
|
|
America/Sao_Paulo
|
|
```
|
|
|
|
Com `daysBack: 1`, uma execução em 14/08 avalia o dia 13/08 completo, de 00:00:00 até 23:59:59.999999 BRT.
|
|
|
|
### 3.5. CONTEXT_TURN_LIMIT
|
|
|
|
`CONTEXT_TURN_LIMIT` controla quantos turnos anteriores são enviados ao judge trace-level.
|
|
|
|
Default:
|
|
|
|
```env
|
|
CONTEXT_TURN_LIMIT=6
|
|
```
|
|
|
|
Ele existe porque uma resposta não deve ser julgada fora do contexto da conversa. Aumentar o valor fornece mais contexto, mas também aumenta tokens, custo e latência do judge.
|
|
|
|
### 3.6. Loop
|
|
|
|
A métrica `loop` não mede repetição textual simples. Ela representa o maior **streak consecutivo de `metadata.intent`** dentro da sessão.
|
|
|
|
Exemplo:
|
|
|
|
```text
|
|
billing
|
|
billing
|
|
billing
|
|
payment
|
|
payment
|
|
```
|
|
|
|
Resultado:
|
|
|
|
```text
|
|
loop = 3
|
|
```
|
|
|
|
---
|
|
|
|
## 4. Fluxo completo de execução
|
|
|
|
O fluxo produtivo é executado pelo comando:
|
|
|
|
```bash
|
|
python -m evaluator.cli run-agents
|
|
```
|
|
|
|
ou pelo entrypoint instalado:
|
|
|
|
```bash
|
|
af-evaluator run-agents
|
|
```
|
|
|
|
Etapas:
|
|
|
|
```text
|
|
1. Carrega agents.yaml
|
|
2. Calcula D-daysBack em BRT
|
|
3. Resolve credenciais Langfuse do agente
|
|
4. Busca TODAS as sessions nativas do período, com paginação
|
|
5. Busca TODOS os traces do período, com paginação
|
|
6. Busca observations em bulk/paginado
|
|
7. Recupera session_id real via metadata quando o trace legado não possui sessionId nativo
|
|
8. Filtra traces do agente/aliases
|
|
9. Faz sampling determinístico das sessions lógicas
|
|
10. Mantém todos os traces das sessions selecionadas
|
|
11. Persiste itens no ADB
|
|
12. Executa judge trace-level
|
|
13. Executa judge session-level
|
|
14. Calcula loop local
|
|
15. Gera .TXT.GZ
|
|
16. Faz upload para GCS
|
|
17. Remove o arquivo local após sucesso
|
|
18. Atualiza auditoria judge-job-{agentId} no Langfuse
|
|
```
|
|
|
|
### 4.1. Por que a coleta não usa N+1
|
|
|
|
A implementação evita o padrão antigo:
|
|
|
|
```text
|
|
1 trace
|
|
-> GET trace detail
|
|
-> GET observations
|
|
```
|
|
|
|
repetido para cada trace.
|
|
|
|
Agora a coleta é paginada em lote:
|
|
|
|
```text
|
|
/api/public/sessions page 1..N
|
|
/api/public/traces page 1..N
|
|
/api/public/observations page 1..N
|
|
```
|
|
|
|
Assim, 10.000 traces não produzem ~20.000 chamadas adicionais. O número de requests cresce com o número de páginas da API.
|
|
|
|
O `PAGE_SIZE` atual é 100.
|
|
|
|
### 4.2. Compatibilidade com traces sem `sessionId` nativo
|
|
|
|
Algumas instrumentações históricas registram a sessão no metadata do trace/observation, mas não promovem o valor para o campo nativo `trace.sessionId` do Langfuse. O evaluator recupera a sessão real com a seguinte precedência:
|
|
|
|
```text
|
|
trace.sessionId / trace.session_id
|
|
-> trace.metadata.session_id / sessionId / conversation_key
|
|
-> observation.metadata.session_id / sessionId / conversation_key
|
|
-> business_context.session_key (último fallback de metadata)
|
|
```
|
|
|
|
O `trace.id` **nunca** é usado como `session_id`. Assim, o evaluator preserva sampling e métricas de session mesmo para traces históricos, sem transformar cada trace em uma sessão artificial. As estatísticas de coleta expõem `native_sessions_read`, `metadata_sessions_recovered` e `traces_without_session`.
|
|
|
|
---
|
|
|
|
## 5. Arquitetura de componentes
|
|
|
|
```text
|
|
agent_framework_oci_evaluator/
|
|
├── evaluator/
|
|
│ ├── analytics/
|
|
│ │ └── vloop.py
|
|
│ ├── collectors/
|
|
│ │ ├── langfuse.py
|
|
│ │ ├── langfuse_credentials.py
|
|
│ │ ├── agent_framework.py
|
|
│ │ └── mock.py
|
|
│ ├── config/
|
|
│ │ ├── agents.py
|
|
│ │ └── settings.py
|
|
│ ├── core/
|
|
│ │ └── models.py
|
|
│ ├── identity/
|
|
│ │ └── resolver.py
|
|
│ ├── judges/
|
|
│ │ └── llm_judge.py
|
|
│ ├── llm/
|
|
│ │ ├── client.py
|
|
│ │ └── profile_resolver.py
|
|
│ ├── output/
|
|
│ │ └── legacy_exporter.py
|
|
│ ├── persistence/
|
|
│ │ ├── oracle_store.py
|
|
│ │ └── repository.py
|
|
│ ├── prompts/
|
|
│ │ └── loader.py
|
|
│ ├── publishers/
|
|
│ │ ├── gcs_export.py
|
|
│ │ ├── langfuse_job_audit.py
|
|
│ │ └── langfuse_scores.py
|
|
│ ├── cli.py
|
|
│ ├── engine.py
|
|
│ └── time_utils.py
|
|
├── configs/
|
|
│ ├── identity.yaml
|
|
│ ├── judge/
|
|
│ │ ├── agents.yaml
|
|
│ │ ├── storage.yaml
|
|
│ │ ├── trace_metrics.yaml
|
|
│ │ └── session_metrics.yaml
|
|
│ ├── langfuse/
|
|
│ │ └── langfuse_credentials.example.yaml
|
|
│ └── llm_profiles/
|
|
│ └── llm_profiles.yaml
|
|
├── deploy/
|
|
├── tests/
|
|
├── .env.example
|
|
├── Dockerfile
|
|
└── pyproject.toml
|
|
```
|
|
|
|
### 5.1. Collectors
|
|
|
|
Transformam fontes externas em `ConversationRecord`.
|
|
|
|
Fontes disponíveis:
|
|
|
|
```text
|
|
langfuse
|
|
agent_framework
|
|
mock
|
|
```
|
|
|
|
`langfuse` é a fonte produtiva padrão.
|
|
|
|
### 5.2. EvaluationEngine
|
|
|
|
`evaluator/engine.py` coordena o pipeline:
|
|
|
|
- criação do run;
|
|
- coleta;
|
|
- amostragem;
|
|
- persistência;
|
|
- judge;
|
|
- export;
|
|
- upload;
|
|
- auditoria.
|
|
|
|
### 5.3. Persistence
|
|
|
|
Os estados e resultados são persistidos em Oracle Database. O schema é criado automaticamente pelo comando `init-db`.
|
|
|
|
As principais tabelas são:
|
|
|
|
```text
|
|
EVALUATION_RUN
|
|
EVALUATION_PROGRESS_EVENT
|
|
EVALUATION_ITEM
|
|
EVALUATION_RESULT
|
|
EVALUATION_METRIC
|
|
EVALUATION_FINDING
|
|
```
|
|
|
|
O prefixo é configurável por:
|
|
|
|
```env
|
|
ADB_TABLE_PREFIX=AGENTFW
|
|
```
|
|
|
|
### 5.4. Publishers
|
|
|
|
- `gcs_export.py` — upload do artefato oficial;
|
|
- `langfuse_job_audit.py` — auditoria `judge-job-{agentId}`;
|
|
- `langfuse_scores.py` — publicação opcional de scores de trace.
|
|
|
|
> **Nota:** a auditoria produtiva do job usa as credenciais dinâmicas do agente. A publicação opcional de scores (`PUBLISH_LANGFUSE_SCORES=true`) ainda utiliza as credenciais globais `LANGFUSE_HOST/PUBLIC_KEY/SECRET_KEY`; deixe-a desabilitada quando não houver um projeto global apropriado.
|
|
|
|
---
|
|
|
|
## 6. Configuração de agentes
|
|
|
|
Arquivo padrão:
|
|
|
|
```text
|
|
configs/judge/agents.yaml
|
|
```
|
|
|
|
Exemplo:
|
|
|
|
```yaml
|
|
agents:
|
|
- agentId: billing
|
|
enabled: true
|
|
daysBack: 1
|
|
percentage: 1.0
|
|
langfuse_agent_aliases:
|
|
- telecom_contas
|
|
gcs_prefix: agnt_ai_contas
|
|
```
|
|
|
|
Campos:
|
|
|
|
| Campo | Descrição |
|
|
|---|---|
|
|
| `agentId` | identidade lógica oficial do agente |
|
|
| `enabled` | habilita/desabilita o agente naquele deployment |
|
|
| `daysBack` | quantos dias voltar a partir do dia atual BRT |
|
|
| `percentage` | percentual de sessions avaliadas, de 0.0 a 1.0 |
|
|
| `langfuse_agent_aliases` | nomes técnicos aceitos para o agente nos traces; quando preenchido, funciona como filtro explícito independentemente da origem das credenciais Langfuse |
|
|
| `gcs_prefix` | prefixo do agente dentro do bucket |
|
|
|
|
Também são aceitos `agent_id` e `days_back` por compatibilidade, mas o formato recomendado é `agentId` / `daysBack`.
|
|
|
|
**Semântica de `langfuse_agent_aliases`:** quando a lista possui valores, somente traces cujo identificador de agente corresponda a um dos aliases são elegíveis para sampling e avaliação. Quando a lista está vazia, o evaluator não aplica filtro por identidade de agente e considera o projeto/endpoint Langfuse configurado exclusivo para aquela entrada.
|
|
|
|
### 6.1. Um evaluator por agente
|
|
|
|
Para o modelo recomendado de uma instância por agente, mantenha apenas uma entrada habilitada naquele deployment:
|
|
|
|
```yaml
|
|
agents:
|
|
- agentId: billing
|
|
enabled: true
|
|
daysBack: 1
|
|
percentage: 1.0
|
|
langfuse_agent_aliases:
|
|
- telecom_contas
|
|
- billing_agent
|
|
gcs_prefix: agnt_ai_contas
|
|
```
|
|
|
|
O mesmo código pode ser usado em outro repositório/deployment apenas trocando os arquivos de configuração.
|
|
|
|
---
|
|
|
|
## 7. Credenciais Langfuse dinâmicas
|
|
|
|
Não existem variáveis hardcoded do tipo:
|
|
|
|
```text
|
|
LANGFUSE_BILLING_*
|
|
LANGFUSE_SALES_*
|
|
```
|
|
|
|
O evaluator lê uma definição declarativa:
|
|
|
|
```env
|
|
LANGFUSE_CREDENTIALS_CONFIG_PATH=configs/langfuse/langfuse_credentials.yaml
|
|
```
|
|
|
|
Crie o arquivo a partir do exemplo:
|
|
|
|
```bash
|
|
cp configs/langfuse/langfuse_credentials.example.yaml \
|
|
configs/langfuse/langfuse_credentials.yaml
|
|
```
|
|
|
|
Exemplo:
|
|
|
|
```yaml
|
|
langfuse:
|
|
agents:
|
|
- agentId: billing
|
|
host: https://langfuse.example.internal
|
|
publicKey: pk-...
|
|
secretKey: sk-...
|
|
|
|
- agentId: outro-agente
|
|
host: https://outro-langfuse.internal
|
|
publicKey: pk-...
|
|
secretKey: sk-...
|
|
```
|
|
|
|
O resolver percorre todas as entradas. Adicionar um agente não exige alteração Python.
|
|
|
|
### 7.1. Referências a env ou arquivos
|
|
|
|
Para não manter secrets no Git:
|
|
|
|
```yaml
|
|
langfuse:
|
|
agents:
|
|
- agentId: billing
|
|
hostEnv: BILLING_LF_HOST
|
|
publicKeyEnv: BILLING_LF_PUBLIC
|
|
secretKeyFile: /var/secrets/langfuse/billing-secret-key
|
|
```
|
|
|
|
Campos suportados:
|
|
|
|
```text
|
|
host / hostEnv / hostFile
|
|
publicKey / publicKeyEnv / publicKeyFile
|
|
secretKey / secretKeyEnv / secretKeyFile
|
|
```
|
|
|
|
Ordem de resolução de cada campo:
|
|
|
|
```text
|
|
valor direto -> variável de ambiente declarada -> arquivo declarado
|
|
```
|
|
|
|
### 7.2. Credenciais globais
|
|
|
|
Estas variáveis continuam disponíveis apenas para o comando manual genérico `run`:
|
|
|
|
```env
|
|
LANGFUSE_HOST=http://localhost:3005
|
|
LANGFUSE_PUBLIC_KEY=...
|
|
LANGFUSE_SECRET_KEY=...
|
|
```
|
|
|
|
O fluxo produtivo `run-agents` resolve credenciais pelo arquivo declarativo por agente.
|
|
|
|
---
|
|
|
|
## 8. Configuração do LLM
|
|
|
|
Providers aceitos:
|
|
|
|
```text
|
|
mock
|
|
oci_openai
|
|
oci_sdk
|
|
openai_compatible
|
|
```
|
|
|
|
A recomendação para os modelos OCI dedicados é:
|
|
|
|
```env
|
|
LLM_PROVIDER=oci_sdk
|
|
```
|
|
|
|
### 8.1. OCI SDK
|
|
|
|
Exemplo local com `~/.oci/config`:
|
|
|
|
```env
|
|
LLM_PROVIDER=oci_sdk
|
|
OCI_AUTH_MODE=config_file
|
|
OCI_CONFIG_FILE=~/.oci/config
|
|
OCI_PROFILE=DEFAULT
|
|
OCI_REGION=sa-saopaulo-1
|
|
OCI_COMPARTMENT_ID=ocid1.compartment...
|
|
OCI_GENAI_BASE_URL=https://inference.generativeai.sa-saopaulo-1.oci.oraclecloud.com
|
|
OCI_GENAI_MODEL=meta.llama-3.3-70b-instruct
|
|
```
|
|
|
|
Modos de autenticação suportados pelo código:
|
|
|
|
```text
|
|
config_file
|
|
instance_principal
|
|
resource_principal
|
|
oke_workload_identity
|
|
workload_identity
|
|
```
|
|
|
|
### 8.2. Dedicated endpoint
|
|
|
|
Para endpoint dedicado:
|
|
|
|
```env
|
|
OCI_GENAI_BASE_URL=https://<private-endpoint>.inference.generativeai.<region>.oci.oraclecloud.com
|
|
OCI_GENAI_ENDPOINT_ID=ocid1.generativeaiendpoint...
|
|
```
|
|
|
|
Também é aceito o OCID do dedicated endpoint em `OCI_GENAI_MODEL`.
|
|
|
|
O provider seleciona `DedicatedServingMode` quando há endpoint OCID; caso contrário usa `OnDemandServingMode`.
|
|
|
|
### 8.3. Perfis do judge
|
|
|
|
Arquivo:
|
|
|
|
```text
|
|
configs/llm_profiles/llm_profiles.yaml
|
|
```
|
|
|
|
Exemplo:
|
|
|
|
```yaml
|
|
profiles:
|
|
judge:
|
|
temperature: 0
|
|
max_tokens: 900
|
|
```
|
|
|
|
Selecionado por:
|
|
|
|
```env
|
|
LLM_PROFILE=judge
|
|
```
|
|
|
|
---
|
|
|
|
## 9. Prompts e métricas
|
|
|
|
### 9.1. Trace metrics
|
|
|
|
Arquivo:
|
|
|
|
```text
|
|
configs/judge/trace_metrics.yaml
|
|
```
|
|
|
|
O judge deve retornar JSON com:
|
|
|
|
```json
|
|
{
|
|
"judgeScore": 0.0,
|
|
"accuracyScore": 0.0,
|
|
"alucinationScore": 0.0,
|
|
"rationale": "..."
|
|
}
|
|
```
|
|
|
|
Se o parse falhar:
|
|
|
|
```text
|
|
1ª tentativa
|
|
-> parse falha
|
|
2ª tentativa com retry-hint
|
|
-> parse falha novamente
|
|
métricas trace-level = None
|
|
-> exportadas como "0.00"
|
|
```
|
|
|
|
### 9.2. Session metrics
|
|
|
|
Arquivo:
|
|
|
|
```text
|
|
configs/judge/session_metrics.yaml
|
|
```
|
|
|
|
Resultado esperado:
|
|
|
|
```json
|
|
{
|
|
"inferredCsiScore": 0.5,
|
|
"resolution": 1,
|
|
"conversationPrecision": 1,
|
|
"rationale": "..."
|
|
}
|
|
```
|
|
|
|
Os valores session-level são replicados no arquivo para todos os traces da mesma session.
|
|
|
|
---
|
|
|
|
## 10. Identity normalization
|
|
|
|
Arquivo:
|
|
|
|
```text
|
|
configs/identity.yaml
|
|
```
|
|
|
|
A camada de identidade converte identificadores específicos de canais/domínios para chaves canônicas como:
|
|
|
|
```text
|
|
customer_key
|
|
contract_key
|
|
interaction_key
|
|
account_key
|
|
resource_key
|
|
session_key
|
|
```
|
|
|
|
Isso evita espalhar lógica como `cpf`, `msisdn`, `invoice_id`, `order_id`, `ura_call_id` etc. pelo código do evaluator.
|
|
|
|
A ordem das fontes funciona como fallback.
|
|
|
|
Exemplo:
|
|
|
|
```yaml
|
|
session_key:
|
|
sources:
|
|
- business_context.session_key
|
|
- session_key
|
|
- conversation_key
|
|
- session_id
|
|
```
|
|
|
|
---
|
|
|
|
## 11. Configuração de GCS
|
|
|
|
Buckets ficam fora do código em:
|
|
|
|
```text
|
|
configs/judge/storage.yaml
|
|
```
|
|
|
|
Exemplo:
|
|
|
|
```yaml
|
|
storage:
|
|
buckets:
|
|
dev: tim-bigdata-dev-ca1f-raw-standard-agnt-ai-atendimento
|
|
fqa: tim-bigdata-fqa-60ce-raw-standard-agnt-ai-atendimento
|
|
prd: tim-bigdata-prod-e305-raw-standard-agnt-ai-atendimento
|
|
```
|
|
|
|
Seleção:
|
|
|
|
```env
|
|
APP_ENV=dev
|
|
STORAGE_CONFIG_PATH=configs/judge/storage.yaml
|
|
```
|
|
|
|
Override de emergência/operação:
|
|
|
|
```env
|
|
JUDGE_GCS_BUCKET=meu-bucket
|
|
```
|
|
|
|
Para habilitar o fluxo produtivo:
|
|
|
|
```env
|
|
ENABLE_GCS_UPLOAD=true
|
|
GOOGLE_APPLICATION_CREDENTIALS=/path/GCP_ACCESS_KEY.json
|
|
```
|
|
|
|
`run-agents` considera GCS obrigatório. Se `ENABLE_GCS_UPLOAD=false` ou o upload falhar, o run do agente termina como `FAILED`.
|
|
|
|
---
|
|
|
|
## 12. Arquivo de saída
|
|
|
|
O nome é configurado diretamente no `.env`:
|
|
|
|
```env
|
|
OUTPUT_FILENAME_PATTERN=AGENTE_{agent_id}_LLM_JUDGE_{timestamp}.TXT.GZ
|
|
```
|
|
|
|
Os placeholders disponíveis são `{agent_id}`, `{run_id}` e `{timestamp}`. O
|
|
`timestamp` é gerado no formato `YYYYMMDD_HHMMSS`, no fuso de São Paulo.
|
|
|
|
Padrão resultante:
|
|
|
|
```text
|
|
AGENTE_{agentId}_LLM_JUDGE_{YYYYMMDD}_{HHMMSS}.TXT.GZ
|
|
```
|
|
|
|
Exemplo:
|
|
|
|
```text
|
|
AGENTE_billing_LLM_JUDGE_20260814_020015.TXT.GZ
|
|
```
|
|
|
|
Cabeçalho:
|
|
|
|
```text
|
|
"judgeScore"|;"accuracyScore"|;"alucinationScore"|;"promptLength"|;"loop"|;"inferredCsiScore"|;"resolution"|;"conversationPrecision"|;"uraCallId"|;"channelId"|;"sessionId"|;"messageId"
|
|
```
|
|
|
|
Linha final:
|
|
|
|
```text
|
|
"TOTAL"|;"<n_traces>"
|
|
```
|
|
|
|
Após upload bem-sucedido para GCS, o arquivo local é apagado.
|
|
|
|
---
|
|
|
|
## 13. Instalação local
|
|
|
|
### 13.1. Pré-requisitos
|
|
|
|
- Python 3.11+;
|
|
- acesso ao Oracle Database/Autonomous Database;
|
|
- Oracle Wallet quando aplicável;
|
|
- acesso ao Langfuse v3;
|
|
- acesso ao OCI Generative AI para execução real do judge;
|
|
- credencial GCP para upload produtivo.
|
|
|
|
### 13.2. Criar venv
|
|
|
|
Linux/WSL/macOS:
|
|
|
|
```bash
|
|
python -m venv .venv
|
|
source .venv/bin/activate
|
|
```
|
|
|
|
Windows PowerShell:
|
|
|
|
```powershell
|
|
python -m venv .venv
|
|
.\.venv\Scripts\Activate.ps1
|
|
```
|
|
|
|
### 13.3. Instalar
|
|
|
|
Modo recomendado durante desenvolvimento:
|
|
|
|
```bash
|
|
python -m pip install --upgrade pip setuptools wheel
|
|
pip install -e .
|
|
```
|
|
|
|
Validar:
|
|
|
|
```bash
|
|
pip check
|
|
python -c "import oci, httpx, oracledb; import google.cloud.storage; print('Dependencias OK')"
|
|
```
|
|
|
|
---
|
|
|
|
## 14. Configuração local passo a passo
|
|
|
|
### Passo 1 — `.env`
|
|
|
|
```bash
|
|
cp .env.example .env
|
|
```
|
|
|
|
Edite os valores reais.
|
|
|
|
Configuração mínima típica:
|
|
|
|
```env
|
|
APP_ENV=dev
|
|
|
|
ADB_USER=admin
|
|
ADB_PASSWORD=...
|
|
ADB_DSN=...
|
|
ADB_WALLET_LOCATION=/path/to/wallet
|
|
ADB_WALLET_PASSWORD=...
|
|
ADB_TABLE_PREFIX=AGENTFW
|
|
|
|
ENABLE_LANGFUSE=true
|
|
LANGFUSE_CREDENTIALS_CONFIG_PATH=configs/langfuse/langfuse_credentials.yaml
|
|
|
|
LLM_PROVIDER=oci_sdk
|
|
LLM_PROFILE=judge
|
|
OCI_AUTH_MODE=config_file
|
|
OCI_CONFIG_FILE=~/.oci/config
|
|
OCI_PROFILE=DEFAULT
|
|
OCI_REGION=sa-saopaulo-1
|
|
OCI_COMPARTMENT_ID=...
|
|
OCI_GENAI_BASE_URL=https://...
|
|
OCI_GENAI_ENDPOINT_ID=ocid1.generativeaiendpoint...
|
|
|
|
CONTEXT_TURN_LIMIT=6
|
|
BATCH_SIZE=50
|
|
MAX_ATTEMPTS=3
|
|
|
|
ENABLE_GCS_UPLOAD=true
|
|
STORAGE_CONFIG_PATH=configs/judge/storage.yaml
|
|
GOOGLE_APPLICATION_CREDENTIALS=/path/GCP_ACCESS_KEY.json
|
|
```
|
|
|
|
### Passo 2 — Langfuse
|
|
|
|
```bash
|
|
cp configs/langfuse/langfuse_credentials.example.yaml \
|
|
configs/langfuse/langfuse_credentials.yaml
|
|
```
|
|
|
|
Declare o agente que será executado.
|
|
|
|
### Passo 3 — agents.yaml
|
|
|
|
Ajuste:
|
|
|
|
```text
|
|
configs/judge/agents.yaml
|
|
```
|
|
|
|
Para uma instância dedicada, deixe somente o agente daquela squad habilitado.
|
|
|
|
### Passo 4 — validar configuração
|
|
|
|
```bash
|
|
python -m evaluator.cli show-config
|
|
```
|
|
|
|
### Passo 5 — inicializar banco
|
|
|
|
```bash
|
|
python -m evaluator.cli init-db
|
|
```
|
|
|
|
> `reset-db` apaga e recria o schema do evaluator. Use apenas em ambiente controlado.
|
|
|
|
---
|
|
|
|
## 15. CLI
|
|
|
|
A ajuda real da versão atual é:
|
|
|
|
```bash
|
|
python -m evaluator.cli --help
|
|
```
|
|
|
|
Comandos disponíveis:
|
|
|
|
```text
|
|
init-db
|
|
reset-db
|
|
show-config
|
|
run
|
|
run-agents
|
|
progress
|
|
runs
|
|
```
|
|
|
|
### 15.1. `run` — execução manual/diagnóstica
|
|
|
|
Sintaxe:
|
|
|
|
```bash
|
|
python -m evaluator.cli run PERIOD_START PERIOD_END [OPTIONS]
|
|
```
|
|
|
|
Exemplo:
|
|
|
|
```bash
|
|
python -m evaluator.cli run \
|
|
2026-08-12T00:00:00 \
|
|
2026-08-12T23:59:59 \
|
|
--source langfuse \
|
|
--limit 10
|
|
```
|
|
|
|
Opções:
|
|
|
|
```text
|
|
--source TEXT default: langfuse
|
|
--limit INTEGER
|
|
--show-progress / --no-show-progress
|
|
```
|
|
|
|
**Importante:** `run` é um caminho manual genérico. Ele coleta, avalia e persiste resultados, mas não executa o contrato produtivo completo por agente (sampling configurado, export GCS e auditoria de job). Para homologação/produção use `run-agents`.
|
|
|
|
### 15.2. `run-agents` — fluxo produtivo
|
|
|
|
```bash
|
|
python -m evaluator.cli run-agents
|
|
```
|
|
|
|
Um agente:
|
|
|
|
```bash
|
|
python -m evaluator.cli run-agents \
|
|
--agent-id billing \
|
|
--source langfuse
|
|
```
|
|
|
|
Teste limitado:
|
|
|
|
```bash
|
|
python -m evaluator.cli run-agents \
|
|
--agent-id billing \
|
|
--limit 10
|
|
```
|
|
|
|
Opções:
|
|
|
|
```text
|
|
--source TEXT default: langfuse
|
|
--agent-id TEXT
|
|
--limit INTEGER
|
|
```
|
|
|
|
`run-agents` usa `daysBack`, `percentage`, credenciais e `gcs_prefix` do agente.
|
|
|
|
### 15.3. Listar runs
|
|
|
|
```bash
|
|
python -m evaluator.cli runs
|
|
```
|
|
|
|
ou:
|
|
|
|
```bash
|
|
python -m evaluator.cli runs --limit 50
|
|
```
|
|
|
|
### 15.4. Progresso de um run
|
|
|
|
```bash
|
|
python -m evaluator.cli progress <RUN_ID>
|
|
```
|
|
|
|
Com mais eventos:
|
|
|
|
```bash
|
|
python -m evaluator.cli progress <RUN_ID> --events 100
|
|
```
|
|
|
|
Eventos típicos do fluxo produtivo:
|
|
|
|
```text
|
|
LANGFUSE_JOB_AUDIT
|
|
RUN_CREATED
|
|
COLLECTING
|
|
COLLECTED
|
|
SAMPLED
|
|
ITEMS_INSERTED
|
|
BATCH_STARTED
|
|
ITEM_COMPLETED
|
|
SESSION_JUDGE_COMPLETED
|
|
COMPLETED
|
|
EXPORTED
|
|
GCS_UPLOADED
|
|
LOCAL_FILE_DELETED
|
|
LANGFUSE_JOB_AUDIT
|
|
```
|
|
|
|
---
|
|
|
|
## 16. Testes
|
|
|
|
Instale `pytest` caso necessário:
|
|
|
|
```bash
|
|
pip install pytest
|
|
```
|
|
|
|
### 16.1. Todos os testes
|
|
|
|
```bash
|
|
python -m pytest -v
|
|
```
|
|
|
|
### 16.2. Conformidade TIM
|
|
|
|
```bash
|
|
python -m pytest tests/test_tim_spec.py -v
|
|
```
|
|
|
|
### 16.3. Conformidade ampliada
|
|
|
|
```bash
|
|
python -m pytest tests/test_full_tim_compliance.py -v
|
|
```
|
|
|
|
### 16.4. Regressão de hardcodes
|
|
|
|
```bash
|
|
python -m pytest tests/test_no_product_hardcodes.py -v
|
|
```
|
|
|
|
### 16.5. Suite recomendada antes de um release
|
|
|
|
```bash
|
|
python -m pytest \
|
|
tests/test_tim_spec.py \
|
|
tests/test_full_tim_compliance.py \
|
|
tests/test_no_product_hardcodes.py \
|
|
-v
|
|
```
|
|
|
|
Validar sintaxe/imports:
|
|
|
|
```bash
|
|
python -m compileall evaluator
|
|
```
|
|
|
|
---
|
|
|
|
## 17. Teste funcional local recomendado
|
|
|
|
### 17.1. Smoke test com mock
|
|
|
|
Configure:
|
|
|
|
```env
|
|
LLM_PROVIDER=mock
|
|
```
|
|
|
|
E rode um período pequeno com source mock quando desejado:
|
|
|
|
```bash
|
|
python -m evaluator.cli run \
|
|
2026-08-12T00:00:00 \
|
|
2026-08-12T23:59:59 \
|
|
--source mock
|
|
```
|
|
|
|
### 17.2. Teste Langfuse sem volume grande
|
|
|
|
```bash
|
|
python -m evaluator.cli run-agents \
|
|
--agent-id billing \
|
|
--limit 5
|
|
```
|
|
|
|
Depois:
|
|
|
|
```bash
|
|
python -m evaluator.cli runs --limit 5
|
|
python -m evaluator.cli progress <RUN_ID> --events 100
|
|
```
|
|
|
|
Confirme:
|
|
|
|
- `COLLECTED` > 0;
|
|
- `SAMPLED` mostra sessions selecionadas;
|
|
- itens concluem sem `ITEM_FAILED`;
|
|
- `EXPORTED` aparece;
|
|
- `GCS_UPLOADED` contém URI `gs://...`;
|
|
- `LOCAL_FILE_DELETED` aparece;
|
|
- auditoria `completed` foi confirmada.
|
|
|
|
---
|
|
|
|
## 18. Docker
|
|
|
|
Build local:
|
|
|
|
```bash
|
|
docker build -t agent-framework-evaluator:local .
|
|
```
|
|
|
|
O runtime produtivo é batch. O container não precisa expor porta HTTP.
|
|
|
|
Para Kubernetes, o `CronJob` chama:
|
|
|
|
```text
|
|
python -m evaluator.cli run-agents --source langfuse
|
|
```
|
|
|
|
---
|
|
|
|
## 19. Kubernetes / OKE
|
|
|
|
O **evaluator propriamente dito continua CronJob-only**, conforme a especificação: ele não abre porta HTTP/gRPC e o processamento continua sendo executado exclusivamente pelo `evaluator-batch`.
|
|
|
|
A interface web foi reintroduzida como um **componente separado e somente leitura**, `evaluator-monitor`. Ela não executa avaliação, não altera runs e não muda o contrato batch do evaluator. O monitor apenas consulta as tabelas de execução/progresso no Autonomous Database.
|
|
|
|
```text
|
|
Evaluator batch (evaluator-batch CronJob)
|
|
│
|
|
├── cria/atualiza EVALUATION_RUN
|
|
├── grava EVALUATION_PROGRESS_EVENT
|
|
└── grava EVALUATION_RESULT
|
|
│
|
|
▼
|
|
Autonomous Database
|
|
▲
|
|
│ somente leitura
|
|
Evaluator Monitor (Deployment HTTP)
|
|
│
|
|
└── /ui + APIs de acompanhamento
|
|
```
|
|
|
|
Recursos Kustomize:
|
|
|
|
```text
|
|
Namespace
|
|
ServiceAccount
|
|
ConfigMap
|
|
CronJob evaluator-batch
|
|
Deployment evaluator-monitor
|
|
Service evaluator-monitor (ClusterIP)
|
|
```
|
|
|
|
Não existe Ingress por default. Assim, a interface não é exposta para fora do cluster automaticamente.
|
|
|
|
CronJob atual:
|
|
|
|
```yaml
|
|
schedule: "0 2 * * *"
|
|
timeZone: "America/Sao_Paulo"
|
|
suspend: false
|
|
concurrencyPolicy: Forbid
|
|
```
|
|
|
|
### 19.1. Preparar arquivos de deploy
|
|
|
|
```bash
|
|
cp deploy/env/evaluator.env.example deploy/env/evaluator.env
|
|
cp deploy/langfuse/langfuse_credentials.example.yaml \
|
|
deploy/langfuse/langfuse_credentials.yaml
|
|
```
|
|
|
|
Coloque o wallet em:
|
|
|
|
```text
|
|
deploy/wallet/
|
|
```
|
|
|
|
Credencial GCP:
|
|
|
|
```text
|
|
deploy/gcp/GCP_ACCESS_KEY.json
|
|
```
|
|
|
|
### 19.2. Criar secrets
|
|
|
|
DEV:
|
|
|
|
```bash
|
|
./deploy/scripts/create-secrets.sh dev
|
|
```
|
|
|
|
HML:
|
|
|
|
```bash
|
|
./deploy/scripts/create-secrets.sh hml
|
|
```
|
|
|
|
PROD:
|
|
|
|
```bash
|
|
./deploy/scripts/create-secrets.sh prod
|
|
```
|
|
|
|
São criados/atualizados:
|
|
|
|
```text
|
|
evaluator-secrets
|
|
evaluator-wallet
|
|
evaluator-langfuse
|
|
evaluator-gcp (quando o arquivo GCP existir)
|
|
```
|
|
|
|
### 19.3. Build e push
|
|
|
|
```bash
|
|
export REGISTRY=tim.azurecr.io
|
|
export IMAGE_TAG=<version>
|
|
./deploy/scripts/build-push.sh prod
|
|
```
|
|
|
|
### 19.4. Deploy
|
|
|
|
```bash
|
|
export REGISTRY=tim.azurecr.io
|
|
export IMAGE_TAG=<version>
|
|
./deploy/scripts/deploy.sh prod
|
|
```
|
|
|
|
Por default o script também executa o job de inicialização do banco.
|
|
|
|
Para não executar:
|
|
|
|
```bash
|
|
export RUN_INIT_DB=false
|
|
```
|
|
|
|
### 19.5. Status
|
|
|
|
```bash
|
|
./deploy/scripts/status.sh prod
|
|
```
|
|
|
|
ou diretamente:
|
|
|
|
```bash
|
|
kubectl -n agent-evaluator-prod get cronjob,jobs,pods
|
|
```
|
|
|
|
### 19.6. Execução imediata fora do horário
|
|
|
|
```bash
|
|
./deploy/scripts/run-now.sh prod
|
|
```
|
|
|
|
O script cria um Job baseado no CronJob.
|
|
|
|
Acompanhar:
|
|
|
|
```bash
|
|
kubectl -n agent-evaluator-prod get jobs,pods
|
|
kubectl -n agent-evaluator-prod logs -f job/<nome-do-job>
|
|
```
|
|
|
|
|
|
### 19.7. Interface web de acompanhamento
|
|
|
|
A UI é servida pelo componente independente `evaluator-monitor`:
|
|
|
|
```text
|
|
GET /ui
|
|
GET /health
|
|
GET /api/runs
|
|
GET /api/runs/{run_id}
|
|
GET /api/runs/{run_id}/results
|
|
```
|
|
|
|
Para acessar localmente um monitor implantado no Kubernetes sem criar Ingress:
|
|
|
|
```bash
|
|
kubectl -n agent-evaluator-prod port-forward svc/evaluator-monitor 8080:8080
|
|
```
|
|
|
|
Depois abra:
|
|
|
|
```text
|
|
http://localhost:8080/ui
|
|
```
|
|
|
|
A tela mostra runs recentes, `RUN_ID`, agente, status, progresso, eventos e resultados. O browser faz auto-refresh a cada 5 segundos.
|
|
|
|
Para executar o monitor localmente:
|
|
|
|
```bash
|
|
python -m uvicorn evaluator_monitor.app:app --host 0.0.0.0 --port 8080
|
|
```
|
|
|
|
O monitor utiliza as mesmas configurações `ADB_*`/wallet do evaluator. Ele é **read-only** do ponto de vista funcional: não há endpoint para iniciar, cancelar, apagar ou alterar runs.
|
|
|
|
> Recomendação de segurança: mantenha o Service como `ClusterIP`. Se futuramente houver necessidade de exposição externa, coloque autenticação/autorização no Ingress/API Gateway corporativo; não exponha o monitor diretamente à Internet.
|
|
|
|
---
|
|
|
|
## 20. Como subir uma nova versão
|
|
|
|
Fluxo recomendado:
|
|
|
|
### 1. Atualizar código/configuração
|
|
|
|
Não coloque credenciais reais no Git.
|
|
|
|
### 2. Rodar testes
|
|
|
|
```bash
|
|
python -m pytest -v
|
|
python -m compileall evaluator
|
|
```
|
|
|
|
### 3. Testar localmente com limite
|
|
|
|
```bash
|
|
python -m evaluator.cli run-agents \
|
|
--agent-id <agentId> \
|
|
--limit 5
|
|
```
|
|
|
|
### 4. Validar o run
|
|
|
|
```bash
|
|
python -m evaluator.cli runs --limit 10
|
|
python -m evaluator.cli progress <RUN_ID> --events 100
|
|
```
|
|
|
|
### 5. Confirmar GCS
|
|
|
|
O evento deve conter:
|
|
|
|
```text
|
|
GCS_UPLOADED
|
|
```
|
|
|
|
com uma URI como:
|
|
|
|
```text
|
|
gs://<bucket>/<prefix>/AGENTE_<agent>_LLM_JUDGE_<timestamp>.TXT.GZ
|
|
```
|
|
|
|
### 6. Atualizar secrets/configuração do ambiente
|
|
|
|
```bash
|
|
./deploy/scripts/create-secrets.sh <dev|hml|prod>
|
|
```
|
|
|
|
### 7. Build/push com uma tag nova
|
|
|
|
```bash
|
|
export REGISTRY=<registry>
|
|
export IMAGE_TAG=<nova-versao>
|
|
./deploy/scripts/build-push.sh <ambiente>
|
|
```
|
|
|
|
### 8. Deploy
|
|
|
|
```bash
|
|
./deploy/scripts/deploy.sh <ambiente>
|
|
```
|
|
|
|
### 9. Rodar manualmente para homologação
|
|
|
|
```bash
|
|
./deploy/scripts/run-now.sh <ambiente>
|
|
```
|
|
|
|
### 10. Verificar logs e artefatos
|
|
|
|
```bash
|
|
kubectl -n agent-evaluator-<ambiente> logs -f job/<job>
|
|
```
|
|
|
|
Confirme também o objeto no bucket GCS e a auditoria `judge-job-{agentId}` no Langfuse.
|
|
|
|
---
|
|
|
|
## 21. Troubleshooting
|
|
|
|
### `Collected 0 traces`
|
|
|
|
Verifique nesta ordem:
|
|
|
|
1. data processada (`daysBack` usa BRT);
|
|
2. credencial Langfuse do `agentId` correto;
|
|
3. `host` do projeto Langfuse;
|
|
4. `langfuse_agent_aliases`;
|
|
5. existência de sessions/traces naquele período;
|
|
6. se o `agentId` lógico é diferente do `metadata.agent_id` dos traces.
|
|
|
|
Exemplo:
|
|
|
|
```yaml
|
|
- agentId: billing
|
|
langfuse_agent_aliases:
|
|
- telecom_contas
|
|
- billing_agent
|
|
```
|
|
|
|
### `No Langfuse credentials configured for agent ...`
|
|
|
|
O agente existe em `agents.yaml`, mas não no arquivo apontado por:
|
|
|
|
```env
|
|
LANGFUSE_CREDENTIALS_CONFIG_PATH
|
|
```
|
|
|
|
Adicione uma entrada com o mesmo `agentId`.
|
|
|
|
### `Langfuse credentials definition file not found`
|
|
|
|
Crie/mapeie o arquivo:
|
|
|
|
```text
|
|
configs/langfuse/langfuse_credentials.yaml
|
|
```
|
|
|
|
ou configure outro path.
|
|
|
|
### `TIM specification requires GCS upload...`
|
|
|
|
`run-agents` foi executado com:
|
|
|
|
```env
|
|
ENABLE_GCS_UPLOAD=false
|
|
```
|
|
|
|
Altere para `true` e configure a credencial GCP.
|
|
|
|
### GCS falha
|
|
|
|
Verifique:
|
|
|
|
```bash
|
|
echo "$GOOGLE_APPLICATION_CREDENTIALS"
|
|
ls -l "$GOOGLE_APPLICATION_CREDENTIALS"
|
|
```
|
|
|
|
E valide o bucket resolvido por `APP_ENV`/`storage.yaml`.
|
|
|
|
### OCI SDK falha em dedicated endpoint
|
|
|
|
Confira:
|
|
|
|
```env
|
|
LLM_PROVIDER=oci_sdk
|
|
OCI_GENAI_BASE_URL=https://<endpoint-nativo-sem-openai-v1>
|
|
OCI_GENAI_ENDPOINT_ID=ocid1.generativeaiendpoint...
|
|
OCI_COMPARTMENT_ID=...
|
|
```
|
|
|
|
Para `oci_sdk`, não use `/openai/v1` no endpoint.
|
|
|
|
### Banco não inicializado
|
|
|
|
```bash
|
|
python -m evaluator.cli init-db
|
|
```
|
|
|
|
### Ver progresso pela CLI
|
|
|
|
O `run-agents` agora imprime o `RUN_ID` assim que a execução é criada:
|
|
|
|
```text
|
|
[telecom_contas] RUN_ID=8d9a2d1e-...
|
|
progress: python -m evaluator.cli progress 8d9a2d1e-... --events 100
|
|
```
|
|
|
|
Também é possível listar runs e consultar qualquer execução:
|
|
|
|
```bash
|
|
python -m evaluator.cli runs
|
|
python -m evaluator.cli progress <RUN_ID> --events 100
|
|
```
|
|
|
|
### Ver progresso pela interface web
|
|
|
|
```bash
|
|
python -m uvicorn evaluator_monitor.app:app --host 0.0.0.0 --port 8080
|
|
```
|
|
|
|
Abra `http://localhost:8080/ui`. Em Kubernetes, prefira `kubectl port-forward svc/evaluator-monitor 8080:8080`.
|
|
|
|
---
|
|
|
|
## 22. Variáveis de ambiente principais
|
|
|
|
| Variável | Uso |
|
|
|---|---|
|
|
| `APP_ENV` | ambiente usado para resolver storage |
|
|
| `ADB_*` | conexão e wallet Oracle |
|
|
| `ENABLE_LANGFUSE` | habilita coleta Langfuse |
|
|
| `LANGFUSE_CREDENTIALS_CONFIG_PATH` | YAML declarativo por agente |
|
|
| `LANGFUSE_*` | fallback global apenas para `run` manual |
|
|
| `PUBLISH_LANGFUSE_SCORES` | publica scores de trace de volta no Langfuse |
|
|
| `LLM_PROVIDER` | `mock`, `oci_openai`, `oci_sdk`, `openai_compatible` |
|
|
| `LLM_PROFILE` | perfil de judge |
|
|
| `OCI_AUTH_MODE` | autenticação OCI SDK |
|
|
| `OCI_GENAI_BASE_URL` | endpoint OCI GenAI |
|
|
| `OCI_GENAI_MODEL` | model ID/nome ou compatibilidade com endpoint OCID |
|
|
| `OCI_GENAI_ENDPOINT_ID` | dedicated endpoint OCID |
|
|
| `OCI_COMPARTMENT_ID` | compartment OCI |
|
|
| `AGENTS_CONFIG_PATH` | arquivo de agentes |
|
|
| `TRACE_PROMPT_PATH` | prompt trace-level |
|
|
| `SESSION_PROMPT_PATH` | prompt session-level |
|
|
| `BATCH_SIZE` | quantidade processada por lote interno |
|
|
| `MAX_ATTEMPTS` | limite configurável de tentativas |
|
|
| `CONTEXT_TURN_LIMIT` | últimos N turnos enviados ao judge trace |
|
|
| `ENABLE_GCS_UPLOAD` | exige upload no fluxo produtivo |
|
|
| `STORAGE_CONFIG_PATH` | mapping de buckets por ambiente |
|
|
| `JUDGE_GCS_BUCKET` | override de bucket |
|
|
| `GOOGLE_APPLICATION_CREDENTIALS` | credencial GCP |
|
|
| `OUTPUT_DIR` | diretório temporário de export |
|
|
| `OUTPUT_FILENAME_PATTERN` | template configurável do nome do arquivo de saída |
|
|
|
|
---
|
|
|
|
## 23. Segurança e operação
|
|
|
|
- não versionar `.env` real;
|
|
- não versionar `langfuse_credentials.yaml` real;
|
|
- não versionar GCP service account JSON;
|
|
- não versionar wallet Oracle;
|
|
- em OKE prefira `oke_workload_identity` quando aplicável;
|
|
- monte credenciais como Kubernetes Secrets;
|
|
- use `readOnlyRootFilesystem` no CronJob;
|
|
- mantenha `concurrencyPolicy: Forbid` para evitar dois D+1 concorrentes do mesmo deployment;
|
|
- nunca use `reset-db` em produção sem plano explícito de restauração.
|
|
|
|
---
|
|
|
|
## 24. Checklist de homologação
|
|
|
|
Antes de promover uma versão:
|
|
|
|
- [ ] `pip check` sem erro;
|
|
- [ ] `python -m pytest -v` passando;
|
|
- [ ] `python -m compileall evaluator` sem erro;
|
|
- [ ] `show-config` aponta para ADB/OCI/configs corretos;
|
|
- [ ] `agents.yaml` contém apenas os agentes esperados para aquele deployment;
|
|
- [ ] credencial Langfuse existe para cada `agentId` habilitado;
|
|
- [ ] `run-agents --limit 5` encontra traces;
|
|
- [ ] sampling seleciona sessions, não traces individuais;
|
|
- [ ] judge trace/session conclui;
|
|
- [ ] arquivo possui cabeçalho de 12 colunas;
|
|
- [ ] nome segue `AGENTE_{agentId}_LLM_JUDGE_{YYYYMMDD}_{HHMMSS}.TXT.GZ`;
|
|
- [ ] evento `GCS_UPLOADED` confirmado;
|
|
- [ ] arquivo local removido depois do upload;
|
|
- [ ] auditoria Langfuse `created/completed` confirmada;
|
|
- [ ] CronJob está `suspend: false`;
|
|
- [ ] timezone do CronJob é `America/Sao_Paulo`;
|
|
- [ ] nenhuma credencial real está no repositório.
|
|
|
|
---
|
|
|
|
## 25. Resumo para quem está chegando no projeto
|
|
|
|
Se você precisa entender o projeto em poucos minutos, pense assim:
|
|
|
|
```text
|
|
Langfuse guarda as conversas
|
|
↓
|
|
Evaluator escolhe sessions D+1
|
|
↓
|
|
OCI GenAI julga traces e sessions
|
|
↓
|
|
ADB guarda execução e resultados
|
|
↓
|
|
GCS recebe o arquivo oficial
|
|
↓
|
|
Langfuse registra a auditoria do batch
|
|
```
|
|
|
|
Os pontos de extensão ficam em configuração:
|
|
|
|
```text
|
|
Qual agente? -> configs/judge/agents.yaml
|
|
Qual projeto Langfuse?-> langfuse_credentials.yaml
|
|
Qual bucket? -> configs/judge/storage.yaml
|
|
Qual prompt? -> trace_metrics.yaml / session_metrics.yaml
|
|
Qual modelo? -> .env + llm_profiles.yaml
|
|
Qual identidade? -> configs/identity.yaml
|
|
```
|
|
|
|
A regra arquitetural mais importante é: **o código do evaluator deve permanecer genérico; detalhes de agentes, ambientes, credenciais e storage pertencem à configuração.**
|