O que vamos construir
A implementação de referência é um pequeno projeto Python com algumas partes claras:
O fluxo se parece com isto:
- 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:
Agora conecte tudo:
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:
Se você quiser manter mais do caminho de busca dentro da Venice, pode adaptar a camada de provedor para chamar o endpoint
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.