O que vamos construir
A implementação de referência é um pequeno projeto Python com algumas partes claras:| Parte | O que faz |
|---|---|
| CLI | Aceita um tópico de pesquisa, modelo, provedores, configurações de profundidade, caminho de saída e diretório de artefatos |
| Cliente Venice | Chama chat completions, streaming chat completions e POST /augment/scrape |
| Camada de busca | Pesquisa no DuckDuckGo por padrão, com descoberta opcional de papers do arXiv |
| Modelos de dados | Rastreia URLs de origem, URLs canônicas, chunks, evidências, notas, erros e relatórios |
| Agente de pesquisa | Planeja buscas, lê fontes, extrai evidências, analisa lacunas, gera queries de follow-up e escreve o relatório final |
| Escritor de artefatos | Armazena registros JSONL auditáveis para queries, lacunas de pesquisa, resultados, fetches, chunks, notas de origem, rascunhos de relatório, erros e relatórios |
- Pedir à Venice para gerar queries de busca diversas para o tópico.
- Pesquisar na web com um ou mais provedores.
- Deduplicar URLs antes de lê-las.
- Usar o endpoint de scrape da Venice para transformar cada página de origem pública em Markdown.
- Dividir páginas longas em chunks.
- Pedir à Venice para extrair evidências de cada chunk.
- Pedir à Venice para transformar evidências de chunks em notas de origem.
- Identificar lacunas de pesquisa e problemas de equilíbrio de origens antes de gerar queries de follow-up.
- Pedir à Venice para sintetizar o relatório final com citações no estilo de notas de rodapé.
Configurando o projeto
O projeto de referência usa Python 3.13 euv, mas o mesmo código funciona com um ambiente virtual normal também.
Crie um novo projeto:
pip, crie um ambiente virtual e instale os mesmos pacotes:
.env para desenvolvimento local:
VENICE_MODEL para que você possa alterar o modelo sem editar código. A implementação de referência atualmente usa openai-gpt-55 como padrão, mas você pode trocá-lo por outro modelo de chat disponível na sua conta Venice.
Criando os modelos de dados
Antes de escrever a lógica do agente, definiremos os objetos que se movem pelo pipeline. Esses modelos mantêm o resto do código mais fácil de raciocinar porque cada fonte carrega proveniência: de onde veio, qual query a encontrou, quando foi recuperada e como foi dividida em chunks. Crieresearch_agent/models.py:
canonical_url, content_hash e chunks.
canonical_url permite ao agente evitar ler a mesma fonte repetidamente quando os resultados de busca diferem apenas por parâmetros de tracking ou fragmentos. content_hash ajuda a capturar páginas duplicadas mesmo quando vivem em URLs diferentes. chunks nos permite sumarizar páginas longas em pedaços menores em vez de perder evidência útil para limites de contexto.
Adicione as funções helper abaixo das dataclasses:
Construindo o cliente Venice
A seguir, criaremos um pequeno cliente Venice. Você poderia usar o SDK Python da OpenAI para chat completions porque a Venice é compatível com OpenAI, mas a implementação de referência usahttpx diretamente para que o mesmo cliente possa chamar o endpoint POST /augment/scrape da Venice.
Crie research_agent/venice.py:
from_env() mantém os segredos fora do seu código-fonte. Também torna o desenvolvimento local conveniente, porque python-dotenv pode carregar VENICE_API_KEY e VENICE_MODEL do .env.
Agora adicione chat completions:
_post_chat_stream() que lê server-sent events de chat completions em streaming. Você pode começar sem streaming e adicioná-lo quando o restante do fluxo de pesquisa funcionar.
Adicionando provedores de busca
A camada de busca tem dois trabalhos: encontrar URLs de origem e buscar essas URLs através do scraper da Venice. A implementação de referência usa o endpoint HTML do DuckDuckGo para busca geral na web e a API Atom do arXiv para papers. Crieresearch_agent/web.py:
WebSearch coordena provedores e busca páginas:
Escrevendo artefatos locais
Para workflows de pesquisa, a auditabilidade importa. Se o relatório final disser algo surpreendente, você deve ser capaz de inspecionar qual fonte levou a isso. Crieresearch_agent/artifacts.py:
Construindo o agente de pesquisa
Agora que temos Venice, busca, modelos e artefatos, podemos construir o agente em si. Crieresearch_agent/agent.py:
models.py se você ainda não as adicionou:
ResearchAgent:
run() coordena os passos de pesquisa:
seen_* são o que impedem o agente de desperdiçar tempo em fontes duplicadas. Dedup de URL captura links repetidos. Dedup por hash de conteúdo captura espelhos, posts sindicalizados e páginas que redirecionam para o mesmo conteúdo final.
Planejando buscas iniciais e de follow-up
A primeira chamada de modelo transforma o tópico em queries de busca:_gap_follow_up_queries(), que pede à Venice para retornar registros de lacunas e queries:
--artifacts está habilitado, esses registros são escritos em research_gaps.jsonl. Isso te dá uma trilha de auditoria útil para entender por que o agente buscou uma query de segundo passo em particular.
O parser deve ser tolerante. Se o modelo retornar JSON malformado, o agente volta ao tópico original:
Lendo e sumarizando fontes
Agora coletamos notas de origem. O agente busca cada query, busca cada resultado através do scrape da Venice, divide o Markdown em chunks e sumariza a evidência útil.Escrevendo o relatório final
Quando o agente tem notas de origem, ele pode escrever o relatório. Comece com um escritor de relatório de uma passada:Adicionando o CLI
Agora precisamos de um ponto de entrada de linha de comando. Criemain.py:
| Opção | O que controla |
|---|---|
--iterations | Número de passos de pesquisa |
--queries | Queries de busca geradas por passo |
--results | Resultados lidos por provedor para cada query |
--providers | Provedores de busca, como duckduckgo ou duckduckgo,arxiv |
--max-sources | Máximo de fontes utilizáveis a coletar |
--chunk-chars | Tamanho aproximado do chunk antes da extração de evidência de origem |
--max-chunks-per-source | Número de chunks sumarizados por fonte |
--report-style | Profundidade do relatório final: brief, standard ou deep |
--artifacts | Diretório para registros JSONL de auditoria |
--output | Caminho para o relatório Markdown final |
Executando o agente
Execute um passo de pesquisa rápido:brief para um briefing conciso baseado em fontes, standard para uma pesquisa mais completa e deep para o fluxo em estágios outline/section/editor.
Salve artefatos auditáveis:
source_notes.jsonl mostra a evidência de origem sumarizada, research_gaps.jsonl mostra por que buscas de follow-up foram geradas e errors.jsonl mostra páginas que falharam durante busca, scraping ou sumarização.
Notas de privacidade e confiabilidade
Um agente de pesquisa toca vários sistemas, então ajuda ser preciso sobre o que vai para onde:| Camada | O que vê os dados |
|---|---|
| CLI local | Tópico, configuração, notas de origem, artefatos e relatórios finais permanecem na sua máquina |
| Provedor de busca | Queries de busca são enviadas ao provedor que você escolher, como DuckDuckGo ou arXiv |
| Scrape da Venice | URLs de origem pública são enviadas ao endpoint de scrape da Venice |
| Chat completions da Venice | Prompts, chunks de origem, notas de origem e instruções de geração de relatório são enviadas à Venice |
| Arquivos de saída | Relatórios Markdown e artefatos JSONL são escritos localmente |
POST /augment/search da Venice em vez de consultar o DuckDuckGo diretamente. A implementação de referência usa provedores públicos leves para que a demo permaneça fácil de executar e entender.
Para confiabilidade, mantenha esses padrões conservadores:
- Use retries para chamadas Venice e requisições web.
- Adicione um pequeno
--request-delayse estiver lendo muitas páginas do mesmo host. - Limite
--max-sourcespara que tópicos amplos não rodem indefinidamente. - Salve
--artifactspara relatórios importantes para poder auditar a saída final. - Trate o relatório como um briefing, não como verdade absoluta. Siga as citações até a fonte original quando a precisão importar.
Testando as peças
Você não precisa de requisições web reais ou chamadas Venice para testar a maior parte do sistema. O repo de referência usa classes Venice e web falsas para testar o loop de pesquisa, comportamento de dedup, artefatos e prompts de relatório. Um primeiro teste útil é a canonização de URL:Benchmarking
Muitos provedores de IA agora têm seus próprios fluxos de pesquisa profunda, então o repo de referência inclui um benchmark simples contra a ferramenta Deep Research da Perplexity. Ambos os agentes foram solicitados a escrever um relatório sobre arquitetura de framework de agente de IA, e depois os relatórios gerados foram comitados no repositório do GitHub. Isso não pretende ser um benchmark formal. É uma maneira prática de inspecionar estrutura de relatório, cobertura de fontes, qualidade de citação e se o agente foca demais em um cluster de origem. Por isso também a implementação atualizada rastreiaresearch_gaps.jsonl e o equilíbrio de origens antes das buscas de follow-up.
Estendendo este exemplo
Quando o agente baseline funcionar, aqui estão maneiras práticas de melhorá-lo:- Adicionar um provedor de busca Venice usando
POST /augment/search. - Armazenar relatórios e artefatos em um pequeno banco SQLite em vez de arquivos JSONL.
- Adicionar allowlists ou blocklists de origem para domínios de pesquisa confiáveis.
- Adicionar suporte a PDF combinando scrape da Venice com parsing de documento para fontes que não expõem HTML limpo.
- Adicionar um conjunto de avaliação de tópicos e tipos de fonte esperados para comparar a qualidade da pesquisa após mudanças de prompt.
- Adicionar um passo de revisão que peça à Venice para encontrar alegações sem suporte no relatório final antes de salvá-lo.