name: web-search description: 统一 Web 搜索 — 自动在 tavily/exa/firecrawl/brave/serper 多 provider + 多 key 池间轮换。必须按场景使用 --scene 参数(不要默认 any),否则会浪费 Serper 终身额度。当用户要求"搜一下""看看 X 上有什么消息""查最新研报/新闻/政策""谁在说什么"时使用。
web-search — Multi-key Pool 统一搜索(带场景路由)
⚠️ 调用前必读:选对 scene
永远优先用 --scene <X> 而不是 --provider any——场景化 chain 比通用 chain 节省 30-50% 额度,因为它会跳过对该场景没用的 provider。
场景路由表(核心)
--scene |
Chain(首选 → fallback) | 适用查询 |
|---|---|---|
general(默认) |
exa → brave → tavily → serper → firecrawl | 不确定时用,Exa 含义匹配兜底 |
news |
serper → brave → tavily → exa | 实时事件、24-48h 内突发、最新公告 |
research |
exa → tavily → serper | 含义查询、长文研究、概念探索 |
social |
serper → brave → tavily | Reddit、X、Stocktwits、社区情绪 |
media |
serper → brave → tavily → exa | WSJ/FT/Barron's/Bloomberg 主流财经 |
academic |
exa → tavily | arxiv、GitHub、技术文档、学术 |
fulltext |
firecrawl | 抓已知 URL 全文(含 JS 渲染) |
stock |
firecrawl → exa → serper | 公司官网实时数据、SEC、IR 页面 |
决策树(30 秒选 scene)
查询想要的是什么?
├── 24h 内的突发事件? → --scene news
├── Reddit/X/论坛在说什么? → --scene social
├── 主流财经媒体怎么报道? → --scene media
├── 含义级查询/长文研究? → --scene research
├── arxiv/GitHub/技术文档? → --scene academic
├── 抓某个已知 URL 全文? → --scene fulltext
├── 公司官网/SEC 实时数据? → --scene stock
└── 不确定/混合性质 → --scene general(默认)
调用模板(按场景)
# 实时新闻(最常用)
python scripts/web_search.py "UMAC drone news" --scene news --time-range day --max 8
# 主流财经媒体扫描
python scripts/web_search.py "Trump drone executive order" --scene media --time-range week
# Reddit/社区情绪
python scripts/web_search.py "site:reddit.com $UMAC bullish" --scene social --time-range week
# 含义级研究(不依赖关键词)
python scripts/web_search.py "Trump family linked drone investments" --scene research
# 抓官网实时数据
python scripts/web_search.py "unusualmachines.com" --scene stock --max 5
# 不确定时
python scripts/web_search.py "QUERY" --scene general
Fallback 行为(自动)
每个 chain 内部的 fallback 是 3 层:
- Key 层:当前 provider 内部,单 key 失败 → 自动换池里下一把(usage 最低优先)
- Quota 层:429 / "exceeds limit" → 标记 exhausted,跳到下一把
- Provider 层:当前 provider 全部 key 死光 → 跳到 chain 下一个 provider
→ 你不用关心降级路径,只要传对 scene,系统自己找有额度的家。
配额预算(基于实测,2026-05-29 状态)
| Provider | 池容量 | 月度可用 | 单次调用消耗 |
|---|---|---|---|
| Exa | 5 keys | 5000/月 | 1 quota |
| Brave | 2 keys | 4000/月 | 1 quota |
| Tavily | 4 keys(2 死) | ~1000/月 | 1 quota |
| Serper | 3 keys | 7500 终身(不刷新) | 1 quota |
| Firecrawl | 5 keys | 2500/月 | 1 quota(search)/ 多 quota(fulltext) |
Serper 是终身额度,最珍贵。news/social/media 三个 chain 都把 Serper 排第一,所以这三类要节制使用。日常优先 general/research(首选 Exa,月度刷新)。
关键事实(实测得出,决策时考虑)
- Brave 的缓存严重过期——抓到的"实时数据"可能是几周前的。永远不要相信搜索引擎给的股价数字,股价用
us-realtime-quoteskill。 - Tavily dev key 极不稳定——4 把已 2 把开池即死。如果用户给的是
tvly-dev-前缀,要手动确认能用。 - Exa 自带 markets/stock 库——搜
UMAC时它会主动返回exa.ai/library/markets/stock/UMAC这种结构化页面。 - Serper 找 Reddit 最准(Google 索引深),其他家挖 Reddit 都不行。
- Firecrawl 唯一能抓 JS 动态渲染,公司官网首页用它最稳。
输出契约
- text 模式:编号列表,每条含 title / url / snippet(截到 300 字符)
- json 模式:
{provider, key_used (redacted), results: [{title, url, snippet, score}]} - 全 chain 死光时:exit 1,stdout
ERROR: all providers exhausted+ 各 provider 失败原因
Key Pool 管理
# 查池子总览
python scripts/key_pool.py list
# 添加新 key
python scripts/key_pool.py add <provider> KEY1 KEY2 ...
# 看池内所有 key 状态(脱敏)
python scripts/key_pool.py show <provider>
# 删除指定 key
python scripts/key_pool.py remove <provider> <key>
# 重置 exhausted 标记(一般月度自动;紧急情况手动)
python scripts/key_pool.py clear-exhausted <provider>
给 Claude 的硬规则
- 优先
--scene,不要--provider any(除非用户明示"任意搜一下") - 时效问题必加
--time-range(news=day/week,media=week/month) - 失败排查加
-v,能看 chain 上每一步是 quota 还是 invalid - 股价数字永远不信搜索结果,用
us-realtime-quote - 节制 Serper——Serper 是终身一次性额度,新闻+社交场景才给它,研究类查询走 Exa
- 不要在对话明文 echo key——
key_used字段已脱敏