Atualização do promt + correção de bug *Cristiano*
This commit is contained in:
13
PROMPT.txt
13
PROMPT.txt
@@ -8,14 +8,9 @@ SEGUINDO OS CRITÉRIOS QUE VÃO ESTAR ABAIXO, AVALIE ATENDIMENTOS PRESTADOS VIA
|
|||||||
|
|
||||||
04 (PROTOCOLO) - O AGENTE DEVE INFORMAR O PROTOCOLO DE ATENDIMENTO DURANTE A CONVERSA.
|
04 (PROTOCOLO) - O AGENTE DEVE INFORMAR O PROTOCOLO DE ATENDIMENTO DURANTE A CONVERSA.
|
||||||
|
|
||||||
05 (USO DO PORTUGUÊS) – ESTE CRITÉRIO SE APLICA SOMENTE ÀS MENSAGENS ENVIADAS PELO AGENTE (TYPE = "OUT").
|
05 (USO DO PORTUGUÊS) – O AGENTE DEVE PONTUAR CORRETAMENTE, ACENTUAR CORRETAMENTE E INICIAR AS FRASES COM LETRA MAIÚSCULA.
|
||||||
AO AVALIAR ESTE CRITÉRIO, IGNORE COMPLETAMENTE QUALQUER ERRO COMETIDO PELO CLIENTE.
|
|
||||||
NÃO ANALISE MENSAGENS COM TYPE = "IN" E NÃO ANALISE MENSAGENS DO BOT AUTOMÁTICO.
|
|
||||||
|
|
||||||
O AGENTE DEVE UTILIZAR CORRETAMENTE O PORTUGUÊS NAS MENSAGENS TYPE OUT, INCLUINDO PONTUAÇÃO, ACENTUAÇÃO E INICIO DE FRASES COM LETRA MAIÚSCULA.
|
|
||||||
|
|
||||||
É PERMITIDO O USO DE LINGUAGEM REGIONAL COMO “TU”, “TEU”, “TUA”, POIS ISSO FAZ PARTE DA IDENTIDADE DA EMPRESA.
|
É PERMITIDO O USO DE LINGUAGEM REGIONAL COMO “TU”, “TEU”, “TUA”, POIS ISSO FAZ PARTE DA IDENTIDADE DA EMPRESA.
|
||||||
IMPORTANTE: NÃO AVALIE MENSAGENS DO CLIENTE (TYPE IN), NÃO AVALIE MENSAGENS DO PIPEBOT, NEM AVALIE MENSAGENS TYPE “SYSTEM”. AVALIE SOMENTE AS MENSAGENS TYPE OUT.
|
ESTE CRITÉRIO SE APLICA SOMENTE ÀS MENSAGENS ENVIADAS PELO AGENTE (TYPE OUT). AO AVALIAR ESTE CRITÉRIO, IGNORE COMPLETAMENTE QUALQUER ERRO COMETIDO PELO CLIENTE.
|
||||||
|
|
||||||
06 (PACIÊNCIA E EDUCAÇÃO) - O AGENTE DEVE SER PACIENTE E EDUCADO, UTILIZANDO O USO DE AGRADECIMENTOS, SAUDAÇÕES, PEDIDOS DE DESCULPAS E LINGUAGEM RESPEITOSA.
|
06 (PACIÊNCIA E EDUCAÇÃO) - O AGENTE DEVE SER PACIENTE E EDUCADO, UTILIZANDO O USO DE AGRADECIMENTOS, SAUDAÇÕES, PEDIDOS DE DESCULPAS E LINGUAGEM RESPEITOSA.
|
||||||
COMO POR EXEMPLO "COMO POSSO TE AJUDAR?", "PERFEITO", "POR GENTILEZA", "OBRIGADO PELAS INFORMAÇÕES", "VOU VERIFICAR, AGUARDE UM MOMENTO POR GENTILEZA", "DESCULPE, MAS NÃO TE COMPREENDI", "PODERIA EXPLICAR DE NOVO?".
|
COMO POR EXEMPLO "COMO POSSO TE AJUDAR?", "PERFEITO", "POR GENTILEZA", "OBRIGADO PELAS INFORMAÇÕES", "VOU VERIFICAR, AGUARDE UM MOMENTO POR GENTILEZA", "DESCULPE, MAS NÃO TE COMPREENDI", "PODERIA EXPLICAR DE NOVO?".
|
||||||
@@ -36,12 +31,14 @@ As mensagens do chat estão estruturadas no formato JSON com os campos:
|
|||||||
|
|
||||||
O fluxo de mensagens inicia-se com o cliente interagindo com o BOT, e então a mensagem é transferida para o atendente.
|
O fluxo de mensagens inicia-se com o cliente interagindo com o BOT, e então a mensagem é transferida para o atendente.
|
||||||
|
|
||||||
Em cada categoria, atribua 0 quando o agente não tiver atendido o critétio e 1 caso tenha atendido.
|
Em cada categoria, atribua 0 quando o agente não tiver atendido o critétio e 1 caso tenha atendido. Não atribua nenhum outro valor além destes dois .
|
||||||
|
|
||||||
Devem ser avaliados somente os agentes que o nome de usuario inicie com "FIN -" .
|
Devem ser avaliados somente os agentes que o nome de usuario inicie com "FIN -" .
|
||||||
|
|
||||||
A sua resposta deve ser apenas uma tabela CSV e nada mais, utilizando como separador o caracter ';' com as colunas: CATEGORIA;PONTOS;MOTIVO;EVIDENCIA; on>
|
A sua resposta deve ser apenas uma tabela CSV e nada mais, utilizando como separador o caracter ';' com as colunas: CATEGORIA;PONTOS;MOTIVO;EVIDENCIA; on>
|
||||||
|
|
||||||
|
Portanto crie essas colunas para todo agente que for avaliado.
|
||||||
|
|
||||||
Na saída CSV, na coluna categoria, utilize o nome correspondente ao invés do número
|
Na saída CSV, na coluna categoria, utilize o nome correspondente ao invés do número
|
||||||
|
|
||||||
A seguir estão as mensagens do atendimento, em JSON, avalie e retorne apenas um CSV.
|
A seguir estão as mensagens do atendimento, em JSON, avalie e retorne apenas um CSV.
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ Padronize o arquivo CSV da seguinte forma, deixando apenas as colunas listadas.
|
|||||||
Título: CATEGORIA;PONTOS
|
Título: CATEGORIA;PONTOS
|
||||||
A sua resposta deve ser apenas o CSV com a formatação corrigida, nada mais deve ser incluído na sua resposta, nem mesmo notas sobre a resposta.
|
A sua resposta deve ser apenas o CSV com a formatação corrigida, nada mais deve ser incluído na sua resposta, nem mesmo notas sobre a resposta.
|
||||||
Se não for possível padronizar o arquivo de entrada de acordo com as instruções fornecidas a resposta deve ser o CSV com o campo de pontuação vazio.
|
Se não for possível padronizar o arquivo de entrada de acordo com as instruções fornecidas a resposta deve ser o CSV com o campo de pontuação vazio.
|
||||||
As categorias são: APRESENTAÇÃO, CONFIRMAÇÃO DE E-MAIL, CONFIRMAÇÃO DE TELEFONE, PROTOCOLO, USO DO PORTUGUÊS, PACIÊNCIA E EDUCAÇÃO, DISPONIBILIDADE, CONHECIMENTO TÉCNICO, DIDATISMO
|
As categorias são: APRESENTAÇÃO, CONFIRMAÇÃO DE E-MAIL, CONFIRMAÇÃO DE TELEFONE, PROTOCOLO, USO DO PORTUGUÊS, PACIÊNCIA E EDUCAÇÃO, DISPONIBILIDADE, ESCLARECIMENTO
|
||||||
A coluna pontos deve ter apenas os valores 0, 1 ou vazio, se no arquivo de entrada não houver a avaliação da categoria, a coluna de pontos deve ser vazia.
|
A coluna pontos deve ter apenas os valores 0, 1 ou vazio, se no arquivo de entrada não houver a avaliação da categoria (somente neste caso), a coluna de pontos deve ser vazio.
|
||||||
|
|
||||||
Aqui estão alguns exemplos de formatação de como deve ser a sua resposta:
|
Aqui estão alguns exemplos de formatação de como deve ser a sua resposta:
|
||||||
Exemplo 01:
|
Exemplo 01:
|
||||||
@@ -55,8 +55,7 @@ PROTOCOLO;1
|
|||||||
USO DO PORTUGUÊS;1
|
USO DO PORTUGUÊS;1
|
||||||
PACIÊNCIA E EDUCAÇÃO;1
|
PACIÊNCIA E EDUCAÇÃO;1
|
||||||
DISPONIBILIDADE;1
|
DISPONIBILIDADE;1
|
||||||
CONHECIMENTO TÉCNICO;1
|
ESCLARECIMENTO;1
|
||||||
DIDATISMO;1
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Exemplo 03:
|
Exemplo 03:
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use polars::prelude::*;
|
|||||||
use reqwest;
|
use reqwest;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
use std::path::Path;
|
||||||
use csv;
|
use csv;
|
||||||
|
|
||||||
use std::fs::metadata;
|
use std::fs::metadata;
|
||||||
@@ -22,15 +22,15 @@ struct CsvHeader {
|
|||||||
|
|
||||||
#[derive(Debug, serde::Deserialize)]
|
#[derive(Debug, serde::Deserialize)]
|
||||||
struct CsvEvaluation {
|
struct CsvEvaluation {
|
||||||
APRESENTAÇÃO: u8,
|
APRESENTACAO: u8,
|
||||||
CONFIRMAÇÃO_DE_EMAIL: u8,
|
CONFIRMAÇÃO_DE_EMAIL: u8,
|
||||||
CONFIRMAÇÃO_DE_TELEFONE: u8,
|
CONFIRMAÇÃO_DE_TELEFONE: u8,
|
||||||
PROTOCOLO: u8,
|
PROTOCOLO: u8,
|
||||||
USO_DO_PORTUGUÊS: u8,
|
USO_DO_PORTUGUES: u8,
|
||||||
PACIÊNCIA_E_EDUCAÇÃO: u8,
|
PACIENCIA_E_EDUCACAO: u8,
|
||||||
DISPONIBILIDADE: u8,
|
DISPONIBILIDADE: u8,
|
||||||
CONHECIMENTO_TÉCNICO: u8,
|
// CONHECIMENTO_TÉCNICO: u8,
|
||||||
DIDATISMO: u8,
|
ESCLARECIMENTO: u8,
|
||||||
ID_TALK: String,
|
ID_TALK: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,47 +254,103 @@ fn main() {
|
|||||||
eprintln!("📏 Tamanho: {} bytes", meta.len());
|
eprintln!("📏 Tamanho: {} bytes", meta.len());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opcional: mostrar as primeiras linhas do CSV
|
// Opcional: mostrar as primeiras linhas do CSV
|
||||||
eprintln!("📄 Primeiras 200 caracteres do CSV:\n{}", &ai_response[..200.min(ai_response.len())]);
|
eprintln!("📄 Primeiras 200 caracteres do CSV antes de sanitizar:\n{}", &ai_response[..200.min(ai_response.len())]);
|
||||||
//
|
//
|
||||||
|
|
||||||
let mut reader = csv::ReaderBuilder::new()
|
// --- SALVAR CSV SANITIZADO PARA INSPEÇÃO ---
|
||||||
.has_headers(true)
|
//let sanitized_path = file_path_csv.path().with_extension("sanitized.csv");
|
||||||
.delimiter(b';')
|
// if let Err(e) = std::fs::write(&sanitized_path, &ai_response) {
|
||||||
.from_reader(ai_response.as_bytes());
|
// eprintln!("⚠️ Erro ao salvar CSV sanitizado: {}", e);
|
||||||
|
//} else {
|
||||||
|
// eprintln!("💾 CSV sanitizado salvo: {:?}", sanitized_path);
|
||||||
|
// }
|
||||||
|
// ---------------------------------------------
|
||||||
|
|
||||||
// ---------- LOG 2: tenta desserializar e conta os registros ----------
|
|
||||||
let deserialized = reader.deserialize::<CsvHeader>().collect::<Vec<_>>();
|
|
||||||
eprintln!("🧾 Total de linhas lidas (incluindo cabeçalho?): {}", deserialized.len());
|
|
||||||
|
|
||||||
for (i, result) in deserialized.iter().enumerate() {
|
// --- SALVAR CSV SANITIZADO EM PASTA SEPARADA ---
|
||||||
match result {
|
// Define o diretório base para os arquivos sanitizados
|
||||||
Ok(record) => {
|
let sanitized_base = Path::new("./evaluations_sanitized");
|
||||||
eprintln!("✅ Linha {}: CATEGORIA={}, PONTOS={:?}", i, record.CATEGORIA, record.PONTOS);
|
|
||||||
}
|
// Obtém o caminho relativo do arquivo original em relação a "./evaluations"
|
||||||
Err(e) => {
|
// Exemplo: "./evaluations/2026-02-09/arquivo.csv" -> "2026-02-09/arquivo.csv"
|
||||||
eprintln!("❌ Linha {} ERRO: {}", i, e);
|
if let Ok(relative_path) = file_path_csv.path().strip_prefix("./evaluations") {
|
||||||
}
|
let dest_path = sanitized_base.join(relative_path);
|
||||||
}
|
|
||||||
}
|
// Cria o diretório de destino, se necessário
|
||||||
//
|
if let Some(parent) = dest_path.parent() {
|
||||||
|
std::fs::create_dir_all(parent).expect("Falha ao criar diretório para sanitizados");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Altera a extensão para .sanitized.csv (ou mantém .csv, como preferir)
|
||||||
|
let dest_path = dest_path.with_extension("sanitized.csv");
|
||||||
|
|
||||||
|
// Escreve o arquivo
|
||||||
|
if let Err(e) = std::fs::write(&dest_path, &ai_response) {
|
||||||
|
eprintln!("⚠️ Erro ao salvar CSV sanitizado em {:?}: {}", dest_path, e);
|
||||||
|
} else {
|
||||||
|
eprintln!("💾 CSV sanitizado salvo em: {:?}", dest_path);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
eprintln!("⚠️ Caminho do arquivo não está dentro de ./evaluations: {:?}", file_path_csv.path());
|
||||||
|
}
|
||||||
|
|
||||||
let mut deserialized_iter = reader.deserialize::<CsvHeader>();
|
|
||||||
|
|
||||||
let mut columns = deserialized_iter
|
let mut reader = csv::ReaderBuilder::new()
|
||||||
.filter_ok(|value| value.PONTOS.is_some())
|
.has_headers(true)
|
||||||
.map_ok(|value| {
|
.delimiter(b';')
|
||||||
let col =
|
.from_reader(ai_response.as_bytes());
|
||||||
Column::new(value.CATEGORIA.into(), [value.PONTOS.unwrap() as u32]);
|
|
||||||
col
|
// ---------- LOG 2: tenta desserializar e conta os registros ----------
|
||||||
})
|
let deserialized = reader.deserialize::<CsvHeader>().collect::<Vec<_>>();
|
||||||
.filter_map(|value| {
|
eprintln!("🧾 Total de linhas lidas (incluindo cabeçalho?): {}", deserialized.len());
|
||||||
if value.is_ok() {
|
|
||||||
return Some(value.unwrap());
|
for (i, result) in deserialized.iter().enumerate() {
|
||||||
}
|
match result {
|
||||||
None
|
Ok(record) => {
|
||||||
})
|
eprintln!("✅ Linha {}: CATEGORIA={}, PONTOS={:?}", i, record.CATEGORIA, record.PONTOS);
|
||||||
.collect_vec();
|
}
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("❌ Linha {} ERRO: {}", i, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
|
||||||
|
//let mut deserialized_iter = reader.deserialize::<CsvHeader>();
|
||||||
|
// let mut columns = deserialized_iter
|
||||||
|
// .filter_ok(|value| value.PONTOS.is_some())
|
||||||
|
// .map_ok(|value| {
|
||||||
|
// let col =
|
||||||
|
// Column::new(value.CATEGORIA.into(), [value.PONTOS.unwrap() as u32]);
|
||||||
|
// col
|
||||||
|
// })
|
||||||
|
// .filter_map(|value| {
|
||||||
|
// if value.is_ok() {
|
||||||
|
// return Some(value.unwrap());
|
||||||
|
// }
|
||||||
|
// None
|
||||||
|
//})
|
||||||
|
//.collect_vec();
|
||||||
|
|
||||||
|
let mut columns = deserialized
|
||||||
|
.into_iter() // usa os registros já lidos
|
||||||
|
.filter_ok(|value| {
|
||||||
|
// Se PONTOS for None, considera como 0 e mantém a linha
|
||||||
|
true // sempre mantém
|
||||||
|
})
|
||||||
|
.map_ok(|value| {
|
||||||
|
let pontos = value.PONTOS.unwrap_or(0) as u32;
|
||||||
|
Column::new(value.CATEGORIA.into(), [pontos])
|
||||||
|
})
|
||||||
|
//.filter_ok(|value| value.PONTOS.is_some())
|
||||||
|
//.map_ok(|value| {
|
||||||
|
//let pontos = value.PONTOS.unwrap() as u32;
|
||||||
|
//Column::new(value.CATEGORIA.into(), [pontos])
|
||||||
|
// })
|
||||||
|
.filter_map(|value| value.ok())
|
||||||
|
.collect_vec();
|
||||||
|
|
||||||
|
|
||||||
if columns.len() != 8 {
|
if columns.len() != 8 {
|
||||||
return None;
|
return None;
|
||||||
|
|||||||
Reference in New Issue
Block a user