Files
agent_framework_oci_evaluator/README.md
2026-06-12 11:36:33 -03:00

28 KiB

agent_framework_evaluator

1. O que é o agent_framework_evaluator?

O agent_framework_evaluator é um serviço complementar ao agent_framework_oci criado para avaliar conversas reais executadas pelos agentes do framework.

Ele coleta conversas de uma fonte, normalmente o Langfuse, reconstrói o contexto da interação, executa um Judge LLM, grava os resultados em banco Oracle/ADB, gera arquivos legados no formato TXT.GZ e, opcionalmente, publica scores de volta no Langfuse.

Em termos simples:

agent_framework_oci gera conversas e telemetria
        ↓
Langfuse armazena traces, spans, generations, metadata e usage
        ↓
agent_framework_evaluator coleta essas conversas
        ↓
LLM Judge avalia qualidade, precisão, alucinação, resolução e CSI
        ↓
Oracle/ADB persiste runs, itens, resultados, achados e progresso
        ↓
Exporter gera arquivo legado AGENTE_<agent>_LLM_JUDGE_YYYYMMDD.TXT.GZ

O evaluator não substitui os guardrails, judges online ou telemetria do agent_framework_oci. Ele atua como uma camada offline/batch de avaliação, auditoria e exportação.


2. Objetivo da solução

O objetivo do evaluator é permitir que conversas já executadas sejam analisadas posteriormente com critérios padronizados.

Ele atende principalmente estes cenários:

  • avaliação diária de conversas por agente;
  • geração de arquivos legados de avaliação;
  • auditoria de qualidade de respostas;
  • identificação de alucinação, baixa precisão, baixa resolução ou baixa experiência do cliente;
  • comparação entre agentes como telecom_contas, retail_orders e financeiro_agent;
  • publicação opcional de scores no Langfuse;
  • persistência de histórico de avaliações no Oracle/ADB;
  • acompanhamento de progresso via API ou CLI.

3. Como ele se integra ao agent_framework_oci

O agent_framework_oci é o runtime principal dos agentes. Ele executa o fluxo conversacional com LangGraph, supervisor, guardrails, judges, MCP tools, memória, RAG e telemetria.

Durante a execução, o framework publica traces no Langfuse contendo:

  • trace_id;
  • session_id;
  • message_id;
  • agent_id;
  • channel;
  • business_context canônico;
  • eventos IC/NOC/GRL;
  • spans de LangGraph;
  • spans de guardrails;
  • spans de judges;
  • generations LLM;
  • usage de modelo, quando disponível;
  • prompt_tokens, completion_tokens e total_tokens, quando retornados pelo provider;
  • input_size, quando emitido pelos spans do framework.

O evaluator usa essa telemetria como fonte de dados.

A integração principal acontece assim:

agent_framework_oci
  ├── executa agentes
  ├── resolve identidade via identity.yaml
  ├── monta BusinessContext canônico
  ├── chama MCP/RAG/LLM
  ├── emite telemetria Langfuse
  └── grava usage/model/tokens quando disponíveis

agent_framework_evaluator
  ├── lê traces no Langfuse
  ├── aplica identity.yaml para normalizar identidade
  ├── reconstrói ConversationRecord
  ├── executa LLM Judge offline
  ├── grava resultados no Oracle/ADB
  ├── exporta TXT.GZ legado
  └── opcionalmente publica scores no Langfuse

4. Arquitetura geral

+------------------------+
| agent_framework_oci    |
|------------------------|
| LangGraph              |
| Supervisor             |
| Guardrails             |
| Judges online          |
| MCP Tool Router        |
| RAG                    |
| Memory / Checkpoint    |
| Langfuse Telemetry     |
+-----------+------------+
            |
            v
+------------------------+
| Langfuse               |
|------------------------|
| Traces                 |
| Spans                  |
| Generations            |
| Metadata               |
| Usage / Tokens         |
+-----------+------------+
            |
            v
+------------------------+
| agent_framework_       |
| evaluator              |
|------------------------|
| Collectors             |
| Identity Resolver      |
| Conversation Records   |
| LLM Judge              |
| VLoop analytics        |
| Repository Oracle      |
| Legacy Exporter        |
| API / CLI              |
+-----------+------------+
            |
            v
+------------------------+
| Oracle ADB             |
|------------------------|
| EVALUATION_RUN         |
| EVALUATION_ITEM        |
| EVALUATION_RESULT      |
| EVALUATION_FINDING     |
| EVALUATION_PROGRESS    |
| EVALUATION_METRIC      |
+-----------+------------+
            |
            v
+------------------------+
| Output                 |
|------------------------|
| TXT.GZ legado          |
| API dashboard          |
| Langfuse scores        |
+------------------------+

5. Componentes da solução

5.1 CLI

Arquivo principal:

evaluator/cli.py

Responsável por expor comandos como:

python -m evaluator.cli init-db
python -m evaluator.cli show-config
python -m evaluator.cli run --source langfuse
python -m evaluator.cli run-agents --source langfuse
python -m evaluator.cli runs
python -m evaluator.cli progress <run_id>

A CLI é a forma principal de operar o evaluator em modo batch.


5.2 API

Arquivo principal:

evaluator/api/main.py

Expõe endpoints HTTP para consultar progresso, runs e resultados.

Exemplos esperados:

GET /health
GET /runs
GET /runs/{run_id}/progress
GET /runs/{run_id}/results
GET /runs/{run_id}/findings

A API permite construir uma interface gráfica simples ou integrar o evaluator com outros sistemas.


5.3 EvaluationEngine

Arquivo principal:

evaluator/engine.py

É o orquestrador central do evaluator.

Responsabilidades:

  1. criar uma nova execução de avaliação (EVALUATION_RUN);
  2. escolher o collector conforme source;
  3. coletar conversas;
  4. aplicar amostragem por agente;
  5. inserir itens em EVALUATION_ITEM;
  6. processar cada item;
  7. chamar o LLM Judge;
  8. salvar resultado de trace;
  9. executar avaliação de sessão;
  10. salvar resultado de sessão;
  11. exportar arquivo legado;
  12. marcar status final da execução;
  13. emitir eventos de progresso.

Fluxo simplificado:

run_agent()
  ↓
collector.collect()
  ↓
repository.insert_items()
  ↓
_process()
  ↓
judge.judge_trace()
  ↓
repository.save_trace_result()
  ↓
judge.judge_sessions()
  ↓
repository.save_session_result()
  ↓
export_legacy_txt_gz()

5.4 Collectors

Diretório:

evaluator/collectors/

Collectors são responsáveis por buscar conversas em uma fonte externa e convertê-las para ConversationRecord.

Collectors típicos:

evaluator/collectors/langfuse.py
evaluator/collectors/agent_framework.py
evaluator/collectors/mock.py
evaluator/collectors/base.py

LangfuseCollector

É o collector principal.

Responsabilidades:

  • buscar traces no Langfuse;
  • filtrar por período;
  • filtrar por agente/alias;
  • recuperar detalhes do trace;
  • extrair input/output;
  • reconstruir mensagens;
  • coletar metadata;
  • aplicar identity.yaml;
  • montar BusinessContext canônico;
  • preencher ConversationRecord.

O collector deve normalizar dados para que o exporter não precise conhecer detalhes internos do Langfuse.


5.5 Identity Resolver

Diretório recomendado:

evaluator/identity/

Arquivo principal:

evaluator/identity/resolver.py

O evaluator deve usar o mesmo conceito de identidade do agent_framework_oci, baseado no arquivo:

configs/identity.yaml

A função do identity.yaml é mapear campos variáveis de entrada para um modelo canônico:

customer_key
contract_key
interaction_key
account_key
resource_key
session_key

Exemplo conceitual:

identity:
  version: 2
  keys:
    customer_key:
      sources:
        - business_context.customer_key
        - metadata.customer_key
        - user_id
    contract_key:
      sources:
        - business_context.contract_key
        - metadata.contract_key
    interaction_key:
      sources:
        - business_context.interaction_key
        - metadata.ura_call_id
        - metadata.message_id
        - message_id
    session_key:
      sources:
        - business_context.session_key
        - session_id
        - conversation_key

Com isso, o evaluator não fica preso a campos como ura_call_id, call_id, message_id ou interaction_key diretamente. Ele resolve tudo para interaction_key.


5.6 Models

Arquivo principal:

evaluator/core/models.py

Define os objetos centrais do evaluator.

Principais modelos:

class ConversationRecord
class ConversationMessage
class TraceJudgeResult
class SessionJudgeResult
class CombinedJudgeResult
class RunStatus
class ItemStatus

ConversationRecord

Representa uma conversa ou turno avaliado.

Campos comuns:

trace_id
session_id
message_id
agent_id
channel
input_text
output_text
messages
metadata
raw

O campo metadata deve conter dados normalizados:

business_context
uraCallId
channelId
messageId
promptLength

O campo raw mantém o payload original para auditoria e fallback.


5.7 LLM Judge

Arquivo principal:

evaluator/judges/llm_judge.py

Classe principal:

TIMStyleLLMJudge

Responsabilidades:

  • carregar prompts de avaliação;
  • montar prompt de trace;
  • montar prompt de sessão;
  • chamar LLM via client configurado;
  • interpretar resposta JSON;
  • retornar TraceJudgeResult e SessionJudgeResult.

O judge avalia métricas como:

judgeScore
accuracyScore
alucinationScore
inferredCsiScore
resolution
conversationPrecision
rationale

O judge deve ser LLM-based, não determinístico.


5.8 Prompts

Diretório:

evaluator/prompts/

Arquivos esperados:

trace_judge_prompt.md
session_judge_prompt.md
loader.py

O prompt de trace avalia uma resposta individual.

O prompt de sessão avalia a conversa agrupada por session_id.

Exemplo de saída esperada do LLM para trace:

{
  "judgeScore": 0.8,
  "accuracyScore": 0.9,
  "alucinationScore": 0.1,
  "rationale": "Resposta aderente ao contexto e baseada em dados disponíveis."
}

Exemplo de saída esperada para sessão:

{
  "inferredCsiScore": 0.5,
  "resolution": 1,
  "conversationPrecision": 1,
  "rationale": "A conversa foi resolvida com informações consistentes."
}

5.9 LLM Client

Diretório:

evaluator/llm/

Arquivos típicos:

evaluator/llm/client.py
evaluator/llm/oci_openai.py

O evaluator deve usar o mesmo padrão de acesso a LLM do agent_framework_oci, preferencialmente via provider oci_openai.

Variáveis comuns:

LLM_PROVIDER=oci_openai
OCI_GENAI_ENDPOINT=...
OCI_GENAI_MODEL_ID=...
OCI_GENAI_API_KEY=...
OCI_GENAI_COMPARTMENT_ID=...

O client precisa retornar texto bruto para o Judge interpretar como JSON.


5.10 Repository / Oracle Store

Diretório:

evaluator/persistence/

Arquivos principais:

evaluator/persistence/oracle_store.py
evaluator/persistence/repository.py

O OracleStore cuida de:

  • conexão com ADB/Oracle;
  • wallet;
  • DSN;
  • criação/ajuste de schema;
  • execução thread-safe para chamadas assíncronas;
  • prefixo de tabelas.

O EvaluationRepository cuida de:

  • criar runs;
  • gravar progresso;
  • inserir itens;
  • buscar próximos itens;
  • marcar item como PROCESSING, COMPLETED ou FAILED;
  • salvar resultados;
  • salvar findings;
  • sumarizar run;
  • listar runs;
  • consultar progresso.

5.11 Legacy Exporter

Arquivo principal:

evaluator/output/legacy_exporter.py

Gera o arquivo legado:

output/AGENTE_<agent_id>_LLM_JUDGE_YYYYMMDD.TXT.GZ

Formato das colunas:

judgeScore
accuracyScore
alucinationScore
promptLength
loop
inferredCsiScore
resolution
conversationPrecision
uraCallId
channelId
sessionId
messageId

Exemplo:

"0.8"|;"0.9"|;"0.1"|;"732"|;"0"|;"0.5"|;"1"|;"1"|;"6d7e85b0-ddd0-4f23-a372-30e754a4491a"|;"web"|;"eba23248-e038-4d33-bc2c-6465ef677d07"|;"6d7e85b0-ddd0-4f23-a372-30e754a4491a"
"TOTAL"|;"19"

promptLength

O campo promptLength deve usar esta prioridade:

  1. prompt_tokens / promptTokens / input_tokens / inputTokens nas observations do Langfuse;
  2. usage.input ou usageDetails.input;
  3. metadata.input_size emitido pelo framework;
  4. fallback para tamanho textual de input_text, output_text e messages.

Exemplo:

promptLength = 732

loop

O campo loop usa o detector VLoop.

0 = sem loop detectado
1 = loop detectado

5.12 VLoop Analytics

Arquivo principal:

evaluator/analytics/vloop.py

Responsável por detectar repetição/loop conversacional em padrão semelhante ao guardrail VLoop do agent_framework_oci.

A função normalmente exposta é:

vloop_flag(raw) -> int

Ela retorna:

0 quando não há evidência de loop
1 quando há repetição suspeita

5.13 Langfuse Score Publisher

Arquivo principal:

evaluator/publishers/langfuse_scores.py

Responsável por publicar scores de avaliação de volta no Langfuse, quando habilitado.

Variável de controle:

PUBLISH_LANGFUSE_SCORES=true

Quando desabilitado, o evaluator apenas grava no banco e exporta arquivo.


6. Estrutura de diretórios

agent_framework_evaluator/
├── configs/
│   ├── identity.yaml
│   └── judge/
│       └── agents.yaml
├── docs/
├── evaluator/
│   ├── __init__.py
│   ├── cli.py
│   ├── engine.py
│   ├── api/
│   │   └── main.py
│   ├── analytics/
│   │   └── vloop.py
│   ├── collectors/
│   │   ├── base.py
│   │   ├── langfuse.py
│   │   ├── agent_framework.py
│   │   └── mock.py
│   ├── config/
│   │   ├── settings.py
│   │   └── agents.py
│   ├── core/
│   │   └── models.py
│   ├── identity/
│   │   └── resolver.py
│   ├── judges/
│   │   └── llm_judge.py
│   ├── llm/
│   │   ├── client.py
│   │   └── oci_openai.py
│   ├── output/
│   │   └── legacy_exporter.py
│   ├── persistence/
│   │   ├── oracle_store.py
│   │   └── repository.py
│   ├── prompts/
│   │   ├── loader.py
│   │   ├── trace_judge_prompt.md
│   │   └── session_judge_prompt.md
│   └── publishers/
│       └── langfuse_scores.py
├── output/
├── Dockerfile
├── docker-compose.yml
├── pyproject.toml
└── README.md

7. Configuração

7.1 Arquivo .env

Exemplo:

# Oracle / ADB
ADB_USER=ADMIN
ADB_PASSWORD=your_password
ADB_DSN=oradb23ai_high
ADB_WALLET_DIR=/path/to/Wallet_ORADB23ai
DB_TABLE_PREFIX=AGENTFW_

# Langfuse
LANGFUSE_ENABLED=true
LANGFUSE_HOST=http://localhost:3005
LANGFUSE_PUBLIC_KEY=pk-lf-...
LANGFUSE_SECRET_KEY=sk-lf-...
PUBLISH_LANGFUSE_SCORES=false

# LLM
LLM_PROVIDER=oci_openai
OCI_GENAI_ENDPOINT=https://...
OCI_GENAI_MODEL_ID=...
OCI_GENAI_API_KEY=...
OCI_GENAI_COMPARTMENT_ID=...

# Evaluator
EVALUATOR_OUTPUT_DIR=output
EVALUATOR_BATCH_SIZE=10
EVALUATOR_MAX_ATTEMPTS=2
EVALUATOR_AGENTS_CONFIG=configs/judge/agents.yaml
IDENTITY_CONFIG_PATH=configs/identity.yaml
TRACE_PROMPT_PATH=evaluator/prompts/trace_judge_prompt.md
SESSION_PROMPT_PATH=evaluator/prompts/session_judge_prompt.md

7.2 Configuração de agentes

Arquivo:

configs/judge/agents.yaml

Exemplo:

agents:
  - agent_id: telecom_contas
    enabled: true
    aliases:
      - telecom_contas
      - billing_agent
      - financeiro_agent
    percentage: 1.0

  - agent_id: retail_orders
    enabled: true
    aliases:
      - retail_orders
      - orders_agent
    percentage: 1.0

  - agent_id: financeiro_agent
    enabled: true
    aliases:
      - financeiro_agent
    percentage: 1.0

O campo aliases é importante porque o Langfuse pode registrar o agente de formas diferentes, por exemplo:

agent_id = telecom_contas
route = financeiro_agent
agent = financeiro_agent

7.3 Configuração de identidade

Arquivo:

configs/identity.yaml

O evaluator deve usar o mesmo padrão do framework.

Exemplo:

identity:
  version: 2
  keys:
    customer_key:
      sources:
        - business_context.customer_key
        - metadata.customer_key
        - user_id

    contract_key:
      sources:
        - business_context.contract_key
        - metadata.contract_key

    interaction_key:
      sources:
        - business_context.interaction_key
        - metadata.ura_call_id
        - metadata.message_id
        - message_id

    session_key:
      sources:
        - business_context.session_key
        - metadata.session_key
        - session_id
        - conversation_key

O campo interaction_key é usado para preencher o uraCallId no export legado.


8. Como executar

8.1 Instalar dependências

python -m venv .venv
source .venv/bin/activate
pip install -e .

Se estiver usando Conda:

conda activate py313
pip install -e .

8.2 Validar configuração

python -m evaluator.cli show-config

Saída esperada:

{
  "env_path": ".../.env",
  "adb_dsn": "oradb23ai_high",
  "wallet": ".../Wallet_ORADB23ai",
  "langfuse": true,
  "publish_langfuse_scores": false,
  "llm_provider": "oci_openai",
  "agents_config": "configs/judge/agents.yaml"
}

8.3 Criar/validar schema

python -m evaluator.cli init-db

Saída esperada:

{'status': 'OK', 'message': 'Evaluator schema checked/created successfully.'}

8.4 Rodar avaliação por período

python -m evaluator.cli run \
  --period-start 2026-06-11T00:00:00 \
  --period-end 2026-06-12T00:00:00 \
  --source langfuse

8.5 Rodar avaliação por agentes configurados

python -m evaluator.cli run-agents --source langfuse

Saída esperada:

[
  {
    'status': 'COMPLETED',
    'run_id': '...',
    'total_items': 19,
    'completed_items': 19,
    'failed_items': 0,
    'evaluations': 19,
    'avg_score': 0.72,
    'agent_id': 'telecom_contas',
    'output_file': 'output/AGENTE_telecom_contas_LLM_JUDGE_20260612.TXT.GZ',
    'uploaded_to': None
  }
]

8.6 Consultar progresso

python -m evaluator.cli progress <run_id>

Ou via API:

curl http://localhost:8001/runs/<run_id>/progress

8.7 Ver arquivo exportado

gzip -cd output/AGENTE_telecom_contas_LLM_JUDGE_20260612.TXT.GZ

Exemplo de linha válida:

"0.8"|;"0.9"|;"0.1"|;"732"|;"0"|;"0.5"|;"1"|;"1"|;"6d7e85b0-ddd0-4f23-a372-30e754a4491a"|;"web"|;"eba23248-e038-4d33-bc2c-6465ef677d07"|;"6d7e85b0-ddd0-4f23-a372-30e754a4491a"
"TOTAL"|;"19"

9. Banco de dados

9.1 Tabelas principais

EVALUATION_RUN

Armazena uma execução de avaliação.

Campos principais:

RUN_ID
PERIOD_START
PERIOD_END
SOURCE
AGENT_ID
STATUS
TOTAL_ITEMS
PROCESSED_ITEMS
FAILED_ITEMS
LAST_HEARTBEAT_AT
CREATED_AT
UPDATED_AT
ERROR_MESSAGE

EVALUATION_ITEM

Armazena cada conversa/turno coletado.

Campos principais:

ITEM_ID
RUN_ID
TRACE_ID
SESSION_ID
MESSAGE_ID
AGENT_ID
CHANNEL
STATUS
ATTEMPT_COUNT
RAW_JSON
CREATED_AT
UPDATED_AT
ERROR_MESSAGE

EVALUATION_RESULT

Armazena resultados de trace e sessão.

Campos principais:

RESULT_ID
RUN_ID
ITEM_ID
TRACE_ID
SESSION_ID
AGENT_ID
JUDGE_TYPE
JUDGE_NAME
JUDGE_SCORE
ACCURACY_SCORE
ALUCINATION_SCORE
INFERRED_CSI_SCORE
RESOLUTION
CONVERSATION_PRECISION
RATIONALE
RESULT_JSON
CREATED_AT

JUDGE_TYPE pode ser:

TRACE
SESSION

EVALUATION_PROGRESS_EVENT

Armazena eventos de progresso da execução.

Exemplos de stage:

RUN_CREATED
COLLECTING
COLLECTED
SAMPLED
ITEMS_INSERTED
BATCH_STARTED
ITEM_COMPLETED
ITEM_FAILED
SESSION_JUDGE_COMPLETED
EXPORTED
COMPLETED
PARTIAL

10. Como os códigos funcionam em conjunto

10.1 Fluxo completo de execução

CLI run-agents
  ↓
carrega configs/judge/agents.yaml
  ↓
para cada agente habilitado
  ↓
EvaluationEngine.run_agent(agent)
  ↓
cria EVALUATION_RUN
  ↓
LangfuseCollector.collect(...)
  ↓
IdentityResolver.resolve(...)
  ↓
ConversationRecord
  ↓
EvaluationRepository.insert_items(...)
  ↓
EvaluationEngine._process(run_id)
  ↓
TIMStyleLLMJudge.judge_trace(record)
  ↓
LLMClient.complete(prompt)
  ↓
save_trace_result(...)
  ↓
TIMStyleLLMJudge.judge_sessions(records)
  ↓
save_session_result(...)
  ↓
export_legacy_txt_gz(...)
  ↓
COMPLETED

10.2 Papel do collector

O collector é responsável por transformar dados externos em dados canônicos.

Ele deve esconder diferenças entre fontes como:

Langfuse
agent_framework database
mock data

A saída sempre deve ser:

ConversationRecord

10.3 Papel do judge

O judge recebe um ConversationRecord, monta um prompt e chama o LLM.

Ele não deve conhecer Oracle, Langfuse, export legado ou API.

Ele só avalia.


10.4 Papel do repository

O repository é a camada de persistência.

Ele não deve conter regra de negócio de avaliação.

Ele apenas grava, busca e atualiza dados.


10.5 Papel do exporter

O exporter transforma dados persistidos em arquivo legado.

Ele não deve resolver identidade de forma complexa.

O ideal é que ele leia campos já normalizados:

metadata.business_context.interaction_key
metadata.channelId
metadata.messageId
metadata.promptLength

No entanto, para resiliência, ele também pode consultar RAW_JSON como fallback.


11. Regras importantes de desenho

11.1 O evaluator não deve ficar chumbado para um agente

Evite lógica como:

if agent_id == "telecom_contas":
    ura_call_id = metadata["ura_call_id"]

O correto é usar identity.yaml.


11.2 O exporter não deve conhecer detalhes internos do Langfuse

Evite acoplamento excessivo a caminhos como:

raw.detail.observations[0].metadata.ura_call_id
raw.trace.input.business_context.interaction_key

Isso deve ser resolvido no collector.


11.3 promptLength deve vir de tokens quando possível

Prioridade recomendada:

1. prompt_tokens / promptTokens
2. input_tokens / inputTokens
3. usage.input / usageDetails.input
4. metadata.input_size
5. tamanho textual de input/output/messages

11.4 uraCallId deve vir do BusinessContext

O campo legado uraCallId deve ser mapeado para:

business_context.interaction_key

Esse é o nome canônico do framework.


11.5 sessionId deve vir do BusinessContext

O campo legado sessionId deve ser mapeado para:

business_context.session_key

Não confundir com a chave composta completa:

default:telecom_contas:<uuid>

O evaluator pode guardar a chave completa, mas o export legado normalmente deve usar o identificador de sessão limpo.


12. Testes recomendados

12.1 Teste de configuração

python -m evaluator.cli show-config

Validar:

ADB_DSN
Wallet
Langfuse enabled
LLM provider
Agents config
Identity config

12.2 Teste de banco

python -m evaluator.cli init-db

Depois validar tabelas:

select table_name
from user_tables
where table_name like 'AGENTFW_EVALUATION%';

12.3 Teste com mock

python -m evaluator.cli run --source mock

Use esse teste para validar schema, judge e export sem depender do Langfuse.


12.4 Teste com Langfuse

python -m evaluator.cli run-agents --source langfuse

Validar:

total_items > 0
completed_items > 0
failed_items = 0
evaluations > 0
output_file preenchido

12.5 Teste do export

gzip -cd output/AGENTE_telecom_contas_LLM_JUDGE_YYYYMMDD.TXT.GZ

Validar colunas:

judgeScore              preenchido
accuracyScore           preenchido
alucinationScore        preenchido
promptLength            maior que 0
loop                    0 ou 1
inferredCsiScore        preenchido
resolution              0 ou 1
conversationPrecision   0 ou 1
uraCallId               preenchido
channelId               preenchido
sessionId               preenchido
messageId               preenchido

13. Troubleshooting

13.1 promptLength sai 0

Causas comuns:

  • find_prompt_tokens não foi incluído no arquivo;
  • promptTokens está zerado no Langfuse;
  • input_size não está sendo percorrido;
  • RAW_JSON está vindo como string não convertida;
  • exporter antigo ainda está rodando;
  • except Exception: pass está mascarando erro.

Debug recomendado:

print("PROMPT_LENGTH", extract_prompt_length(raw))
print("RAW_TYPE", type(raw))
print("RAW_KEYS", list(raw.keys())[:20])

13.2 uraCallId sai vazio

Causas comuns:

  • identity.yaml não está sendo carregado;
  • collector não está copiando business_context para metadata;
  • interaction_key não existe no trace;
  • exporter não usa business_context.interaction_key.

Validação:

select RAW_JSON
from AGENTFW_EVALUATION_ITEM
where MESSAGE_ID = '<message_id>';

Procurar:

interaction_key
ura_call_id
business_context

13.3 ORA-00904 invalid identifier

Geralmente indica schema antigo.

Exemplos já encontrados:

ORA-00904: UPDATED_AT invalid identifier
ORA-00904: REASONING invalid identifier
ORA-00904: JUDGE_TYPE invalid identifier

Correção:

python -m evaluator.cli init-db

Se a tabela já existir sem a coluna nova, o _init_schema precisa executar ALTER TABLE ADD de forma idempotente.


13.4 ORA-00054 resource busy

Indica lock em tabela.

Causas comuns:

  • API rodando enquanto init-db tenta alterar schema;
  • outro processo usando a tabela;
  • transação aberta no SQL Developer.

Correção:

  1. parar API/CLI;
  2. fechar sessões abertas;
  3. executar novamente init-db.

13.5 OCI LLM 401

Indica problema de autenticação no LLM.

Validar:

OCI_GENAI_ENDPOINT
OCI_GENAI_MODEL_ID
OCI_GENAI_API_KEY
OCI_GENAI_COMPARTMENT_ID

Também confirmar se o evaluator está lendo o .env correto:

python -m evaluator.cli show-config

13.6 Entity with key ${OCI_GENAI_MODEL_ID} not found

Indica que o valor literal ${OCI_GENAI_MODEL_ID} chegou ao provider.

Causas comuns:

  • variável não expandida;
  • YAML usando ${OCI_GENAI_MODEL_ID} sem interpolação;
  • .env não carregado;
  • configuração do LLM client não resolve placeholders.

Correção:

  • colocar o model ID real no .env;
  • garantir interpolação em settings.py;
  • validar com show-config.

14. Checklist de validação final

Antes de considerar o evaluator pronto, validar:

[ ] init-db executa sem erro
[ ] show-config mostra .env correto
[ ] Langfuse retorna traces
[ ] run-agents coleta itens por agente
[ ] LLM Judge responde JSON válido
[ ] EVALUATION_RESULT grava TRACE e SESSION
[ ] progress mostra eventos úteis
[ ] export TXT.GZ é gerado
[ ] promptLength > 0
[ ] uraCallId preenchido
[ ] sessionId preenchido
[ ] messageId preenchido
[ ] loop preenchido com 0 ou 1
[ ] arquivo termina com TOTAL
[ ] scores podem ser publicados no Langfuse quando habilitado

15. Exemplo de resultado final validado

"0.8"|;"0.9"|;"0.1"|;"732"|;"0"|;"0.5"|;"1"|;"1"|;"6d7e85b0-ddd0-4f23-a372-30e754a4491a"|;"web"|;"eba23248-e038-4d33-bc2c-6465ef677d07"|;"6d7e85b0-ddd0-4f23-a372-30e754a4491a"
"0.9"|;"1"|;"0"|;"642"|;"0"|;"0.5"|;"1"|;"1"|;"5ab3ea80-7428-402f-98ec-04e7cd5327e4"|;"web"|;"eba23248-e038-4d33-bc2c-6465ef677d07"|;"5ab3ea80-7428-402f-98ec-04e7cd5327e4"
"TOTAL"|;"19"

Esse resultado indica:

  • Judge funcionando;
  • prompt tokens extraídos corretamente;
  • VLoop sem ocorrência;
  • métricas de sessão preenchidas;
  • identidade canônica funcionando;
  • export legado no layout esperado.

16. Resumo executivo

O agent_framework_evaluator é a camada batch/offline de avaliação do ecossistema agent_framework_oci.

Ele consome a telemetria gerada pelo framework, aplica um Judge LLM com regras de avaliação, persiste resultados em Oracle/ADB, gera arquivo e pode republicar scores no Langfuse.

A arquitetura correta separa responsabilidades:

Collector normaliza dados
IdentityResolver resolve identidade
Judge avalia conversa
Repository persiste
Exporter gera legado
API/CLI operam a solução

Com isso, o evaluator fica genérico para múltiplos agentes e evita acoplamento direto a formatos específicos de trace ou payload.