YaCy improved-search

一个实验性的 YaCy 分支:更好的排序、签名的结果、NAT 后面的节点

这是 YaCy 的一个分支(fork)。它修正了在公共网络上测出的弱点,加入了一层信任机制以便过滤伪造结果和垃圾结果,并让 NAT 后面的节点通过中继参与网络。本页的每一项结论都是在封闭的 P2P 网络中测得的,任何人都可以用 docker compose 重建这些网络。

状态:实验。这不是 YaCy 项目的发布版本,也与 YaCy 项目没有关联。它有意打破了与公共 YaCy 网络的兼容性(节点 ID、seed、CJK 词哈希)。公开它是为了用数据展示这些改动的效果,以便讨论其中的想法,并在合适的地方以小块的形式向上游提出。

为什么

在公共 YaCy 网络(freeworld)上用 16 个查询测量,前 10 个结果中只有 11% 包含全部查询词。追查原因:

改了什么

排序

更严格的最小匹配、在每节点归一化之后按查询词覆盖率加权、对内容单薄页面的降权,以及在小网络中搜索所有节点。

CJK

中文、日文和韩文文本以重叠的二元组(bigram)进行索引和搜索,Solr 和词索引中都是如此。

信任

Ed25519 节点密钥、签名的 seed、由协调者签名并带有声明标签的信任列表,以及节点抓取(crawl)的每个文档上的作者签名。

NAT 穿透

一个小型的 go-libp2p sidecar(伴随进程)在 circuit relay 上预留一个槽位,使 NAT 后面的节点能够响应搜索。

搜索质量

症状原因改动
只匹配一个词的页面(关键词堆砌)排在最前多词查询使用 Solr mm=1最小匹配 2<-1 5<80%:两个词必须都匹配,3–5 个词可以缺一个(search.ranking.solr.mm、.mm.cjk)
某个节点的最佳部分匹配与其他节点的完全匹配排名相当每节点分数归一化将归一化后的分数乘以(找到的词数 / 查询词数)²,至少为 0.05,且不低于最小匹配所保证的值(search.ranking.coverage.exponent)
词索引中找不到日文 / 中文CJK 没有分词在词索引和查询中使用重叠二元组;Solr schema 中使用 CJKWidthFilter + CJKBigramFilter
标题包含整个查询的单薄页面(标签列表)排在最前默认 qf 给 title^5 和 h1^5(以及 host ^6、URL 文件名 ^4、路径 ^3)的权重,而 text 只有 ^1少于 100 个词的结果按 词数 / 100 加权,至少为 0.1(search.ranking.thin.words);修正了 CJK 词数统计(原来统计的是空格)
由新节点组成的网络从不搜索其他节点的词索引DHT 搜索需要年龄超过 3 天的节点可配置(remotesearch.dht.minage,默认 3)
小网络把远程 Solr 查询发给零个节点,或跳过 DHT 目标目标数量公式得出 0;DHT 目标被排除在 Solr 之外不超过 32 个节点的网络会询问每一个已连接的受信任节点(开放模式下为每一个节点),包括 DHT 目标

信任层

NAT 穿透

一个 sidecar 进程(Go,go-libp2p)与 YaCy 并行运行,使用同一个密钥。在 NAT 后面时,它在 circuit relay v2 上预留一个槽位,并在签名的 seed 中公布 circuit 地址(Reach=relay)。其他节点为它打开一个本地隧道端口并使用普通 HTTP,因此 YaCy 现有的客户端无需改动即可工作。默认情况下,这样的节点只响应搜索;除非主动选择加入,否则它们不存储 DHT 数据。

详情见信任与 NAT 设计 (English)。

结果

yacy-lab 中的两个实验。两者都在 docker compose 中运行封闭网络,使用确定性的语料和查询集。

搜索质量:上游 vs 分支,各 3 个节点

每个节点抓取一个站点。查询以 resource=global 发送到节点 1,而大多数相关页面位于其他节点上。语料包含两类诱饵:堆砌某一个查询词的页面,以及标题中包含整个查询的单薄“标签归档”页面。结果为 11 个查询(6 个英文、4 个日文、1 个中文)的平均值,共运行 2 次,除注明处外两次结果相同。

集群 / 路径R-precision ↑Recall@10 ↑前 R 名中的诱饵 ↓前 10 名包含全部词 ↑
上游,默认0.520.960.480.42
分支,默认0.79–0.861.000.14–0.210.75
上游,仅词索引0.020.020.000.09
分支,仅词索引0.930.950.070.77

信任与 NAT:6 个分支节点、一个中继和一个 NAT

三个受信任节点,一个声明了 ads 的受信任节点,一个已签名但不受信任的节点(它抓取垃圾内容,并植入借用他人签名的文档),以及一个位于 MASQUERADE 路由器后面的节点。全部 26 项检查通过,其中包括:

试一试

无需 Docker:在浏览器中打开演示。它以模拟模式运行,重放从真实演示中记录的响应(页面为日文)。

演示在一台机器上启动两个网络(3 个上游节点,以及分支的信任与 NAT 配置),并在它们前面放一个搜索页面。你需要 Docker,并预留大约 7 GB 内存。

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
# 打开 http://localhost:8800(初始化约需 10 分钟,并会显示进度)
演示页面:同一查询分别发送到上游网络(左)和分支(右)。上游先列出垃圾页面;分支先列出已验证的相关页面,并在开放模式下把垃圾页面列在其下方,标记为 unverified。
开放模式下的 “bitcoin lightning channel”。左:上游先显示垃圾内容。右:分支先显示已验证的结果,垃圾内容标记为 unverified,排在下方。

该页面还允许你更改信任:选择发起搜索的节点信任哪些协调者(第二个协调者只列出了垃圾节点,因此信任它会让垃圾内容变成“verified”),编辑并重新签名信任列表,把新版本交给一个节点并观察它传播开,以及撤销或恢复运营者的委托。

实验本身:docker compose -p yacylab up -d && docker compose -p yacylab run --rm runner(搜索质量)和 docker compose -f compose.trust.yaml -p yacytrust up -d && docker compose -f compose.trust.yaml -p yacytrust run --rm runner(信任与 NAT)。见 lab README。

加入:无需许可

任何人,无论是人还是代理(agent),都可以运行一个节点,用某一个成员的 URL 连接(p2p.bootstrap.peers,也可以跨 Tailscale 网络),为自己的页面和服务建立索引并签名,还可以运行自己的协调者或运营者:协调者只是一个密钥加上放在任意 URL 上的一个签名文件,不需要服务器。允许声明过的广告(ads 标签);信任谁的列表由用户选择。如何加入 · 欢迎 pull request。

面向 AI 代理

代理可以运行自己的节点,并把它当作搜索工具使用,无需搜索 API 或 API 密钥:

局限