当前位置: 首页 > news >正文

浏览器自动化与AI结合:基于谷歌浏览器插件调用Nanbeige 4.1-3B

浏览器自动化与AI结合:基于谷歌浏览器插件调用Nanbeige 4.1-3B

你有没有过这样的体验?在网上阅读一篇长文,想快速抓住核心观点;或者看到一段外文资料,需要立刻翻译成中文;又或者想对一段文案进行润色,让它更专业、更有吸引力。通常,你需要复制文本,打开另一个AI工具,粘贴,等待结果,再复制回来。这个过程繁琐且打断了你的阅读和工作流。

如果能直接在网页上,选中文本,一键完成所有操作,那该多方便?今天,我们就来聊聊如何打造这样一个“网页上的AI瑞士军刀”——一个谷歌浏览器插件,它能无缝调用你本地部署的Nanbeige 4.1-3B大模型,实现文本的即时总结、翻译、改写,甚至进行深度搜索。

这不仅仅是技术上的整合,更是对工作流的一次彻底优化。想象一下,在浏览技术文档、查阅论文、阅读新闻时,一个右键菜单就能为你提供智能辅助,效率的提升是立竿见影的。下面,我将带你一步步实现这个想法,从插件的基础结构到与本地AI模型的通信,让你也能拥有一个专属的网页智能助手。

1. 为什么要在浏览器里集成AI?

在深入代码之前,我们先聊聊“为什么”。将AI能力直接嵌入浏览器,其价值远超一个简单的工具聚合。

最直接的感受是效率的飞跃。传统的“复制-切换应用-粘贴-等待-再复制”流程被简化为“选中-点击”两步。这个看似微小的改变,在实际高频使用中节省的时间是惊人的。它消除了上下文切换的成本,让你能完全沉浸在当前浏览的页面中。

其次,是场景的深度融合。AI处理的结果可以直接应用于原网页内容。例如,翻译后的文本可以悬浮显示在原文字旁边,总结的要点可以一键插入到你的笔记软件中,改写的文案能直接替换网页表单里的内容。这种“所见即所得,所点即所用”的体验,是独立AI应用难以提供的。

最后,结合本地部署的模型如Nanbeige 4.1-3B,还带来了隐私与可控性的优势。你的所有文本数据都在本地进行处理,无需上传到第三方服务器,这对于处理敏感或机密信息尤为重要。同时,你可以根据自己的需求调整模型的参数,获得更符合预期的结果。

我们的目标,就是构建一个轻量、快速、安全且强大的桥梁,连接起开放的网页世界和你本地的智能大脑。

2. 项目蓝图:插件如何与AI对话

一个谷歌浏览器插件,本质上是一组HTML、CSS、JavaScript和配置文件(Manifest)的集合。要让它在网页中捕获文本,并与后台的AI模型通信,我们需要设计一个清晰的架构。

整个系统可以看作三个核心部分:

  1. 内容脚本(Content Script):这是插件的“触手”。它被注入到我们访问的每一个网页中,负责监听我们的操作(比如鼠标选中文本),并捕获选中的内容。它生活在网页的上下文中,可以直接操作DOM。
  2. 后台脚本/服务(Background Service):这是插件的“大脑”和“调度中心”。它一直在后台运行,不直接与网页交互。它的核心职责是接收来自内容脚本的请求,然后代表插件去和“外部世界”——也就是我们本地运行的Nanbeige 4.1-3B模型API——进行通信。
  3. 用户界面(UI):这是插件的“脸”。通常是一个简单的弹出页面(Popup),用于展示设置选项,或者作为另一种触发AI功能的入口。在我们的场景中,更常见的是通过右键菜单(Context Menu)或页面内悬浮按钮来触发。

数据流是这样的:你在网页上选中文本 → 内容脚本捕获文本并发送消息给后台脚本 → 后台脚本向本地AI API发送HTTP请求 → AI模型返回处理结果 → 后台脚本将结果传回给内容脚本 → 内容脚本将结果以弹窗、侧边栏或直接修改DOM的方式展示给你。

理解了这套流程,我们就可以开始动手搭建了。

3. 第一步:搭建插件的基础骨架

首先,创建一个新的文件夹,比如叫做nanbeige-browser-helper。所有插件文件都将放在这里。

3.1 核心配置文件:manifest.json

这是插件的“身份证”和“说明书”,必须放在根目录下。

{ "manifest_version": 3, "name": "网页AI助手 (Nanbeige 4.1-3B)", "version": "1.0", "description": "选中网页文本,调用本地Nanbeige模型进行总结、翻译、改写等操作。", "permissions": [ "activeTab", "contextMenus", "storage" ], "host_permissions": [ "http://localhost:*/*", "http://127.0.0.1:*/*" ], "background": { "service_worker": "background.js" }, "content_scripts": [ { "matches": ["<all_urls>"], "js": ["content.js"], "css": ["content.css"] } ], "action": { "default_popup": "popup.html", "default_icon": { "16": "icons/icon16.png", "48": "icons/icon48.png", "128": "icons/icon128.png" } }, "icons": { "16": "icons/icon16.png", "48": "icons/icon48.png", "128": "icons/icon128.png" } }

关键点解释:

  • manifest_version: 3:必须使用Manifest V3,这是谷歌浏览器插件的新标准。
  • permissions:申请插件需要的权限。
    • activeTab:获取当前活动标签页的信息。
    • contextMenus:创建右键菜单。
    • storage:存储用户设置(如本地API地址)。
  • host_permissions非常重要!这里我们允许插件访问本地环回地址(localhost/127.0.0.1)的任何端口。因为你的Nanbeige模型API很可能就在http://localhost:8000或类似地址上运行。
  • background.service_worker:指定后台脚本文件。
  • content_scripts:定义注入到所有网页(<all_urls>)的内容脚本和样式。
  • action:定义了浏览器工具栏图标点击后弹出的页面,以及图标资源。

3.2 创建后台调度中心:background.js

后台脚本负责创建右键菜单,并处理来自内容脚本的请求。

// background.js // 存储本地API的基础URL,可以从存储中读取或使用默认值 let apiBaseUrl = 'http://localhost:8000'; // 监听插件安装事件,创建右键菜单 chrome.runtime.onInstalled.addListener(() => { chrome.contextMenus.create({ id: "nanbeige-process", title: "使用Nanbeige处理", contexts: ["selection"] // 仅在选中文本时显示 }); // 创建子菜单项 chrome.contextMenus.create({ id: "summarize", parentId: "nanbeige-process", title: "总结摘要", contexts: ["selection"] }); chrome.contextMenus.create({ id: "translate", parentId: "nanbeige-process", title: "翻译成中文", contexts: ["selection"] }); chrome.contextMenus.create({ id: "rewrite", parentId: "nanbeige-process", title: "润色改写", contexts: ["selection"] }); // 可以继续添加更多功能,如“深度搜索”、“解释代码”等 console.log('Nanbeige AI助手插件已安装,右键菜单创建成功。'); }); // 监听右键菜单点击事件 chrome.contextMenus.onClicked.addListener((info, tab) => { // 确保是在选中文本且点击了我们创建的菜单项 if (info.menuItemId && info.selectionText && ['summarize', 'translate', 'rewrite'].includes(info.menuItemId)) { const selectedText = info.selectionText; const action = info.menuItemId; // 首先,通知内容脚本:准备展示一个加载状态 chrome.tabs.sendMessage(tab.id, { type: 'PROCESSING_START' }).catch(err => console.log('页面未加载内容脚本,忽略初始化消息。')); // 然后,调用AI处理函数 processWithAI(selectedText, action, tab.id); } }); // 核心函数:调用本地AI API async function processWithAI(text, action, tabId) { // 构建请求体,格式需要匹配你的Nanbeige API let prompt = ''; switch (action) { case 'summarize': prompt = `请用中文简要总结以下文本的核心内容:\n\n${text}`; break; case 'translate': prompt = `请将以下文本翻译成流畅、专业的中文:\n\n${text}`; break; case 'rewrite': prompt = `请对以下文本进行润色和改写,使其更通顺、更有文采:\n\n${text}`; break; default: prompt = text; } const requestBody = { model: "nanbeige-4.1-3b", // 根据你的模型名称调整 messages: [ { role: "user", content: prompt } ], stream: false // 我们一次性获取结果 }; try { const response = await fetch(`${apiBaseUrl}/v1/chat/completions`, { // 假设使用OpenAI兼容的API端点 method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(requestBody) }); if (!response.ok) { throw new Error(`API请求失败: ${response.status}`); } const data = await response.json(); const aiResponse = data.choices[0]?.message?.content || '模型未返回有效内容。'; // 将处理结果发送回内容脚本,让其展示 chrome.tabs.sendMessage(tabId, { type: 'PROCESSING_RESULT', result: aiResponse, action: action }); } catch (error) { console.error('调用AI模型失败:', error); // 发送错误信息到内容脚本 chrome.tabs.sendMessage(tabId, { type: 'PROCESSING_ERROR', error: `处理失败: ${error.message}。请检查:1. 本地模型服务是否运行(如Ollama)。2. API地址(${apiBaseUrl})是否正确。` }); } }

4. 第二步:让插件在网页中“活”过来

后台脚本准备好了,现在需要让网页感知到我们的插件。

4.1 网页内的触手:content.js

内容脚本负责与用户交互,并渲染结果。

// content.js // 创建一个用于显示结果的浮动容器 let resultContainer = null; // 监听来自后台脚本的消息 chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { switch (request.type) { case 'PROCESSING_START': showLoadingIndicator(); break; case 'PROCESSING_RESULT': hideLoadingIndicator(); showResult(request.result, request.action); break; case 'PROCESSING_ERROR': hideLoadingIndicator(); showError(request.error); break; } }); // 显示加载动画 function showLoadingIndicator() { if (!resultContainer) { createResultContainer(); } resultContainer.innerHTML = `<div class="loading">AI正在思考中...</div>`; resultContainer.style.display = 'block'; } // 隐藏加载动画 function hideLoadingIndicator() { // 加载状态会被后续的结果或错误覆盖 } // 创建结果展示容器 function createResultContainer() { resultContainer = document.createElement('div'); resultContainer.id = 'nanbeige-ai-result'; document.body.appendChild(resultContainer); // 点击容器外部关闭它 document.addEventListener('click', (e) => { if (resultContainer && !resultContainer.contains(e.target)) { resultContainer.style.display = 'none'; } }); } // 展示AI处理结果 function showResult(result, action) { if (!resultContainer) { createResultContainer(); } const actionName = { 'summarize': '总结摘要', 'translate': '翻译结果', 'rewrite': '改写润色' }[action] || '处理结果'; resultContainer.innerHTML = ` <div class="result-header"> <strong>${actionName}</strong> <span class="close-btn">×</span> </div> <div class="result-content">${result.replace(/\n/g, '<br>')}</div> <div class="result-footer"> <button id="copyResultBtn">复制</button> </div> `; // 定位容器到鼠标选中的区域附近(简单实现,定位到页面中央) const viewportWidth = window.innerWidth; const viewportHeight = window.innerHeight; resultContainer.style.top = '50px'; resultContainer.style.left = `${(viewportWidth - 400) / 2}px`; // 假设容器宽400px resultContainer.style.display = 'block'; // 绑定关闭按钮事件 resultContainer.querySelector('.close-btn').addEventListener('click', () => { resultContainer.style.display = 'none'; }); // 绑定复制按钮事件 document.getElementById('copyResultBtn').addEventListener('click', () => { navigator.clipboard.writeText(result).then(() => { alert('结果已复制到剪贴板!'); }); }); } // 展示错误信息 function showError(errorMsg) { if (!resultContainer) { createResultContainer(); } resultContainer.innerHTML = `<div class="error">${errorMsg}</div>`; resultContainer.style.display = 'block'; }

4.2 美化结果界面:content.css

为我们的浮动容器添加一些基本样式。

/* content.css */ #nanbeige-ai-result { display: none; position: fixed; z-index: 10000; /* 确保在最上层 */ top: 50px; width: 400px; max-height: 500px; background-color: #f9f9f9; border: 1px solid #ccc; border-radius: 8px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; overflow: hidden; } .result-header { background-color: #2c3e50; color: white; padding: 12px 15px; display: flex; justify-content: space-between; align-items: center; font-size: 16px; } .close-btn { cursor: pointer; font-size: 20px; line-height: 1; } .close-btn:hover { color: #ecf0f1; } .result-content { padding: 20px; max-height: 350px; overflow-y: auto; line-height: 1.6; color: #333; background-color: white; } .result-footer { padding: 12px 15px; text-align: right; border-top: 1px solid #eee; background-color: #f9f9f9; } #copyResultBtn { background-color: #3498db; color: white; border: none; padding: 8px 16px; border-radius: 4px; cursor: pointer; font-size: 14px; } #copyResultBtn:hover { background-color: #2980b9; } .loading, .error { padding: 30px; text-align: center; font-size: 14px; color: #7f8c8d; } .error { color: #e74c3c; }

5. 第三步:连接你的本地AI大脑

插件本身已经就绪,现在需要让它知道和谁对话。这里假设你已经在本地通过类似OllamaOpenAI-Compatible API Server部署了Nanbeige 4.1-3B模型。

  1. 启动你的模型服务。例如,使用Ollama运行ollama run nanbeige:4.1-3b,它会默认在http://localhost:11434提供API服务。或者使用其他框架,确保其提供兼容OpenAI的/v1/chat/completions接口。
  2. 修改API地址。在background.js文件的开头,将let apiBaseUrl = 'http://localhost:8000';修改为你的模型服务实际地址,例如http://localhost:11434
  3. 调整请求格式。根据你的模型服务API文档,微调processWithAI函数中的requestBody结构。上面的代码示例是遵循OpenAI的格式,大多数兼容服务都支持。

6. 第四步:加载、测试与优化

6.1 加载插件到浏览器

  1. 打开谷歌浏览器,进入chrome://extensions/
  2. 打开右上角的“开发者模式”
  3. 点击“加载已解压的扩展程序”
  4. 选择你创建的nanbeige-browser-helper文件夹。
  5. 插件图标应该出现在浏览器工具栏。

6.2 进行功能测试

  1. 打开任意一个网页,比如一篇新闻文章。
  2. 用鼠标选中一段文本。
  3. 右键点击,你应该能看到“使用Nanbeige处理”的菜单及其子项。
  4. 点击“总结摘要”。页面上应该会出现一个加载提示,然后弹出一个美观的浮动窗口,里面是模型生成的总结内容。
  5. 尝试“翻译成中文”“润色改写”功能。
  6. 点击结果窗口的“复制”按钮,测试复制功能。
  7. 点击窗口外的区域或“×”按钮,测试关闭功能。

6.3 可能遇到的问题与优化方向

  • API连接失败:检查background.js中的apiBaseUrl是否正确,以及本地模型服务是否正在运行。可以在浏览器中直接访问http://localhost:11434/v1/models(替换成你的地址)测试API是否通畅。
  • 右键菜单不出现:检查manifest.json中的permissions是否包含"contextMenus",以及content_scriptsmatches是否匹配你测试的网页。
  • 结果不显示:打开浏览器的开发者工具(F12),切换到Console标签页,查看是否有来自内容脚本或后台脚本的错误日志。
  • 功能扩展
    • 添加快捷键:在manifest.json中配置commands,实现快捷键触发。
    • 增加设置页面:创建一个options.html页面,让用户可以自由配置API地址、模型参数、默认操作等。
    • 优化UI:让结果浮动窗可以拖动,或者定位到鼠标光标附近。
    • 增加模型:在后台脚本中支持调用多个不同的本地模型,让用户选择。

整个项目搭建下来,你会发现核心逻辑其实非常清晰:捕获、发送、处理、展示。这个框架具有很强的扩展性,你可以轻松地将“总结翻译”替换成“代码解释”、“情感分析”、“提取关键词”等任何你的本地模型支持的能力。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

http://www.cnnetsun.cn/news/1440213.html

相关文章:

  • 手把手教你修改miniwiggler配置信息,解决UDE连接问题(附FT_PROG工具下载)
  • 手把手教你用fscan+MSF搞定CTFshow内网靶场(附PHAR攻击技巧)
  • ESP32 Arduino平台MQTT v5.0客户端封装库详解
  • Houdini VEX实战:5个新手必学的几何体操作技巧(附代码示例)
  • Metpy实战:从数据到洞察——湿位涡剖面分析与暴雨预报
  • 智标领航AI写标书限时福利:冲刺榜单,永久字数轻松拿!
  • Pixel Dimension Fissioner惊艳效果:技术文档→极客漫画脚本的跨维度改写实录
  • 江苏南京消控证培训靠谱机构推荐
  • MinIO vs 阿里云OSS:SpringBoot项目中如何选择最适合的文件存储方案?
  • 宝塔面板+FTP+cpolar内网穿透:无公网IP也能远程管理文件的完整指南
  • Zynq MPSoC双R5裸机程序与Linux协同运行实战指南
  • GTE-Pro视频内容分析:基于CLIP的多模态检索
  • Keil开发MSPM0G3507遇到L6002U错误?手把手教你修复driverlib.a路径问题
  • Pixel Dimension Fissioner效果展示:儿童绘本文案风格一致性裂变
  • Power Designer 数据建模实战:从概念到物理模型的完整指南
  • SAP PP模块实战:生产计划与物料计划事务码速查手册(附Excel导出技巧)
  • 想高效写专著?AI专著写作工具全解析,让你少走弯路
  • 【 股票分析】
  • 从摩斯电码到SENT协议:一文读懂PWM编码在汽车电子中的进化史
  • STM32CubeIDE调试PWM波形:不用示波器,用Keil仿真看呼吸灯占空比变化
  • 【车载以太网C语言配置黄金法则】:20年AUTOSAR专家首曝ECU通信零丢包配置模板(含ASAM MCD-2MC实测参数)
  • ESP32-S3开发板双麦克风阵列与回声消除实战指南
  • 别再让这个Chrome警告拖慢你的Vue3+ECharts页面了!手把手教你用default-passive-events搞定
  • Qt版IEC61850建模工具实战:从SCL解析到动态模拟全流程指南
  • 告别Pyecharts!我用原生ECharts+Python打造轻量级桑基图生成器
  • 推理引擎系列(七)《InfiniLM》
  • 伊朗战争会给磁性元件行业带来怎样的影响?
  • 探索双馈风力发电机多机多节点一次调频模型:虚拟惯性与下垂控制的融合
  • 土壤湿度传感器原理与STM32驱动实战
  • 改稿速度拉满!风靡全网的降AIGC工具 —— 千笔·专业降AIGC智能体