跳到主内容
创建时间:最后更新:作者:白川

网页与浏览器类包:让 Agent 上网的两条路

拆解 6 个网页与浏览器类 Pi 包:无头 HTTP 抓取(pi-web-access、pi-smart-fetch、rpiv-web-tools、ollama 版)与有头真浏览器(pi-chrome、pi-agent-browser-native)。讲清 provider 数量、反爬能力、已登录状态复用、私网防护,以及每个包背后已经失效的安装路径。

网页与浏览器类包:让 Agent 上网的两条路

让 Agent 查个资料、读个文档、点个按钮,是最常见的需求。但生态里这批包的名字长得几乎一样——pi-web-access、pi-smart-fetch、rpiv-web-tools、pi-web-search、pi-chrome、pi-agent-browser-native——工具名也都叫 web_search 或 web_fetch。装错一个不是"多个功能",是工具名直接撞车,模型看到两个同名工具,行为立刻变得不可预测。

更麻烦的是这里面有几个坑:pi-web-access 依赖很重;@ollama/pi-web-search 的 GitHub 仓库已经 404,README 里写的安装命令根本跑不通;@juicesharp/rpiv-web-tools 已经搬到 monorepo,旧命令 /web-search-config 直接消失了。

还有一个更隐蔽的问题:web_fetch 这类工具本质上是在替模型发起 HTTP 请求,目标 URL 由模型决定。 这意味着 SSRF 风险——模型可以让你的机器去访问内网地址、云厂商的 metadata 接口、或者你本机的服务。

这篇把 6 个包按**"无头 HTTP 抓取"和"有头真浏览器"**两条路分开,讲清每个包实际提供的工具、命令、依赖,以及哪些安装说明已经过期。读完你能按需求选包,也能避开那几个已经失效的安装命令。

前置知识:知道 Pi 的包机制和扩展怎么注册工具(第十章第一节),以及工具的 promptGuidelines 是什么(第六章)。

两条路的分水岭

先把 6 个包放到同一张表里。"浏览器级"这三个字是分界线——左边只发 HTTP 请求,拿到的就是服务器返回的 HTML;右边开一个真的浏览器,能执行 JS、能点按钮、能带着你已登录的 cookie 访问页面。

包版本路线核心能力需要 API key
pi-web-access
0.46.0
无头 HTTP
40+ 搜索 provider、GitHub 克隆、PDF/视频理解
可选(Exa MCP 零配置)
pi-smart-fetch
0.3.23
无头 HTTP
TLS 指纹伪装 + Defuddle 抽取
不需要
@juicesharp/rpiv-web-tools
2.15.0
无头 HTTP
10 个可插拔 provider、私网地址拦截
视 provider 而定
@ollama/pi-web-search
0.0.5
无头 HTTP
走本地 Ollama 的 web API
不需要(但要本地 Ollama)
pi-chrome
0.15.57
有头真浏览器
复用已登录的真实 Chrome profile
不需要
pi-agent-browser-native
0.9.16
有头真浏览器
agent-browser 原生工具化,JS 跑在浏览器里
可选(搜索才要)

这张表里最该先记住的一行是 pi-chrome。 它是这六个包里唯一能复用你已登录状态的——别的包发出去的是匿名请求,你在自己浏览器里能看到的页面,它们大概率看到登录墙。

反过来说,如果你的任务需要"登录后才能看到的内容",pi-chrome 是唯一解,其它五个都做不到,再换 provider 也没用。

另一个容易忽略的维度是反爬能力。pi-smart-fetch 在这一维上是唯一的赢家,原因很具体:它做了浏览器级的 TLS/SSL 与 HTTP 指纹伪装。当目标站点对普通 HTTP 客户端做了指纹检测时,别的包拿到的是 403 挑战页,只有它能拿到正文。

无头 HTTP 这一侧

pi-web-access:功能最全,也最重

pi-web-access 是这批包里功能最宽的一个。搜索、内容抽取、视频理解、GitHub 克隆都做了,搜索 provider 数量是 40+ 量级:OpenAI/Codex、Exa、Brave、Parallel、TinyFish、Search1API、Searchinfinity、Querit、Tavily、Firecrawl、Jina、SERPdive、Kagi、Bocha、Ollama、AnySearch、XCrawl、Valyu、xAI/Grok、Mistral、Bright Data SERP、SerpBase、SerpApi、Linkup、Serper、Serply、SearchApi、SearXNG、degoog metasearch、Crawl4AI、DuckDuckGo、Keenable、Gemini Web、Kimi Code Plan 等。

它的四个工具各自负责一段链路:

能力工具说明
搜索
web_search
多 provider 自动回退链,一个返回空或跑题就换下一个
抓取
fetch_content
抽正文;传 GitHub URL 时克隆到本地给模型真实文件路径,不是渲染后的 HTML
取片段
get_search_content
拿搜索结果里某一段的正文,支持 offset
溯源
source_check
拿 responseId 校验某个说法在页面上是否成立

对应的斜杠命令有四个:/websearch(直接打开搜索策展界面,跑完搜索后你可以审阅、增删、勾选结果,批准摘要后才回到对话里)、/curator(运行时开关或配置策展工作流,持久化到 ~/.pi/agent/web-search.json)、/search(交互浏览当前会话存下来的搜索结果,带 response ID)、/google-account(显示 Gemini Web 当前认证的 Google 账号)。

API key 是可选的。 Exa MCP 提供零配置搜索,装完就能用。如果 Pi 已经用 Codex 订阅登录(/login),OpenAI 的搜索也能复用这份认证,不用单独配 key。要接更多 provider 就写 ~/.pi/agent/web-search.json:

json
{
  "openaiApiKey": "sk-...",
  "braveApiKey": "BSA_...",
  "exaApiKey": "exa-..."
}

它的依赖是这批里最重的。 unpdf(PDF)、undici(HTTP)、defuddle + linkedom + turndown + @mozilla/readability(抽取)、@modelcontextprotocol/sdk(MCP server 模式)。engines 要求 Node >= 22.19.0。

它还带一个容易被忽略的能力:搜索和抓取工具同时可以跑成本地 MCP server,给 Claude Code、Codex、Cursor 用。

代价是明确的:依赖树大。如果你只是想让 Agent 能读一篇文章,这是杀鸡用牛刀。

pi-smart-fetch:只做一件事,做到极致

pi-smart-fetch 定位非常窄:把 web_fetch 升级成浏览器级的抓取。两个工具:

text
web_fetch(url, browser?, os?, headers?, maxChars?, timeoutMs?, format?, removeImages?, includeReplies?, proxy?, verbose?)
batch_web_fetch(requests, verbose?)

batch_web_fetch 的每个条目接受和 web_fetch 相同的参数(除了 verbose),用来并发抓一批 URL。

它比同类强在两个地方:

能力机制
TLS/SSL + HTTP 指纹伪装
依赖 wreq-js,发出的请求在 TLS 握手和 HTTP 头层面像浏览器
Defuddle 抽取
剥掉导航、侧栏、相关链接、分享组件、页脚,只留正文

输出格式有 markdown、html、text、json、raw 五种,默认 markdown。

但有个边界必须说清楚:Defuddle 不执行 JavaScript,也不解决交互式反爬和登录流程。 所以 smart-fetch 能绕过"看你的指纹不像浏览器",但绕不过"必须点开弹窗才给内容"或者"必须登录"。

它的抽取层对特定站点特别友好:YouTube、Reddit、X/Twitter、GitHub(页面、issue、PR、discussion)、Hacker News、Substack,以及带代码块、脚注、数学公式的页面。

依赖情况有个反直觉的地方:peerDependencies 是 @sinclair/typebox、@earendil-works/pi-tui、@earendil-works/pi-coding-agent,dependencies 是 wreq-js、defuddle、linkedom。typebox 这里写的是 @sinclair/typebox,和别处常见的 typebox 不是同一个名字。engines 写的是 bun >= 1.3.0 和 node >= 22.19.0——声明支持 Bun,但这不是说只能在 Bun 上跑。

@juicesharp/rpiv-web-tools:provider 可插拔,还带私网防护

@juicesharp/rpiv-web-tools 需要先讲一件迁移的事,否则你会被旧文档坑到。

juicesharp 的所有独立仓库都已经迁移到 juicesharp/rpiv-mono monorepo。 旧的独立仓库现在是只读归档状态,README 顶部挂着一块 CAUTION 牌子:

This repository has moved to juicesharp/rpiv-mono. This package now lives at packages/rpiv-web-tools. npm: still published as @juicesharp/rpiv-web-tools — no install change.

npm 包名没变,安装命令不变,但包内容已经换了一代。差异很大:

独立仓库版(旧)monorepo 版(2.15.0,当前)
后端数量
只有 Brave Search API
10 个:Brave、Tavily、Serper、Exa、You.com、Jina、Firecrawl、Perplexity、SearXNG、Ollama
配置命令
/web-search-config
/web-tools(旧命令已不存在)
provider 切换
不支持
每次调用可传 provider 参数覆盖
GitHub URL 拦截
无
有
私网/loopback 拦截
无
有
长文处理
截断 + spill 到临时文件
同

如果你按旧教程敲 /web-search-config,会得到"命令不存在"。 这是迁移期最常见的报错。

monorepo 版的两个工具:

text
web_search({ query, max_results?, provider? })
web_fetch({ url, raw? })

max_results 是钳制而不是拒绝——小于 1 变 1,大于 10 变 10,不给默认 5。provider 参数可以让单次调用换一个后端,不改动持久化的配置:

text
web_search({ query: "pi agent 生态", provider: "tavily" })

这个覆盖有个严格规则:目标 provider 必须自己有凭证,不继承当前 provider 的 key。 未配置的目标会直接抛 ... is not set 错误,不会静默回退——这样调用方能立刻发现配置错了。

web_fetch 的正文解析走三层,命中即停:

text
1. URL 拦截器链      → 目前只有 opt-in 的 GitHub 拦截器
2. provider 原生 fetch → Tavily / Exa / You.com / Jina / Firecrawl / Ollama 有厂商抽取端点
3. 内置 HTTP + HTML 转文本 → 纯搜索类 provider(Brave/Serper/Perplexity/SearXNG)走这条

第 3 层不需要任何 API key,所以即使当前 provider 是个没配 key 的纯搜索后端,web_fetch 照样能工作。但反过来,没配 key 的抽取类 provider(Tavily、Exa、You.com、Jina、Firecrawl)会直接抛错——因为它的原生 fetch 在第 2 层就跑了,根本到不了第 3 层。

旧独立仓库版的 API key 解析顺序是 BRAVE_SEARCH_API_KEY 环境变量,其次 ~/.config/rpiv-web-tools/config.json 的 apiKey 字段(文件权限 chmod 0600)。

monorepo 版的 active provider 有四层解析,先命中先赢:单次调用的 provider 参数 → WEB_SEARCH_PROVIDER 环境变量 → 配置文件里的 provider 字段 → 内置默认 brave。/web-tools --show 会打印最终生效的名字和它来自哪一层(env、config 或 default)。

API key 是按 provider 分别解析的三层:该 provider 自己的环境变量 → 配置文件里的 apiKeys.<provider> → 遗留的顶层 apiKey(仅 Brave,下次 /web-tools 保存时自动迁移到 apiKeys.brave)。没有跨 provider 回退——解析出来的 provider 没配 key 就直接抛错。

它的 web_fetch 带私网防护,这是这批包里唯一一个默认做的:

类别拒绝的主机
回环/未指定
localhost、*.localhost、0.0.0.0/8、127.0.0.0/8、::1、::
RFC 1918
10.0.0.0/8、172.16.0.0/12、192.168.0.0/16
链路本地
169.254.0.0/16(含云 metadata 169.254.169.254)、fe80::/10
IPv6 唯一本地
fc00::/7

拒绝时报 Refusing to fetch private/loopback address: <host>。防护在拦截器链之前跑,所以一个 github.com 形状的路径也绕不过去。

但这个防护只认主机字面量。 它不解析 DNS,也不校验重定向——一个公网域名解析到私网 IP、或者一个公网 URL 302 跳到私网,都能穿透。文档自己的建议是:在不可信的自动化环境里,再叠一层出网代理或防火墙。

它的 peerDependencies 是 typebox、@earendil-works/pi-tui、@earendil-works/pi-coding-agent,没有 pi-ai——它不直接调模型。monorepo 根目录的 engines 要求 Node >= 22。

@ollama/pi-web-search:唯一完全本地的,但说明和代码对不上

@ollama/pi-web-search 的价值在于它是这六个里唯一完全不联网的——搜索和抓取都转发给本机的 Ollama 实例。

先说三个必须知道的事实,否则你装不上:

第一,GitHub 仓库已经不存在了。 ollama/pi-web-search 返回 404。但 npm 包是好的,还在。package.json 的 repository 字段是 null,所以 Pi 也不会拿它当 git 来源。README 里写着可以 pi install git:github.com/ollama/pi-web-search,这条命令现在必然失败。可用的只有两条:

bash
pi install npm:@ollama/pi-web-search
pi install /path/to/pi-web-search

第二,README 里的工具名和源码里注册的工具名不一样。 README 说工具叫 ollama_web_search 和 ollama_web_fetch,但 index.ts 里 pi.registerTool 的 name 字段实际是 web_search 和 web_fetch。以源码为准。 你在 Pi 里看到的工具名是 web_search / web_fetch,不是 ollama_web_*。如果你按 README 写脚本调用 ollama_web_search,会得到"工具不存在"。

它调的是 Ollama 的实验性接口 POST {host}/api/experimental/web_search 和 POST {host}/api/experimental/web_fetch。

第三个坑:getOllamaHost() 硬编码了 http://localhost:11434,根本不读 OLLAMA_HOST 环境变量。 README 让你"检查 OLLAMA_HOST 环境变量是否符合你的设置",但源码里那个环境变量压根没被读取。远程 Ollama 的用户只能自己改代码。

用之前要满足:本机跑着 ollama serve、Ollama 的 web search / web fetch 已启用。返回 401 时提示 Run \ollama signin` to authenticate;连接被拒时提示 Could not connect to Ollama at http://localhost:11434`。

包本身很轻:7KB、4 个文件(index.ts、package.json、README.md、LICENSE)。但没有声明任何 dependencies——源码里 import 了 @mariozechner/pi-coding-agent 和 @sinclair/typebox,这俩属于隐式依赖。照第十章第一节的规则,宿主包本该写进 peerDependencies。

另外,2026-03 之后就没有新版本了。0.0.5 是最新的。

有头真浏览器这一侧

pi-chrome:唯一能复用你已登录状态的包

pi-chrome 定位一句话说得清:把 Pi 接到你已经登录的 Chrome 上。 不是开一个干净的自动化浏览器,是复用你日常那个 profile——所以你的登录态、你打开的标签页、你登录过的后台系统,Pi 都能直接看。

它的工具分两类:

类别工具能做什么
页面操作
页面检查、点击、输入、滚动、上传、截图
常规交互
诊断
控制台日志、fetch/XMLHttpRequest 响应
抓前端报错
底层
chrome_cdp
原始 CDP:设备模拟、cookie、PDF、无障碍树

chrome_cdp 是那个"兜底"工具——README 里说得很清楚,凡是上面那些工具覆盖不到的,都用它。

命令只有一个根命令,下面挂五个子命令:

text
/chrome onboard      # 装伴生扩展,显示扩展目录路径
/chrome authorize    # 授权 Pi 使用 Chrome(默认 15 分钟)
/chrome doctor       # 诊断连接状态
/chrome revoke       # 撤销授权并清理
/chrome background   # 后台模式

装伴生扩展这一步必须手动做。 /chrome onboard 会打开 chrome://extensions、在 Finder 里显示扩展目录、把路径复制到剪贴板(macOS 才有这自动化,Windows/Linux 要手动复制路径)。然后你在 Chrome 里开开发者模式、"加载已解压的扩展程序"、选那个目录。

授权是按会话给的,默认 15 分钟。 这不是可以关掉的设定——/chrome revoke 才是关的手段。

关于隐私,README 有一句必须读的提醒:伴生扩展权限很宽,而且跑在你真实的 Chrome profile 里。 官方让你在加载前读一遍扩展源码,只授权你信任的任务。还有一句:页面内容返回给 Pi 之后,可能会被发给你配置的模型 provider。 已登录页面的内容会进你的模型上下文。

peerDeps 是 typebox、@earendil-works/pi-tui、@earendil-works/pi-coding-agent,不需要 API key。

pi-agent-browser-native:把 agent-browser 工具化

pi-agent-browser-native 做的事是把 agent-browser 变成 Pi 的原生工具。注意这个包自己不包含浏览器——你得先单独装 CLI:

bash
npm install -g agent-browser --allow-scripts=agent-browser
agent-browser install          # 下载 Chrome for Testing
pi install npm:pi-agent-browser-native

--allow-scripts=agent-browser 是必须的,浏览器 CLI 的安装脚本要跑。Linux 上缺浏览器库时用 agent-browser install --with-deps。

四个工具:agent_browser(浏览器命令 + 固定 batch --bail 序列)、agent_browser_code、在同一个浏览器里跑 JavaScript 循环与分支、agent_browser_tools(启用 action、QA、Electron、source、network-source 工具)、agent_browser_web_search(可选的 Exa 或 Brave 搜索)。

agent_browser_code 是这个包和 pi-chrome 的分水岭。 它让模型写 JS 在浏览器上下文里跑,能循环遍历列表页、能按条件分支、能一次处理几十个页面。pi-chrome 的 chrome_cdp 是单步命令,复杂流程要模型自己一环一环调。

快照机制值得知道:一次 snapshot -i 给每个控件一个 @eN 引用,后续操作引用这些 ID。导航或页面变化之后要重新快照,否则引用会失效。README 里有句话很实在:命令返回成功不代表页面真的变了,所以要点完之后检查结果。

配套 CLI 有三个:pi-agent-browser-config(配置 provider 偏好和浏览器默认值)、pi-agent-browser-doctor(诊断)、pi-agent-browser-convert(转换旧浏览器会话)。配置写在 ~/.pi/config/pi-agent-browser-native/config.json。

搜索是可选功能,需要 EXA_API_KEY 或 BRAVE_API_KEY,两个都能用时默认 Exa。

它的 engines 要求 Node >= 24.21.0——这批包里要求最高的。peerDeps 含 pi-ai、pi-tui、pi-coding-agent、typebox。

更新包之后要完全退出 Pi 再启动。 /reload 可能还留着旧的编译代码。

工具名会撞车

这六个包里有四个注册了 web_search 或 web_fetch:

包注册的工具
pi-web-access
web_search、fetch_content、get_search_content、source_check
pi-smart-fetch
web_fetch、batch_web_fetch
@juicesharp/rpiv-web-tools
web_search、web_fetch
@ollama/pi-web-search
web_search、web_fetch

同时装两个以上,模型会看到同名工具。 这时候的表现不是"报错",而是模型在两个同名工具之间随机挑——表现出来的症状是"同样的问题,时好时坏"。

所以:

  • 想要搜索 + 抓取,用 pi-web-access 一个包就够了,它自己就全了。
  • 想要可插拔 provider,用 @juicesharp/rpiv-web-tools 一个包就够了,Brave 是它的 10 个后端之一。
  • 想要本地 Ollama,就用 @ollama/pi-web-search,别再叠一个搜索包。

真要同时用多套,得在 ~/.pi/agent/settings.json 里用过滤规则把重复的类型裁掉。但要注意第十章第一节的规则:过滤只能缩小,不能扩大——包没声明的资源你写路径也加载不出来。

SSRF:抓 URL 的真实风险面

这一节值得单独讲,因为我核对了源码,发现防护的覆盖度比想象中窄。

问题的本质很简单:web_fetch 拿一个 URL,发起 HTTP 请求。这个 URL 是模型给的。如果模型被诱导去 fetch http://169.254.169.254/latest/meta-data/iam/security-credentials/,那它就是在替你读云厂商的实例凭据。

包私网防护
@juicesharp/rpiv-web-tools
有。主机字面量匹配,含 metadata 地址
pi-web-access / pi-smart-fetch
无内置网段拦截
@ollama/pi-web-search
无。而且请求转发给你自己的 Ollama 实例
pi-chrome
无。而且它在你的真实浏览器里跑
pi-agent-browser-native
无

注意后两行的放大效应。 一个纯 HTTP 客户端访问内网,影响范围基本就是这个进程能碰到的。pi-chrome 是在你已登录的真实浏览器里,拿到的是完整的会话上下文;@ollama/pi-web-search 把请求交给本地 Ollama,Ollama 再去访问——URL 会离开你的机器。

具体到实践,三条建议:

第一,在不可信环境里用 rpiv-web-tools 的 web_fetch,别用别的。 它至少挡住了字面量形式的 localhost、127.0.0.0/8、10/8、172.16/12、192.168/16、169.254/16、fc00::/7。

第二,知道那个防护只认字面量。 它不解析 DNS,不跟重定向。公网域名解析到私网 IP、或者公网 URL 302 跳到内网,都能穿过去。要真堵住,得在网络层加出网代理或防火墙,靠应用层判断不够。

第三,给本地 Ollama 的 web API 加访问控制。 那个接口能替你发任意 URL 的请求,等同于一个开放代理。

顺带提一句:pi-web-access 自己也承认这类风险——它的 README 里写了,第三方托管的页面抓取器对远程 HTTP(S) 目标需要显式 fetchRouting.allowRemoteHostedProviders 才能开。默认关着是有道理的。

谁负责什么

职责由谁承担
提供搜索后端
provider 厂商(Exa、Brave、Tavily 等)或自建(SearXNG、Crawl4AI)
提供抽取能力
每个包自己的实现:Defuddle、Readability、厂商抽取端点
反爬对抗
目标站点决定;pi-smart-fetch 只能在指纹这一层帮忙
是否复用已登录状态
只有 pi-chrome 能
私网/loopback 拦截
只有 @juicesharp/rpiv-web-tools 默认做
网络出口与防火墙
你——应用层判断挡不住 DNS 和重定向
请求会不会带着你的凭据发出去
你——pi-chrome 和本地 Ollama 都要自己审
provider 数量
各包自己定,pi-web-access 最多

三种场景的可观察结果

场景一:Agent 要读一篇需要登录才能看的文档。 装 pi-chrome,跑 /chrome onboard 装伴生扩展,再 /chrome authorize。可观察结果:/chrome doctor 报 ✓ Chrome is connected (...),然后模型直接读到了你登录后的页面内容。如果这时你改用其它五个包,会看到登录墙页面——不是报错,是内容变成登录提示。

场景二:某个站点对 Agent 返回 403,浏览器里却能正常打开。 这通常是指纹检测。装 pi-smart-fetch,它的 web_fetch 带浏览器级 TLS/HTTP 指纹。可观察结果:正文拿到了,而不是挑战页。但如果站点要求点弹窗或登录,还是不行——Defuddle 不执行 JS。

场景三:想完全离线,或者不希望 URL 离开机器。 用 @ollama/pi-web-search,前提是本机跑着 Ollama 且开了 web search。可观察结果:工具名是 web_search / web_fetch(不是 README 写的 ollama_web_*),搜索走 /api/experimental/web_search。如果你看到 Could not connect to Ollama at http://localhost:11434,检查 ollama serve;如果看到 401,跑 ollama signin。

你现在能做什么

  • 装 pi-web-access,用它自带的四个工具跑一次搜索和一次抓取,确认零配置状态下 Exa MCP 路径是通的。
  • 装 pi-smart-fetch,用 batch_web_fetch 一次抓一批 URL,对比它和 pi-web-access 的 fetch_content 在同一个反爬站点上的差别。
  • 用 pi-web-access 抓一个 GitHub URL,确认模型拿到的是本地克隆路径而不是 HTML。
  • 装 @juicesharp/rpiv-web-tools,跑 /web-tools 配一个 provider,然后用 web_fetch 试一个 http://169.254.169.254/... 和一个 http://localhost:...,确认两个都被 Refusing to fetch private/loopback address 挡下。
  • 装 pi-chrome,走完 /chrome onboard → /chrome authorize → /chrome doctor,然后在已登录的后台页面上跑一次只读任务。
  • 装 @ollama/pi-web-search,确认工具名是 web_search 而不是 ollama_web_search,并验证 ollama serve 停了之后的报错文案。
  • 打开 ~/.pi/agent/settings.json,检查自己有没有同时装了多个提供 web_search 的包——有的话用过滤规则裁掉重复的那类资源。
  • 对每个 web_fetch 类的包,自己审一遍它发出的 URL 会落到哪里:本地 Ollama、云端 provider、还是你自己的浏览器。

排障速查

现象检查点处理
/web-search-config 命令不存在
包版本
已迁到 monorepo,命令改成 /web-tools
pi install git:github.com/ollama/pi-web-search 失败
仓库状态
该仓库已 404,改用 npm:@ollama/pi-web-search 或本地路径
找不到 ollama_web_search 工具
工具名
源码注册的是 web_search / web_fetch,以源码为准
模型在两个同名工具间摇摆
工具名撞车
多个包都注册了 web_search,裁掉重复的那类资源
Refusing to fetch private/loopback address
防护生效
这是 rpiv-web-tools 的正常行为,别去关它
公网 URL 能穿透私网防护
防护深度
只认主机字面量,不解析 DNS 也不校验重定向,需网络层兜底
站点返回 403,浏览器正常
指纹检测
换 pi-smart-fetch,它做 TLS/HTTP 指纹伪装
智能抓取仍拿到登录页
能力边界
Defuddle 不执行 JS、不解交互式反爬,这类只能上 pi-chrome
chrome_cdp 连不上
伴生扩展
/chrome onboard 装扩展,再 /chrome authorize
Chrome 授权过期
授权时长
默认 15 分钟,重新 /chrome authorize
agent_browser 报错找不到浏览器
CLI 未装
npm install -g agent-browser --allow-scripts=agent-browser + agent-browser install
agent-browser 更新后行为没变
进程残留
完全退出 Pi 再启动,/reload 可能留着旧编译代码
快照引用 @eN 失效
快照过期
导航或页面变化后重新 snapshot
rpiv-web-tools 报 ... is not set
provider 无凭证
provider 覆盖不继承别的 provider 的 key,目标必须自己配
rpiv-web-tools 报 provider 名不认识
拼写
合法值:brave、tavily、serper、exa、youcom、jina、firecrawl、perplexity、searxng、ollama
扩展报重复注册警告
依赖声明
宿主包必须在 peerDependencies,typebox 与 @sinclair/typebox 别混用

参考资料