ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

AI实现个人阅读网页插件:用TaoToken统一Key打通Chrome插件配置

AI实现个人阅读网页插件:用TaoToken统一Key打通Chrome插件配置 1. 从「读不完的网页」到一键摘要这个插件到底解决什么问题每天打开浏览器收藏夹里躺着几十篇「稍后阅读」GitHub 上点开的项目 README 越滚越长技术博客动辄上万字。逐字读完不现实可只扫标题又怕漏掉关键信息。我想要的其实很简单打开任意网页按一个快捷键侧边栏直接弹出这段内容的结构化摘要再顺手问几个追问读完摘要再决定要不要深读原文。这个需求落到 Chrome 插件上核心链路只有四步快捷键唤起 → 抓取当前标签页正文 → 把正文发给大模型 → 把返回的摘要渲染到弹窗。听起来不复杂但真正动手时会卡在三个地方manifest.json 的权限声明写不对background.js 的消息转发收不到响应以及最要命的——每接一个模型就要换一套 Key 和请求格式settings.json 里塞满各种 base_url 和 api_key维护成本比写业务逻辑还高。这篇就聚焦「个人阅读类 Chrome 插件」的落地配置把 manifest.json、background.js、settings.json 三个文件的骨架给全并说明怎么用 TaoToken 的统一 Key 和 API 通道让插件只认一个地址、一个 Key就能在多个模型之间切换。适合有基础 JS 能力、想自己做一个阅读辅助插件、但不想在模型接入上反复折腾的人。全程可复制跟着改完就能加载运行。2. 前置准备TaoToken 统一 Key 与 API 通道在写插件代码之前先把「模型通道」这件事定下来。传统做法是插件里硬编码某家厂商的 endpoint比如https://api.xxx.com/v1/chat/completions再配一个该厂商的 Key。问题是你想换个模型试试摘要效果就得改代码、改 Key、重新加载插件想同时支持摘要和翻译两个不同模型settings.json 里就得维护两套配置。TaoToken 的思路是提供一个统一的 API 通道插件侧只认一个 base_url 和一个 Key具体调用哪个模型由请求体里的model字段决定。这样 settings.json 里只需要存一份凭证切换模型只是改一个字符串。你需要先拿到两样东西第一是 API Key。登录 TaoToken 控制台在 API Keys 页面创建一个新 Key复制保存。这个 Key 就是插件 settings.json 里要填的值。第二是 API 地址。统一通道的 base_url 是https://taotoken.net/api注意这里不带任何查询参数直接作为请求前缀使用。完整的对话补全路径是https://taotoken.net/api/v1/chat/completions和 OpenAI 兼容格式一致所以插件里用标准的 fetch 就能调通。提示Key 只存在本地 settings.json 或 chrome.storage 里不要提交到 Git也不要在 content script 里硬编码。插件发布时尤其注意别把 Key 打进包里。如果你还没创建 Key可以先到控制台的 API Keys 页面生成一个想先确认通道是否可用可以用模型对话页面手动发一条消息验证确认能正常返回再写进插件。3. 可复制配置manifest.json 与 background.js 骨架3.1 manifest.json权限声明与快捷键Chrome 插件的第一道门槛就是 manifest.json。阅读类插件需要三个关键权限activeTab拿到当前标签页、scripting注入脚本抓正文、storage存配置。快捷键用commands声明后台脚本用service_worker指定。{ manifest_version: 3, name: 阅读摘要助手, version: 1.0.0, description: 快捷键唤起抓取当前网页正文并调用 AI 生成摘要, permissions: [ activeTab, scripting, storage ], host_permissions: [ https://taotoken.net/* ], commands: { open-summary: { suggested_key: { default: CtrlShiftZ, mac: CommandShiftZ }, description: 打开摘要面板 } }, background: { service_worker: background.js }, action: { default_title: 阅读摘要助手 } }这里有两个容易踩的点。一是host_permissions必须包含https://taotoken.net/*否则 background.js 里 fetch 会被跨域拦截报Failed to fetch。二是 manifest v3 里 background 只能用service_worker不能用 v2 的scripts数组写错会直接加载失败。3.2 background.js消息转发与 API 调用background.js 承担两个职责监听快捷键、接收 content script 发来的正文并转发给 TaoToken。核心是chrome.commands.onCommand和chrome.runtime.onMessage两个监听器。// background.js // 快捷键唤起向当前标签页注入并激活摘要面板 chrome.commands.onCommand.addListener(async (command) { if (command ! open-summary) return; const [tab] await chrome.tabs.query({ active: true, currentWindow: true }); if (!tab?.id) return; chrome.tabs.sendMessage(tab.id, { type: TOGGLE_PANEL }); }); // 接收 content script 的摘要请求转发到 TaoToken chrome.runtime.onMessage.addListener((msg, sender, sendResponse) { if (msg.type SUMMARIZE) { callTaoToken(msg.text) .then((summary) sendResponse({ ok: true, summary })) .catch((err) sendResponse({ ok: false, error: err.message })); return true; // 异步响应必须返回 true } }); async function callTaoToken(pageText) { const { apiKey, model } await chrome.storage.local.get([apiKey, model]); if (!apiKey) throw new Error(未配置 API Key请先在设置中填写); const resp await fetch(https://taotoken.net/api/v1/chat/completions, { method: POST, headers: { Content-Type: application/json, Authorization: Bearer ${apiKey} }, body: JSON.stringify({ model: model || claude-3-5-sonnet, messages: [ { role: system, content: 你是阅读助手。请用中文输出三段式摘要核心观点、关键论据、一句话结论。控制在 200 字内。 }, { role: user, content: pageText.slice(0, 12000) } ], temperature: 0.3 }) }); if (!resp.ok) { const detail await resp.text(); throw new Error(请求失败 ${resp.status}: ${detail.slice(0, 200)}); } const data await resp.json(); return data.choices?.[0]?.message?.content ?? 模型未返回内容; }return true这行是异步 sendResponse 的关键漏掉的话 content script 会收到undefined表现为「点了没反应」。正文截断到 12000 字符是防止超长页面把 token 打满实际可按模型上下文调整。3.3 settings.json统一 Key 与模型配置插件本身不直接读 settings.json而是通过设置页写入chrome.storage.local。但为了让你有个可复制的配置模板这里给一份 settings.json 结构设置页读取后写入 storage 即可。{ apiBase: https://taotoken.net/api, apiKey: sk-你的TaoToken密钥, model: claude-3-5-sonnet, summaryPrompt: 请用中文输出三段式摘要核心观点、关键论据、一句话结论。, maxChars: 12000 }设置页的保存逻辑大致是这样// options.js async function saveSettings() { const cfg { apiKey: document.getElementById(apiKey).value.trim(), model: document.getElementById(model).value, maxChars: Number(document.getElementById(maxChars).value) || 12000 }; await chrome.storage.local.set(cfg); document.getElementById(status).textContent 已保存; } document.getElementById(save).addEventListener(click, saveSettings);这样切换模型只需要在设置页改一个下拉框不用动 background.js 一行代码。统一 Key 的好处在这里体现得很直接摘要用 Claude、翻译用另一个模型settings.json 里只维护一份 apiKey。4. 验证请求加载插件并确认摘要成功代码写完接下来是验证。这一步别跳过很多「插件没反应」的问题都出在加载和权限确认上。第一步打开chrome://extensions/右上角开启「开发者模式」点「加载已解压的扩展程序」选择你的插件目录。加载成功后能看到插件卡片如果 manifest.json 有语法错误这里会直接报红并提示行号。第二步点插件卡片里的「Service Worker」链接打开后台调试面板。这一步很关键background.js 的 console 输出和网络请求都在这里看。第三步随便打开一个内容较长的网页按CtrlShiftZ。如果 content script 注入正常页面右侧会出现摘要面板。首次使用需要先到设置页填入 TaoToken 的 Key 和模型名。第四步在面板里点「生成摘要」观察 Service Worker 面板的 Network 标签。应该能看到一条发往https://taotoken.net/api/v1/chat/completions的 POST 请求状态码 200响应体里choices[0].message.content就是摘要文本。实测下来从按键到摘要渲染出来大约 2 到 5 秒取决于网页长度和模型响应速度。如果返回 401说明 Key 没填对或没保存返回 404检查 base_url 是否写成了https://taotoken.net/api正确而不是带/v1的重复路径。注意manifest v3 的 service worker 会休眠调试时如果发现监听器不触发先在扩展页点一下「重新加载」再重新打开调试面板。5. 本篇常见错排查报错一Failed to fetch或net::ERR_BLOCKED_BY_CLIENT九成是host_permissions没加https://taotoken.net/*。manifest v3 对跨域请求管得很严background 里 fetch 外部域名必须在 host_permissions 里显式声明。改完记得重新加载插件。报错二content script 收不到TOGGLE_PANEL消息检查chrome.tabs.sendMessage的目标 tab.id 是否存在。如果当前页是chrome://开头的内部页或扩展商店页content script 无法注入消息自然发不到。换一个普通网页测试。报错三sendResponse返回 undefinedbackground.js 的 onMessage 监听器里异步分支必须return true否则消息通道会在同步代码结束后立即关闭。这个坑很隐蔽表现是「请求发出去了但面板一直转圈」。报错四401 UnauthorizedKey 没写对或者写进了 settings.json 但没通过chrome.storage.local.set存进去。打开 Service Worker 调试面板在 Console 里执行chrome.storage.local.get([apiKey], console.log)确认实际存储的值。报错五摘要内容为空或截断maxChars设得太小或者网页正文抓取逻辑把导航栏、评论区也算进去了。建议在 content script 里优先取document.querySelector(article)或main的 innerText取不到再回退到document.body.innerText。报错六切换模型后仍走旧模型chrome.storage.local有缓存设置页保存后需要重新触发一次请求才会读到新值。如果确认保存了还是旧模型在 Service Worker 面板执行chrome.storage.local.clear()后重新配置。6. 把统一 Key 用顺下一步可以怎么扩展插件跑通摘要只是起点。阅读类场景里翻译、追问、划词解释都是高频需求而它们本质上都是「把一段文本发给模型、拿回结果」。既然 TaoToken 的统一 Key 已经打通扩展时就不需要再引入新的凭证体系。比如加一个划词翻译在 content script 里监听mouseup取window.getSelection().toString()通过chrome.runtime.sendMessage发一个type: TRANSLATE的请求background.js 里复用同一个callTaoToken函数只改 system prompt 和 model 字段即可。想用更便宜的模型做翻译、用更强的模型做摘要settings.json 里加一个translateModel字段就行。如果你打算把这个插件长期用下去甚至接上 Agent 做自动整理阅读笔记可以了解一下 Coding Plan 这类面向长期编码和 Agent 场景的方案配合统一 Key 能把多模型调用的成本和管理都收拢到一处。接入文档里有完整的请求格式和参数说明排障时对照着看比盲猜快得多。最后留一个我踩过的坑content script 注入的摘要面板样式一定要加z-index: 2147483647和position: fixed否则会被某些网站的浮层盖住表现为「按了快捷键但看不到面板」。这个和模型无关但排查起来很费时间提前加上省事。
返回列表