mcpField
W
webfetch

webfetch

本地服务
github.com/firish搜索与检索6014 周前更新

关于 webfetch

webfetch 是可自托管的网页搜索 MCP 服务,面向 LLM Agent,采用搜索、抓取、排序的流程,并带有语义缓存。它以 web_search 工具的形式提供给模型调用,目标是降低输入 token 与费用。

主要功能

  1. 01多引擎 RRF 融合,DDG 无需密钥即可使用
  2. 02本地抓取与提取页面内容,支持 JS 渲染
  3. 03混合排序加交叉编码器,并进行句子级压缩
  4. 04精确与语义双层缓存,TTL 随查询类型变化
  5. 05save_finding 与 status、savings_report 等工具

适用场景

  1. 01为 Claude Code 等客户端提供零额外费用的网页搜索
  2. 02减少长对话中搜索结果占用的上下文 token
  3. 03对改写后的重复查询复用缓存结果

MCP 相关

该项目是 MCP 服务,向 MCP 客户端暴露 web_search、fetch_url、save_finding、status 和 savings_report 五个工具。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"firish-webfetch": {
"command": "uvx",
"args": [
"webfetch-llm"
],
"env": {
"BRAVE_API_KEY": "<BRAVE_API_KEY>",
"SERPER_API_KEY": "<SERPER_API_KEY>",
"TAVILY_API_KEY": "<TAVILY_API_KEY>",
"WEBFETCH_PROVIDER": "<WEBFETCH_PROVIDER>"
}
}
}
}
启动命令uvx webfetch-llm
需要配置的环境变量
BRAVE_API_KEY密钥Optional - adds Brave to the multi-engine fusion. DDG works with no keys at all.
SERPER_API_KEY密钥Optional - adds Serper (Google results) to the multi-engine fusion.
TAVILY_API_KEY密钥Optional - adds Tavily to the multi-engine fusion.
WEBFETCH_PROVIDEROptional - search strategy: multi (RRF fusion of available engines, default), fallback (priority failover), or a single engine name like ddg.

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypiwebfetch-llm0.1.3

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

webfetch

面向自行运行的 LLM Agent 的网页搜索——在准确度相同的情况下,输入 token 最多减少 8 倍,成本降低 3 倍,相较于托管式 web_search。

托管式网页搜索工具每千次搜索收费 10 美元,之后还会对其传入上下文窗口的每个内容 token 再次收费。webfetch 以本地流水线取代它们——多引擎搜索、网页获取与提取、语义重排、句子级压缩——并将其作为 web_search 工具提供,让模型像调用其他工具一样调用它。与我们调查过的所有托管工具和搜索 API 不同,重复或改写后的查询都由语义缓存免费处理。

(使用 pip install webfetch-llm 安装;导入名称为 webfetch。)

跳转至: 核心结论 · 你将获得什么 · 快速开始 · 检查设置 · 完整基准测试结果 · Claude Code · Agent 循环 · 节省报告 · 工作原理 · 注意事项

准确度相同。成本降至三分之一。Token 降至八分之一。

一个 Agent 循环、一个模型、一个评判器、50 个 SimpleQA 问题。每行之间唯一变化的是搜索工具:

搜索工具准确度每次查询的输入 token每次查询的成本
Anthropic 托管式 web_search96%17,408$0.108
webfetch(4 引擎融合)92%3,467$0.035
webfetch(仅 DDG,费用为 $0)84%3,623$0.026

将 Opus 换成 gpt-5.6-sol,同一个 webfetch 工具即可达到 96% 的准确度——与托管式工具持平——每次查询仅需 $0.040 和 2,156 个 token:仅为托管式工具传入上下文的八分之一。完整结果涵盖了我们测试的所有方案。

这些数据是 webfetch 表现的最差情况——测试时缓存为空。实际使用中,差距会自然扩大:重复查询和改写后的查询都由缓存免费处理,而且后续每一轮只要继续保留搜索结果,token 优势就会再次体现。积少成多,就能得到这样的账单。这是一段普通 Claude Code 会话中的节省报告:

在 Claude Code 中呈现的节省报告

本 README 中的每项声明都由此仓库附带的评测工具生成——问题集、逐题记录、评判协议和负面结果均位于 evals/ 中,所有表格都能通过一条命令重新生成。评分结果不必只听我们说:evals/results/README.md 将每行表格数据对应到生成它的原始结果文件,细化到逐题评判结果。

你将获得什么

**由你掌控的搜索管线(4 引擎 RRF 融合、本地提取、句子级压缩)。**搜索结果由 DuckDuckGo、Brave、Serper 和 Tavily 的倒数排名融合而来,你有哪家的密钥就能用哪家。DDG 无需密钥,因此该工具开箱即可零成本使用;你添加的每个密钥都会自动加入融合。网页会在本地抓取和提取(trafilatura、readability、newspaper4k,以及用于 JS 页面和 403 拦截页面的 Playwright 渲染),然后进行分块,再通过混合 BM25 + 双编码器级联排序,并在顶部使用交叉编码器,最后压缩为回答查询所需的句子——实测在召回率零损失的情况下,令牌数减少了 50%。

**别处没有的缓存(精确 + 语义匹配、感知内容时效性的 TTL)。**在同一个 sqlite 文件中使用两层缓存:按 URL 缓存网页文本,按查询缓存排序结果。完全相同的查询会命中精确缓存。改述后的查询会命中语义缓存——先通过嵌入模型生成候选列表,再由 NLI 交叉编码器验证;我们优先针对精度进行评测调优(在我们进行的所有线上运行中,均未出现错误目标匹配)。缓存时长会根据查询动态调整:价格和分数在 15 分钟后过期,近期话题在 7 天后过期,发布说明和规格在 90 天后过期——分类依据是调用模型提供的提示,或本地分类器。每条缓存结果都会向模型显示来源信息([cache: semantic match to "...", 2h old, recent]),模型若不认可,可发送 force_fresh。我们调研过的托管工具或搜索 API 均未提供客户端可见的缓存功能。

**模型可以维护自己的缓存(save_finding,标记为 UNVERIFIED,含熔断开关)。**如果搜索没有结果,而模型从其他来源(例如托管搜索回退)获得了答案,就可以调用 save_finding 存储所学内容——标记为模型贡献,提供时附带明确的 UNVERIFIED 警告和 force_fresh 退出方式,并按常规 TTL 规则过期。对于永远不想缓存未经验证内容的部署,可使用熔断开关(SAVE_FINDING_ENABLED = False)。

**模型真正需要的控制项(full_results、fetch_url、freshness、force_fresh)。**对于列表和排序查询,full_results 会返回未压缩的摘录(压缩会缩减并列列表项——这是我们的实测结果)。fetch_url 会完整抓取一篇引用的网页;如果管线之前抓取过该网页,则可立即返回。freshness 提示控制缓存时长;force_fresh 可绕过缓存。

**用量凭据(会话和累计用量,精确计数)。**用量计数器会持久保存在缓存文件中;webfetch-savings(或 savings_report 工具)会显示你省下了哪些托管搜索费用,并分别统计本次会话和累计用量。 下方示例。

开始使用

一行命令即可(uv 会在首次启动时安装软件包,@latest 会自动获取新版本):

claude mcp add webfetch -- uvx --from webfetch-llm@latest webfetch-mcp

或者自行管理安装,只需两条命令:

pip install "webfetch-llm[all]"
claude mcp add webfetch -- webfetch-mcp

精简安装(不含额外项的 webfetch-llm)可在数秒内启动并以降级模式运行:BM25 排序、仅精确匹配的缓存、词法压缩。[all] 会安装语义组件(torch,首次安装需几分钟),以及 Playwright、PDF 和表格提取功能;本 README 中的所有基准数据均基于此配置测得。在全新的 venv 中需要 pip >= 24(运行 python -m pip install -U pip——较旧的 pip 会因我们的依赖树中有重复的 extra 而崩溃)。如果安装到 venv 中,请注册 webfetch-mcp 的绝对路径,或保持 venv 处于激活状态。

密钥为可选项(DDG 无需密钥即可使用),但能提高召回率——所有引擎都提供免费套餐:

cp .env.example .env    # fill in what you have

控制台脚本和 MCP 服务会读取其运行目录中的 .env;导出的环境变量和 claude mcp add 上的 --env 标志始终具有更高优先级。将 webfetch 作为库导入时,永远不会读取 .env——你的进程环境由你掌控。

检查设置

webfetch-status(或让模型调用 status 工具)会回答 “我的密钥是否已被读取,以及我实际运行的是什么?”:

webfetch 0.1.3

search engines:
  ddg      ready (no key needed)
  brave    ready (BRAVE_API_KEY is set)
  serper   off   (SERPER_API_KEY not set)
  tavily   ready (TAVILY_API_KEY is set)

active provider: multi(ddg+brave+tavily) (RRF fusion)

optional features:
  semantic ranking/cache/compression: on
  JS-page rendering (playwright):     on
  PDF extraction (pdfplumber):        OFF (pip install 'webfetch-llm[pdf]')
  HTML tables (pandas+tabulate):      on
  result compression:                 on (crossencoder)

cache: /Users/you/.webfetch/cache.db
  5.4 MB, 70 lifetime searches (webfetch-savings for the receipt)

仅显示密钥名称——绝不打印密钥值。配置通过环境变量提供,并在服务启动时读取:

变量作用
BRAVE_API_KEY、SERPER_API_KEY、TAVILY_API_KEY每个密钥都会为融合添加一个引擎
WEBFETCH_PROVIDERmulti(默认:融合所有已配置密钥的引擎)、fallback(由 DDG 提供服务,已配置密钥的引擎在 DDG 受阻时接手),或单个引擎名称
WEBFETCH_CACHE_DB更改缓存文件位置(默认 ~/.webfetch/cache.db)

如果没有配置任何密钥,默认会使用纯 DDG;状态输出会如实说明这一点,而不会称之为融合。库的使用者可以完全跳过环境变量:Pipeline(search=get_search_adapter("fallback"), cache=...)。

完整基准测试结果

所有测试组均使用相同的 50 个 SimpleQA 问题和相同的评判器,在同一天运行一次 (2026-07-14)。Agent 循环测试组采用完全相同的循环;唯一不同的是搜索工具。成本包括模型 token 和各提供商公布的每次搜索费用;我们的成本还包括估算的引擎费用。

搜索工具模型准确率每题输入 token每题成本
OpenAI 托管的 web_searchgpt-5.6-sol100%10,027$0.066
webfetch(4 引擎融合)gpt-5.6-sol96%2,156$0.040
Anthropic 托管的 web_searchOpus 4.796%17,408$0.108
webfetch(4 引擎融合)Opus 4.792%3,467$0.035
Exa(搜索 + 内容)Opus 4.790%5,496$0.053
TavilyOpus 4.788%6,387$0.047
webfetch(仅 DDG)Opus 4.784%3,623$0.026
webfetch(4 引擎融合)Haiku 4.576%*3,021$0.031

* Haiku 的失败大多是因为在轮次上限之后仍反复搜索,而且在基准测试中途耗尽免费额度后,最后几个问题使用了性能下降的引擎组合。应将其视为下限。

请注意 token 列:webfetch 结果所需的输入 token 是摘要 API 的一半、托管工具的五分之一到八分之一——这就是为什么即使每次搜索的费用相近,我们的总成本仍然最低。

在另一组包含 27 个关于运行前两周内事件的问题的数据集上(手工编写,从未发布,因此没有供应商能够据此调整),webfetch 使用融合和仅 DDG 时的得分均为 100%;托管工具也均为 100%。新近事件并不难——真正的难题是日期注入陷阱。

复现方法:python evals/run_e2e_eval.py --arms ours-multi,hosted——测试框架、数据集和逐题记录都在 evals/ 中。上表的数据来自 e2e_eval_20260714_005531.json (以及 Haiku 测试和新近事件数据集——完整的声明与文件对应关系见 evals/results/README.md)。这些问题是从 OpenAI 的公开 SimpleQA 数据集中按随机种子(seed 42)抽取的样本,因此 build_datasets.py 会在你的机器上重新生成相同的 50 个问题。有一点需要坦诚说明:实时网络内容会随运行时间而变化,而且在 n=50 时,96% 对 92% 的准确率差距相当于答对 48 题与 46 题——在噪声范围内持平。token 和成本两列则是通过机械方式计算、结果稳定的指标。

在 Claude Code / Claude Desktop 中使用

在 Claude Code 中最快的方法是将其安装为插件,提供两个斜杠命令(底层运行相同的 uv 单行命令):

/plugin marketplace add firish/webfetch
/plugin install webfetch@webfetch

或者自行注册 MCP 服务。无论采用哪种方式,新会话中都会在 /mcp 下显示 webfetch,并提供五个工具:web_search、fetch_url、save_finding、status 和 savings_report。询问任何近期事件并观察工具调用;再用不同措辞询问同一件事,结果会带有 [cache: semantic match ...] 标头,而不是重新搜索。会话中的首次调用较慢(编码器预热加上实际网页抓取,需要 10-40 秒);缓存调用则会即时返回。

可在 /mcp 中按会话关闭服务;通过 /plugin uninstall webfetch 或 claude mcp remove webfetch 将其移除,具体取决于安装方式。缓存及其回执历史记录位于 ~/.webfetch/,重新安装后仍会保留。每台机器运行一个服务即可——语义缓存假定只有一个进程拥有其文件。

更新通知:每个进程都会向 pypi.org 发送一次请求,以检查是否有更新版本,并在 savings_report 输出中显示一行提示。在 webfetch/config.py 中设置 UPDATE_CHECK_ENABLED = False 即可禁用此功能;除此之外,绝不会向任何地方发送数据。

在你自己的 Agent 循环中使用

import time
import anthropic
from webfetch import WEB_SEARCH_TOOL, handle_web_search

client = anthropic.Anthropic()
messages = [{"role": "user", "content": "What did the FOMC decide this week?"}]
system = (f"Today's date is {time.strftime('%Y-%m-%d')}. "
          "Use web_search for recent facts.")

while True:
    response = client.messages.create(
        model="claude-opus-4-7", max_tokens=2000, system=system,
        tools=[WEB_SEARCH_TOOL], messages=messages,
    )
    if response.stop_reason != "tool_use":
        break
    messages.append({"role": "assistant", "content": response.content})
    results = [{"type": "tool_result", "tool_use_id": b.id,
                "content": handle_web_search(b.input)}
               for b in response.content if b.type == "tool_use"]
    messages.append({"role": "user", "content": results})

带提示词缓存和自适应思考的完整版本见 examples/agent_loop.py。工具架构在设计上与提供商无关——OpenAI 函数调用只需对字典进行机械式改造。

请在系统提示词中加入今天的日期。 这不是可选项。模型会拒绝搜索它们认为尚未发生的事件:在我们的近期事件数据集中,未提供日期的循环中,模型对多达 27 个问题中的 10 个甚至拒绝调用工具(“Wimbledon 2026 还没有举行”)。只需一行即可解决。托管搜索工具会在服务端处理这一点,所以只有在运行自己的工具时,人们才会注意到这个问题。

handle_web_search 不会抛出异常。引擎故障、空结果和格式错误的输入都会以可读字符串的形式返回,供模型处理,因为对话中途出现异常会导致整个 Agent 循环中断。

节省情况报告

搜索时,计数器会累积在缓存文件中。让模型运行报告,或者自行运行 webfetch-savings。MCP 工具会分别统计本次会话和累计数据,因此你可以查看一次对话节省了多少:

本次会话与累计节省情况

下面是这一行输出的详细内容——这台机器上的一次 30 次搜索会话:

本次会话累计
已处理的搜索3076
来自缓存17(57%)- 10 次精确匹配,7 次语义匹配-
避免的搜索费用~$0.30
避免的内容令牌成本~$2.56
估算的总节省~$2.86~$7.21

计数器数据精确;美元金额为估算值,所采用的假设(每次托管搜索费用、每次调用的托管令牌数——两者均经过测量,以及你的模型令牌价格)可作为参数传入 webfetch.savings_report()。

工作原理

query -> multi-engine search (RRF fusion, circuit breakers)
      -> semantic query cache? serve with provenance header
      -> fetch pages concurrently (page cache by URL)
      -> extract (trafilatura -> readability -> newspaper4k -> playwright)
      -> chunk (400 chars) -> BM25 + bi-encoder fusion -> cross-encoder top 5
      -> compress to query-relevant sentences -> source-labeled result

所有重量级功能都是可选的:不安装 [rerank] 时仍可使用 BM25 排名、精确匹配缓存和词法压缩,并会记录警告,而不是抛出 ImportError。DDG 值得特别说明:它会通过不返回任何内容的空响应,对自动化客户端进行指纹拦截。webfetch 会检测这种情况(融合搜索中出现“部分引擎有结果、部分为空”,或回退链中出现任何空结果),通过熔断器暂时停用该引擎并改用其他引擎;TLS 相关处理由 ddgs 依赖项负责。

设计决策及其测量结果会随进展记录在 docs/architecture.md 和 docs/ROADMAP.md 中,其中也包括负面结果。

坦诚说明

  • 延迟。全新搜索需要 10-40 秒——页面会被实际获取并在本地排序。托管搜索约 10 秒返回,摘要 API 约 6 秒。命中缓存则即时返回。如果你需要亚秒级搜索且不在意成本,这个工具并不适合你。
  • 缓存是单进程的。一次只能用于一个 Agent 循环、一个 MCP 服务或一个笔记本;共享团队缓存后端已列入路线图。
  • 引擎的免费额度是真实配额。基准测试期间,我们用完了 Brave 的月度额度。弹性层会平稳降级,但召回率也会随之下降。表格中的引擎费用是根据公开价格估算的。
  • 答案质量取决于驱动工具的模型——能力较弱的模型会构造出更差的查询,并反复搜索而不是阅读(参见 Haiku 行)。
  • 对于跨形式改写(“X 添加了什么”与“X 的新功能”),语义缓存的召回率有限:调优后,在真实配对上的测量结果为 6/10,因为某些释义形式会让所有可用的验证器都无法判断。漏检会导致重新搜索,但绝不会产生错误答案。

基准测试与数据

共有三个评估层,全部位于 evals/ 中:用于确定语义缓存阈值的离线匹配器评估、实时检索评估(召回率、令牌、缓存诊断),以及上文引用的端到端答案评估(SimpleQA 协议:先进行标准化精确匹配,再由大模型评审)。数据集根据 SimpleQA(MIT)、QQP/GLUE 和 FreshQA(CC-BY-SA)确定性构建,每个文件旁都附有来源说明文件。fresh-events 集合是在基准测试运行前几天,根据经过核实的新闻来源手动编写的,专门确保没有任何模型或供应商流水线接触过它。

许可证

MIT。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。