Gemini CLI 联网实战:google_web_search 与 web_fetch 工具的原理与用法
本文围绕 Gemini CLI(gemini-cli)的 Web 工具教程展开,覆盖两个核心工具——google_web_search(联网搜索)与 web_fetch(抓取指定 URL 内容)——的典型使用场景、完整参数说明与安全机制,并结合开源仓库中的工具实现源码(web-search.ts、web-fetch.ts)拆解引用标注、限速、私有网络拦截与本地回退抓取等底层原理。读完后,你将能够在终端中让 Agent 检索最新文档、读取指定网页并据此生成或修改代码。
前置条件
- 已安装并完成认证的 Gemini CLI;
- 可用的互联网连接。
两个核心工具概览
| 工具 | 适用场景 | 核心参数 |
|---|---|---|
google_web_search |
需要检索模型训练数据之外的最新信息、新闻、文档 | query(string,必填):要执行的搜索查询 |
web_fetch |
将提示词中给出的具体 URL(最多 20 个)直接喂入上下文进行处理 | prompt(string,必填):包含不超过 20 个 http:// 或 https:// URL 及处理指令 |
两个工具的参数定义可见工具声明文件 default-legacy.ts,并通过 coreTools.ts 中的 WEB_SEARCH_DEFINITION / WEB_FETCH_DEFINITION 暴露给 Agent 循环。
场景一:研究新技术(google_web_search)
典型 Prompt
设想你要使用一个昨天才发布的库,模型并不知道它,需要"教"给它:
Search for the 'Bun 1.0' release notes and summarize the key changes.
Find the documentation for the 'React Router v7' loader API.
Gemini 会调用 google_web_search 工具查找相关页面并综合成答案。这个"grounding(接地)"过程确保 Agent 不会幻觉出不存在的特性。
源码级原理:搜索如何变成带引用的答案
工具实现位于 web-search.ts,其执行链路为:
- 发起搜索:
WebSearchToolInvocation.execute将查询以model: 'web-search'的名义调用geminiClient.generateContent(web-search.ts),即搜索由 Gemini API 侧的 Google Search 能力完成,而不是 CLI 本地发起 HTTP 请求。 - 解析接地元数据:响应中的
groundingMetadata携带两类数据(web-search.ts):groundingChunks:每个来源的uri与title,最终在回答末尾拼成Sources:列表,格式为[1] 标题 (URI);groundingSupports:指出回答中哪些字节区间对应哪个来源,工具据此在正文的精确位置插入[1]、[2]等引用标记。
- 精确插入引用标记:由于 API 返回的
segment索引是 UTF-8 字节位置,实现中专门使用TextEncoder/TextDecoder把响应编码为字节流,按降序插入标记后再解码,避免偏移错位(web-search.ts)。 - 空结果与错误处理:无结果时返回
No information found.;抛出异常时返回ToolErrorType.WEB_SEARCH_FAILED类型的错误结果(web-search.ts)。
场景二:抓取深度上下文(web_fetch)
搜索只能给你摘要,但有时你需要原始细节。web_fetch 工具允许把一个具体 URL 直接喂进 Agent 的上下文。
阅读博客文章
假设你找到一篇恰好解决你 bug 的博客:
Read https://example.com/fixing-memory-leaks and explain how to apply it to my code.
Gemini 会获取页面内容(剔除广告与导航等干扰信息)并基于它回答你的问题。
对比多个来源
也可以一次抓取多个页面来对比方案:
Compare the pagination patterns in https://api.example.com/v1/docs and https://api.example.com/v2/docs.
参数与确认机制
- 工具参数为单个
prompt字符串,内含最多 20 个 URL 与处理指令(例如"总结 A 页面并抽取 B 页面的关键数据")。URL 必须是完整、以http://或https://开头的形式,example.com这种不带协议的写法不合法。 - 每次调用都会触发一个确认对话框,展示解析出的 URL 列表,等待用户批准后才执行(
getConfirmationDetails,web-fetch.ts)。 - 在 Plan Mode 下,
web_fetch可用但因涉及访问外部/私有网络地址,始终需要显式用户确认(见 web-fetch.md 与 plan-mode.md)。
源码级原理:一条稳健的抓取管线
实现位于 web-fetch.ts,值得了解的机制包括:
- URL 解析与协议白名单:
parsePrompt按空白分词,用 WHATWGnew URL()校验,只接受http:/https:协议,畸形 URL 会直接报参数错误(web-fetch.ts)。 - URL 规范化:
normalizeUrl将主机名转小写、去掉尾部斜杠与默认端口,用于去重(web-fetch.ts)。 - 主机级限速:同一主机名每 60 秒最多 10 次请求(
MAX_REQUESTS_PER_WINDOW = 10),超限的 URL 会被跳过并在结果中警告(web-fetch.ts)。 - 私有网络与本地地址拦截:
isBlockedHost拦截localhost、127.0.0.1及私有 IP,防止工具被用于探测内网(SSRF 防护),被跳过的 URL 会记录private_ip_skipped遥测事件(web-fetch.ts)。 - GitHub 链接优化:
convertGithubUrlToRaw自动把github.com/.../blob/...转换为raw.githubusercontent.com的原始文件地址,拿到的是纯文本而非 HTML 外壳(web-fetch.ts)。 - 主通道 + 本地回退:主路径通过 Gemini API 的 URL 上下文能力抓取;若主通道失败,工具会回退到从本地机器直接 fetch(超时 10 秒,
URL_FETCH_TIMEOUT_MS),HTML 用html-to-text转纯文本,单页内容截断到MAX_CONTENT_LENGTH = 250000字符(web-fetch.ts)。 - 多 URL 预算分配:回退抓取多个页面时,采用"水填充"式公平算法在总字符预算内为各页面分配配额,短内容页优先拿满,避免单个超长页面挤掉其他来源(web-fetch.ts)。
- 反提示注入包装:所有抓取到的网页内容在回填给模型前会经过
wrapUntrusted包装,明确其为不可信外部内容(web-fetch.ts)。 - 实验性直接抓取模式:当配置开启
directWebFetch时,工具参数切换为单个url,CLI 直接抓取(上限 10MB),支持文本、JSON、HTML,甚至把图片/视频/PDF 以 base64inlineData形式交给模型(web-fetch.ts、web-fetch.ts)。
场景三:把网页知识落到代码
真正的威力来自 Web 工具与文件编辑工具的联动。典型工作流三步走:
- 搜索:"How do I implement auth with Supabase?"
- 抓取:"Read this guide: https://supabase.com/docs/guides/auth."
- 实现:"Great. Now use that pattern to create an
auth.tsfile in my project."
前两步分别触发 google_web_search 与 web_fetch 把最新资料注入上下文,第三步由文件编辑工具落地。生成代码的本地写入可参考 File management 教程。
场景四:排查报错
遇到费解的报错信息时,直接把错误粘进对话:
I'm getting 'Error: hydration mismatch' in Next.js. Search for recent solutions.
Agent 会搜索 GitHub issues、StackOverflow、论坛等来源,找出可能因太新而不在其训练集中的修复方案。
参考资料
- Web search 工具参考(google_web_search):参数、grounding 与引用行为说明;
- Web fetch 工具参考(web_fetch):
urlContext处理机制、Plan Mode 行为与回退策略说明; - File management 教程:将检索生成的代码写入项目;
- 实现源码:web-search.ts、web-fetch.ts,对应测试 web-search.test.ts 与 web-fetch.test.ts,以及集成测试 google_web_search.test.ts。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00