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/,包含ask、image、models、new、deep-research、deep-research-result、status、history、detail、read共 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 本身的安装配置。
命令总览
| Command | Description |
|---|---|
opencli gemini new | Start 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 models | List 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 status | Check 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 read | Read the turns visible in the current Gemini web conversation |
从命令的access属性(定义于各命令注册处)可以看到权限划分:
- 只读命令(
access: 'read'):new、models、status、history、detail、read、deep-research-result; - 写命令(
access: 'write'):ask、image、deep-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 chat或Success / 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 standardask的完整执行流程(源码见 ask.js)值得细说:
- 新会话先行:若
--new true,先调用startNewGeminiChat新建会话; - 参数预校验:
--model必须符合规范 ID 格式(见下文),--thinking仅接受standard或extended;--timeout必须是正整数(默认 60 秒); - 模型/思考发现:当指定了
--model或--thinking时,脚本点击模型选择器按钮、等待 React 渲染菜单、读取模型条目后关闭菜单; - 模型选择:校验目标模型 ID 存在于发现列表中,然后调用
selectGeminiModel选中; - 思考等级选择:优先按目标模型(指定
--model时为该模型,否则为当前页面模型)对应的thinkingValues校验,再调用selectGeminiThinking选择; - 发送与等待:读取会话快照 →
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-imagesimage命令(源码见 image.js)有几点实现细节:
- 总是新会话:每次执行前都会调用
startNewGeminiChat,确保从干净的对话开始(源码硬编码const startFresh = true); - 比例与风格会拼进提示词:
buildImagePrompt会把aspect ratio <ratio>与style <style>追加为 "Image requirements: ..." 段落(image.js); - 比例白名单:
--rt仅接受1:1、16:9、9:16、4:3、3:4、3:2、2: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 jsonmodels命令(源码见 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-flash、2.5-pro、2.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 readstatus:通过getGeminiPageState检测页面 URL、标题、登录态(是否存在 "Sign in" / "登录" 链接或 Google 登录跳转)、composer 是否可用。isSignedIn为true/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 / Text,Role取User或Assistant;无可读轮次时抛出EmptyResultError(read.js)。轮次提取脚本见 utils.js 的getTurnsScript,通过[data-testid*="message"]、[data-test-id*="message"]、[class*="message"]等选择器定位消息节点,并结合 DOM 顺序排序、按data-message-author-role等属性推断角色;detail:接受会话 ID、完整 URL 或侧边栏标题,定位后打开并读取轮次。
参数详解
ask参数
| Option | Description |
|---|---|
prompt | Prompt to send (required positional argument) |
--model | Gemini model to use (e.g.2.5-flash,2.5-pro). Useopencli gemini modelsto list available values. |
--timeout | Max seconds to wait for a reply (default:60) |
--new | Start a new chat before sending (default:false) |
--thinking | Thinking level:standardorextended(omitted = leave unchanged) |
关于--model的格式约束:源码中的validateAskModelValue(ask.js)规定了两条硬性规则:
- 必须包含版本号(匹配
\d+\.\d+),因此pro、flash、flash-lite这类短别名一律被拒绝; - 必须是
X.Y-variant的规范格式(正则^\d+\.\d+-[a-z][a-z-]*$),例如2.5-flash、3.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:仅接受standard或extended(大小写不敏感),其余值直接抛ArgumentError。指定后,脚本会先按目标模型(或当前模型)的thinkingValues校验可用性,再调用selectGeminiThinking实际操作页面控件;若无法在 UI 中选中,会给出包含可用取值提示的错误。
关于--timeout:必须是正整数,等待回复期间先等提交(waitForGeminiSubmission),提交成功后再用剩余时间等回复(waitForGeminiResponse),两个阶段合计不超过--timeout秒(ask.js)。
image参数
| Option | Description |
|---|---|
prompt | Image prompt to send (required positional argument) |
--rt | Aspect ratio shorthand:1:1,16:9,9:16,4:3,3:4,3:2,2:3 |
--st | Optional style shorthand, e.g.icon,anime,watercolor |
--op | Output directory for downloaded images (default:~/tmp/gemini-images) |
--sd | Skip 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输出列
| Column | Description |
|---|---|
model | Canonical model ID (e.g.2.5-flash,2.5-pro,2.5-flash-lite) |
thinkingValues | Per-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影响:image、deep-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 status与opencli gemini models快速探测适配器是否仍然可用。
【免费下载链接】OpenCLIMake Any Website into CLI & Use your logged-in browser by AI agent.项目地址: https://gitcode.com/gh_mirrors/ope/OpenCLI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考