使用 Transformers.js 在 Chrome 扩展程序中

使用 Transformers.js 在 Chrome 扩展程序中

Hugging Face 发布了一个由 Gemma 4 E2B 驱动的演示浏览器扩展,以展示如何在 Chrome 扩展程序中运行本地 AI 功能。该实现利用 Transformers.js 在清单 V3 限制下,采用了一种解耦架构:后台服务工作器管理模型编排,而 UI 和内容脚本保持为薄客户端。

Chrome 扩展程序架构(清单 V3)

核心架构策略是将关注点分离到三个主要的 Chrome 运行时上下文,以确保 UI 响应能力并避免重复加载模型。

运行时上下文和入口点

manifest.json 所定义,扩展程序使用三个入口点:

  • 后台服务工作器 (background.js):充当代理生命周期、模型初始化和工具执行的控制平面。
  • 侧边面板 (sidebar.html):作为聊天输入/输出和流式更新的交互层。
  • 内容脚本 (content.js):作为页面桥梁,用于 DOM 提取和突出显示操作。

消息传递和编排

由于这些运行时是隔离的,一个通过枚举定义的类型化消息协议协调操作。后台服务工作器充当单一协调者:

  1. 侧边面板发送请求(例如,AGENT_GENERATE_TEXT)。
  2. 后台工作器将消息追加到对话历史中,运行推理,并执行工具。
  3. 后台工作器发送更新(例如,MESSAGES_UPDATE)回到侧边面板以进行渲染。

Transformers.js 集成详情

模型角色和职责

扩展程序采用两种不同的模型来平衡推理和检索:

  • 文本生成 (LLM): onnx-community/gemma-4-E2B-it-ONNX (q4f16) 负责推理和工具调用决策。
  • 向量嵌入: onnx-community/all-MiniLM-L6-v2-ONNX (fp32) 为历史和网站内容中的语义相似性搜索生成嵌入。

推理和缓存

所有推理在后台服务工作器中使用 pipeline("text-generation", ...)DynamicCache 类进行一致的 KV 缓存,以及使用 pipeline("feature-extraction", ...) 进行嵌入。

将推理托管在后台工作器中可确保模型工件缓存在扩展源 (chrome-extension://<extension-id>) 下,而不是按网站源,从而在整个安装过程中提供共享缓存。开发者必须考虑清单 V3 的生命周期,因为服务工作器可能会被挂起和重启,需要模型运行时状态可恢复。

代理和工具执行循环

工具调用机制

Transformers.js 使用特定于模型的聊天模板来格式化提示。对于 Gemma 4,模型在决定调用工具时会发出特殊的工具调用令牌块(例如,<|tool_call>call:getWeather{location:<|">Bern<|">}<tool_call|>)。扩展程序使用归一化层(webMcp)和解析器(extractToolCalls)将这些模型输出转换为确定性执行。

循环设计 (Agent.runAgent)

扩展程序将内部模型转录与面向用户的聊天消息分开:

  • 内部转录:包含用于 generator(...) 函数的系统、用户、工具和助手轮次。
  • UI 转录:包含流式助手文本、工具执行元数据和性能指标。

执行流程遵循一个循环:用户输入被添加 $\rightarrow$ 令牌被流式传输 $\rightarrow$ 在后台解析并执行工具调用 $\rightarrow$ 结果被反馈到提示中 $\rightarrow$ 循环重复,直到没有工具调用为止。

数据边界和持久性

状态根据生命周期和访问模式进行分布,以优化性能和持久性:

  • 对话状态:存储在后台内存(Agent.chatMessages)中以实现快速编排。
  • 工具偏好:在会话之间持久化存储在 chrome.storage.local 中。
  • 语义历史向量:存储在 IndexedDB(VectorHistoryDB)中以进行本地检索。
  • 提取的页面内容:在后台缓存(WebsiteContentManager)中进行管理,以活动 URL 为键。

构建和打包

为了满足清单 V3 的要求,项目通过 Vite 使用多入口构建,确保每个 Chrome 入口点有一个工件。内容脚本被保持为自包含输出,以防止运行时块加载问题,输出名称完全对齐于 manifest.json 的定义。

Sources