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_ordersefinanceiro_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_contextcanô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_tokensetotal_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:
- criar uma nova execução de avaliação (
EVALUATION_RUN); - escolher o collector conforme
source; - coletar conversas;
- aplicar amostragem por agente;
- inserir itens em
EVALUATION_ITEM; - processar cada item;
- chamar o LLM Judge;
- salvar resultado de trace;
- executar avaliação de sessão;
- salvar resultado de sessão;
- exportar arquivo legado;
- marcar status final da execução;
- 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
BusinessContextcanô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
TraceJudgeResulteSessionJudgeResult.
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,COMPLETEDouFAILED; - 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:
prompt_tokens/promptTokens/input_tokens/inputTokensnas observations do Langfuse;usage.inputouusageDetails.input;metadata.input_sizeemitido pelo framework;- fallback para tamanho textual de
input_text,output_textemessages.
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_tokensnão foi incluído no arquivo;promptTokensestá zerado no Langfuse;input_sizenão está sendo percorrido;RAW_JSONestá vindo como string não convertida;- exporter antigo ainda está rodando;
except Exception: passestá 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.yamlnão está sendo carregado;- collector não está copiando
business_contextparametadata; interaction_keynã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-dbtenta alterar schema; - outro processo usando a tabela;
- transação aberta no SQL Developer.
Correção:
- parar API/CLI;
- fechar sessões abertas;
- 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; .envnã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.