OpenCLI Gemini Adapter 实战指南:用浏览器会话在命令行驱动 Gemini Web
2026/9/19 22:15:24 网站建设 项目流程

OpenCLI Gemini Adapter 实战指南:用浏览器会话在命令行驱动 Gemini Web

【免费下载链接】OpenCLIMake Any Website into CLI & Use your logged-in browser by AI agent.项目地址: https://gitcode.com/gh_mirrors/ope/OpenCLI

本指南围绕 docs/adapters/browser/gemini.md 展开,系统讲解 OpenCLI 如何通过已登录的浏览器会话,把gemini.google.com消费版 Web UI 变成一套可脚本化的命令行接口(opencli gemini)。读完本文,你将掌握 Gemini 的对话问答、图像生成、模型枚举、Deep Research 启动与报告导出、历史会话管理等全部子命令的用法与参数,并理解其背后"驱动真实浏览器而非公共 API"的实现原理与注意事项。

Gemini 适配器是什么

Gemini 适配器是 OpenCLI 众多"网站适配器"之一,通过 Browser Bridge 扩展 与正在运行的 Chrome 通信,复用你已登录的浏览器会话操作 Gemini 网页。它不调用 Gemini 公共 API,而是直接驱动消费版网页:自动定位输入框(composer)、点击模型选择器、读取对话快照、等待回复生成。

该适配器对应源码位于 clis/gemini/,包含askimagemodelsnewdeep-researchdeep-research-resultstatushistorydetailread共 10 个命令。核心工具函数集中在 utils.js(约 2700 行),其中定义了域名常量、composer 定位脚本、对话快照读取脚本、回复去噪逻辑等。

从 utils.js 可以看到适配器的目标域与入口页:

export const GEMINI_DOMAIN = 'gemini.google.com'; export const GEMINI_APP_URL = 'https://gemini.google.com/app';

所有opencli gemini命令的domain均指向该域名,并以Strategy.COOKIE策略(复用浏览器 Cookie 会话)和siteSession: 'persistent'(持久站点会话)运行。

环境要求(Prerequisites)

使用前需满足以下三个条件(对应原文档 Prerequisites 章节):

  • Chrome 正在运行:适配器通过浏览器桥接控制已打开的 Chrome 实例;
  • 已登录gemini.google.com:命令复用的是登录态,不会替你处理账号密码;
  • 已安装 Browser Bridge 扩展:它是 OpenCLI 与浏览器页面之间的通信通道。

此外,可参考 入门指南 和 安装指南 完成 OpenCLI 本身的安装配置。

命令总览

CommandDescription
opencli gemini newStart a new Gemini web chat
opencli gemini ask <prompt> [--model <value>] [--thinking <level>]Send a prompt and return only the assistant reply
opencli gemini image <prompt>Generate images in Gemini and optionally save them locally
opencli gemini modelsList available Gemini models
opencli gemini deep-research <prompt>Start a Gemini Deep Research run and confirm it
opencli gemini deep-research-result <query>Export Deep Research report URL from a Gemini conversation
opencli gemini statusCheck Gemini web page availability and login state
opencli gemini history [--limit N]List visible Gemini conversation history from the sidebar
opencli gemini detail <id>Open a Gemini conversation by id, URL, or sidebar title and read its turns
opencli gemini readRead the turns visible in the current Gemini web conversation

从命令的access属性(定义于各命令注册处)可以看到权限划分:

  • 只读命令access: 'read'):newmodelsstatushistorydetailreaddeep-research-result
  • 写命令access: 'write'):askimagedeep-research

例如 new.js 注册为只读命令并输出Status/Action两列;ask.js 注册为写命令、默认纯文本输出;status.js 输出Status/Login/Url三列;history.js 输出Index/Id/Title/Url四列。

快速上手:十个命令的实战用法

原文档给出了完整的命令行示例,下面逐组展开并补充参数说明:

新建会话

opencli gemini new

该命令调用startNewGeminiChat(page),优先点击侧边栏 "New chat" 按钮;若按钮不可用则回退为重新加载/app页面(源码见 new.js,对应startNewGeminiChat返回'clicked''navigate'两种动作)。命令完成后会输出Success / Clicked New chatSuccess / Reloaded /app as fallback

问答(ask)

# 发送 prompt,只返回助手回复 opencli gemini ask "Reply with exactly: HELLO" # 指定模型 opencli gemini ask "Explain quantum computing in one sentence" --model 2.5-flash # 新开会话并延长等待时间 opencli gemini ask "Summarize this design in 3 bullets" --new true --timeout 90 # 扩展思考模式 opencli gemini ask "Explain quantum computing" --thinking extended # 标准思考 + 新会话 opencli gemini ask "Hello" --new true --thinking standard # 模型 + 思考等级组合 opencli gemini ask "Explain quantum computing in one sentence" --model 2.5-pro --thinking extended # 新会话 + 指定模型 + 指定思考等级 opencli gemini ask "Summarize this design in 3 bullets" --new true --model 2.5-flash --thinking standard

ask的完整执行流程(源码见 ask.js)值得细说:

  1. 新会话先行:若--new true,先调用startNewGeminiChat新建会话;
  2. 参数预校验--model必须符合规范 ID 格式(见下文),--thinking仅接受standardextended--timeout必须是正整数(默认 60 秒);
  3. 模型/思考发现:当指定了--model--thinking时,脚本点击模型选择器按钮、等待 React 渲染菜单、读取模型条目后关闭菜单;
  4. 模型选择:校验目标模型 ID 存在于发现列表中,然后调用selectGeminiModel选中;
  5. 思考等级选择:优先按目标模型(指定--model时为该模型,否则为当前页面模型)对应的thinkingValues校验,再调用selectGeminiThinking选择;
  6. 发送与等待:读取会话快照 →sendGeminiMessage发送 →waitForGeminiSubmission等待提交 →waitForGeminiResponse等待回复。

回复以💬前缀输出纯文本;若在超时内未获得回复,则返回💬 [NO RESPONSE] No Gemini response within <timeout>s.。回复文本会经过 utils.js 的sanitizeGeminiResponseText清洗,去除 "Gemini can make mistakes"、"Google Terms" 等页面噪音文案,并剥离与 prompt 相同的前缀部分。

图像生成(image)

# 生成图标,指定比例与风格 opencli gemini image "Generate a tiny cyan moon icon" --rt 1:1 --st icon # 仅在 Gemini 中生成,打印页面链接,不下载 opencli gemini image "A watercolor sunset over a lake" --sd true # 自定义图片保存目录 opencli gemini image "A flat illustration of a robot" --op ~/tmp/gemini-images

image命令(源码见 image.js)有几点实现细节:

  • 总是新会话:每次执行前都会调用startNewGeminiChat,确保从干净的对话开始(源码硬编码const startFresh = true);
  • 比例与风格会拼进提示词buildImagePrompt会把aspect ratio <ratio>style <style>追加为 "Image requirements: ..." 段落(image.js);
  • 比例白名单--rt仅接受1:116:99:164:33:43:22:3,非法值回退为1:1(image.js);
  • 输出目录解析--op支持~展开与绝对/相对路径,默认~/tmp/gemini-images(image.js);
  • 下载逻辑:等待图像 URL 出现 → 通过exportGeminiImages导出 base64 → 按 MIME 类型推断扩展名(png/webp/gif/jpg)→ 保存为gemini_<时间戳>[_N].<ext>
  • 输出格式:不使用表格,纯文本输出status / file / link三元组,如✅ saved / 📁 ~/tmp/gemini-images/gemini_1717....png / 🔗 <链接>--sd true时输出🎨 generated / 📁 - / 🔗 <链接>,仅保留对话链接不下载;
  • 超时--timeout默认 240 秒,控制整个等待生成过程。

若未检测到生成的图片,命令会抛出EmptyResultError并提示打开对话链接人工确认(image.js)。

枚举模型(models)

# 列出可用模型 opencli gemini models # 以 JSON 输出,便于脚本处理 opencli gemini models -f json

models命令(源码见 models.js)是只读命令,其行为要点与原文档一致:

  • 从 Gemini Web UI 可见的模型选择器中动态发现可用模型,而不是硬编码列表;
  • 依次执行:点击模型选择器按钮 → 等待 React 渲染菜单(page.wait(1.0))→ 读取菜单项并解析规范模型 ID → 关闭菜单;
  • 不会选择模型、更改思考等级、新建会话或提交任何提示词;
  • 解析逻辑(canonicalModelId,见 models.js)支持从显示文本中提取规范 ID,例如"3.1 flash-lite"3.1-flash-lite"2.5-flash-thinking"2.5-flash-thinking"Gemini 3.0 Pro experimental"3.0-pro-experimental,也兼容带中文描述的条目(如"3.1 Flash-Lite 极速回答");
  • 输出两列:model(规范 ID,如2.5-flash2.5-pro2.5-flash-lite)与thinkingValues
  • thinkingValues仅在 Gemini 直接在模型条目上暴露思考等级时才填充,否则为[]——当前 Gemini UI 通常只对当前激活模型显示思考控件,因此该命令不做全模型的推断(models.js 注释对此有明确说明);
  • 当模型选择器无法打开时抛出命令错误(用于暴露 Gemini Web UI 的变更);仅当选择器成功打开但没有任何模型条目时才返回空列表。

Deep Research 启动与报告导出

# 启动一次 Gemini Deep Research 运行并确认 opencli gemini deep-research "<研究主题>" # 从某个会话导出 Deep Research 报告 URL opencli gemini deep-research-result "<会话标题或 URL>"

deep-research(源码见 deep-research.js)的执行链路是:新建会话 → 通过工具菜单选择 "Deep Research"(默认工具标签列表见 utils.js 的GEMINI_DEEP_RESEARCH_DEFAULT_TOOL_LABELS,同时兼容英文 "Deep Research" 与中文 "深度研究")→ 发送提示词 → 等待提交 → 等待确认按钮(默认标签 "Start research" / "开始研究" 等,见GEMINI_DEEP_RESEARCH_DEFAULT_CONFIRM_LABELS)→ 输出status / url

实现上还包含多重容错:

  • 提交失败时自动重试一次(重新选工具、重新发送);
  • 确认点击出现"假阳性"(仍在/app根 URL)时重试确认;
  • 若页面先渲染出研究计划卡片,会再次点击确认按钮(不重复发送 prompt,避免产生重复会话);
  • 通过parseDeepResearchProgress解析回复文本,判断是否处于 "researching"(研究中)状态。

--tool--confirm参数可覆盖默认标签;--timeout默认 180 秒,其中提交等待被内部限制在 6~20 秒。

deep-research-result(源码见 deep-research-result.js)用于导出报告:

  • query可选:可以是会话标题URL,缺省时取最新会话;
  • --match contains|exact控制标题匹配模式,默认contains
  • 若是 URL 且属于gemini.google.com/app/路径,直接跳转;否则先从侧边栏会话列表解析目标会话;
  • 等待导出后返回Docs 报告 URL;若研究仍在运行返回提示等待重试;若已完成但未找到 Docs URL,提示在 Gemini UI 中通过 "Share & Export → Export to Docs" 手动导出。

状态、历史、详情与阅读

# 检查页面可用性与登录状态 opencli gemini status # 列出侧边栏可见的历史会话(默认 20 条,最多 200 条) opencli gemini history [--limit N] # 按 id / URL / 侧边栏标题打开会话并读取轮次 opencli gemini detail <id> # 读取当前 Gemini 会话中可见的轮次 opencli gemini read
  • status:通过getGeminiPageState检测页面 URL、标题、登录态(是否存在 "Sign in" / "登录" 链接或 Google 登录跳转)、composer 是否可用。isSignedIntrue/false/null三态,null表示可见 composer 但未发现显式登录入口,按已登录处理(status.js);
  • history:从侧边栏收集a[href*="/app"]链接并展开折叠的 "最近 / Recents" 分区(见 utils.js 的expandGeminiRecentScript),过滤掉无 ID 的 "New chat" 项,输出Index / Id / Title / Url--limit必须为 1~200 的整数(history.js);
  • read:读取当前页面可见的对话轮次,输出Index / Role / TextRoleUserAssistant;无可读轮次时抛出EmptyResultError(read.js)。轮次提取脚本见 utils.js 的getTurnsScript,通过[data-testid*="message"][data-test-id*="message"][class*="message"]等选择器定位消息节点,并结合 DOM 顺序排序、按data-message-author-role等属性推断角色;
  • detail:接受会话 ID、完整 URL 或侧边栏标题,定位后打开并读取轮次。

参数详解

ask参数

OptionDescription
promptPrompt to send (required positional argument)
--modelGemini model to use (e.g.2.5-flash,2.5-pro). Useopencli gemini modelsto list available values.
--timeoutMax seconds to wait for a reply (default:60)
--newStart a new chat before sending (default:false)
--thinkingThinking level:standardorextended(omitted = leave unchanged)

关于--model的格式约束:源码中的validateAskModelValue(ask.js)规定了两条硬性规则:

  1. 必须包含版本号(匹配\d+\.\d+),因此proflashflash-lite这类短别名一律被拒绝
  2. 必须是X.Y-variant的规范格式(正则^\d+\.\d+-[a-z][a-z-]*$),例如2.5-flash3.1-pro合法,2.5flash非法。

错误信息会明确提示:"Short aliases like 'pro', 'flash', or 'flash-lite' are not supported. Use a canonical model id (e.g. '2.5-flash')."

关于--thinking:仅接受standardextended(大小写不敏感),其余值直接抛ArgumentError。指定后,脚本会先按目标模型(或当前模型)的thinkingValues校验可用性,再调用selectGeminiThinking实际操作页面控件;若无法在 UI 中选中,会给出包含可用取值提示的错误。

关于--timeout:必须是正整数,等待回复期间先等提交(waitForGeminiSubmission),提交成功后再用剩余时间等回复(waitForGeminiResponse),两个阶段合计不超过--timeout秒(ask.js)。

image参数

OptionDescription
promptImage prompt to send (required positional argument)
--rtAspect ratio shorthand:1:1,16:9,9:16,4:3,3:4,3:2,2:3
--stOptional style shorthand, e.g.icon,anime,watercolor
--opOutput directory for downloaded images (default:~/tmp/gemini-images)
--sdSkip download and only print the Gemini page link

补充说明:

  • --rt为白名单校验,非法值静默回退为1:1
  • --st为自由文本风格,会拼入提示词的 "Image requirements" 段;
  • --op支持~开头路径展开;未指定时保存到~/tmp/gemini-images,文件名形如gemini_<毫秒时间戳>.png,多图时追加_1_2后缀;
  • --sd为布尔开关,开启后不下载,仅打印🎨 generated / 📁 - / 🔗 链接
  • 另有未在文档表格中列出的--timeout(默认 240 秒),用于控制整个生成等待。

models输出列

ColumnDescription
modelCanonical model ID (e.g.2.5-flash,2.5-pro,2.5-flash-lite)
thinkingValuesPer-model thinking levels only when Gemini exposes them directly on the model entry; otherwise[]. The current Gemini UI usually exposes thinking controls for the active model, so this command does not infer support for every model.

补充行为要点(与源码一致):

  • models从可见的 Gemini Web UI 模型选择器中动态发现可用模型;
  • 命令是只读的:不选择模型、不改变思考等级、不新建会话、不提交提示词;
  • 模型 ID 与后续gemini ask --model使用的规范格式一致;
  • 模型选择器无法打开时抛出命令错误(用于暴露 Gemini Web UI 变更);仅当选择器打开但无模型条目时返回空列表。

关键行为细节

以下行为均可在源码中得到印证:

  • --new true--model/--thinking的组合顺序:先创建新会话,再选择模型与思考等级,然后读取快照,最后提交提示词(ask.js 的注释与调用顺序明确说明了这一点);
  • ask --model的可见副作用:选定模型后,该模型在 Gemini Web UI 中保持选中状态;省略--model时不会改变当前模型(ask.js);
  • 其余命令不受--model影响imagedeep-research等命令不接受--model
  • ask使用极简输出:只返回💬前缀的助手回复文本,而不是表格;
  • image同样使用纯文本输出:打印status / file / link而非表格;
  • image总是从全新会话开始startFresh = true硬编码);
  • --sd启用时:图像保留在 Gemini 中,只打印会话链接。

会话模型与持久化

原文档 Caveats 章节提到的一个关键机制是持久站点会话(persistent site session)。所有 Gemini 命令注册时都带有siteSession: 'persistent'(如 ask.js、image.js),含义是:连续的gemini ask/gemini image/gemini deep-research-result调用会继续使用同一个 Gemini 页面标签,而不是每次新建标签页。这样既减少了重复登录/加载开销,也让命令之间可以共享上下文。

若希望一次性标签(one-shot tab)执行,可以传入--site-session ephemeral

实现原理:网页驱动的关键机制

为了让文章不仅"会用",还能理解"为什么这样实现",下面补充几个源码层面的核心机制:

1. composer 定位与操作。适配器通过一组选择器定位输入框(utils.js):优先匹配.ql-editor[contenteditable="true"],其次按aria-label包含 "Gemini" 或 "prompt for Gemini" 的[contenteditable]元素。定位成功后,会打上data-opencli-gemini-composer标记以去重,并通过焦点管理、InputEvent派发等模拟真实输入(prepareComposerScript/insertComposerTextFallbackScript)。发送时优先点击附近符合条件的发送按钮,否则回退为派发 Enter 键事件(submitComposerScript/dispatchComposerEnterScript)。

2. 快照与增量比对readGeminiSnapshotScript会采集当前页面的 URL、对话轮次(turns)、文本行(transcriptLines)、composer 是否有文本、是否正在生成(通过是否存在 "Stop response / 停止回答" 控件判断)等状态(utils.js)。发送 prompt 前后各取一次快照,通过比对增量行/追加轮次来确定"哪些内容是本次回复",从而精准提取助手输出。

3. 回复去噪sanitizeGeminiResponseText会移除 "Gemini can make mistakes"、"Google Terms"、"Google Privacy Policy"、"Opens in a new window" 等常见页面噪音(utils.js 定义的正则列表),确保返回给脚本的是干净的回复文本。

4. 会话列表与标题定位。侧边栏会话通过a[href*="/app"]链接收集,并自动展开折叠的 "Recents / 最近" 分区;detail支持按标题匹配(contains/exact两种模式)定位会话,标题会先做空白归一化与小写化再匹配(utils.js)。

常见问题与注意事项(Caveats)

原文档明确了以下边界,使用时应特别留意:

  • 该适配器驱动的是 Gemini 消费版 Web UI,而非公共 API。这意味着它依赖页面的 DOM 结构,行为可能随 Gemini 前端更新而变化;
  • 依赖当前浏览器会话:若 Gemini 出现登录、同意(consent)、验证(challenge)、配额(quota)或其他门禁 UI,命令可能失败;
  • DOM 或产品变更风险:Gemini 页面变化可能破坏 composer 检测、新会话处理或图片导出行为。models命令在模型选择器无法打开时抛出错误,正是为了尽早暴露这类 UI 变更;
  • 持久会话:默认在同一个 Gemini 页面中连续操作,需要一次性标签时使用--site-session ephemeral

结合测试用例进一步验证

仓库为 Gemini 适配器提供了较完整的测试覆盖,可作为行为契约参考:

  • commands.test.js:命令注册与参数契约测试;
  • ask.test.js:ask命令的模型校验、thinking 校验等行为测试(含validateAskModelValue的导出测试入口,见 ask.js);
  • models.test.js:模型发现脚本与规范 ID 解析测试;
  • image.test.js、image-pipeline.test.js:图像生成管线测试;
  • deep-research.test.js、deep-research-result.test.js:Deep Research 启动与导出测试;
  • reply-state.test.js:回复状态/快照比对逻辑测试;
  • utils.test.js:工具函数(URL 解析、标题匹配、文本清洗、会话列表等)测试。

这些测试一方面固化了命令行为,另一方面也说明该适配器对 Gemini 网页 DOM 的强依赖——任何 UI 改版都可能需要同步调整脚本。

小结

OpenCLI 的 Gemini 适配器把浏览器会话变成了可编程接口:ask负责纯文本问答、image负责图像生成与本地保存、models动态枚举模型、deep-research/deep-research-result覆盖完整的研究闭环,status/history/detail/read则提供会话管理与只读巡检能力。它不依赖 Gemini API 密钥,仅需一个已登录的 Chrome 与 Browser Bridge 扩展即可工作,非常适合与 OpenCLI 的自动化管线、脚本任务结合使用。唯一需要留意的是它面向网页 DOM 的脆弱性——建议在 Gemini 页面改版后通过opencli gemini statusopencli gemini models快速探测适配器是否仍然可用。

【免费下载链接】OpenCLIMake Any Website into CLI & Use your logged-in browser by AI agent.项目地址: https://gitcode.com/gh_mirrors/ope/OpenCLI

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询