Conteúdo da trilha
Cenário realDados e documentos

Pesquisa profunda com citações

Deep research with citations

Pesquisa profunda com citações (Deep research with citations) é um estudo de caso real de sistema com LLM, do grupo Dados e documentos. Investigar uma pergunta aberta em dezenas de fontes e entregar um relatório citado.

Elemento
11/25
Nível
Avançado
Leitura
11 min
Atualizado
Nesta página 11
  1. 01O negócio
  2. 02Versão 1
  3. 03O que quebrou
  4. 04Smells encontrados
  5. 05Refatorações aplicadas
  6. 06Arquitetura final
  7. 07Números
  8. 08Padrões usados
  9. 09Código de referência
  10. 10Lições
  11. 11Teste seu entendimento
  12. ··Perguntas rápidas

O negócio

Uma consultoria de estratégia faz dezenas de pesquisas de mercado por mês: tamanho de mercado, concorrentes, regulação, tendências. Cada uma leva dois a três dias de um analista júnior, a maior parte lendo fontes e organizando anotações.

O produto que o cliente paga é um relatório em que cada afirmação tem uma fonte que dá para abrir. Número sem fonte não entra. Trecho que não está na página citada não entra. O analista júnior hoje faz esse trabalho com dez abas no navegador, um documento de notas e muito copiar e colar.

O objetivo é um sistema que recebe uma pergunta aberta (“como está o mercado de energia solar residencial no Nordeste?”) e entrega, em minutos, um relatório em que toda afirmação tem uma fonte verificável. O analista passa a revisar e aprofundar, em vez de começar do zero. Nordeste, aqui, é a região Nordeste do Brasil: sol forte, programas estaduais e regras federais de geração distribuída que mudam o retorno de um telhado solar.

Isso não é um luxo de redação. Em Mata v. Avianca (2023), advogados nos Estados Unidos protocolaram uma petição com jurisprudência inventada pelo ChatGPT. O tribunal descobriu, e o episódio virou aula de citação falsa. Um relatório de mercado com fonte que não diz o que o texto afirma é o mesmo defeito, vendido por hora.

O que este cenário mede: afirmações com fonte válida, tempo por relatório e custo por relatório.

Versão 1

A equipe de inovação montou a primeira versão com um framework de agentes e cinco papéis. A configuração parecia uma equipe humana:

agents:
  - role: Pesquisador
    tools: [web_search, fetch_page]
  - role: Analista
  - role: Redator
  - role: Revisor
  - role: Editor
flow: sequential
flowchart LR
  Q(["1. Pergunta"]):::io --> P(["2. Pesquisador"]):::llm
  P --> W["Busca web"]:::untrusted
  W --> P
  P --> A(["3. Analista"]):::llm
  A --> R(["4. Redator"]):::llm
  R --> V(["5. Revisor"]):::llm
  V --> E(["6. Editor"]):::llm
  E --> OUT(["7. Relatório"]):::io
  1. A pergunta chega.
  2. O pesquisador faz buscas em sequência e escreve um resumo com tudo que leu.
  3. a 6. Analista, redator, revisor e editor reescrevem o texto em fila, cada um lendo o anterior.
  4. O relatório sai.

Na demo, a pergunta era estreita (“qual a alíquota do ICMS na Bahia para GD?”). O pesquisador achou uma página, os outros quatro reescreveram, o relatório saiu em poucos minutos e soou profissional. Ninguém mediu uma pergunta ampla, ninguém conferiu se as URLs abriam, ninguém pôs teto de custo.

O guia “Building effective agents”, da Anthropic (dezembro de 2024), recomenda começar pelo fluxo mais simples que resolve a tarefa e só acrescentar agentes quando há um motivo técnico. Cinco cargos na fila é o contrário disso.

O que quebrou

Semana 1. Um relatório levava 25 minutos. O pesquisador fazia uma busca, lia, fazia outra, lia. Nada rodava em paralelo. “Tamanho de mercado” e “regulação da ANEEL” não dependem um do outro. A fila indiana somava as latências.

Semana 2. O custo por relatório era várias vezes o esperado. O trace mostrou que analista, redator e revisor reliam o texto inteiro e devolviam versões quase iguais. Remover três dos cinco agentes não mudou a qualidade no eval. O editor respondia “aprovado”. Você estava pagando quatro reescritas para um único trabalho de busca.

Semana 3. O pesquisador acumulava dezenas de páginas no mesmo contexto. Quando o redator recebia o resumo, fatos de fontes diferentes estavam misturados, e citações apontavam para a fonte errada. Uma frase sobre a Lei 14.300/2022 (marco legal da geração distribuída no Brasil) saía ligada a um post de blog de 2020. O analista júnior teria aberto os dois links. O sistema não abriu nenhum.

Semana 4. Uma pergunta ampla (“e o hidrogênio verde no mundo?”) fez o pesquisador buscar por mais de uma hora. Não havia limite de passos nem de custo. A pesquisa custou mais que o valor cobrado pelo relatório. O cliente recebeu um rascunho incompleto, e a fatura do provedor chegou inteira.

Os quatro incidentes não pedem um modelo melhor. Pedem menos agentes, mais estrutura e um teto.

Checagem +20 XP de primeiraO trace mostra cinco agentes em fila. Só o primeiro tem ferramenta de busca. Os outros quatro devolvem o texto com outras palavras. Remover três deles não muda o eval. Qual é o diagnóstico e o primeiro corte?

Smells encontrados

Multi-Agente Decorativo

Cinco cargos, três deles só reescrevendo. O YAML da versão 1 é o trecho que mostra o smell: papéis de empresa, fluxo sempre sequencial, ferramentas só no primeiro. Causou a semana 2.

Fila Indiana de Chamadas

Buscas independentes em sequência. O pesquisador só começava “concorrentes” depois de terminar “mercado”. Causou a semana 1. Paralelismo aqui não é otimização precoce: as subperguntas já eram independentes no briefing do cliente.

Rascunho Compartilhado

Todas as fontes no mesmo texto, sem estrutura. O pesquisador escrevia um resumo em prosa. O redator citava de memória do resumo. Causou as citações erradas da semana 3. Quem mistura páginas num parágrafo único perde o dono de cada frase.

Custo Sem Teto

Nenhum limite por pesquisa. Causou a semana 4. Um relatório tem preço. Uma execução sem teto não é “completa”: é um loop que o cartão para.

Refatorações aplicadas

1. Adicionar Orçamento ao Loop

Primeiro o teto: passos, tempo e custo por relatório, compartilhados entre todos os agentes. No limite, o relatório sai marcado como parcial, com as lacunas listadas. Parar com exceção muda deixa o analista sem texto e o financeiro sem teto.

O orçamento é um só para a árvore. Teto de 20 passos por subagente, com três subagentes que disparam outros três, não é teto. É o smell vizinho de subagentes em cascata.

2. Fundir Agentes

Analista, revisor e editor saíram. Ficou um orquestrador que planeja e escreve, e a revisão de fontes virou checagem em código. Quem não tem ferramenta e só reescreve prosa não justifica uma chamada.

3. Extrair Subagente

Cada subpergunta é investigada por um subagente com contexto próprio, que devolve afirmações estruturadas com a fonte de cada uma. As páginas lidas ficam com ele. O orquestrador não recebe HTML. Recebe linhas no quadro: afirmação, URL, trecho, data de acesso.

Isso é isolamento de contexto, não “mais um cargo”. O motivo técnico é a janela: dezenas de páginas no mesmo histórico misturam fontes e empurram o trecho certo para o meio, de novo o efeito de Liu et al. (2023).

4. Paralelizar Etapas Independentes

Os subagentes rodam ao mesmo tempo. Mercado, concorrentes e regulação não esperam um ao outro. O tempo do relatório deixa de ser a soma das leituras e passa a ser a mais lenta, mais o plano e a escrita.

Checagem +20 XP de primeiraO pesquisador cola 40 páginas num único resumo e o redator cita a Lei 14.300 apontando para um blog de 2020. Qual mudança ataca a mistura de fontes?

Arquitetura final

flowchart TD
  Q(["1. Pergunta"]):::io --> O(["2. Orquestrador planeja"]):::llm
  O --> S1(["3. Subagente: mercado"]):::llm
  O --> S2(["3. Subagente: concorrentes"]):::llm
  O --> S3(["3. Subagente: regulação"]):::llm
  S1 --> B[("4. Quadro de afirmações com fonte")]:::store
  S2 --> B
  S3 --> B
  B --> C["5. Checar citações"]:::tool
  C --> O2{"6. Lacunas e orçamento?"}
  O2 -->|"lacuna, há orçamento"| O
  O2 -->|"pronto ou limite"| W(["7. Escrever relatório"]):::llm
  W --> OUT(["8. Relatório citado"]):::io
  1. A pergunta chega com um orçamento de passos, tempo e custo.
  2. O orquestrador divide a pergunta em subperguntas e define o que conta como resposta suficiente. É Planejar e Executar mais Orquestrador e Trabalhadores: o plano depende da pergunta, não de cinco cargos fixos.
  3. Subagentes pesquisam em paralelo, cada um num contexto próprio, com busca e leitura de páginas. Conteúdo da web entra como não confiável: a página pode pedir no HTML que o agente ignore o briefing.
  4. Cada subagente grava afirmações estruturadas (texto curto, fonte, trecho que sustenta) num quadro compartilhado. O quadro tem schema e dono por linha. Não é um bloco de notas em prosa.
  5. O código confere se o trecho citado existe na página e se a afirmação está nele, com uma checagem automática.
  6. O orquestrador vê o quadro, decide se faltam pontos e se ainda há orçamento. Condições de Parada são três: suficiente, limite atingido, lacuna declarada.
  7. O relatório é escrito a partir das afirmações conferidas, não das páginas. O escritor não visita a web.
  8. O relatório sai com cada afirmação ligada à fonte, e marcado como parcial se parou no limite.

Quando o modelo de relatório é estável (sempre mercado, concorrentes, regulação, riscos), Seccionamento fixa as seções e as roda em paralelo sem o orquestrador decidir a divisão. Quando a pergunta muda a forma (“compare três editais da ANEEL”), o orquestrador monta o plano. Os dois padrões convivem: seções fixas para o produto recorrente, plano livre para o briefing atípico.

Map-Reduce aparece quando uma única fonte é enorme: um relatório da EPE de 200 páginas, lido por capítulos, cada capítulo devolvendo afirmações, o reduce juntando sem duplicar. Isso é varrer um documento. Não substitui subagentes em temas diferentes.

Exemplo trabalhado: solar residencial no Nordeste

A pergunta chega: “como está o mercado de energia solar residencial no Nordeste?”. O orçamento do job é um teto de passos, um teto de minutos e um teto de dinheiro, definidos pelo preço que a consultoria cobra daquele tipo de relatório. Os valores exatos ficam no código de referência, não nesta página.

O orquestrador devolve um plano, não um rascunho:

{
  "suficiente_quando": [
    "marco legal federal identificado com fonte primária",
    "pelo menos uma regra da ANEEL citada com trecho",
    "dois concorrentes ou programas estaduais com fonte",
    "uma tendência recente com data"
  ],
  "subperguntas": [
    "Qual o marco legal da geração distribuída no Brasil?",
    "O que a ANEEL define hoje para micro e minigeração?",
    "Quais programas ou restrições aparecem em estados do Nordeste?",
    "Quem são os players visíveis no residencial?"
  ]
}

Três subagentes sobem em paralelo. O de regulação busca “Lei 14.300 geração distribuída” e abre o texto em Planalto, não um resumo em blog. Ele grava:

{
  "id": "c-014",
  "afirmacao": "A Lei 14.300/2022 instituiu o marco legal da microgeração e minigeração distribuída no Brasil.",
  "url": "https://www.planalto.gov.br/ccivil_03/_ato2019-2022/2022/lei/l14300.htm",
  "trecho": "Institui o marco legal da microgeração e minigeração distribuída",
  "acessado_em": "2026-10-02",
  "subagente": "regulacao"
}

A Lei 14.300/2022 existe e o trecho acima está no ementa oficial. É o tipo de afirmação que o sistema deve preferir: fonte primária, trecho curto, data de acesso. O que o sistema não faz é inventar gigawatts instalados no Ceará ou um market share. Se a fonte com número não passou na checagem, o número não entra no relatório.

O verificador baixa a URL (ou usa o HTML que o subagente já guardou), procura o trecho como substring, e recusa a linha se não achar. Parafrase longa demais falha de propósito: o subagente precisa copiar um pedaço que dá para conferir.

O orquestrador olha o quadro. Falta “tendência recente com data”. Ainda há orçamento: ele dispara um quarto subagente só nisso. Se o teto estourar antes, o relatório sai parcial, com a lacuna explícita. O analista júnior vê o buraco. Ele não recebe um parágrafo fluido que esconde a ausência.

A escrita final só vê linhas com status: conferido. HTML da web não entra nesse contexto. Injeção indireta na página de um concorrente pode tentar mandar o subagente “ignorar o briefing”. O subagente não tem ferramenta de enviar email nem de alterar o relatório final. Ele só grava linhas no quadro, e o quadro só aceita o schema.

Como a citação é conferida

flowchart LR
  L[("1. Linha do quadro")]:::store --> D["2. Baixar URL"]:::untrusted
  D --> V{"3. Trecho na página?"}
  V -->|não| X["4. Recusar linha"]:::tool
  V -->|sim| K["4. Marcar conferido"]:::tool
  K --> W(["5. Escritor lê só conferidas"]):::llm
  1. A linha chega com URL e trecho literal.
  2. O fetch é dado não confiável: a página pode ter mudado ou ser hostil.
  3. Substring, em código. Não é um modelo dizendo “parece verdadeiro”.
  4. Falhou: a linha não alimenta o relatório. Passou: status conferido.
  5. O escritor nunca vê página. Vê afirmações já ancoradas.

Essa checagem é o antídoto de Mata v. Avianca. O modelo é bom em produzir texto que parece jurisprudência, paper ou nota da ANEEL. Abrir a URL é barato perto do prejuízo de um cliente que decide com número fantasma.

Armadilhas comuns

  • Organograma de agentes. Pesquisador, analista, redator, revisor, editor. Se só um tem ferramenta, você comprou reescrita cara. O post da Anthropic (dez. 2024) é direto: complexidade se justifica com ganho medido.
  • Resumo único com todas as páginas. É rascunho compartilhado. A citação escorrega. Afirmação estruturada é o contrato.
  • Pesquisa sem teto. “Até ficar bom” não é condição de parada. Bom precisa de critério no plano, e o cartão precisa de limite.
  • Juiz LLM no lugar do fetch. Um segundo modelo que dá nota à citação reproduz a fluência da invenção. A prova é o trecho na página.
  • Subagente que devolve prosa. Se a saída não cabe num schema, o quadro vira de novo um bloco de notas, e a semana 3 volta.
  • Paralelizar o que tem dependência. Não peça “compare com o número da seção 2” antes da seção 2 existir. Paralelismo é para subperguntas independentes.

O eval que segura as refatorações

O conjunto de perguntas tem briefing real anonimizado e, para cada um, uma lista de afirmações que um analista marcou como obrigatórias, com a URL que ele mesmo abriu. O eval não pede o relatório “bonito”. Pede: cada afirmação obrigatória apareceu com fonte que passa no verificador? O relatório saiu dentro do teto de tempo e de custo? As recusas (lacunas) estão declaradas, e não escondidas em prosa segura?

Um caso do eval tem esta cara:

{
  "id": "solar-ne-014",
  "pergunta": "Como está o mercado de energia solar residencial no Nordeste?",
  "obrigatorias": [
    {
      "tema": "marco legal GD",
      "fonte_tipo": "lei",
      "exemplo_aceitavel": "planalto.gov.br ... lei/l14300"
    }
  ],
  "proibidas": ["afirmação numérica sem URL conferida"]
}

A versão 1 foi medida nesse conjunto antes das fusões. Sem isso, “remover três agentes” seria opinião. Com isso, foi o eval da semana 2.

Checagem +20 XP de primeiraUma pergunta ampla está em 40 minutos de busca, ainda sem teto, e o cliente cobra o relatório hoje. Qual é a peça que faltava na versão 1?

Números

As métricas deste cenário são afirmações com fonte válida, tempo por relatório e custo por relatório, comparando a versão 1 com a arquitetura final num conjunto de perguntas de pesquisa com revisão humana das fontes.

As três se puxam. Tempo mínimo com um só agente sequencial reproduz a semana 1. Custo mínimo sem busca reproduz Mata v. Avianca: texto fluido, fonte nenhuma. Fonte válida em 100% das linhas, sem teto, reproduz a semana 4.

A leitura certa é: das afirmações que saíram no relatório, quantas passaram no verificador de trecho; quanto tempo até o PDF; quanto a execução custou em relação ao preço cobrado. Relatório parcial com lacuna declarada conta como parada correta, não como falha de qualidade.

Os números ainda não foram publicados. Eles virão do código de referência executável, rodando as duas versões contra as mesmas perguntas, e esta seção será atualizada com o resultado e o script que gera os números. Até lá, nenhum número aparece aqui.

Padrões usados

Padrão Papel no sistema
Planejar e Executar O orquestrador define subperguntas antes de pesquisar
Orquestrador e Trabalhadores A divisão depende da pergunta
Delegação a Subagentes Cada subpergunta num subagente
Isolamento de Contexto As páginas lidas ficam com o subagente
Seccionamento Subperguntas fixas do modelo de relatório rodam em paralelo
Quadro compartilhado Afirmações estruturadas com dono e fonte
Ancoragem com citação Toda afirmação conferida contra o trecho citado
Condições de Parada Suficiente, limite ou lacuna declarada
Orçamento de custo Teto por relatório compartilhado entre agentes
Map-Reduce Documento longo lido por partes, depois juntado
RAG agêntico O subagente decide a próxima busca a partir do que leu

A lista completa de padrões ligados a este cenário está em Relações, abaixo.

Código de referência

O sistema completo, com as duas versões, as perguntas do eval e o script que gera os números desta página, fica no repositório de código de referência do ai-guru, em scenarios/deep-research/. O repositório está sendo preparado, e o link entra aqui quando for publicado.

Lições

  1. Divida por contexto, não por cargo. Os subagentes que ficaram têm motivo técnico: cada um isola a leitura de uma subpergunta. Analista e revisor na fila não isolavam nada.
  2. Afirmação estruturada é melhor que resumo. Gravar “afirmação, fonte, trecho” acabou com a mistura de fontes. O relatório passou a ser um reduce de linhas conferidas.
  3. Conferir a citação em código muda o jogo. O relatório deixou de ter fontes que não dizem o que o texto afirma. Mata v. Avianca é o que acontece quando a conferência é “parece verdadeiro”.
  4. Teto de custo é requisito de produto. Uma pesquisa precisa caber no preço do relatório. Sem teto, a execução mais cara ganha da venda.
  5. Paralelismo é onde o tempo cai. As subperguntas eram independentes desde o começo; só faltava rodar ao mesmo tempo. Fila de reescritores não é paralelismo.

Teste seu entendimento

Checagem +20 XP de primeiraO time quer acelerar o relatório colocando redator, revisor e editor em paralelo sobre o mesmo rascunho. O que acontece?

Checagem +20 XP de primeiraUm subagente devolve uma afirmação numérica sobre capacidade instalada no Ceará, com URL de um infográfico em JavaScript. O verificador não acha o trecho no HTML. O que o sistema faz?

Checagem +20 XP de primeiraO modelo de relatório da consultoria é sempre o mesmo: mercado, concorrentes, regulação, riscos. Quando você usa seccionamento fixo em vez de deixar o orquestrador inventar a divisão a cada briefing?

Perguntas rápidas

O que é Pesquisa profunda com citações?

Pesquisa profunda com citações (Deep research with citations) é um estudo de caso real de sistema com LLM, do grupo Dados e documentos. Investigar uma pergunta aberta em dezenas de fontes e entregar um relatório citado.

Quais padrões de IA o cenário Pesquisa profunda com citações usa?

Seccionamento, Orquestrador e Trabalhadores, Map-Reduce de Documentos, Reordenação, RAG Agêntico, Isolamento de Contexto, Ancoragem com Citação, Quadro Compartilhado, Planejar e Executar, Delegação a Subagentes, Condições de Parada e Orçamento de Custo.

Para ir além

Relações

Buscar