[!NOTE] Tradução automática Este artigo foi traduzido automaticamente a partir da versão original em inglês.
Avaliação de RAG: Métricas para Cada Etapa de um Sistema RAG em Produção
Parte 1 da série de produção RAG
Um sistema RAG com filtros danificados pode permanecer em funcionamento durante meses sem disparar nenhum alerta operacional. Ele continua a fornecer respostas e a cumprir o seu objetivo de latência, mas essas respostas baseiam‑se em evidências incompletas. A análise de recall@k em relação ao conjunto de referência original revela essa perda; os painéis de latência e disponibilidade, no entanto, não a detetam.
A avaliação só consegue detetar uma falha quando cada fase pipeline dispõe da sua própria métrica. Este artigo estabelece uma correspondência entre os modos de falha mais comuns e essas métricas, abrangendo desde a análise de documentos até à monitorização em produção.
[!TIP] Quer pular para a frente e executar o código?
O código executável
slavadubrov/rag-evals-demoo repositório aplica as métricas ao SciFact.make evalexecuta o conjunto de testes, emake benchmarkCompara as configurações de chunking, embedding, e LLM. Os notebooks de 00 a 09 isolam cada uma dessas métricas. A demonstração utiliza o Qdrant integrado, pelo que não requer a utilização do Docker.
TL;DR
- A avaliação define o comportamento do sistema. Uma fase que carece de métricas corresponde a uma fase que falha de forma silenciosa.
- Uma pilha de avaliação eficaz abrange a ingestão de dados, a recuperação de informações, a fundamentação da geração de conteúdo, a conformidade com ontologias e os sinais emitidos pelo sistema. RAGAS, TruLens, DeepEval, Arize Phoenix, e o TREC 2024 RAG Categorização Fornecemos as ferramentas necessárias. Eles não escolhem as métricas por si mesmos.
- No caso de sistemas baseados em metadados e ontologias RAG, um rótulo incorreto ou um predicado rígido e frágil pode fazer com que a taxa de recuperação caia para zero. O método padrão Recall@k deteta essa perda ao manter o conjunto de referência original. Uma métrica de filtragem de falsas exclusões identifica a causa do problema, embora a fidelidade possa ainda parecer adequada, uma vez que o modelo afirma fielmente “Não sei”.
As secções seguem a ordem definida pelo pipeline. Comece com a tabela de decisão e, em seguida, utilize as secções seguintes como referência para cada fase.
Tabela de decisão de avaliação RAG
Utilize esta tabela como ponto de partida antes de selecionar um framework. A métrica adequada depende do modo de falha que se pretende detetar, e não do nome da ferramenta.
| Pergunta | Família de métricas | Utilize isto quando | Cuidado com |
|---|---|---|---|
| A análise de sintaxe preservou o conteúdo original? | Completude da extração, cobertura de tabelas/figuras | PDFs, diapositivos, imagens escaneadas e páginas HTML são inseridos no corpus. | Um texto com aparência limpa ainda pode apresentar falhas em legendas, notas de rodapé ou na estrutura das tabelas. |
| A fase de recuperação encontrou as evidências corretas? | Recall@k, nDCG@k, MRR, precisão/recall de contexto | Pode rotular os trechos ou documentos relevantes. | Um filtro rigoroso de metadados pode excluir o documento correto antes mesmo do início da classificação. |
| Será que o reranking melhorou a lista de candidatos? | Reranker aumento, Precisão@1, delta nDCG | Os cross-encoders ou classificadores LLM são utilizados após a fase de recuperação. | Meça a latência e o custo com o ganho de qualidade |
| A resposta utilizou as evidências? | Fidelidade, fundamentação e suporte à citação | A resposta cita documentos ou retira factos do contexto. | A fidelidade não consegue diagnosticar uma análise de dados incorreta ou uma recuperação inadequada. |
| O sistema é estável em produção? | Deriva, regeneração, plano de fallback, latência p95, custo por resposta | Alterações no tráfego após o lançamento | A telemetria de produção requer revisão humana amostrada para manter a calibração adequada |
Para uma comparação mais concisa de ferramentas, consulte Os melhores ferramentas e métricas de avaliação RAG em 2026.
Parte 1: Defina o sucesso antes da arquitetura
Elabore o conjunto de avaliação antes do diagrama de arquitetura. Isso permite definir um objetivo mensurável para cada escolha de componente posterior.
Não é possível escolher entre BM25 e recuperação densa, chunking recursivo e semântico, ou Cohere Rerank e BGE até se saber o que se está a otimizar. “Respostas melhores” não é uma métrica adequada. Um contrato ilustrativo seria “fidelidade ≥ 0,85 num conjunto de referência com 200 consultas que abranja as nossas três principais intenções, com latência p95 < 1,5 s e taxa de exclusão falsa por filtro < 2%”. Os valores numéricos são apenas placeholders; o importante é que a qualidade, a cobertura, a latência e o filtragem tenham critérios explícitos.
Defina o harness antes de escrever o código de recuperação. O primeiro harness estará incorreto, e você terá de o rever. Revisar uma métrica é muito mais barato do que reestruturar um sistema que já foi lançado.
Três camadas pipeline e dois modos de execução
O RAG moderno é um pipeline, pelo que a avaliação tem de ser realizada de forma pipeline. Nenhum valor numérico isolado consegue detetar todos os modos de falha.
A avaliação em produção possui três camadas pipeline. A avaliação de ingestão verifica se o corpus e o índice preservam as características originais dos dados. A avaliação em tempo de consulta analisa se a reescrita, filtragem, recuperação, reranking e montagem do contexto permitiram identificar as evidências corretas. Já a avaliação da resposta e da operação em produção avalia se a resposta utilizou efetivamente essas evidências e se a sua qualidade se mantém sob carga real de tráfego. Ao combinar essas camadas num único valor de pontuação, erros de normalização podem passar despercebidos dentro de um resultado aceitável.
Essas camadas descrevem onde ocorre uma falha. Os modos offline e online indicam quando e com base em quais dados a verificação é realizada. A avaliação offline utiliza um dataset fixo e com valores de referência conhecidos; sendo reprodutível, é adequada para a seleção de componentes, comparações A/B e verificações em pipelines de integração contínua. Já a avaliação online analisa tráfego em tempo real, capturando fatores como regeneração, tempo de permanência, feedback explícito e deriva nas consultas reais. Esse método gera mais ruído nos resultados e é mais difícil de instrumentar.
Cada camada pipeline pode fornecer verificações tanto offline como online. Um conjunto de dados de ingestão fixo permite detetar regressões no parser antes do lançamento, enquanto monitores de atualização em tempo real e de falhas de análise cobrem as alterações em curso. Um conjunto de consultas fixo avalia o desempenho de recuperação de informações antes do lançamento, ao passo que rastreios em tempo real amostrados revelam desvios na produção. As verificações exclusivamente offline não permitem detetar mudanças em tempo real; por sua vez, as verificações exclusivamente online dificultam a reprodução de regressões.
A nível de componente vs. de ponta a ponta
Existem dois erros comuns. A avaliação apenas de ponta a ponta indica que o sistema está avariado, mas não onde exatamente. Por outro lado, a avaliação apenas de componentes pode mostrar que todas as partes funcionam corretamente, mesmo quando o sistema como um todo continua a falhar. A solução passa por utilizar algumas métricas principais de ponta a ponta para tomar decisões de aceitação ou rejeição, juntamente com métricas de componente para fins de diagnóstico. As métricas de recuperação detetam regressões no módulo responsável pela busca de informação, enquanto as métricas de geração identificam regressões no módulo responsável pela criação de respostas. A correção das respostas em nível de ponta a ponta permite detetar falhas na integração entre os diferentes componentes.
A referência frameworks (tour opinativo)
| Framework | Melhor em | Onde ocorrem os problemas |
|---|---|---|
| RAGAS | Métricas RAG sem referência (fidelidade, relevância da resposta, precisão/recall do contexto); o vocabulário de facto | LLM – avaliar o custo; componentes de pontuação opacos durante a depuração; predefinições centradas no inglês |
| ARES | O classificador treinado avalia os resultados com base em pipeline; existem menos anotações em comparação com abordagens do estilo RAGAS; alta precisão para sistemas semelhantes | Configuração mais pesada; é necessário efetivamente treinar modelos. |
| TruLens | Funções de feedback compostas com elevada capacidade de explicabilidade; rastreios OpenTelemetry; adequadas para ambiente de produção | Menos baterias incluídas nas métricas específicas de RAG em comparação com as do RAGAS. |
| DeepEval | Testes unitários no estilo Pytest para os resultados gerados por LLM; G-Eval, métricas personalizadas, integrados nativamente em pipelines CI/CD | Uso intensivo de LLM-judge = aumentos significativos nos custos |
| Arize Phoenix | Rastreio detalhado e visualização de embedding; deteta visualmente a deriva de embedding; nativo para OTEL | Você deve trazer as suas próprias definições de métricas. |
| Track TREC 2024 RAG | Publicação de benchmark para avaliação de nuggets (AutoNuggetizer), suporte à avaliação e medição da fluência no MS MARCO Segment v2.1 | Não é uma ferramenta runtime, mas sim um benchmark para calibração. |
A minha pilha padrão inclui o RAGAS para o vocabulário de métricas, o DeepEval para os gateways de CI, o Phoenix para rastreio em produção, além de código personalizado para métricas específicas da ontologia. Qualquer solução com que comece acabará por se revelar insuficiente. Escolha o framework que facilite a criação de métricas personalizadas.
Para benchmarks, utilize BEIR (Thakur et al., NeurIPS 2021) para a generalização da recuperação zero-shot, MTEB para uma qualidade geral embedding, MIRACL para recuperação multilíngue, e o TREC 2024 RAG Categorização para avaliação end-to-end RAG.
Parte 2: Mapear os pontos de avaliação para o pipeline
Um sistema RAG em produção é muito mais complexo do que apenas “incorporar documentos, recuperar trechos e chamar um LLM”. Cada etapa, desde a aquisição do documento até a entrega da resposta, pode falhar.
Cada fase no diagrama possui, pelo menos, uma métrica. Uma fase que não tenha nenhuma métrica pode falhar sem que ninguém perceba.
A via de processamento em três etapas corresponde aos locais onde as evidências podem ser perdidas. A via de ingestão abrange a análise estrutural, a limpeza dos dados, o particionamento, embedding, e a indexação. A via de consulta abrange a reescrita das consultas, a filtragem, a recuperação de resultados, reranking, e a montagem do contexto. A via de geração de respostas e produção final abrange a fidelidade às informações, a verificação de citações, os sinais fornecidos pelos utilizadores, a deriva nos parâmetros, a latência e os custos operacionais.
Os erros vão se acumulando ao longo da cadeia de processamento. Uma análise de dados deficiente limita a divisão dos dados em blocos. Uma divisão inadequada dos blocos restringe a recuperação das informações necessárias. Uma recuperação insuficiente limita o reranking. Já um reranking deficiente limita a geração do resultado final. A fidelidade ao conteúdo original avalia apenas a resposta obtida no final, e nunca as causas que ocorreram anteriormente na cadeia de processamento.
Parte 3: Avaliação da ingestão
Muitas falhas em produção relacionadas com RAG começam na fase de ingestão de dados. O sistema funciona corretamente com documentos de teste limpos, mas falha ao lidar com PDFs reais, imagens escaneadas, tabelas e páginas de corpus desorganizadas.
Aquisição e análise de documentos
O que medir:
-
Completude da extração de texto:
extracted_chars / expected_charsem um exemplo rotulado, calculado por classe de documento. Não existe um pacote canónico — escreva um pequeno harness que compare a saída do analisador com uma referência limpa manualmente. Fique atento à ausência de notas de rodapé, cabeçalhos e legendas. -
OCR precisão: CER (Character Error Rate) e WER (Word Error Rate), as métricas padrão de fala/OCR:
onde , , representam substituições, deleções e inserções a nível de caractere, e é o número de caracteres de referência (subscrito para a versão por palavra). Não se deve aplicar um único limite CER a todo o corpus. Calibre-o em função da classe do documento e da perda nas respostas finais; textos impressos, escrita à mão e materiais multilíngues apresentam perfis de erro diferentes. Calcule com
jiwer(jiwer.cer(refs, hyps),jiwer.wer(refs, hyps)) ou HuggingFaceevaluate. Para os corpos de avaliação, FunSD e SROIE são públicos benchmarks.from jiwer import cer, wer refs = ["Mars has two moons, Phobos and Deimos."] hyps = ["Mars has two m00ns, Phobos and Deirnos."] print(f"CER = {cer(refs, hyps):.3f}") # CER = 0.105 print(f"WER = {wer(refs, hyps):.3f}") # WER = 0.286 -
Fidelidade na extração de tabelas: A TEDS (Similaridade baseada em Distância de Edição em Árvore) mede o quão próximo está a árvore HTML prevista de uma tabela de referência, normalizada em função do tamanho da árvore maior. De Zhong et al., 2020 (PubTabNet):
O TEDS utiliza tanto a estrutura (linhas, colunas, extensões) como o conteúdo das células; o TEDS-S remove o conteúdo e avalia apenas a estrutura. Implementação de referência: PubTabNet’s
teds.py(utiliza)aptedem nível interno). Para conjuntos de dados de avaliação, consulte o PubTabNet. FinTabNet, e o SciTSR. Os analisadores ingênuos costumam falhar ao lidar com tabelas; benchmark antes de se confiar neles. -
Preservação de layout/estrutura: ordem das secções, integridade das listas, ordem de leitura em PDFs com várias colunas. Utilize DocLayNet para um benchmark rotulado. Uma comparação pronta no mercado pode abranger um analisador de elementos como
unstructured, uma biblioteca PDF comopymupdf, e um analisador VLM comodocling.
Compare famílias de analisadores distintas, como, por exemplo, uma linha de base do Tesseract, um modelo OCR baseado em VLM, e a solução proposta pelo seu fornecedor. Utilize uma amostra estratificada de categorias reais de documentos com uma resolução DPI fixa, incluindo digitalizações nítidas, fotografias, tabelas, texto multilíngue, equações matemáticas e escrita à mão. Relate o CER ou o WER para cada categoria, bem como o TEDS para as páginas com tabelas.
Limpeza e normalização
-
Precisão na remoção de texto genérico: precisão/recolha em relação aos trechos de texto genérico rotulados por humanos. Uma remoção excessivamente agressiva destrói conteúdo relevante; uma remoção negligente contamina embeddings. Ferramentas para comparação:
trafilatura,jusText,Resiliparse. Barbaresi (2021) benchmarks estes confrontos diretos. -
Normalização Unicode: percentagem de documentos que produzem resultados idênticos em NFC e NFKC (calculada com a stdlib)
unicodedata.normalize) -
Precisão de deteção de idioma: F1 num conjunto de amostras multilíngues rotuladas. É fundamental para índices multilíngues. Utilize
fasttext-langdetect(do Facebook)lid.176),lingua-py, oucld3. FLORES-200 Fornece texto de avaliação em 200 idiomas diferentes, mas a combinação de idiomas utilizada na produção deve determinar o conjunto de testes a ser aplicado. -
Eficácia da deduplicação (MinHash / LSH): precisão/recall do seu detetor de quase-duplicatas face a um conjunto rotulado manualmente. A ideia subjacente: estimar a semelhança de Jaccard J(A, B) = \frac|A ∩ B|}{|A ∪ B| entre conjuntos de “shingles” de documento através de hashes de permutação aleatória (Broder, 1997) e agrupar quase-duplicatas através de bandas LSH (Indyk e Motwani, 1998). Efetue uma análise ao número de hashes e ao limiar de Jaccard no seu corpus. Registe a taxa de fusão falsa (que corrompe as respostas) separadamente da taxa de fusão perdida (que desperdiça espaço no índice).
datasketchfornece a implementação utilizada abaixo; os seus parâmetros são meramente ilustrativos:from datasketch import MinHash, MinHashLSH def shingles(text: str, k: int = 5) -> set[str]: text = text.lower() return {text[i:i + k] for i in range(len(text) - k + 1)} def to_minhash(text: str, num_perm: int = 128) -> MinHash: m = MinHash(num_perm=num_perm) for s in shingles(text): m.update(s.encode("utf-8")) return m docs = { "d1": "Mars has two moons, Phobos and Deimos.", "d2": "Mars has two moons, Phobos and Deimos!", # near-dup "d3": "Curiosity rover landed on Mars in 2012.", } lsh = MinHashLSH(threshold=0.8, num_perm=128) for did, text in docs.items(): lsh.insert(did, to_minhash(text)) print(sorted(lsh.query(to_minhash(docs["d1"])))) # ['d1', 'd2'] -
Limpeza de PII: precisão e recall, calculados separadamente por tipo de entidade (e-mails, NIFs, nomes, endereços). Erros de recall criam riscos de conformidade; erros de precisão afetam a qualidade das respostas. Defina o ponto de operação em conjunto com a equipa jurídica. Ferramentas candidatas incluem Microsoft Presidio,
scrubadub, ou um modelo NER afinado com base num conjunto rotulado.
O processamento em blocos controla a qualidade da recuperação de informações
O chunking pode gerar uma lacuna de recuperação em vários pontos, mesmo quando o modelo embedding permanece inalterado. Em O fornecedor de 2024 da NVIDIA benchmark, O particionamento a nível de página gerou a maior precisão e a menor variância para documentos paginados. Trate esse resultado como evidência específica para o corpus testado, e não como uma solução válida para todos os casos.
O agrupamento semântico organiza frases adjacentes com base na semelhança embedding e realiza a separação em pontos de transição onde a similaridade é baixa. O LangChain’s SemanticChunker e o LlamaIndex’s SemanticSplitterNodeParser Implemente esta estratégia. Ela consegue melhorar o recall em janelas fixas quando as fronteiras temáticas são relevantes.
A divisão recursiva de caracteres tenta primeiro quebras de parágrafo, depois quebras de frase e, por fim, quebras de palavra, até que cada fragmento atinja o tamanho alvo. O LangChain’s RecursiveCharacterTextSplitter Implementa a sequência. Escolha os valores de janela e sobreposição adequados à estrutura do seu documento e, em seguida, deixe o conjunto dourado determinar os valores finais.
Métricas a monitorizar:
- Coerência de trechos: , onde são frases embeddings. Os trechos saudáveis apresentam semelhança interna e diferenças nas fronteiras. Calcule com
sentence-transformersmaisscikit-learn’scosine_similarity. - Qualidade das fronteiras: avaliação feita por humanos com a pergunta “este é um corte sensato?”, aplicada a uma amostra, além de uma verificação estrutural para garantir que os trechos não dividam tabelas, listas ou seções numeradas.
- Tamanho ótimo dos trechos: teste tamanhos de tokens diferentes (128, 256, 512, 1024) e trace o gráfico Recall@k em função do tamanho no conjunto de referência. Escolha o ponto de inflexão adequado; não siga simplesmente o que é indicado nos tutoriais.
- Eficácia da sobreposição: teste várias frações de sobreposição e meça o Recall@k correspondente. Pare de aumentar a sobreposição quando a curva de recall local se estabilizar ou quando o custo de duplicação superar os benefícios.
- Fidelidade na atribuição dos trechos: porcentagem de trechos que mantêm um indicador de origem verificável (número de página, âncora de seção, ID do documento). A auditabilidade exige isso.
- Divisão em chunks tardia vs. precoce: agrupamento tardio de blocos (Günther et al., 2024) incorpora o documento completo para posterior segmentação, preservando assim o contexto global (implementação de referência em)
jina-embeddings-v3). Recuperação Contextual (Anthropic, 2024) acrescenta um contexto gerado por LLM no início de cada bloco de dados. Ambas as abordagens aumentam o custo operacional. É necessário realizar um Benchmark no seu conjunto de dados antes de adotar qualquer uma delas.
A minha opinião: chunking estrutural (divisão com base em títulos, tabelas e secções — implementado por analisadores como unstructured.io ou percorrendo a AST já gerada pelo seu analisador) é subutilizado. Se os seus documentos possuem estrutura, utilize-a antes de adicionar heurísticas de similaridade. A divisão recursiva de caracteres constitui o ponto de partida; o agrupamento semântico só justifica o esforço adicional em textos não estruturados.
Extração e enriquecimento de metadados
- NER precisão/recall/F1: por tipo de entidade, num subconjunto rotulado. No estilo padrão CoNLL/MUC. Calcula‑se com
seqeval(from seqeval.metrics import f1_score) para a versão sensível às tags BIO/IOB, ou o scikit-learn para comparações de conjuntos de intervalos. O CoNLL-2003 e o OntoNotes 5.0 são os corpora de referência canónicos. - F1 de extração de relações: ainda mais importante para sistemas baseados em ontologias. Rotule manualmente um conjunto estratificado por tipo de relação e classe de documento. O TACRED e o DocRED são ferramentas públicas benchmarks; entre as implementações candidatas encontram-se
opennreespaCyrelação pipelines. - Precisão de extração de título/título principal: correspondência exata somada à similaridade Levenshtein normalizada () em comparação com os valores de verdade real —
python-LevenshteinourapidfuzzFornecer ambos num único chamada. - Preservação hierárquica de metadados: percentagem de blocos que mantêm corretamente a sua secção pai, documento pai e caminho de ancestralidade. É esta métrica que determina se o seu RAG consegue responder a perguntas do tipo “o que diz o filho da política X?”.
Geração Embedding
- Seleção de modelo benchmarks: MTEB para capacidade geral (o nDCG@10 é o indicador principal; o pacote Python MTEB permite reproduzir o ranking localmente), BEIR para generalização zero-shot, MIRACL No que diz respeito às aplicações multilíngues, os melhores modelos de recuperação de informação agrupam‑se numa faixa estreita de nDCG@10, mas as pontuações de MTEB em inglês prevêem de forma insuficiente o desempenho em línguas com recursos mais limitados.
- Avaliação específica de domínio: não trate uma classificação geral de benchmark como um resultado aplicável ao domínio. Defina um conjunto de referência para o domínio com base na sua matriz de cobertura e na incerteza que a sua decisão consegue tolerar. Em seguida, reclassifique os modelos candidatos com base nesse conjunto.
ranxoupytrec_eval. Um conjunto de domínios pode inverter a ordem do ranking, pelo que é necessário publicar o slice dataset, o protocolo de recuperação e o intervalo de confiança juntamente com o resultado. - Embedding deteção de deriva: monitorizar a deriva distribucional com base no KL ou na estrutura do modelo entre uma janela de referência fixa e um conjunto de produção em tempo real embeddings; além disso, avaliar a estabilidade com base nos vizinhos mais próximos para um conjunto fixo de amostras de teste.
evidentlyealibi-detectImplementar detetores baseados em modelos e estatísticos. Os da Evidently estudo comparativo Trata‑se de uma avaliação de fornecedor; compare os métodos face a mudanças conhecidas nos seus próprios embeddings. - Multi-vector vs. single-vector: a interação tardia preserva as representações a nível de token em vez de reduzir cada documento a um único vetor; ColBERT é o design canónico, com implementações de referência em RAGatouille e PyLate. Essa representação mais rica aumenta o custo de indexação e recuperação. Antes de a adotar, compare a qualidade, o armazenamento e a latência em relação a uma linha de base de vetor único no mesmo conjunto de domínios.
Construção do índice
- Recall@k sob aproximação: compare o índice de vizinho mais próximo aproximado (ANN) com uma linha de base exata por força bruta no mesmo k — em FAISS, Isso é
IndexHNSWFlat(ou)IndexIVFFlat) vs.IndexFlatIP/IndexFlatL2. Defina a perda de recall aceitável com base no seu orçamento de qualidade em camadas posteriores. Oann-benchmarksO projeto monitoriza as curvas Pareto de recall e QPS em diferentes bibliotecas. - HNSW de ajuste: HNSW (Hierarchical Navigable Small World — um grafo de proximidade em camadas; ver Malkov e Yashunin, 2018, implementado em
hnswlib, FAISS’sIndexHNSWFlat, e a maioria dos bancos de dados vetoriais) expõe três parâmetros de ajuste:M(efusão do grafo)efConstruction(largura candidata em tempo de compilação),efSearch(largura de candidatos em tempo de consulta). Comece com os valores padrão documentados pela biblioteca e, em seguida, varie os parâmetros até que a curva de recall–latência atenda aos requisitos do seu conjunto de avaliação. - Ajuste do IVF: IVF (Índice de Ficheiros Invertido — particionar vetores com k-means em
nlistcélulas e, em seguida, durante a consulta, efetuar a varredura dasnprobecélulas mais próximas; consulte o FAISS’sIndexIVFFlateIndexIVFPQ). Varreduranlistenprobeem contraste com a taxa de recuperação e a latência da busca exata. Benchmark as consultas filtradas são tratadas separadamente, uma vez que as famílias de índices e os bancos de dados vetoriais implementam a traversão de filtros de maneira diferente. - Atraso na atualização da frescura: período entre o registo de um documento e a sua disponibilidade para recuperação. Devem ser monitorizados os valores p50 e p99. Em sistemas sujeitos a requisitos regulatórios, é igualmente necessário registar a percentagem de consultas atendidas a partir de índices desatualizados.
Parte 4: Avaliação em tempo de consulta
A faixa de tempo de consulta contém as métricas que permitem diagnosticar o percurso de recuperação de dados. O Recall@k, por si só, não consegue indicar se a reescrita, a filtragem, reranking, ou a montagem de contexto foram as causas do falhanço.
Compreensão e reescrita de consultas
- Qualidade de expansão da consulta: Aumento no Recall@k no conjunto de referência, entre consultas expandidas e as originais. Defina previamente o ganho útil mínimo e a sua incerteza antes dos testes. Se a expansão não superar esse limiar local, ela não justifica a sua latência e custo. Linhas de base clássicas de PRF (pseudo-relevance feedback) como RM3 e Bo1 Continuam a ser verificações de sanidade úteis; a expansão baseada em LLM precisa de superá-las.
- Avaliação HyDE: HyDE (Gao et al., 2022) gera uma resposta hipotética utilizando o LLM, incorpora-a no resultado e realiza uma busca com base nela. Tal abordagem introduz latência na geração e uma nova superfície de falha potencial. Deve-se medir o Recall@10 separadamente para os conjuntos de dados do domínio, fora do domínio e com baixa confiança, para depois decidir se essa resposta deve ser incluída no caminho padrão, como solução alternativa ou descartada.
- Geração de múltiplas consultas: união do Recall@k de N reescritas em comparação com uma única consulta. Varie o valor de N e escolha um ponto na fronteira recall–latência. Implementações: da LangChain
MultiQueryRetriever, LlamaIndex’sQueryFusionRetriever. - Precisão de classificação de intenção: precisão/recall/F1 padrão por intenção (calcular com
sklearn.metrics.classification_report), mas a métrica relevante é a correção de roteamento — o pipeline descendente correto é acionado? - Roteamento adaptativo: Adaptativo-RAG (Jeong et al., NAACL 2024) defende que nem toda consulta merece a mesma estratégia de recuperação de informação. A precisão do roteador de rastreamento deve ser avaliada como um problema de classificação, com base num conjunto rotulado que indica se há “necessidade nenhuma de recuperação / abordagem de um único tentativa / processo iterativo”.
Métricas de recuperação
Estas são as métricas de referência. Se não as monitorizar, não será possível determinar se a recuperação de informação está a melhorar.
| Métrica | O que é medido | Quando utilizar |
|---|---|---|
| Recall@k | fração de documentos relevantes de uma consulta retornados nos k principais | Utilizar quando a ausência de qualquer componente do conjunto relevante tem impacto significativo |
| Precisão@k | percentagem dos top-k que são relevantes | útil quando a janela de contexto é o gargalo |
| média de 1/rank do primeiro documento relevante | quando os utilizadores analisam apenas os resultados de topo-1 ou topo-3 | |
| nDCG@k | ganho descontado em função da posição, ponderado por graus de relevância | métrica padrão de recuperação para relevância graduada |
| MAP | média de precisão média ao longo das consultas | quando se dá importância a toda a lista classificada |
| Taxa de Acerto@k | se pelo menos um documento relevante está presente nos k principais | Calcular a média do resultado binário entre as consultas, como métrica rápida de verificação. |
| Cobertura | percentagem de documentos “dourados” já recuperados em todas as consultas | deteta lacunas sistemáticas no índice |
As fórmulas, para referência (relevância binária com o conjunto relevante para a consulta , e se o -ésimo documento recuperado estiver em ):
\text{Recall@k} = \frac|R_q ∩ {d_1, …, d_k}|}{|R_q|}, \quad \text{Precisão@k} = \frac|R_q ∩ {d_1, …, d_k}|{k}Para a relevância graduada, ; o nDCG binário é o caso específico utilizado no código abaixo. O MAP corresponde à média, calculada sobre todas as consultas, de . Ver Manning, Raghavan, Schütze, Introdução à Recuperação de Informação, capítulo 8 para as derivações.
Para código de produção, utilize ranx, pytrec_eval, ou ir_measures — Eles implementam toda a família de métricas TREC e lidam corretamente com a relevância graduada. Defina objetivos de lançamento com base num conjunto de referência realista, na qualidade das respostas finais e no custo associado a erros. Não herde limiares de tutoriais.
O teste harness para estes casos é breve. Pode executá‑lo a partir de um notebook mesmo antes de escolher uma base de dados vetorial.
from math import log2
from statistics import mean
# synthetic gold set: query_id -> set of relevant doc ids
gold = {
"q1": {"d3"},
"q2": {"d7", "d2"},
"q3": {"d11"},
"q4": {"d5"},
}
# ranked retrieval results: query_id -> ranked list of doc ids (top-10)
runs = {
"q1": ["d8", "d3", "d1", "d4", "d2", "d9", "d6", "d10", "d12", "d13"],
"q2": ["d2", "d6", "d4", "d7", "d1", "d3", "d8", "d11", "d5", "d9"],
"q3": ["d11", "d2", "d3", "d4", "d1", "d6", "d7", "d8", "d10", "d12"],
"q4": ["d1", "d2", "d3", "d6", "d8", "d9", "d10", "d12", "d13", "d14"],
}
def recall_at_k(ranked, gold_set, k):
if not gold_set:
return 0.0
hit = sum(1 for d in ranked[:k] if d in gold_set)
return hit / len(gold_set)
def reciprocal_rank(ranked, gold_set):
# MRR contribution per query: 1/rank of the first relevant doc.
for rank, d in enumerate(ranked, start=1):
if d in gold_set:
return 1.0 / rank
return 0.0
def ndcg_at_k(ranked, gold_set, k):
# binary relevance: rel ∈ {0, 1}
gains = [1.0 if d in gold_set else 0.0 for d in ranked[:k]]
dcg = sum(g / log2(i + 2) for i, g in enumerate(gains))
# ideal DCG: all gold docs ranked first, capped by k
n_gold_in_topk = min(k, len(gold_set))
idcg = sum(1.0 / log2(i + 2) for i in range(n_gold_in_topk))
return dcg / idcg if idcg else 0.0
K = 5
print(f"Recall@{K}: {mean(recall_at_k(runs[q], gold[q], K) for q in gold):.3f}")
print(f"MRR: {mean(reciprocal_rank(runs[q], gold[q]) for q in gold):.3f}")
print(f"nDCG@{K}: {mean(ndcg_at_k(runs[q], gold[q], K) for q in gold):.3f}")
# Recall@5: 0.750
# MRR: 0.625
# nDCG@5: 0.627
Esse é o seu ponto de controlo CI para recuperação de dados. Ligue-o a um subconjunto rápido baseado em cobertura em cada PR e execute o conjunto completo “golden” no ponto de controlo de lançamento, que é mais lento. Bloqueie a fusão quando uma métrica pré-registrada ultrapassar o seu orçamento de regressão.
O repositório complementar fixa os valores exatos acima.Recall@5 = 0.750, MRR = 0.625, nDCG@5 = 0.627) como um teste de unidade em tests/test_retrieval_metrics.py; Notebook 01 realiza análises de Recall@k / MRR / nDCG num índice real do SciFact, e o modelo harness adaptado para produção encontra-se em evaluation/retrieval.py.
Fusão híbrida de recuperação e de rank recíproco
BM25 é um pontuador léxico esparsa que combina correspondência de termos exatos, ponderação de termos e normalização de comprimento. Está disponível em rank_bm25, Elasticsearch, OpenSearch e a maioria dos motores de busca.
Fusão de Rank Recíproco (Cormack, Clarke e Buettcher, SIGIR 2009) combina o BM25 com classificações densas por posição. A versão original k=60 A definição de parâmetros constitui uma base útil. O RRF é independente da pontuação, o que evita a normalização entre faixas necessária na interpolação linear. Com um conjunto rotulado suficientemente grande para estimar um valor de delta estável, teste também uma combinação convexa e ajuste o valor de α.
A recuperação híbrida combinada com um codificador cruzado reranker melhora frequentemente corpora técnicos, de logs e de código. O ganho pode ser reduzido em corpora fortemente semânticos. É necessário comparar os resultados com as abordagens que utilizam apenas dados densos ou apenas dados esparsos, uma vez que uma configuração deficiente de fusão pode resultar em desempenho inferior face a qualquer um desses tipos de entrada.
A implementação cabe em poucas linhas.
from collections import defaultdict
# two retrieval lanes: dense embeddings and BM25.
dense = ["d3", "d7", "d1", "d4", "d2", "d9", "d10"]
sparse = ["d2", "d3", "d8", "d1", "d11", "d4", "d6"]
def rrf(rankings: list[list[str]], k: int = 60) -> list[tuple[str, float]]:
"""Reciprocal Rank Fusion (Cormack et al., SIGIR 2009).
score(d) = sum over rankings of 1 / (k + rank(d))
Score-agnostic: only rank position matters. k=60 is the canonical default.
"""
scores: dict[str, float] = defaultdict(float)
for ranking in rankings:
for rank, doc in enumerate(ranking, start=1):
scores[doc] += 1.0 / (k + rank)
return sorted(scores.items(), key=lambda kv: kv[1], reverse=True)
fused = rrf([dense, sparse], k=60)
for doc, score in fused[:5]:
print(f"{doc} score={score:.5f}")
# d3 score=0.03252 <- rank 1 dense, rank 2 sparse
# d2 score=0.03178 <- rank 5 dense, rank 1 sparse
# d1 score=0.03150
Observe o que o RRF não faz: ele nunca analisa as pontuações de similaridade brutas. Um recuperador denso que retorna um valor de cosseno de 0,98 e um algoritmo BM25 que devolve uma pontuação de 17,4 não são diretamente comparáveis. Se os normalizar com valores z ou através de escala min-máx, pode acabar por favorecer o método com a maior variância nesse lote.
O RRF utiliza apenas a classificação. Se um recuperador colocar um documento na posição 2, esse voto tem valor 1 / (60 + 2)independentemente da pontuação bruta que o gerou.
Hybrido + RRF em SciFact: Notebook 02 compara o método dense com o BM25 e o RRF, utilizando deltas por consulta. O fusor adaptado para produção encontra-se em retrieval/hybrid_rrf.py; tests/test_rrf.py fixa o canónico d3 / d2 / d1 realização de pedidos em k=60.
Reranking
- ΔnDCG / ΔMRR: a única métrica fiável reranker — representa o ganho em relação à ordenação padrão, no conjunto de referência, na profundidade efetivamente utilizada pela aplicação. Calcula‑se executando as métricas de recuperação com e sem o reranker em conjuntos de candidatos idênticos.
- Cross-encoder vs. bi-encoder: um bi-encoder incorpora a consulta e o documento de forma independente (um vetor para cada um) e calcula a pontuação através do produto escalar; um cross-encoder concatena consulta+documento e executa uma única passagem forward que considera ambos em conjunto. Os cross-encoders sacrificam uma passagem forward por candidato em troca de uma interação consulta–documento mais rica. Implementação de referência:
sentence-transformersCrossEncoder. Benchmark relevância e latência no hardware específico, tamanho do lote e profundidade dos candidatos; não transfira os resultados de um modelo ou serviço gerido para outro ambiente. - Por par vs. por lista: a avaliação por par calcula independentemente cada par (pergunta, documento); a avaliação por lista calcula conjuntamente toda a lista de candidatos, permitindo que o modelo compare os mesmos. Avalie ambos nos mesmos conjuntos de candidatos. Calibre qualquer limiar de pontuação para cada modelo e corpus, em vez de considerar um exemplo publicado como universalmente aplicável.
from sentence_transformers import CrossEncoder
reranker = CrossEncoder("BAAI/bge-reranker-v2-m3")
query = "How do I rotate database credentials in production?"
candidates = [
"Production database credentials are rotated via Vault every 30 days.",
"The new logo was unveiled at the all-hands meeting.",
"To rotate prod DB creds, run the `rotate-secrets` GitHub Action.",
]
scores = reranker.predict([(query, c) for c in candidates])
ranked = sorted(zip(candidates, scores), key=lambda x: -x[1])
for doc, score in ranked:
print(f"{score:+.3f} {doc}")
Um reranker é um candidato com alto potencial para ser utilizado como base num RAG pipeline, mas não representa uma solução garantida de sucesso. Avalie os valores de ΔPrecision@1 e ΔnDCG neste conjunto de referência, mantendo-o apenas se o ganho obtido for suficientemente significativo para compensar o aumento da latência e dos custos envolvidos. Compare esse ganho medido com as alterações menores na recuperação de dados antes de optar pela próxima otimização.
ΔnDCG e ΔPrecision@1 obtidos a partir de um cross-encoder no SciFact: Notebook 03; módulo: retrieval/reranker.py.
Construção de contexto e problema do “perdido no meio”
É aqui que surgem muitos dos falhas do tipo “recuperação adequada, resposta inadequada”.
- Relevância de contexto: pontuação de relevância por bloco de dados RAGAS
ContextRelevancyou um cross-encoder, agregado como média e como percentagem dos blocos abaixo de um limiar. - Utilização de contexto: dos trechos inseridos no contexto, quantos foram efetivamente citados ou utilizados na resposta. Calcule como \frac|\text{trechos citados}|}{|\text{blocos recuperados}|$ calculado sobre uma amostra rotulada. Defina o limiar de operação com base na qualidade da resposta e no custo dos tokens, em vez de utilizar uma percentagem universal.
- Deteção de perda no meio: avaliação sintética na qual o trecho de referência é colocado nas posições {primeiro, meio, último} de um contexto extenso, sendo medida a precisão da resposta. A degradação em forma de U é real e está documentada em Liu e colaboradores (TACL 2023). Os modelos modernos apresentam desempenho superior aos modelos da era de 2023, mas o viés continua presente. Medidas de atenuação: realizar um reclassificação e, em seguida, reorganizar os resultados do top-k de modo que o trecho com a pontuação mais alta fique no início ou no final (do LangChain’s)
LongContextReorderfaz exatamente isto), ou compacte os blocos intermédios de forma agressiva. Meça com uma avaliação estratificada por posição, e não apenas com uma pontuação agregada. Um exemplo funcional de avaliação estratificada por posição já pronto para execução encontra-se em Notebook 06 (módulo:evaluation/lost_in_middle.py). - Compressão de contexto: informar a taxa de compressão (tokens de entrada / tokens de saída) juntamente com a precisão da resposta. As ferramentas incluem a do LangChain
ContextualCompressionRetrievere LongLLMLingua. Defina previamente a maior perda de precisão aceitável, com base no orçamento de risco e de tokens da aplicação, e rejeite posteriormente as configurações que excedam esse limite.
Parte 5: A taxa de falsa exclusão do filtro
Esta métrica possui uma secção própria porque as pontuações agregadas de recuperação não permitem atribuir um erro ao filtro.
Um filtro de metadados rígido como tenant_id = X AND product = Y AND locale = en-US Pode reduzir o recall efetivo a zero. O Recall@k, quando implementado corretamente, deteta essa perda, uma vez que o seu denominador permanece o conjunto original de documentos relevantes. No entanto, ele não indica se o filtro, o recuperador ou o classificador foram responsáveis pelo erro de recuperação. A fidelidade pode ainda parecer adequada, pois avalia a resposta com base no contexto recuperado, que é incompleto; nesse caso, o modelo respondeu fielmente “Não sei”.
O ramo vermelho na árvore representa a falha mais comum: o documento correto existe, mas o filtro elimina-o antes da sua recuperação.
A métrica
filter_false_exclusion_rate =
(# queries where all gold docs were excluded by metadata filter) /
(# queries with at least one gold doc)
Esta definição a nível de consulta conta as exclusões catastróficas: não sobra nenhum documento relevante. No caso de consultas multi-gold, o Recall@k padrão ainda revela uma perda parcial; adicione uma taxa de exclusão por documento se esse critério for importante. Para calcular qualquer uma destas taxas, é necessário (a) os IDs dos documentos verdadeiros para cada consulta de avaliação e (b) instrumentação que registe os predicados de filtro aplicados, e não apenas os resultados finais. Defina o objetivo com base no custo de excluir uma resposta válida e no intervalo de confiança da sua amostra de produção.
Aqui está uma implementação funcional. Ela compara o recall padrão correto com um avaliador inválido que redefine a relevância após a filtragem.
# A small worked example where hard filters remove relevant documents.
docs = [
{"id": "d1", "tenant": "acme", "locale": "en-US"},
{"id": "d2", "tenant": "acme", "locale": "en-GB"},
{"id": "d3", "tenant": "globex", "locale": "en-US"},
{"id": "d4", "tenant": "acme", "locale": "en-US"},
{"id": "d5", "tenant": "acme", "locale": "de-DE"},
]
queries = [
# the gold doc lives in en-GB but the dynamic filter forced en-US
{"qid": "q1", "gold": {"d2"}, "filter": lambda d: d["locale"] == "en-US"},
# the gold doc is correctly within the tenant filter
{"qid": "q2", "gold": {"d4"}, "filter": lambda d: d["tenant"] == "acme"},
# the gold doc is in a different tenant and gets dropped
{"qid": "q3", "gold": {"d3"}, "filter": lambda d: d["tenant"] == "acme"},
# the gold doc passes the filter (de-DE locale match)
{"qid": "q4", "gold": {"d5"}, "filter": lambda d: d["locale"] == "de-DE"},
]
def filter_false_exclusion_rate(queries, docs):
n_with_gold, n_excluded = 0, 0
for q in queries:
if not q["gold"]:
continue
n_with_gold += 1
survivors = {d["id"] for d in docs if q["filter"](d)}
if not (q["gold"] & survivors):
n_excluded += 1
return n_excluded / n_with_gold if n_with_gold else 0.0
rate = filter_false_exclusion_rate(queries, docs)
print(f"filter_false_exclusion_rate = {rate:.2%}")
# filter_false_exclusion_rate = 50.00%
# Correct Recall@k keeps the original gold set as its denominator.
def standard_recall_at_k(queries, docs, k=10):
recalls = []
for q in queries:
survivors = [d for d in docs if q["filter"](d)][:k]
survivor_ids = {d["id"] for d in survivors}
recalls.append(len(q["gold"] & survivor_ids) / len(q["gold"]))
return sum(recalls) / len(recalls) if recalls else 0.0
print(f"standard recall@10 = {standard_recall_at_k(queries, docs):.2%}")
# standard recall@10 = 50.00%
# INVALID: rebuilding the gold set after filtering changes the question.
# It drops queries whose relevant documents did not survive, then scores 100%.
def invalid_recall_over_filtered_gold(queries, docs, k=10):
recalls = []
all_doc_ids = {d["id"] for d in docs}
for q in queries:
all_survivors = {d["id"] for d in docs if q["filter"](d)}
filtered_gold = q["gold"] & all_doc_ids & all_survivors
if not filtered_gold:
continue
top_k_ids = set(list(all_survivors)[:k])
recalls.append(len(filtered_gold & top_k_ids) / len(filtered_gold))
return sum(recalls) / len(recalls) if recalls else 0.0
invalid = invalid_recall_over_filtered_gold(queries, docs)
print(f"INVALID recall (filtered gold) = {invalid:.2%}")
# INVALID recall (filtered gold) = 100.00%
assert rate == 0.5
assert standard_recall_at_k(queries, docs) == 0.5
assert invalid == 1.0
Metade das consultas perde o seu documento de referência devido ao filtro, fazendo com que a taxa correta de Recall@10 caia para 50%. Esse valor identifica o sintoma, mas não consegue atribuí-lo a uma causa específica. A taxa de exclusão falsa indica que o predicado removeu duas respostas antes mesmo de o mecanismo de recuperação ser acionado. O avaliador intencionalmente inválido reporta 100% apenas porque descarta esses falhanços do seu conjunto de referência. Nenhum modelo consegue recuperar um documento que foi filtrado.
A taxa de 50% mencionada acima é reproduzida como um teste unitário no repositório complementar: tests/test_filter_exclusion.py::test_50_percent_exclusion_rate. Notebook 04 roda-o no SciFact com metadados sintéticos, de modo a ser possível observar um filtro real a eliminar completamente a taxa de recall; a métrica runtime (juntamente com as métricas complementares de precisão/predicado e recall) encontra-se em evaluation/filter_exclusion.py.
Métrica complementar: precisão e recuperação do predicado
Quando a filtragem é dinâmica (por exemplo, um LLM extrai os predicados de filtro da consulta), trate o extractor de predicados como um modelo de classificação e avalie-o como tal. Meça a precisão e a recuperação dos predicados com base num conjunto rotulado de (query, correct predicate) pares. Uma taxa de erro preditiva não se traduz diretamente na mesma perda de ponto em termos de recall de recuperação; é necessário medir com que frequência esses erros excluem um documento de referência. Uma vez que um filtro rigoroso elimina o documento de referência, nenhuma quantidade de reranking consegue ajudar.
Reforço suave vs. filtro rígido
Esta métrica obriga a uma decisão de projeto. Devem ser utilizados filtros rígidos quando a correção é binária — como em questões de jurisdição legal, limites de ACL ou entre versões publicadas e em rascunho. Por outro lado, devem ser aplicados reforços suaves quando a relevância é avaliada de forma gradual, tendo em conta preferências de localização, data de atualização ou versão do conteúdo. Sem a medição da taxa de exclusão, é difícil identificar a escolha incorreta.
A regra de decisão, mensurável:
For each filter predicate F:
hard_recall_F = retrieval_recall@k with F as a hard filter
soft_recall_F = retrieval_recall@k with F as a +0.X rerank boost
hard_precision = relevant_in_top_k / k under hard filter
soft_precision = relevant_in_top_k / k under soft boost
exclusion_rate = % of queries where the gold doc was filtered out (hard)
Use hard filter only if exclusion_rate < ε AND hard_precision >> soft_precision.
Otherwise prefer soft boost.
Escolha o valor de ε com base no dano causado por uma exclusão errónea, no benefício da maior precisão obtida e no tamanho da amostra de avaliação. Um artigo específico desta série aborda mais a fundo este equilíbrio.
Parte 6: Avaliação da geração
As métricas de recuperação indicam se o sistema poderia responder corretamente. Elas não indicam se ele de fato o fez. As métricas de geração preenchem essa lacuna.
Fidelidade e ancoragem
Fidelidade RAGAS decompõe a resposta em afirmações atómicas (declarações factuais curtas e autónomas), verificando posteriormente cada uma delas em relação ao contexto recuperado através de um juiz LLM:
A percentagem de reivindicações suportadas corresponde à pontuação obtida. Esta estrutura é mais útil do que qualquer número isolado, uma vez que indica quais reivindicações não são suportadas. O código de produção encontra-se em ragas package — a utilização é semelhante a:
from datasets import Dataset
from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy, context_precision
samples = Dataset.from_dict({
"question": ["How many moons does Mars have?"],
"answer": ["Mars has two moons, Phobos and Deimos."],
"contexts": [["Mars has two moons named Phobos and Deimos."]],
"ground_truth": ["Mars has two moons."],
})
result = evaluate(samples, metrics=[faithfulness, answer_relevancy, context_precision])
print(result)
Abaixo encontra-se a mesma estrutura de loop desdobrada, com um juiz substituto determinístico, para que possa visualizar o fluxo de ponta a ponta.
def extract_claims(answer: str) -> list[str]:
# Production: an LLM call that decomposes the answer.
# Demo: split on sentence-final punctuation.
return [c.strip() for c in answer.replace("?", ".").replace("!", ".").split(".") if c.strip()]
def verify_claim(claim: str, context: str) -> bool:
# Production: an NLI (natural-language inference) model or LLM judge.
# Demo: a deterministic stand-in so the example runs offline.
entailed_pairs = {
"Mars has two moons": True,
"Phobos and Deimos orbit Mars": True,
"Mars has a thick atmosphere": False, # unsupported by context
"Curiosity landed in 2012": True,
}
for k, v in entailed_pairs.items():
if k.lower() in claim.lower() or claim.lower() in k.lower():
return v
words = [w.lower() for w in claim.split() if len(w) > 3]
return all(w in context.lower() for w in words) if words else False
context = (
"Mars has two moons, Phobos and Deimos. NASA's Curiosity rover "
"landed on Mars in 2012."
)
answer = (
"Mars has two moons. Phobos and Deimos orbit Mars. "
"Mars has a thick atmosphere. Curiosity landed in 2012."
)
claims = extract_claims(answer)
verdicts = [(c, verify_claim(c, context)) for c in claims]
faithfulness = sum(1 for _, ok in verdicts if ok) / len(verdicts)
for c, ok in verdicts:
print(f" [{'✓' if ok else '✗'}] {c}")
print(f"faithfulness = {faithfulness:.2f}")
# faithfulness = 0.75 (one unsupported claim about the atmosphere)
A estrutura é fundamental. Em produção, verify_claim torna‑se um modelo NLI ou uma chamada ao LLM. O resto do processo de harness permanece inalterado: extrair, verificar, agregar.
Extração e verificação end-to-end de reivindicações em respostas SciFact geradas: caderno de notas 05; módulo: evaluation/faithfulness.py. O repositório também executa um verificador de tipo HHEM entre diferentes famílias de algoritmos no mesmo ciclo, para que possa verificar qual família de juízes concorda com qual.
Uma alternativa desenvolvida especificamente para substituir o LLM-como-jurado HHEM-2.1-Aberto (O Hughes Hallucination Evaluation Model, Vectara), um classificador otimizado para a deteção de alucinações. O seu documento de descrição do modelo detalha o checkpoint, o limite de decisão padrão, bem como os resultados obtidos nos testes AggreFact e RAGTruth. Considere esses dados como evidências contidas no documento do modelo, e não como uma garantia relativa ao seu próprio conjunto de dados: ajuste o limiar com base em etiquetas locais e compare-o com o critério de avaliação escolhido por si antes da implementação.
Avaliação de factos atómicos
FActScore (Min et al., EMNLP 2023) decompõe as gerações de formato longo em factos atómicos, recupera evidências para cada facto e atribui uma etiqueta a cada um deles supported / not-supportede informa a fração suportada:
Implementação de referência: shmsw25/FActScore. Funciona bem para biografias, resumos e outros tipos de saídas de formato extenso. Cuidado: factos triviais e repetitivos podem elevar a pontuação, e ataques do tipo “MontageLie” (factos verdadeiros apresentados em ordem enganosa) podem anular os seus resultados. VeriScore lida com reivindicações utilizando os modificadores necessários; o Core O filtro ajuda a evitar o preenchimento artificial de dados.
Precisão das citações
Acompanhe a precisão das citações (os trechos citados realmente suportam a afirmação) e o recall das citações (as afirmações que deveriam ser citadas, de fato o são):
\text{cite\_precision} = \frac{|\text{trechos citados que suportam uma afirmação}|}{|\text{intervalos citados}|}, \quad \text{cite\_recall} = \frac|\text{afirmações que contêm pelo menos um trecho citado de suporte}|}{|\text{afirmações que devem ser citadas}|}A faixa TREC 2024 RAG define um protocolo de avaliação de suporte reprodutível. Upadhyay e colaboradores (SIGIR 2025) Relata-se que o GPT-4o concorda com os juízes humanos em 56% das vezes nas avaliações manuais realizadas a partir do zero, taxa que sobe para 72% após a edição pós-processamento das previsões de LLM. Isso é útil como um fator de amplificação nas condições em que é utilizado, mas não substitui a avaliação humana em contextos de alto risco. Trata-se, portanto, de uma aproximação automatizada. ALCE (Gao et al., EMNLP 2023) implementam precisão/recall de citações através de verificação baseada em NLI.
Correção, completude e recusa da resposta
- Correção da resposta vs. verdade real: quando esta está disponível, comparação exata ou F1 por token para tarefas de resposta curta (
evaluate.load("squad")), similaridade semântica para questões abertasbert-score, embedding cosseno viasentence-transformers, ou RAGASAnswerCorrectness). - Completude por meio de “nuggets”: um “nugget” é um único elemento atómico de informação que qualquer resposta correta deve conter (por exemplo, para “Quando foi fundada a empresa?”, os nuggets podem ser
{year: 1994, founder: Jane Doe}). O TREC’s AutoNuggetizer Extraí os elementos mais valiosos de uma resposta correta a partir de uma referência, avaliando em seguida qual fração do conteúdo é coberta pelo sistema — observou-se uma forte correlação com a avaliação feita manualmente em 21 tópicos, ao longo de 45 execuções no TREC 2024. - Comportamento de recusa: as consultas para as quais não existe resposta no corpus devem resultar em abstenção, e não em alucinações. Deve ser monitorizada a precisão da abstenção (recusas que estiveram corretas) e o recall da abstenção (consultas fora do escopo que provocaram recusa). NoMIRACL O benchmark público encontra‑se no seu próprio domínio; rotule uma parte das consultas fora do escopo e monitorize a precisão da abstenção.
Verificação pós-geração
Os maiores ganhos em termos de fiabilidade geralmente provêm de verificações pós-processamento determinísticas, e não de modelos mais complexos.
- Verificação de ancoragem de entidades: cada entidade nomeada na resposta deve estar presente no contexto recuperado (ou ser derivável dele). Uma verificação simples por regex + comparação exata (ou
spaCy’sentscontra uma string de contexto normalizada) deteta uma fração surpreendente de alucinações. - Verificação de afirmações: extrair as afirmações, executar NLI em relação ao contexto e rejeitar ou sinalizar quaisquer que estejam abaixo do limiar. Modelos NLI-as-faithfulness:
cross-encoder/nli-deberta-v3-large,MoritzLaurer/DeBERTa-v3-large-mnli-fever-anli-ling-wanli. Cria latência. Vale a pena em domínios de alta relevância. - Autoconsistência (Wang et al., ICLR 2023): Examine múltiplas gerações com temperatura superior a 0; informe a taxa de concordância (por exemplo, a proporção de gerações que correspondem à resposta modal ou o BERTScore entre pares); selecione o número de amostras com base na curva estabilidade–custo e assinale as respostas com baixa concordância para revisão humana.
- Calibração de confiança: recolher a confiança verbalizada (“Qual é a sua confiança, de 0 a 1?”) e compará-la com a precisão real no conjunto de avaliação. Plotar uma curva de calibração e reportar o Erro de Calibração Esperado: \text{ECE} = \sum_{m=1}^{M} \frac{|B_m|{n} |\text{acc}(B_m) - \text{conf}(B_m)|, onde são os intervalos de confiança. Implementações:
netcal,torchmetrics.CalibrationError. Um modelo que apresenta uma confiança de 0.9 deve estar correto em aproximadamente 90% dos casos comparáveis; deve‑se medir a diferença em vez de assumir que a calibração está correta.
Parte 7: Avaliação baseada em ontologias RAG
As métricas padrão mencionadas acima abrangem o conjunto de dados aberto RAG. Os sistemas baseados em ontologias exigem mais indicadores. Se o seu RAG efetuar buscas com base numa ontologia estruturada, numa taxonomia ou num grafo de conhecimento (produtos num catálogo, condições no SNOMED, componentes numa lista de materiais, técnicas de segurança no MITRE ATT&CK), as métricas padrão RAG são necessárias, mas não suficientes. É igualmente necessário medir o nível da ontologia.
Precisão de ligação de entidades
A primeira tarefa consiste em mapear uma menção numa consulta para uma entidade da ontologia (“Aspirin” → wikidata:Q18216”o 737” aircraft:Boeing_737).
- Precisão/recall/F1 a nível de menção: padrão, em comparação com os intervalos de menção de referência (calcular com
seqevalou um comparador de conjunto de intervalos). - Precisão de desambiguação: entre as menções detetadas corretamente, que fração corresponde ao ID da entidade correto? As referências públicas incluem ReFinED, REL, e GENRE; semelhante a benchmarks AIDA-CoNLL e BELB Demonstre que os resultados variam consoante o sistema e o domínio.
- Tratamento de NIL: precisão/recall para o caso de “entidade não presente na ontologia”. Meça o sobrevinculamento a entidades próximas, mas incorretas, separadamente da abstenção correta.
Avaliação com consciência hierárquica
A precisão simples trata o caso em que “previsto Sedan quando a realidade é Hatchback” da mesma forma que o caso em que “previsto Sedan quando a realidade é Submarine”. Esses erros não são equivalentes.
-
Precisão/recall/F1 hierárquicos (Kosmopoulos et al., 2015): Atribua crédito aos ancestrais e descendentes na DAG da ontologia. Onde representa o nó previsto juntamente com todos os seus ancestrais, e representa o nó real juntamente com todos os seus ancestrais:
Implemente com
networkxno grafo da ontologia; verhierarchical-classifier-metricspara referência. -
Semelhança Wu-Palmer entre a entidade prevista e a entidade de referência na taxonomia (Wu e Palmer, 1994):
onde LCA é o ancestral comum mais baixo na taxonomia. Está disponível de forma pronta a usar no NLTK para o WordNet.
from nltk.corpus import wordnet as wn; wn.synset("car.n.01").wup_similarity(wn.synset("truck.n.01"))); para taxonomias personalizadas, calcule o LCA comnetworkx. -
Taxa de confusão entre irmãos/pais: registar separadamente as confusões com irmãos, pais e filhos —
count_sibling / total_errors,count_parent / total_errors,count_descendant / total_errors. Utilize exemplos já avaliados para testar se os erros entre elementos irmãos resultam de menções ambíguas ou se os erros nos elementos pais derivam de uma generalização excessiva.
Taxa de filtragem de falsas exclusões (reprise, agora crítica)
Em sistemas baseados em ontologias, os filtros rígidos provêm frequentemente da própria ontologia (“apenas recuperar documentos marcados com a categoria X”). A métrica de taxa de exclusão (definida em Parte 5) Torna‑se um sinal principal de correção. Uma previsão de categoria incorreta pode anular o recall; a taxa de exclusão atribui essa perda ao filtro.
Conformidade de geração condicionada
Quando a sua saída deve estar em conformidade com uma ontologia (cada nome de entidade na resposta tem de ser um membro válido da ontologia; cada predicado tem de provir de um vocabulário fechado), meça:
- Taxa de validade do esquema: percentagem de resultados que são analisados e validados em relação ao esquema da ontologia. Validar com
jsonschemaoupydantic. JSONSchemaBench O benchmark público serve para structured output em geral; para esquemas específicos de ontologias, é necessário criar o próprio validador. - Conformidade de vocabulário: percentagem de entidades nomeadas no resultado que correspondem a IDs de ontologia válidos — uma verificação de pertença à lista em apenas uma linha, face ao vocabulário fechado.
- Conformidade semântica: a validade é necessária, mas insuficiente. Um resultado sintaticamente válido pode selecionar uma entidade válida, mas incorreta. É preciso combinar a conformidade com a correção das respostas finais.
Constrained decoding frameworks (Esboços, XGrammar, Orientações, OpenAI Structured Outputs) São projetados para garantir a validade do esquema. JSONSchemaBench Compara a eficiência, a cobertura e a qualidade entre as diferentes implementações. Execute novamente os seus casos que correspondem aos seus esquemas e serving backend, uma vez que tanto a cobertura como o tempo de resposta dependem de ambos.
Auditabilidade
Em sistemas baseados em ontologias onde as respostas são sujeitas a revisão:
- Completude das citações: percentagem de afirmações factuais que dispõem de, pelo menos, uma citação verificável.
- Profundidade da proveniência: percentagem de citações que remontam diretamente a um documento de origem com um ID estável, e não apenas a um hash de trecho.
- Taxa de reprodutibilidade: a execução repetida da mesma consulta, com base num instantâneo fixo, deve retornar sempre a mesma resposta. É necessário fixar a versão do modelo, runtime, a configuração de decodificação e o seed, definindo em seguida a taxa de repetição exigida de acordo com as necessidades de auditoria do fluxo de trabalho. Apenas a temperatura zero não garante determinismo; um erro pode surgir durante a geração, no serving runtime, ou em qualquer fase anterior do processo.
Parte 8: Avaliação a nível de sistema
Qualidade global da resposta
- LLM-como-jurado (Zheng et al., NeurIPS 2023): uma abordagem de avaliação baseada em modelos escalável. O G-Eval (um protocolo de LLM-júri que faz com que o modelo gere a sua própria rubrica chain-of-thought antes de efetuar a pontuação) obtém uma rubrica a partir de um critério em linguagem natural e, em seguida, realiza a avaliação utilizando resultados ponderados por log-probabilidade. O grau de concordância depende do júri, da tarefa, do prompt e do conjunto de calibração.
- Preferência em pares: apresentar ao júri a resposta A em comparação com a resposta B; registar a preferência escolhida. Isto evita problemas relacionados com a calibração de valores absolutos. MT-Bench Foi relatado que o nível de concordância do GPT-4 Judge ultrapassa 80%, tanto em relação às preferências humanas como à concordância entre humanos, nas condições estabelecidas pelo benchmark; não se deve transferir essa taxa para outro domínio sem realizar a devida calibração.
LLM-como juiz, possui vieses reais:
- Viés de posição: os avaliadores preferem a primeira ou a segunda resposta, independentemente da qualidade. Atenuação: randomizar a ordem ou executar as duas ordens e calcular a média.
- Viés de verbosidade: os avaliadores podem confundir o comprimento com a qualidade. Um Estudo controlado de 2026 Foi detetado um comportamento heterogéneo nas pares de expansão: três avaliadores preferiram respostas mais longas, o Claude optou por respostas concisas, enquanto o GPT-4o manteve uma atitude aproximadamente neutra. Todos os cinco modelos tiveram um desempenho sólido nos testes de controlo de truncamento. O resultado está limitado por benchmark, portanto, indique ao seu avaliador como tratar a completude e os elementos desnecessários, e registre depois o desempenho sob controlo de comprimento segundo a sua própria escala de avaliação.
- Viés de auto-preferência: o GPT-4 prefere as suas próprias saídas; este viés está correlacionado com a perplexidade da saída (os avaliadores preferem texto que lhes é familiar). Mitigação: utilize um conjunto de avaliadores diferente do sistema que está a ser avaliado. Não utilize um modelo para se avaliar a si mesmo.
Receita prática: selecione um avaliador com base em dados de calibração rotulados por humanos, randomize a ordem das respostas, oculte as identidades dos modelos e especifique a política de comprimento na rubrica. Repita os casos apenas quando as amostras adicionadas reduzirem significativamente a incerteza. Em avaliações de alto risco, compare avaliadores de diferentes famílias de modelos e analise as discrepâncias em relação aos rótulos fornecidos por humanos.
Raciocínio Orientado por Esquema para juízes
A saída em formato livre é uma das causas de variação nos resultados obtidos pelos avaliadores. Duas avaliações da mesma resposta podem organizar a rubrica de forma diferente, resultando em pontuações distintas. Raciocínio Guiado por Esquema (SGR) Torna essa rubrica explícita: defina as fases de avaliação como um esquema Pydantic e, em seguida, utilize uma saída restrita através de Outlines, XGrammar, vLLM structured outputs, ou OpenAI response_format Assim, cada execução devolve os mesmos campos na mesma ordem.
Para RAG eval, o esquema degrada o julgamento em campos explícitos e auditáveis, em vez de permitir que o modelo chegue diretamente a um número:
from pydantic import BaseModel, Field
from typing import Literal
class FaithfulnessJudgment(BaseModel):
extracted_claims: list[str] = Field(
description="Atomic factual claims in the answer, one per item."
)
supported_claims: list[str] = Field(
description="Subset of extracted_claims that are entailed by the context."
)
unsupported_claims: list[str] = Field(
description="Subset that is NOT entailed by the context."
)
failure_mode: Literal[
"none", "fabrication", "overgeneralization", "wrong_entity", "stale_fact"
]
score: float = Field(ge=0.0, le=1.0)
rationale: str
Os campos estruturados permitem que a pontuação seja recuperada. len(supported) / len(extracted) E indica exatamente quais afirmações geraram desacordo entre os dois juízes. O modelo Pydantic também torna visível uma alteração na rubrica na forma de um diff de código. A saída condicionada garante apenas a estrutura esperada, e não um veredito imparcial; portanto, a randomização de posições, a utilização de juízes de famílias diferentes e a calibração humana continuam a ser aplicadas.
Isto funciona para qualquer avaliador baseado em rubricas, não apenas no critério de fidelidade. A preferência entre pares, o suporte a citações e a correção de recusas beneficiam todos do mesmo tratamento.
Um avaliador G-Eval / emparelhado / com viés de posição / interfamiliar harness encontra-se em caderno de notas 07; módulo: evaluation/llm_judge.py. A varredura benchmarkmake benchmark no repositório) conecta três modelos de nível avançado — gpt-5-mini, claude-haiku-4-5, gemini-2.5-flash — transformando-o num teste A/B emparelhado com juízes rotativos, de modo que cada modelo avalie os outros dois, revelando numericamente as suas preferências próprias.
Latência e custo
- p50, p95, p99 em cada fase pipeline. Escolha o percentil do SLO e o limiar de alerta com base na jornada do utilizador, no volume de tráfego e no orçamento de erros disponível.
- Tempo até ao primeiro token versus tempo total de geração. Para uma experiência de utilizador em fluxo contínuo, os utilizadores dão importância ao TTFT.
- Divisão por fases: recuperação de dados, reranking, geração e pós-processamento. Utilize o rastreio para identificar a causa raiz em vez de assumir qual fase a provocou; registe o dispositivo reranker e o tamanho do lote ao comparar diferentes execuções.
- Custo total por consulta = embedding + custos de recuperação de dados + reclassificação + geração + armazenamento (amortizado). Acompanhe os valores p50 e p99; é na “cauda longa” que o orçamento é maioritariamente consumido.
- Taxas de sucesso de cache nos níveis de cache embedding, cache de recuperação de dados e cache KV. Defina objetivos separados com base na repetição observada, na política de invalidação e nos custos evitados em cada camada.
A medição de p50/p95/p99 por fase, juntamente com a detalhamento da estrutura por fases, está integrada diretamente caderno de notas 08 e o executor em evaluation/latency.py; o relatório benchmark combina a latência com a fidelidade numa única matriz que pode ser executada novamente make benchmark.
Teste A/B
- Unidade de randomização: escolha a unidade entre o estimando, o carryover e a interferência. Utilize a atribuição por utilizador ou por sessão quando a exposição repetida possa alterar o comportamento ou criar uma experiência do utilizador inconsistente. A atribuição por consulta só é defensável quando esses efeitos são negligenciáveis e os modelos de análise consideram observações repetidas.
- Métricas primárias, de salvaguarda e exploratórias: registe-as previamente. Escolha a métrica principal com base no resultado do produto; os indicadores de satisfação incluem “thumbs”, regenerações e tempo de permanência. Trate a latência e o custo como métricas de salvaguarda, uma vez que condicionam a experiência do utilizador.
- Tamanho da amostra: realize uma análise de poder antes do lançamento, tendo em conta o efeito mínimo digno de deteção, a variância de base, a unidade de atribuição e a regra de interrupção.
Parte 9: Construção do conjunto de teste
Uma métrica só é tão boa quanto o conjunto de teste em que é aplicada. Se o seu conjunto de referência abranger três intenções e o tráfego de produção incluir doze, a Recall@10 irá medir apenas essas três intenções. Pior ainda, um conjunto de teste que sofre sobreajuste com perguntas fáceis (“Qual é a política de reembolso da empresa?”) pode aprovar um sistema que falha nas questões mais difíceis (“Quais são os requisitos para reembolso em caso de cancelamento parcial, nos termos da Lei dos Serviços Digitais da UE de 2023, com faturação em euros e origem na Irlanda?”). A pontuação global aumenta, mas o sistema continua a falhar numa parte importante do tráfego real.
O mesmo problema afeta a verdade real. Se as PME rotularem os documentos óbvios, mas deixarem passar aqueles de cauda longa que são relevantes, o Recall@k atribuirá uma avaliação insuficiente a um recuperador que, na verdade, os encontrou. Otimiza-se em direção aos rótulos, e não em direção à verdade real.
Construa primeiro o conjunto de teste com base na distribuição real das consultas e no seu nível de dificuldade. Em seguida, selecione métricas que reflitam os modos de falha desejados e ajuste o sistema em função deles.
Geração de consultas sintéticas
Utilize um LLM para gerar perguntas a partir do seu corpus:
- Por bloco: “Gerar 3 perguntas que um utilizador possa fazer e às quais este bloco responde.”
- Multi-hop: selecionar dois blocos, gerar uma pergunta que exija conhecimentos de ambos.
- Adversarial: gerar perguntas com entidades enganosas, formulações quase idênticas e menções ambíguas.
RAGAS Possui uma distribuição de tipos de questões integrada (raciocínio, condicional, multi-contexto). DataMorgana Gera benchmarks sintético configurável nas categorias de utilizador e de pergunta. Os dados sintéticos são úteis para situações de “cold start” e para testes de cobertura. Não podem substituir as consultas reais de utilizadores.
Construção Golden dataset
Os dados curados por humanos servem de referência fundamental para o conjunto ideal.
- Amostras de consultas reais de utilizadores (ou simuladas, se ainda antes do lançamento), estratificadas por intenção.
- Fazer com que especialistas respondam a cada pergunta e identifiquem qual(is) documento(s) contém a resposta.
- Definir o tamanho do conjunto com base na matriz de cobertura e no intervalo de confiança necessário para tomar decisões de lançamento; a cobertura é mais importante do que o número de consultas obtidas.
- Realizar uma nova curadoria sempre que o ritmo de lançamentos, sinais de desvio, riscos do domínio e a capacidade de anotação o justifiquem.
Conjuntos de teste adversariais
- Contrafactuais: troca de entidades-chave na consulta. O sistema recupera os trechos corretos para a consulta alterada?
- Distratores: consultas nas quais o corpus contém uma resposta plausível, mas incorreta, que não deve ser recuperada. É isto que RGB (Chen et al., AAAI 2024) realizam testes de esforço em: robustez ao ruído, rejeição negativa, integração de informações e robustez contrafactual.
- Negação e quantificadores: consultas que contêm “not”, “except” e “only”. Os recuperadores densos costumam ter dificuldades com estes casos.
- Fora do escopo: consultas para as quais não existe resposta no corpus. O sistema deve indicar “Não sei”, em vez de gerar fantasias. NoMIRACL Vive aqui. Avalie explicitamente a abstenção nos seus tipos de consulta em produção.
Cobertura e avaliação contínua
- Construa uma matriz de cobertura: intenção da consulta × tipo de documento × ramo da ontologia. O objetivo é ter ≥1 consulta por célula. As células vazias representam regiões não monitorizadas onde regressões podem passar despercebidas.
- Execute um subconjunto limitado e rápido de testes de regressão em cada PR, e o conjunto completo em um cronograma mais lento.
- Defina o agendamento para a avaliação completa do conjunto “golden set” com base na frequência de lançamentos e no custo associado; os candidatos a lançamento funcionam como um filtro natural nesse processo.
- Planeje a avaliação de deriva com base no volume de tráfego, nas mudanças esperadas e no risco envolvido. Utilize uma amostra dinâmica da produção e estratifique os resultados de acordo com o feedback recebido, em vez de alterar silenciosamente a distribuição-alvo.
Parte 10: Monitorização em produção
O conjunto de testes de avaliação que é disponibilizado descreve o sistema no momento do lançamento. O tráfego em produção sofre alterações após esse período.
Feedback implícito e explícito
- Taxa de cliques/abertura nas fontes citadas (se a sua interface as exibir).
- Tempo de permanência na resposta.
- Taxa de regeneração: percentagem de respostas que o utilizador solicita novamente ou pede ao sistema que repita. Trate-a como um sinal de insatisfação e ajuste-a com base em conversas analisadas.
- Taxas de cópia/compartilhamento/exportação — sinal positivo muito forte.
- Padrões de acompanhamento: frases como “Tem a certeza?” ou “Mas e quanto a X?” indicam desconfiança.
- Botões de aprovação/reprovação com categorias opcionais de motivo (incorreto, incompleto, fora de tema, prejudicial, lento). As edições inline, quando a sua interface as permitir, são o sinal de feedback mais rico em informações disponível.
Deteção de deriva
- Deriva de consultas: monitorize a distribuição das consultas embedding em comparação com uma janela de referência, utilizando divergência KL, MMD ou um detetor baseado em modelos. Ative alertas sempre que ocorrer uma alteração e, em seguida, proceda à segmentação e depuração.
- Deriva de Embedding: defina um conjunto fixo de documentos de teste; incorpore-os novamente periodicamente e meça o seu ângulo de cosseno em relação ao embeddings original. Mesma uma pequena deriva entre versões do modelo do fornecedor pode comprometer silenciosamente a recuperação de informações. O armazenamento versionado de embedding (fotografias imutáveis por versão) é a solução mais económica para mitigar este problema.
- Deriva de desempenho: acompanhe, ao longo do tempo, métricas equivalentes às utilizadas em produção (taxa de regeneração por intenção). Saltos repentinos indicam que algo se partiu; derivas lentas sugerem que as condições externas mudaram.
Avaliação em sombra e human-in-the-loop
Execute o sistema candidato em paralelo com a versão em produção, compare os resultados off-line e não os exiba aos utilizadores. Esta abordagem permite detetar regressões antes do lançamento. Embora implique um custo adicional de inferência, não tem qualquer impacto nos clientes.
Para revisão do human-in-the-loop (HITL):
- Incluir resultados de baixa confiança numa fila de revisão.
- Adicionar uma amostra aleatória do tráfego em produção para revisão cega; definir a sua taxa com base no volume de tráfego, no risco e na capacidade dos revisores.
- Dar maior peso aos resultados classificados como “não aprovados”.
- Utilizar os resultados já revistos para expandir o conjunto de referência.
O conjunto mínimo de restrições de segurança
Aviso sobre estes, por ordem de prioridade:
- Pontuação de fidelidade/HHEM abaixo do limiar num conjunto de amostra em produção em tempo real.
- Latência p95 acima do SLO.
- Taxa de falsa exclusão pelo filtro acima do limiar (baseada em amostras).
- Taxa de regeneração fora de uma faixa de controlo calibrada localmente, que leva em conta o tamanho da janela, o tráfego, a sazonalidade e o orçamento de alertas falsos.
- Custo/consulta acima do orçamento estabelecido.
Se um alerta for acionado sem uma alteração correspondente no código ou no modelo, é provável que esteja a ocorrer deriva. Se for acionado após uma alteração, é provável que haja regressão. Em qualquer dos casos, recebe-se um sinal antes mesmo de chegarem os pedidos de suporte.
Considerações importantes
- Os alvos são locais, e não universais. Qualquer valor indicado como exemplificativo neste guia representa uma configuração de exemplo ou um resultado obtido em testes, e não um limiar de lançamento. Ajuste os limites de acordo com o seu domínio, as implicações associadas, a incerteza do conjunto de avaliação e as expectativas dos utilizadores.
- O espaço framework evolui rapidamente. As versões do HHEM, os nomes das métricas RAGAS, as fichas técnicas dos modelos e a ordem no ranking podem sofrer alterações após a publicação. Verifique novamente a fonte referenciada e realize uma nova benchmark antes de proceder com a implementação.
- Os números de concordância LLM-como-jurados vêm acompanhados de asteriscos. O valor de 80% entre GPT-4 e humanos refere-se a condições do MT-Bench / Chatbot Arena. Em domínios especializados e cenários adversariais, essa taxa de concordância diminui significativamente. Utilize jurados como um reforço, e não como substituto, para verificações pontuais.
- Os ganhos prometidos pelos fornecedores benchmark raramente conseguem ser reproduzidos de forma independente. Reproduza os resultados nos seus próprios dados antes de confiar num número, especialmente no que diz respeito a sistemas mais recentes como rerankers e OCR.
- Nenhuma métrica substitui a análise direta das saídas. Agende revisões cegas de amostras aleatórias produzidas em ambiente real, dependendo do tráfego, do risco envolvido e da capacidade dos revisores. As métricas servem apenas para quantificar esse processo; elas não o substituem.
O que virá nesta série
Este era o índice. As próximas etapas que estou a planear:
- Soft Boosts vs. Hard Filters: uma análise aprofundada da taxa de falsa exclusão por filtros, com código, exemplos reais de produção e uma decisão framework.
- Chunking é a Variável Oculta: um experimento controlado entre chunking recursivo, semântico, tardio e estrutural em três corpora.
- Seleção de Reranker em 2026: BGE vs. Cohere vs. ZeRank vs. modelos de cross-encoder atuais, comparados em termos de custo, latência e melhoria de desempenho.
- RAG Baseado em Ontologias: Um Guia Do Início ao Fim: como construir a avaliação completa harness para um sistema de recuperação baseado em entidades.
- Uso de LLM como Avaliador Sem a Armadilha da Preferência Pessoal: técnicas práticas para avaliações automatizadas imparciais.
- Avaliação Online em Produção: padrões de instrumentação, políticas de alerta e os painéis que detetam regressões reais.
Referências
Frameworks e benchmarks
- Es et al., Ragas: Avaliação Automatizada de Geração Aprimorada por Recuperação de Informação, 2023.
- Documentação RAGAS e GitHub.
- Saad-Falcon e colaboradores, ARES: Uma avaliação automatizada Framework para sistemas de geração reforçada por recuperação de informação, NAACL 2024.
- TruLens, DeepEval, Arize Phoenix.
- Thakur et al., BEIR: Uma Benchmark heterogénea para avaliação zero-shot de modelos de recuperação de informação, NeurIPS 2021.
- Classificação MTEB.
- TREC 2024 RAG Categorização.
- Pradeep et al., Resultados iniciais de avaliação dos nuggets para a trilha TREC 2024 RAG com o AutoNuggetizer Framework, 2024.
Recuperação e classificação
- Cormack, Clarke, Buettcher, A Fusão de Rank Recíproco supera os métodos de Aprendizagem de Rank Individual e o algoritmo de Condorcet., SIGIR 2009.
- Gao et al., Recuperação Densoa Zero-Shot de Alta Precisão Sem Rótulos de Relevância (HyDE), 2022.
- Jeong et al., Adaptativo-RAG: Aprendizagem para adaptar modelos de linguagem de grande escala reforçados por recuperação à complexidade das perguntas, NAACL 2024.
- Anthropic, Apresentamos a Recuperação Contextual, Setembro de 2024.
- Günther et al., Chunking tardio: Agrupamento contextual Embeddings com modelos de contexto longo Embedding, 2024.
- Sarthi e colaboradores, RAPTOR: Processamento Abstrativo Recursivo para Recuperação Organizada em Árvore, 2024.
Geração, fidelidade, avaliadores
- Min et al., FActScore: Avaliação Atómica e de Alta Resolução da Precisão Factual na Geração de Texto de Formato Longo, EMNLP 2023.
- Liu et al., Perdido no Meio: Como os Modelos de Língua Utilizam Contextos Longos, TACL 2023.
- Chen et al., Realização de benchmarks em modelos de linguagem de grande escala no contexto da geração reforçada por recuperação de informação (RGB), AAAI 2024.
- Vectara, HHEM-2.1 – Modelo de avaliação de alucinações abertas.
- Zheng et al., Avaliação de LLM como juiz com o MT-Bench e o Chatbot Arena, NeurIPS 2023.
- Upadhyay et al., Avaliação de Suporte para a Trilha TREC 2024 RAG: Comparação entre Julgadores Humanos e LLM, SIGIR 2025.
- Thakur et al., NoMIRACL: Saber Quando Não Se Sabe para Geração Aprimorada por Recuperação Multilíngue Robusta, 2023.
- Geng et al., JSONSchemaBench: Um Benchmark rigoroso de Structured Outputs para modelos de linguagem, 2025.
- Kosmopoulos et al., Medidas de Avaliação para Classificação Hierárquica: uma visão unificada e abordagens inovadoras, 2015.
Derivação e produção
- Evidentemente, Embedding Metodologias de deteção de deriva comparadas.
Código complementar
slavadubrov/rag-evals-demo— um harness executável para cada métrica deste artigo no corpus SciFact, além de uma varredura de chunking × embedding × LLM benchmark. Incluem-se os notebooks de 00 a 09, os testes unitários que validam os exemplos apresentados e um índice Qdrant embutido, permitindo assim a execução sem a necessidade de Docker.