Phase 05 - Lesson 28
Avaliação de Contexto Longo — NIAH, RULER, LongBench, MRCR
O Gemini 3 Pro anuncia 10M de tokens de contexto. Em 1M de tokens, o MRCR de 8 agulhas cai para 26,3%. Anunciado ≠ utilizável. A avaliação de contexto longo revela a capacidade real do modelo no qual você está embarcando.
Tipo: Aprender Linguagens: Python Pré-requisitos: Fase 5 · 13 (Perguntas e Respostas), Fase 5 · 23 (Estratégias de Chunking) Tempo: ~60 minutos
O Problema
Você tem um contrato de 200 páginas. O modelo afirma ter um contexto de 1M de tokens. Você cola o contrato inteiro e pergunta: "Qual é a cláusula de rescisão?" O modelo responde — mas responde a partir da página de capa, porque a cláusula de rescisão está a 120k tokens de profundidade, além de onde o modelo realmente presta atenção.
Esse é o vão de capacidade de contexto de 2026. As fichas técnicas dizem 1M ou 10M. A realidade diz que 60-70% disso é utilizável, e "utilizável" depende da tarefa.
- Recuperação (uma única agulha no palheiro): quase perfeita até o máximo anunciado em modelos de fronteira.
- Multi-salto / agregação: degrada acentuadamente acima de ~128k na maioria dos modelos.
- Raciocínio sobre fatos dispersos: a primeira tarefa a falhar.
A avaliação de contexto longo mede esses eixos. Esta lição nomeia os benchmarks, o que cada um realmente mede, e como construir um teste de agulha personalizado para o seu domínio.
O Conceito
Needle-in-a-Haystack (NIAH, 2023). Coloque um fato ("a palavra mágica é abacaxi") em uma profundidade controlada dentro de um contexto longo. Peça ao modelo que o recupere. Varra profundidade × comprimento. O benchmark original de contexto longo. Modelos de fronteira agora saturam este teste; ele é uma linha de base necessária, mas não suficiente.
RULER (Nvidia, 2024). 13 tipos de tarefa em 4 categorias: recuperação (chave única / múltiplas chaves / múltiplos valores), rastreamento multi-salto (rastreamento de variáveis), agregação (frequência de palavra comum), QA. Comprimento de contexto configurável (4k a 128k+). Revela modelos que saturam o NIAH mas falham em multi-salto. No lançamento de 2024, apenas metade dos 17 modelos que afirmavam ter contexto de 32k+ manteve a qualidade em 32k.
LongBench v2 (2024). 503 perguntas de múltipla escolha, contextos de 8k a 2M palavras, seis categorias de tarefa: QA de documento único, QA multi-documento, aprendizado em contexto longo, diálogo longo, repositório de código, dados estruturados longos. O benchmark de produção para comportamento de contexto longo no mundo real.
MRCR (Multi-Round Coreference Resolution). Correferência multi-turno em escala. Variantes de 8 agulhas, 24 agulhas, 100 agulhas. Expõe quantos fatos um modelo consegue manejar antes que a atenção degrade.
NoLiMa. "Agulha não lexical." A agulha e a consulta não compartilham nenhuma sobreposição literal; a recuperação exige um passo de raciocínio semântico. Mais difícil que o NIAH.
HELMET. Concatena muitos documentos, faz uma pergunta a partir de qualquer um deles. Testa a atenção seletiva.
BABILong. Insere cadeias de raciocínio bAbI dentro de palheiros irrelevantes. Testa raciocínio-no-palheiro, não apenas recuperação.
O que de fato reportar
- Janela de contexto anunciada. O número da ficha técnica.
- Comprimento efetivo de recuperação. Aprovação no NIAH em algum limiar (por exemplo, 90%).
- Comprimento efetivo de raciocínio. Aprovação em multi-salto ou agregação naquele limiar.
- Curva de degradação. Acurácia vs comprimento de contexto, plotada por tipo de tarefa.
Dois números para a sua ficha técnica: efetivo-para-recuperação e efetivo-para-raciocínio. Normalmente o efetivo-para-raciocínio é 25-50% da janela anunciada.
Construa Isso
Passo 1: um NIAH personalizado para o seu domínio
Veja code/main.py. O esqueleto:
def build_haystack(filler_text, needle, depth_ratio, total_tokens):
if not (0.0 <= depth_ratio <= 1.0):
raise ValueError(f"depth_ratio must be in [0, 1], got {depth_ratio}")
if total_tokens <= 0:
raise ValueError(f"total_tokens must be positive, got {total_tokens}")
filler_tokens = tokenize(filler_text)
needle_tokens = tokenize(needle)
if not filler_tokens:
raise ValueError("filler_text produced no tokens")
# Repeat filler until long enough to fill the haystack body.
body_len = max(total_tokens - len(needle_tokens), 0)
while len(filler_tokens) < body_len:
filler_tokens = filler_tokens + filler_tokens
filler_tokens = filler_tokens[:body_len]
insert_at = min(int(body_len * depth_ratio), body_len)
haystack = filler_tokens[:insert_at] + needle_tokens + filler_tokens[insert_at:]
return " ".join(haystack)
def score_niah(model, haystack, question, expected):
answer = model.complete(f"Context: {haystack}\nQ: {question}\nA:", max_tokens=50)
return 1 if expected.lower() in answer.lower() else 0
Varra depth_ratio ∈ {0, 0.25, 0.5, 0.75, 1.0} × total_tokens ∈ {1k, 4k, 16k, 64k}. Plote o mapa de calor. Esse é o cartão NIAH do seu modelo-alvo.
Passo 2: uma variante multi-agulha
def build_multi_needle(filler, needles, total_tokens):
depths = [0.1, 0.4, 0.7]
chunks = [filler[:int(total_tokens * 0.1)]]
for depth, needle in zip(depths, needles):
chunks.append(needle)
next_chunk = filler[int(total_tokens * depth): int(total_tokens * (depth + 0.3))]
chunks.append(next_chunk)
return " ".join(chunks)
Perguntas como "Quais são as três palavras mágicas?" exigem recuperar as três. O sucesso com uma única agulha não prevê o sucesso com múltiplas agulhas.
Passo 3: rastreamento de variáveis multi-salto (estilo RULER)
haystack = """X1 = 42. ... (filler) ... X2 = X1 + 10. ... (filler) ... X3 = X2 * 2."""
question = "What is X3?"
A resposta exige encadear três atribuições. Modelos de fronteira em 128k frequentemente caem para 50-70% de acurácia aqui.
Passo 4: LongBench v2 na sua stack
from datasets import load_dataset
longbench = load_dataset("THUDM/LongBench-v2")
def eval_model_on_longbench(model, subset="single-doc-qa"):
tasks = [x for x in longbench["test"] if x["task"] == subset]
correct = 0
for x in tasks:
answer = model.complete(x["context"] + "\n\nQ: " + x["question"], max_tokens=20)
if normalize(answer) == normalize(x["answer"]):
correct += 1
return correct / len(tasks)
Reporte a acurácia por categoria. Pontuações agregadas escondem grandes diferenças no nível da tarefa.
Armadilhas
- Avaliação apenas com NIAH. Passar no NIAH em 1M de tokens não diz nada sobre multi-salto. Sempre execute o RULER ou um teste multi-salto personalizado.
- Amostragem uniforme de profundidade. Muitas implementações só testam depth=0.5. Teste depth=0, 0.25, 0.5, 0.75, 1.0 — o efeito "perdido no meio" é real.
- Sobreposição lexical com o preenchimento. Se a agulha compartilha palavras-chave com o preenchimento, a recuperação se torna trivial. Use agulhas sem sobreposição no estilo NoLiMa.
- Ignorar a latência. Prompts de 1M de tokens levam de 30 a 120 segundos para o prefill. Meça o tempo até o primeiro token junto com a acurácia.
- Números autorreportados pelos fornecedores. OpenAI, Google e Anthropic publicam todos as suas próprias pontuações. Sempre execute novamente de forma independente no seu caso de uso.
Use Isso
A stack de 2026:
| Situação | Benchmark |
|---|---|
| Verificação rápida de sanidade | NIAH personalizado em 3 profundidades × 3 comprimentos |
| Seleção de modelo para produção | RULER (13 tarefas) no seu comprimento-alvo |
| Qualidade de QA no mundo real | Subconjunto single-doc-QA do LongBench v2 |
| Raciocínio multi-salto | BABILong ou rastreamento de variáveis personalizado |
| Conversacional / diálogo | MRCR 8 agulhas no seu comprimento-alvo |
| Regressão em atualização de modelo | Harness NIAH + RULER interno fixo, executado em cada novo modelo |
Regra prática para produção: nunca confie em uma janela de contexto até ter NIAH + 1 tarefa de raciocínio no comprimento pretendido.
Entregue Isso
Salve como outputs/skill-long-context-eval.md:
---
name: long-context-eval
description: Design a long-context evaluation battery for a given model and use case.
version: 1.0.0
phase: 5
lesson: 28
tags: [nlp, long-context, evaluation]
---
Given a target model, target context length, and use case, output:
1. Tests. NIAH depth × length grid; RULER multi-hop; custom domain task.
2. Sampling. Depths 0, 0.25, 0.5, 0.75, 1.0 at each length.
3. Metrics. Retrieval pass rate; reasoning pass rate; time-to-first-token; cost-per-query.
4. Cutoff. Effective retrieval length (90% pass) and effective reasoning length (70% pass). Report both.
5. Regression. Fixed harness, rerun on every model upgrade, surface deltas.
Refuse to trust a context window from the model card alone. Refuse NIAH-only evaluation for any multi-hop workload. Refuse vendor self-reported long-context scores as independent evidence.
Exercícios
- Fácil. Construa um NIAH com 3 profundidades (0.25, 0.5, 0.75) × 3 comprimentos (1k, 4k, 16k). Execute em qualquer modelo. Plote a taxa de aprovação como um mapa de calor 3×3.
- Médio. Adicione uma variante de 3 agulhas. Meça a recuperação das 3 em cada comprimento. Compare com a taxa de aprovação de agulha única no mesmo comprimento.
- Difícil. Construa uma tarefa de rastreamento de variáveis (X1 → X2 → X3, com 3 saltos) embutida em 64k de preenchimento. Meça a acurácia em 3 modelos de fronteira. Reporte o comprimento efetivo de raciocínio por modelo.
Termos-Chave
| Termo | O que as pessoas dizem | O que realmente significa |
|---|---|---|
| NIAH | Agulha no palheiro | Planta um fato no preenchimento e pede ao modelo que o recupere. |
| RULER | NIAH turbinado | 13 tipos de tarefa em recuperação / multi-salto / agregação / QA. |
| Contexto efetivo | A capacidade real | Comprimento no qual a acurácia ainda se mantém acima do limiar. |
| Perdido no meio | Viés de profundidade | Modelos prestam menos atenção ao conteúdo no meio de entradas longas. |
| Multi-agulha | Muitos fatos de uma vez | Múltiplas plantas; testa o manejo da atenção, não apenas a recuperação. |
| MRCR | Correferência multi-turno | Correferência de 8, 24 ou 100 agulhas; expõe a saturação da atenção. |
| NoLiMa | Agulha não lexical | Agulha e consulta não compartilham tokens literais; exige raciocínio. |
Leitura Adicional
- Kamradt (2023). Needle in a Haystack analysis — o repositório original do NIAH.
- Hsieh et al. (2024). RULER: What's the Real Context Size of Your Long-Context LMs? — o benchmark multi-tarefa.
- Bai et al. (2024). LongBench v2 — avaliação de contexto longo no mundo real.
- Modarressi et al. (2024). NoLiMa: Non-lexical needles — agulhas mais difíceis.
- Kuratov et al. (2024). BABILong — raciocínio-no-palheiro.
- Liu et al. (2024). Lost in the Middle: How Language Models Use Long Contexts — o artigo sobre o viés de profundidade.