怎么选
| 你想让模型做什么 | 用哪个 | 为什么 |
|---|---|---|
| 找到相关页面列表 | search | 只返回结构化结果,快且省 token |
| 基于多个网页回答一个问题 | research | 一次调用拿到「结果 + 正文」,省掉多轮往返 |
| 深入读某一页 | fetch_page | 把 URL 或搜索结果 id 转成 Markdown |
| 搜索失败了,想搞清楚原因 | status | 看引擎健康状态与冷却截止,区分「引擎挂了」和「IP 被限」 |
search — 搜索
搜索网页并返回结构化结果数组。这是最基础也最常用的工具。
参数
| 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
| query必填 | string | — | 搜索关键词 |
| maxResults可选 | number | 10 | 返回条数,取值 1–20;默认值来自 SEARCH_MAX_RESULTS |
| site可选 | string | — | 限定单个域名,如 github.com(等价于只含一个元素的 includeDomains) |
| includeDomains可选 | string[] | — | 只返回这些域名的结果,最多 5 个 |
| excludeDomains可选 | string[] | — | 排除这些域名的结果,最多 5 个 |
| region可选 | string | — | 区域提示,如 cn-zh / us-en;同时参与引擎自动选择 |
| freshness可选 | string | — | day | week | month | year |
| timeRange可选 | string | — | "YYYY-MM-DD..YYYY-MM-DD",优先级高于 freshness |
返回字段
| 字段 | 说明 |
|---|---|
| query | 原始查询 |
| queryRewritten | 仅当查询被改写时出现(去年份词后的查询) |
| queryYear | 仅当查询中识别到「20xx 年」时出现 |
| engine | 实际生效的引擎 |
| engineSwitched | 是否发生了故障转移(不是链上第一个引擎) |
| cached | 是否命中缓存 |
| total | 返回条数 |
| deduped | 被去重合并的条数 |
| filtered | 是否应用了客户端侧域名过滤 |
| freshnessApplied | 生效的引擎是否真正支持时间过滤 |
| freshnessAutoInferred | 时效是否由中文查询改写自动推断而来 |
| timeRange | 实际生效的时间窗(仅当 freshnessApplied 为真) |
| results[] | { id, title, url, snippet, domain } |
示例
{
"query": "2026年 大模型 最新进展",
"maxResults": 8,
"region": "cn-zh",
"freshness": "week"
}
id(URL 的 sha1 前缀)。把它交给 fetch_page 即可读取该页正文,
由服务器负责复用缓存与 URL 索引。
research — 一次调用完成整轮调研
这个工具替代 Agent 自己写循环:内部先跑一遍完整搜索,再按域名多样性挑选若干条结果, 并行抓取页面正文,最后返回一份「证据简报」。
参数
继承 search 的全部参数(query 仍为必填),额外增加三项:
| 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
| fetchTopN可选 | number | 2 | 抓取前 N 条结果作为完整页面;取值 0–5,0 表示只返回结果概览不抓页 |
| extractMode可选 | string | summary | summary 返回去噪后的正文要点(省 token);full 返回整页 Markdown |
| maxPageLength可选 | number | 8000 | 单页保留的字符数,取值 500–100000;默认受 FETCH_MAX_LENGTH 约束 |
选页策略
页面的挑选不是简单地「取前三名」,而是按域名轮转:
- 先为每个不同域名取其中排名最高的一条;
- 名额还有剩余时,再按原始排名依次补足。
这样做有两个好处:避免单个站点垄断整份简报;某个站反爬返回 403 时,其他域名的页面不受影响。
每个页面都带 rank 字段,标明它在搜索结果中的原始名次。
返回结构
{
"query": "2026 LLM open source models comparison",
"engine": "bing",
"engineSwitched": false,
"cached": false,
"freshnessApplied": true,
"timeRange": "2026-07-12..2026-08-12",
"overview": {
"total": 5,
"deduped": 1,
"results": [
{ "id": "a1b2c3d4", "title": "...", "url": "...", "snippet": "...", "domain": "..." }
]
},
"pages": [
{
"id": "a1b2c3d4",
"url": "https://example.com/a",
"rank": 1,
"title": "页面标题",
"headings": [ { "level": 1, "text": "..." } ],
"content": "去噪后的正文……",
"length": 4000,
"truncated": false
},
{ "id": "b2c3d4e5", "url": "https://other.com/b", "rank": 3, "error": "HTTP 403" }
],
"note": "Evidence brief ready. Summarize based on the page contents and cite source URLs."
}
{ url, rank, error }。
宿主模型应当基于成功页面作答,并在结论里标注来源 URL。
fetch_page — 抓取网页转可读内容
把任意 URL 转成适合模型阅读的文本,或者先用返回的 headings 大纲判断值不值得深读。
| 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
| url可选 | string | — | 要抓取的页面地址 |
| id可选 | string | — | 搜索结果的 id,与 url 二选一 |
| extractMode可选 | string | summary | summary → 去噪正文 mainText;full → 整页 markdown |
| maxLength可选 | number | 8000 | 返回字符上限,默认来自 FETCH_MAX_LENGTH |
返回字段:
- title / description页面标题与描述
- headings
[{ level, text }]标题大纲 - mainText去噪正文(优先取
<article>/<main>容器) - markdown整页 Markdown
- length / truncated实际长度与是否被截断
- cached是否命中缓存
{ "id": "a1b2c3d4", "extractMode": "summary", "maxLength": 8000 }
status — 引擎健康诊断
只读、零网络请求、无参数。搜索失败时第一个应该调用的工具。
引擎状态机
| 状态 | 含义 | 引擎链是否使用 |
|---|---|---|
untested | 本次进程内从未使用过 | 会尝试 |
healthy | 最近一次调用成功 | 会尝试 |
degraded | 出现连续失败但未达冷却阈值 | 会尝试 |
cooling | 处于冷却期 | 跳过 |
冷却规则:
RATE_LIMITED—— 立即冷却,时长取响应的retryAfter,默认 60 秒;- 其他失败(超时、网络错误、解析失败)—— 连续 2 次后进入冷却;
- 冷却中的引擎会被引擎链直接跳过,不再对它发出请求。
同时返回缓存统计(size / hits / misses)、运行时长与当前生效配置。
时效过滤怎么映射
传入统一的 freshness 或 timeRange,服务器按各引擎的实际能力翻译,不支持的引擎不会假装支持。
| 引擎 | 映射方式 | 是否支持 |
|---|---|---|
bing | qft=+filterui:age-lt<秒数> | 支持 |
duckduckgo | df=YYYY-MM-DD..YYYY-MM-DD | 支持 |
brave | freshness=pd|pw|pm|py,自定义窗口回落为日期区间 | 支持 |
tavily | 请求体 time_range=day|week|month|year | 支持 |
google / yandex | 无稳定的时间过滤参数 | 不支持 |
so360 / baidu / sogou | SERP 参数不稳定,不做映射 | 不支持 |
timeRange 字段也只在为真时才返回,
避免在不支持时间过滤的引擎上给模型错误暗示。
中文查询为什么会被改写
Bing 等引擎对中文分词较弱。当查询形如「2026年 大模型 最新进展」时,年份词会被当成主题, 结果容易跑偏到「2026 年日历 / 百科 / 赛事」这类页面。
因此当查询同时满足「含中文」与「含 20xx 年」时,服务器会:
- 移除年份词,得到
queryRewritten; - 用
freshness=year补偿时间意图; - 在返回值里通过
queryYear与freshnessAutoInferred透明告知。
{
"query": "2026年 大模型 最新进展",
"queryRewritten": "大模型 最新进展",
"queryYear": 2026,
"freshnessAutoInferred": true,
"freshnessApplied": true
}
你也可以显式传入 freshness 或 timeRange 覆盖这个自动推断 —— 显式值永远优先。
域名限定的两层保证
site、includeDomains、excludeDomains 会先被翻译成引擎认识的
site: / -site: 操作符(多个包含项用 site:a OR site:b 形式)。
但部分引擎(尤其是 Bing 处理中文查询时)不总是执行 site:,所以结果返回前会再做一次
客户端侧兜底过滤:按域名精确匹配或子域匹配校验包含/排除契约。命中兜底时
filtered 为 true。
缓存行为
- 缓存 key 由查询、条数、区域、域名限定、时效与引擎链共同决定 —— 换引擎链不会误命中旧结果。
- 默认 TTL 10 分钟,可通过
SEARCH_CACHE_TTL调整,设为0关闭。 fetch_page的缓存 key 额外包含extractMode,summary与full互不污染。research的简报同样带短 TTL 缓存(构建成本高)。
推荐的 Agent 使用姿势
-
默认走 research
对「需要依据的事实型问题」,直接一次
research(fetchTopN: 2、extractMode: "summary"), 让模型基于正文作答并引用 URL。 -
证据不足再补 search
如果简报里的页面覆盖不够,用
search换关键词或加域名限定扩大候选, 再用fetch_page深读其中 1–2 页。 -
失败先看 status
返回
RATE_LIMITED或全部引擎失败时,先调status。 若显示全部cooling,大概率是网络受限或 IP 被临时限制 —— 此时重试无用,应当等待或换代理。