Um fork experimental do YaCy: ranking melhor, resultados assinados, peers atrás de NAT
Um fork do YaCy que corrige fraquezas medidas na rede pública, adiciona uma camada de confiança para que resultados forjados e spam possam ser filtrados, e permite que peers atrás de um NAT participem por meio de um relay. Cada afirmação desta página foi medida em redes peer-to-peer fechadas que qualquer pessoa pode reconstruir com docker compose.
Status: experimento. Isto não é uma versão lançada pelo projeto YaCy e não tem afiliação com ele. Quebra deliberadamente a compatibilidade com a rede pública do YaCy (ids de peer, seeds, hashes de palavras CJK). É compartilhado para mostrar, com dados, o que as mudanças fazem, para que as ideias possam ser discutidas e, onde fizerem sentido, propostas upstream em partes pequenas.
Por quê
Medido na rede pública do YaCy (freeworld) com 16 consultas, apenas 11% dos 10 primeiros resultados continham todos os termos da consulta. Investigando as causas:
- Consultas com vários termos eram enviadas ao Solr com correspondência mínima 1 (uma consulta OR), tanto ao índice próprio quanto a cada peer remoto.
- As pontuações do Solr de cada peer são normalizadas pelo seu melhor resultado, então um peer que só tem correspondências de um termo coloca a melhor delas no mesmo nível das correspondências exatas de outros peers.
- Texto em japonês e chinês só é dividido em espaços e pontuação, então uma frase inteira vira uma única "palavra" e o índice de palavras (RWI) não consegue encontrá-la.
- Em uma rede de peers novos, peers com menos de 3 dias nunca são consultados em uma busca no índice de palavras, e definições de rede pequenas não enviam consultas Solr remotas a ninguém.
- Os resultados não trazem nenhuma prova de origem. Um peer pode devolver qualquer URL com qualquer título para qualquer consulta, e seeds podem ser reenviados ou alterados por terceiros.
- Peers atrás de um NAT só podem ser "junior": não são alcançáveis, então o que eles indexam é invisível para os outros.
O que mudou
Ranking
Correspondência mínima mais rigorosa, ponderação por cobertura de termos após a normalização por peer, um peso contra páginas rasas e busca em todos os peers de redes pequenas.
CJK
Texto em chinês, japonês e coreano é indexado e buscado como bigramas sobrepostos, no Solr e no índice de palavras.
Confiança
Chaves de peer Ed25519, seeds assinados, listas de confiança assinadas por coordenadores com tags declaradas, e uma assinatura de autor em cada documento que o peer rastreia.
Travessia de NAT
Um pequeno sidecar go-libp2p reserva um slot em um circuit relay, para que peers atrás de um NAT respondam buscas.
Qualidade da busca
| Sintoma | Causa | Mudança |
|---|---|---|
| Páginas que correspondem a um só termo (keyword stuffing) ficam no topo | Solr mm=1 para consultas com vários termos | Correspondência mínima 2<-1 5<80%: com dois termos, ambos precisam corresponder; com 3–5 termos, pode faltar um (search.ranking.solr.mm, .mm.cjk) |
| A melhor correspondência parcial de um peer é classificada como as correspondências exatas de outros peers | Normalização da pontuação por peer | Multiplicar a pontuação normalizada por (termos encontrados / termos da consulta)², no mínimo 0.05, e nunca abaixo do que a correspondência mínima garante (search.ranking.coverage.exponent) |
| Japonês / chinês não são encontrados no índice de palavras | Não há segmentação de palavras para CJK | Bigramas sobrepostos no índice de palavras e na consulta; CJKWidthFilter + CJKBigramFilter no schema do Solr |
| Páginas rasas com a consulta inteira no título (listas de tags) ficam no topo | O qf padrão pondera title^5 e h1^5 (e host ^6, nome de arquivo da URL ^4, caminho ^3) contra text^1 | Resultados com menos de 100 palavras são ponderados por palavras / 100, no mínimo 0.1 (search.ranking.thin.words); contagem de palavras CJK corrigida (contava espaços) |
| Uma rede de peers novos nunca busca nos índices de palavras de outros peers | A busca DHT precisa de peers com mais de 3 dias | Configurável (remotesearch.dht.minage, padrão 3) |
| Redes pequenas não enviam consultas Solr remotas a ninguém, ou ignoram os alvos DHT | A fórmula do número de alvos dá 0; os alvos DHT eram excluídos do Solr | Redes de até 32 peers consultam cada peer confiável conectado (cada peer no modo aberto), alvos DHT incluídos |
Camada de confiança
- Identidade do peer. Cada peer tem uma chave Ed25519. Seu hash de peer de 12 caracteres é derivado da chave pública, e o núcleo do seu seed (nome, portas, chave, alcançabilidade, tags declaradas) é assinado. Seeds sem assinatura são rejeitados por padrão. Um desafio hello prova que o dono da chave responde em um endereço.
- Listas de confiança. Os usuários configuram chaves de coordenador. Um coordenador delega a operadores, e os operadores assinam listas de peers confiáveis com uma prioridade e tags declaradas como
adsouproxy:<engine>. As listas são versionadas em vez de expirarem e se propagam de peer para peer. - Assinaturas de autor. O peer que rastreia uma página assina sua URL, seu título e um filtro de Bloom das suas palavras. Por padrão, um resultado só é exibido se sua assinatura for válida e seu autor estiver no conjunto de confiança (exceções: documentos sem assinatura no índice próprio do peer que não vieram pela DHT contam como seus, e resultados de mecanismos de busca externos são marcados como "externos"). Um peer que armazena um documento para a DHT não pode forjá-lo. Só pode retê-lo.
- Modo aberto. Resultados sem assinatura ou não confiáveis podem ser exibidos, marcados como "não verificados" e sempre classificados abaixo dos verificados. Resultados com assinatura forjada nunca são exibidos.
Travessia de NAT
Um processo sidecar (Go, go-libp2p) roda ao lado do YaCy com a mesma chave. Atrás de um NAT, ele reserva um slot em um circuit relay v2 e anuncia o endereço do circuito no seed assinado (Reach=relay). Os outros peers abrem uma porta de túnel local até ele e usam HTTP comum, então os clientes existentes do YaCy funcionam sem alterações. Por padrão, esses peers só respondem buscas. Eles não armazenam dados da DHT, a menos que optem por isso.
Os detalhes estão no design de confiança e NAT (em inglês).
Resultados
Dois experimentos no yacy-lab. Ambos rodam redes fechadas em docker compose, com um corpus e um conjunto de consultas determinísticos.
Qualidade da busca: upstream vs fork, 3 peers cada
Cada peer rastreia um site. As consultas vão para o peer 1 com resource=global, e a maioria das páginas relevantes está nos outros peers. O corpus contém dois tipos de iscas: páginas recheadas com um termo da consulta e páginas rasas de "arquivo de tags" com a consulta inteira no título. Média de 11 consultas (6 em inglês, 4 em japonês, 1 em chinês), 2 execuções com o mesmo resultado, exceto onde indicado.
| Cluster / caminho | R-precision ↑ | Recall@10 ↑ | Iscas no top R ↓ | Todos os termos no top 10 ↑ |
|---|---|---|---|---|
| upstream, padrão | 0.52 | 0.96 | 0.48 | 0.42 |
| fork, padrão | 0.79–0.86 | 1.00 | 0.14–0.21 | 0.75 |
| upstream, só índice de palavras | 0.02 | 0.02 | 0.00 | 0.09 |
| fork, só índice de palavras | 0.93 | 0.95 | 0.07 | 0.77 |
- Páginas com keyword stuffing no top 5 (soma das 11 consultas): upstream 14, fork 0.
- As páginas rasas de arquivo de tags descem, mas continuam no top 5. Sua posição média é 4.5 na busca padrão e 5.0 só com o índice de palavras. Só com o Solr, vai de 2.0 sem a ponderação de páginas rasas para 3.1 com ela. Elas ainda ficam acima de páginas relevantes que não têm os termos da consulta no título. Uma ponderação mais forte as empurraria mais para baixo, mas também rebaixaria páginas curtas legítimas, então o padrão foi mantido suave.
- O upstream não consegue usar os índices de palavras de outros peers em uma rede de peers novos, e ali não consegue encontrar palavras em japonês ou chinês de forma alguma.
- O padrão da correspondência mínima foi escolhido com este corpus. Se ele é adequado para a rede pública ainda precisa ser medido lá.
Confiança e NAT: 6 peers do fork, um relay e um NAT
Três peers confiáveis, um peer confiável que declara ads, um peer assinado mas não confiável que rastreia spam e planta documentos com uma assinatura emprestada, e um peer atrás de um roteador MASQUERADE. Todas as 26 verificações passam, entre elas:
- Os ids de peer são derivados das chaves. O spam do peer não confiável não é exibido por padrão, nem mesmo quando um peer confiável guarda uma cópia.
- No modo aberto, o spam aparece marcado como não verificado e abaixo de todos os resultados verificados. O documento com assinatura emprestada nunca aparece.
- Os resultados do peer
adstrazem a tag, eexcludeTags=adsos remove. - O peer atrás do NAT não pode ser alcançado diretamente, mas suas páginas são encontradas pelo relay, e ele continua conectado.
- Uma nova versão da lista se propaga apenas pela troca entre peers. Revogar um operador remove os resultados dos seus peers.
Experimente
Sem Docker: abra a demo no navegador. Ela roda em modo simulado, reproduzindo respostas gravadas da demo real (a página está em japonês).
A demo sobe as duas redes (3 peers upstream, e a configuração de confiança e NAT do fork) em uma única máquina e coloca uma página de busca na frente delas. Você precisa de Docker com cerca de 7 GB de memória.
git clone https://github.com/pad01g/yacy_search_server.git yacy
git clone https://github.com/pad01g/yacy-lab.git
cd yacy
git checkout baseline && docker build -t yacy-lab/upstream:baseline -f docker/Dockerfile .
git checkout improved-search && docker build -t yacy-lab/fork:latest -f docker/Dockerfile .
docker build -t yacy-lab/sidecar:latest sidecar/
cd ../yacy-lab
docker compose -f compose.demo.yaml -p yacydemo up -d
# abra http://localhost:8800 (a preparação leva cerca de 10 minutos e mostra o progresso)
A página também permite mudar a confiança: escolher em quais coordenadores o peer que busca confia (um segundo coordenador lista apenas o peer de spam, então confiar nele torna o spam "verificado"), editar e assinar de novo a lista de confiança, entregar a nova versão a um peer e ver como ela se propaga, e revogar ou restaurar a delegação do operador.
Os experimentos em si: docker compose -p yacylab up -d && docker compose -p yacylab run --rm runner (qualidade da busca) e docker compose -f compose.trust.yaml -p yacytrust up -d && docker compose -f compose.trust.yaml -p yacytrust run --rm runner (confiança e NAT). Veja o README do laboratório.
Participar: sem pedir permissão
Qualquer um, pessoa ou agente, pode rodar um peer, conectá-lo com a URL de um membro (p2p.bootstrap.peers, também por uma rede Tailscale), indexar e assinar suas próprias páginas e serviços, e ter seu próprio coordenador ou operador: um coordenador é só uma chave e um arquivo assinado em qualquer URL, sem servidor. Anúncios declarados (tag ads) são permitidos; os usuários escolhem em quais listas confiam. Como participar · pull requests são bem-vindos.
Para agentes de IA
Um agente pode rodar seu próprio peer e usá-lo como ferramenta de busca, sem API de busca nem chave de API:
- Servidor MCP (
io.github.pad01g/yacy-search):docker run -i --rm --network yacy -e YACY_URL=http://yacy:8090 -e YACY_ADMIN_PASSWORD=<sua senha> ghcr.io/pad01g/yacy-search-mcp:0.2.1(com o peer iniciado comodocker run -d --name yacy --network yacy -p 127.0.0.1:8090:8090 -v yacy_data:/opt/yacy_search_server/DATA ghcr.io/pad01g/yacy-improved-search:latest; troque antes a senha padrãoyacy). Ferramentas:search,crawl,index_status,peers,get_ranking_settings,set_ranking_setting,evaluate_ranking,trust_status. Ele roda ao lado do agente e fala com o peer próprio do agente; não há nenhum serviço central. - Skill de agente:
npx skills add pad01g/yacy-labinstala yacy-p2p-search (iniciar um peer, rastrear, buscar, avaliar e ajustar o ranking). - Registro de confiança: pad01g/yacy-trust. Um pull request aceito inclui seu peer na lista ou torna você um operador que avaliza peers.
- Resumo legível por máquina: llms.txt.
Limitações
- Incompatível por padrão com a rede pública do YaCy (seeds sem assinatura rejeitados, hashes de palavras CJK alterados). O modo aberto pode buscar em peers antigos, mas apenas como resultados não verificados.
- Sem coordenadores configurados, um peer só confia nos seus próprios documentos. Redes fechadas podem usar
trust.signedOnly=true. Uma rede pública precisa de alguém que atue como coordenador. - O corpus é sintético e pequeno (160 páginas). Ele reproduz as fraquezas encontradas na rede pública. Não prevê o tamanho da melhoria lá.
- O teste de NAT usa um roteador MASQUERADE, não roteadores domésticos reais. O hole punching (DCUtR) está ativado, mas não foi medido.
- Um autor confiável ainda pode assinar conteúdo falso (a resposta são as tags e a auditoria). Um peer que armazena ainda pode reter resultados.
Links
- Código: pad01g/yacy_search_server, branch
improved-search(mudanças listadas em FORK.md) - Experimentos e demo: pad01g/yacy-lab
- Documento de design completo (em japonês): docs/trust-and-nat.md
- Upstream: yacy/yacy_search_server · fórum do YaCy