Gemini Voyager 默认模型功能解析:为 Gemini 设置默认模型并自动切换的完整实现指南
【免费下载链接】voyagerEnhancement suite for Gemini, AI Studio, Claude & ChatGPT — plus a prompt manager for any websites, DeepSeek Harness included. / 面向 Gemini、AI Studio、Claude 与 ChatGPT 的增强套件;其中的提示词管理器可用于任意网站,如 DeepSeek Harness。项目地址: https://gitcode.com/gh_mirrors/ge/voyager
默认模型(Default Model)是 Gemini Voyager 为 Gemini™ 提供的一项增强能力:在 Gemini 的模型选择菜单中注入“星标”按钮,让用户为模型设置默认项,并在每次开启新对话时由插件自动切换过去,省去手动切换的重复操作。本文基于仓库中的功能文档与源码实现,完整讲解该功能的使用方法、数据模型、底层注入与自动切换原理,以及仓库测试所验证的边界行为,帮助你既会用它,也理解它背后的浏览器扩展工程细节。
功能版本说明:该功能仅在 Gemini Voyager 1.1.9 及后续版本中支持,对应源码位于 src/pages/content/defaultModel/。
功能特点
在 Gemini 中开启新对话后,模型选择器默认停留在 Gemini 自带的快速模型上;如果你习惯使用 Pro 或其他模型,每次新对话都需要手动切换。默认模型功能从四个方面解决这个问题:
- 交互式设置:在 Gemini 的模型选择菜单中直接注入“星标”按钮,无需进入扩展设置页即可完成配置;
- 自动切换:开启新对话时,插件会自动为你切换到预设的默认模型;
- 持久化保存:偏好会被保存,如果开启了插件同步,还会跨设备同步;
- 优化体验:针对单页应用(SPA)优化,无论是点击“新对话”按钮、使用快捷键,还是直接访问
/app路径,都能准确触发。
从源码结构看,该功能同时支持模型默认与“思考级别”(Standard / Extended)默认两套偏好,二者共用同一套星标交互与自动应用框架。
如何使用
按照以下步骤即可完成默认模型的设置与取消:
- 点击 Gemini 输入框上方的模型选择器,打开模型菜单;
- 鼠标悬停在想要设为默认的模型上,点击出现的空心星标;
- 星标变为实心后,该模型即被设为默认,页面底部会弹出“Default model set: xxx”的提示;
- 下次访问首页或发起新对话时,系统会自动为你选中该模型;
- 如需取消,再次点击实心星标即可,此时提示为“Default model cleared”。
如果你将鼠标悬停到某个模型项上但星标未出现,可以确认扩展版本是否不低于 1.1.9,并检查模型菜单是否成功被扩展识别(见下文“注入逻辑”)。
偏好数据模型与存储键
默认模型的偏好通过扩展的存储服务持久化,底层存储键定义在 src/core/types/common.ts:
| 存储键 | 值 | 说明 |
|---|---|---|
gvDefaultModel | 模型 ID + 名称(或兼容的纯名称字符串) | 用户星标的默认模型 |
gvDefaultThinkingLevel | 索引 + 标签 + 模式 | 用户星标的默认思考级别 |
gvDefaultModelAutoApply | true/false | 自动应用开关(主开关) |
从 modelLocker.ts 的解析逻辑(parseStoredDefaultModel)可以看出存储的两种形态:
- 对象形态:
{ id, name, pill? },id是 Gemini 页面上的稳定模型标识(data-mode-id),name是完整名称,pill是 Gemini 触发器上显示的短标签(如 “Flash”),由插件从页面学习而非用户输入; - 兼容形态:纯字符串(仅旧版本名称),会被自动升级为带 ID 的对象形态。
思考级别的存储为{ index, label, mode? },其中mode取standard或extended。值得注意的是,源码注释明确说明Standard 是 Gemini 内置的默认思考级别,因此锁定到 Standard 永远不会产生实际动作(见checkAndLockModel中isPageDefaultThinkingLevel的判断),只会白白让选择器闪开一次,实现时将其视为“无思考偏好”。
星标注入:在模型菜单中“长”出来的按钮
默认模型功能的交互入口是注入到 Gemini 模型菜单中的星标按钮,核心实现在 DefaultModelManager(单例类)的injectStarButtons与injectThinkingLevelStars方法中。整个注入过程需要考虑 Gemini 复杂的 DOM 结构:
- 菜单面板识别:Gemini 的历史版本使用 Material 菜单(
.mat-mdc-menu-panel),2026 年改版后模型选择器渲染在普通的cdk-overlay-pane中,通过包含[data-mode-id]条目来识别;移动端则是mat-action-list.gds-mode-switch-menu-list底部面板; - 模型项定位:菜单项同时兼容
role="menuitemradio"与role="menuitem"两种形态,模型 ID 从data-mode-id属性读取,紧凑布局下则回退解析jslog元数据中的 16 位十六进制 ID; - 星标按钮生命周期:按钮类名为
gv-default-star-btn,通过MutationObserver监听菜单面板的挂载,注入失败时最多重试 10 次(间隔 50ms),并在每次注入前清理不属于当前菜单项的“孤儿星标”,避免 Angular 视图复用造成的重复星标; - 命中校验:为避免把星标注入到设置/主题等非模型菜单,注入前会校验面板是否包含
[data-mode-id]、.mode-title或.title-and-description等模型菜单特征;测试 modelLocker.test.ts 中专门验证了“不向设置菜单注入星标”与“不向主题子菜单注入星标”。
星标按钮的点击通过e.stopPropagation()与e.preventDefault()阻止冒泡,避免误触发 Gemini 自身的菜单项选中逻辑,同时采用“先更新 UI 再异步写存储”的乐观更新策略,保证点击反馈即时。
自动切换:面向 SPA 的锁定循环
设置默认模型后,插件通过checkAndLockModel及其内部的锁定循环(lock loop)在每次新对话时自动切换模型。仓库测试对该循环的描述将其称为default model locker(默认模型锁)。
触发时机:新对话判定
isNewConversation使用正则/^\/(u\/\d+\/)?(app\/?|gem\/.*)$/判定当前是否处于新对话页,兼容多账号路径/u/0/app以及/gem/xxx路径。触发来源包括:
- 页面加载:
init时立即执行一次; - SPA 路由变化:通过共享的路由监听器
watchRouteChanges(来自src/pages/content的路由工具)覆盖浏览器历史事件与页面内 SPA 导航,仅当路径变化且判定为新对话时才触发,避免重复执行; - 同路径“新对话”点击:点击当前
/app页面内 href 不变的“新对话”链接时,路由监听器无法感知,因此单独注册了捕获阶段的 click 监听作为语义化例外。
锁定循环与快速路径
每次触发后,插件以 1 秒为间隔运行最多 5 次tickLock。每次 tick 先读取模型选择器触发按钮(pill)上的文本行做快速路径判定:
- 模型名匹配采用双向整词匹配:既判断存储名称是否是 pill 文本的整词子串,也判断 pill 是否是存储名称的整词子串——因为 Gemini 的 pill 显示短名(“Pro”)而菜单项保存全名(“3.1 Pro”);
- 若 pill 已显示正确模型且无思考级别偏好,则立刻停止循环,不会闪烁式地打开选择器;
- 若不匹配,才打开模型菜单,按 ID 优先、名称其次、全文整词匹配兜底的顺序查找目标项并模拟点击,成功后延迟 120ms 聚焦回聊天输入框,让用户可以直接输入。
智能跳过与防打扰
实现中包含多项避免打扰用户的设计:
- Flash/快速模型跳过:
FAST_MODEL_IDS与FAST_MODEL_NAMES记录了 Gemini 默认的 Flash/Fast 模型,如果默认就是它们,直接跳过自动切换(页面本来就是这个状态); - 让位于用户输入:通过
shouldYieldToUserComposerActivity检测聊天输入框是否已有内容或在 8 秒内有过输入活动,若用户在操作则立即停止循环,绝不打断输入; - 会话去重:每次导航生成唯一的
autoSelectSessionId,循环过程中若发现会话已变化(用户导航离开又回来)立即终止,防止重复切换; - 失败熔断:连续 3 次无法找到目标模型(例如模型配额耗尽或 Gemini 改版)时停止重试,并弹出一次提示 toast,建议用户在设置中暂停该功能。
思考级别:扩展默认偏好
除了模型本身,2026 年改版后的 Gemini 在选择器中提供了“思考级别”选项。该功能同样支持将其设为默认:
- 对当前的单行Extended thinking开关(通过稳定的 jslog 事件 ID 识别),注入“思考级别星标”;
- 对旧版 Standard / Extended 子菜单形态,通过
value="thinking_level"行及其aria-controls关联的子菜单面板定位并注入星标; - 存储的标签用于在菜单中回填星标状态,采用“先按标签匹配、标签失效才回退索引”的策略(
resolveThinkingDefaultIndex),避免存储索引与标签漂移时同时点亮两颗星标的问题。
自动应用开关:随时可暂停的总闸
当 Gemini 改版导致自动切换失效时,用户无需卸载扩展,可以在扩展弹窗中关闭自动应用。该开关位于 GeneralSettingsCard.tsx 的“Auto-apply default model on new chats”项,由 useGeneralPopupSettings.ts 读写gvDefaultModelAutoApply键,默认值为true(缺失视为开启,兼容旧版本用户)。
关闭开关后:
- 所有自动应用路径短路,但页内星标 UI 仍然可用,用户依然可以设置/清除默认模型;
- 通过
chrome.storage.onChanged监听实现无需刷新页面即时生效:关闭时立即清除已注入的星标并终止正在运行的锁定循环,重新开启时重置失败计数并立即执行一次锁定检查; - 防止“星标残留”:初始化与观察器在关闭状态下仍会主动清扫 DOM 中残留的
gv-default-star-btn,避免用户看到可点击但无效果的星标。
仓库测试:行为边界的工程保障
该功能配套了详尽的单元测试 modelLocker.test.ts(基于 Vitest),用模拟 DOM 验证了关键行为,可作为理解实现的补充证据:
- 性能保障:50 次无关 DOM 突变不会触发对菜单面板的全局查询,避免页面卡顿;
- 菜单形态兼容:菜单项后渲染、
role="menuitem"变体、移动端底部面板、jslog 元数据兜底等场景均能正确注入星标; - 自动锁定正确性:按 ID 锁定不受语言影响(日语“思考モード”也能命中);不会把描述文本中的 “pro” 误认为 “Pro” 模型;默认 Flash 时零点击跳过;
- 防打扰:用户在输入框开始输入或 8 秒内有键盘活动时,不会自动切换模型;
- pill 标签学习:对已选中的 Flash 变体学习其短标签(“Flash”),之后可快速确认而无需打开选择器;同时拒绝学习与所选行不一致的标签,防止“教坏”快速路径;
- 跟随改名:同一模型 ID 被 Gemini 改名(3.8 Flash → 3.9 Flash)时,自动更新存储名称并保持默认设置有效。
常见问题与失败兜底
- 为什么自动切换偶尔闪一下选择器?这是锁定循环正在读取菜单项状态以确认目标模型;若你已经手动选择过正确模型,快速路径会直接判定成功而不再打开菜单。
- 为什么提示“Default model couldn't auto-apply after 3 tries”?连续 3 次无法完成自动切换时触发,通常意味着 Gemini 改版导致菜单结构变化或目标模型在当前账号不可用。toast 上的“Pause in settings”按钮会尝试直接打开扩展弹窗(Firefox 等禁止程序化弹窗的浏览器中会退化为手动打开弹窗的提示文案)。
- 如何彻底关闭?打开扩展弹窗,关闭 “Auto-apply default model on new chats” 开关;已设置的默认模型不会被删除,随时可以重新开启。
总结
默认模型功能是 Gemini Voyager 对“重复操作自动化”的一次完整实践:通过星标注入提供零成本配置入口,用面向 SPA 的路由监听与锁定循环实现可靠自动切换,以存储键 + 同步机制保证跨设备一致性,再用熔断、防打扰与总开关设计保障稳定性。从 功能文档 到 核心实现 与 测试套件,这份代码为理解浏览器扩展如何优雅地增强第三方 SPA 提供了一个高完成度的参考样本。
【免费下载链接】voyagerEnhancement suite for Gemini, AI Studio, Claude & ChatGPT — plus a prompt manager for any websites, DeepSeek Harness included. / 面向 Gemini、AI Studio、Claude 与 ChatGPT 的增强套件;其中的提示词管理器可用于任意网站,如 DeepSeek Harness。项目地址: https://gitcode.com/gh_mirrors/ge/voyager
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考