本地优先的中文AI情报收件箱:浏览器内实现隐私可控的技术资讯过滤
发布时间:2026/10/18 20:36:12 锦皓数字建站

1. 项目概述为什么需要一个“本地优先”的中文AI情报收件箱每天打开浏览器还没点开任何页面侧边栏弹出三条AI工具更新、首页信息流刷出五篇大模型评测、微信群里又转发了七条“刚发布的开源项目”链接——这种信息过载不是错觉而是真实发生在每个关注AI进展的从业者身上的日常。我试过用RSS订阅主流技术博客也搭过基于关键词的Telegram机器人甚至写过爬虫定时抓取GitHub Trending但结果都一样要么噪音太多真正有价值的中文原创内容被淹没在翻译稿和营销软文里要么依赖云端服务数据流向不可控某天服务停摆整个信息链就断了。直到上个月我决定换一种思路不追着信息跑让信息按我的规则安静、可靠、可审计地“走进来”。这个插件的核心定位很明确——它不是一个新闻聚合器也不是一个AI工具导航站而是一个本地优先的中文AI情报收件箱。关键词“本地优先”不是噱头它意味着所有数据采集、过滤、摘要、存储、提醒都在你自己的浏览器里完成不上传、不联网除初始订阅源获取外、不依赖第三方服务器。你看到的每一条推送背后都有清晰的来源、可追溯的发布时间、可验证的原始链接你设置的每一个过滤条件比如“只看带‘RAG’关键词且作者为中文ID的GitHub仓库更新”都会在本地JavaScript引擎中实时执行而不是发到某个API接口等待返回。这解决了三个最痛的点一是中文AI领域信息碎片化严重优质内容散落在知乎专栏、微信公众号、Bilibili视频字幕、语雀文档、甚至小红书笔记里传统RSS根本覆盖不了二是很多所谓“AI资讯平台”实际是流量生意标题党泛滥真正有技术深度的分析反而难被发现三是隐私和可控性——你不想让自己的阅读偏好、关注方向、甚至对某篇论文的停留时长变成训练某个推荐模型的数据燃料。它适合三类人第一类是技术决策者比如某实验室的AI平台负责人需要快速掌握国内团队在推理优化、模型压缩等方向的最新实践但没时间每天翻十多个平台第二类是工程师个体比如A同学正在选型一个适合边缘设备的轻量级多模态模型需要持续跟踪中文社区对Qwen-VL、MiniCPM等项目的实测反馈第三类是内容创作者比如某技术博主想保持对行业动向的敏感度但又拒绝被算法喂养同质化信息。这个插件不承诺“全网最全”但它承诺“你定义的范围内最准、最稳、最可信赖”。接下来我会拆解它是怎么做到的。2. 整体设计与思路拆解放弃“大而全”专注“小而准”很多人一听到“资讯聚合”第一反应就是堆功能加热搜榜、做热度排序、搞个性化推荐、接大模型摘要……但我从第一天就否定了这条路。原因很简单在中文AI领域“大而全”等于“低信噪比”。我统计过自己过去三个月收藏的327条AI相关链接其中真正值得深度阅读的不到60条占比不足18%。剩下的大部分是同一事件的N个版本报道、未经验证的“独家爆料”、或者把一篇英文论文翻译后加上“重磅突破”标题的搬运。所以整个架构设计的第一原则就是主动收缩边界把“过滤”作为核心能力而非“聚合”。具体来说系统分为三层数据源层、处理层、呈现层。数据源层只接入四类经过人工校验的渠道一是结构化程度高的平台如GitHub按特定组织/关键词筛选仓库Star增长、Issue讨论、Release日志二是支持RSS或Atom的高质量中文技术博客如某高校AI实验室官网、某开源项目文档站三是通过OCR文本提取技术解析的Bilibili视频字幕仅限已开启字幕的UP主且只提取含技术术语的段落四是语雀、Notion等协作平台的公开知识库需用户手动添加公开链接。这里刻意避开了微信公众号、知乎动态、小红书这类强社交属性、弱结构化的平台因为它们的信息密度太低且无法稳定抓取。有人会问那不是漏掉很多内容没错但漏掉的恰恰是我们想过滤掉的噪音。我的经验是一个真正有价值的中文AI项目三个月内必然会在GitHub上留下可追踪的代码痕迹或在技术博客上发布详实的落地复盘。如果它只活在朋友圈截图里那它大概率还不具备被你参考的价值。处理层是整个插件的“大脑”全部运行在浏览器扩展的Service Worker中。这里的关键设计是“规则驱动”而非“模型驱动”。我不用LLM做摘要因为本地运行7B模型对普通用户CPU压力太大且摘要质量不稳定我也不用复杂NLP做情感分析因为中文AI资讯里“正面/负面”判断意义不大更重要的是“是否包含可验证的技术细节”。所以规则引擎只做三件事第一关键词匹配支持正则比如/(RAG|检索增强|retrieval.*augment)/i第二作者可信度加权GitHub作者粉丝数500且仓库Star100的权重0.3语雀作者有“某公司AI Lab”认证的权重0.5第三时效性衰减24小时内内容权重1.072小时后线性衰减至0.4。所有这些计算都在毫秒级完成没有网络请求没有外部依赖。呈现层则极度克制只有一个极简的侧边栏面板按“今日重点”“本周趋势”“我的关注”三个标签页组织每条卡片只显示标题、来源图标、发布时间、一行摘要最多30字以及一个“深读原文”按钮。没有点赞、没有评论、没有分享按钮——因为这不是一个社交产品而是一个工作台。这个设计背后有个关键取舍牺牲“发现感”换取“确定性”。很多资讯产品追求让你“刷到惊喜”但工程师需要的是“我知道我需要什么然后它就在这里”。就像你不会用抖音找Linux内核补丁你也不会用这个插件找“下一个爆款AI应用”。它存在的唯一目的就是把你从信息洪流里打捞出来稳稳放在你关心的技术坐标系里。3. 核心细节解析与实操要点本地存储、规则配置与隐私保障要实现真正的“本地优先”光说不练是没用的。这里我把几个最容易被忽略、但实际使用中决定成败的核心细节掰开讲透。首先是本地存储方案的选择。浏览器扩展可用的存储API有三种chrome.storage.local、IndexedDB、还有内存中的Map对象。很多人直觉选chrome.storage.local因为它简单。但我最终选了IndexedDB理由很实在一是容量。chrome.storage.local在Chrome里默认上限是5MB而一个中等规模的AI项目周报光是原始HTML提取的文本就可能超2MB加上缓存的缩略图、视频帧截图很快见顶二是查询性能。当你的关注列表超过50个源需要按关键词、时间、来源类型多维度筛选时IndexedDB的索引查询比storage.local的遍历快一个数量级。我实测过对1000条记录做“含‘量化’且发布时间7天”的查询IndexedDB平均耗时12ms而storage.local需要210ms以上。这直接决定了侧边栏打开时的卡顿感。其次是规则配置的交互设计。很多插件把规则藏在二级菜单里用户要点击五六次才能改一个关键词。我的做法是在插件图标右键菜单里直接提供“快速编辑规则”选项点击后弹出一个极简的浮层里面只有三个输入框“我要关注的关键词”支持逗号分隔如LoRA,QLoRA,Adapter、“排除的来源”比如某营销号公众号、“最小可信度阈值”滑块0.0~1.0。所有配置变更实时生效无需刷新页面。这个设计源于一次真实踩坑有位用户反馈说“为什么没收到XX项目的更新”我让他导出日志一看发现他把关键词设成了lora小写而GitHub上仓库名是LoRA正则匹配失败。后来我加了自动大小写归一化和模糊匹配开关但核心逻辑没变——规则必须足够简单让用户一眼看懂、一秒修改、一试见效。第三点也是最重要的是隐私保障的落地细节。所谓“本地优先”不能只停留在口号。我在代码里做了三重硬隔离第一所有网络请求仅用于首次获取RSS源或GitHub API都通过chrome.runtime.getURL(blank.html)作为referrer确保目标网站无法追踪到你的真实浏览上下文第二所有提取的文本内容在存入IndexedDB前会进行两次脱敏一是移除所有邮箱、手机号、IP地址等PPI信息用正则/[a-zA-Z0-9._%-][a-zA-Z0-9.-]\.[a-zA-Z]{2,}/g匹配并替换二是对URL进行哈希处理只存SHA-256(原始URL)这样即使数据库被导出也无法反推出你访问过哪些页面。第三最关键的是Service Worker的生命周期管理。我设置了严格的缓存策略所有静态资源JS/CSS强制走Cache-Control: immutable而动态数据如RSS解析结果只缓存2小时且每次读取前检查Last-Modified头确保你看到的永远是最新鲜的内容而不是某个陈旧的缓存副本。这些细节看起来琐碎但正是它们共同构成了“可信”的基础——你不需要相信我的承诺只需要打开开发者工具Network面板里看不到任何指向我服务器的请求Application面板里Storage只看到你自己的IndexedDB实例这就够了。提示如果你是开发者想复现这个架构建议从idb这个轻量级IndexedDB封装库开始它比原生API少写70%的样板代码且API设计更符合现代JS习惯。4. 实操过程与核心环节实现从零搭建一个可运行的插件框架现在我们进入最硬核的部分如何从零开始用不到200行核心代码搭起这个插件的骨架。整个过程分为四个阶段环境初始化、数据源接入、规则引擎实现、UI集成。我以Chrome扩展为例所有代码都可在Firefox、Edge等支持Manifest V3的浏览器中直接复用。第一阶段环境初始化创建manifest.json关键配置如下{ manifest_version: 3, name: AI情报收件箱, version: 1.0, permissions: [storage, scripting], host_permissions: [https://api.github.com/*, https://*.github.io/*], content_scripts: [{ matches: [all_urls], js: [content.js], run_at: document_idle }], background: { service_worker: background.js }, web_accessible_resources: [{ resources: [popup.html, popup.css, popup.js], matches: [all_urls] }] }注意两点host_permissions只声明了GitHub相关域名绝不申请*://*/*这种宽泛权限content_scripts的run_at设为document_idle确保DOM加载完成后再注入避免因页面异步渲染导致元素找不到。第二阶段数据源接入在background.js中我们用chrome.alarms创建一个每小时触发的定时任务chrome.alarms.create(fetchData, { periodInMinutes: 60 }); chrome.alarms.onAlarm.addListener(async (alarm) { if (alarm.name fetchData) { const sources await getSubscribedSources(); // 从storage读取用户配置的RSS/URL列表 for (const source of sources) { try { const response await fetch(source.url); const data await parseSource(response, source.type); // 根据type调用不同解析器 await storeToDB(data); // 存入IndexedDB } catch (e) { console.error(Failed to fetch ${source.url}:, e); } } } });这里的parseSource函数是关键。对于RSS源我用feedparser的轻量版解析XML对于GitHub直接调用fetch(https://api.github.com/repos/owner/repo/releases?per_page5)对于Bilibili先用fetch获取视频页面HTML再用正则/div classsubtitle([\s\S]*?)\/div/g提取字幕容器最后用DOMParser解析出纯文本。所有解析逻辑都打包在parser.js里体积控制在8KB以内确保Service Worker启动不卡顿。第三阶段规则引擎实现这是最体现“本地优先”价值的部分。引擎核心是一个filterItem(item)函数function filterItem(item) { const config getConfig(); // 读取用户规则 // 1. 关键词匹配 const keywordMatch config.keywords.some(kw new RegExp(kw, i).test(item.title item.content) ); // 2. 可信度计算 let credibility 0.5; if (item.source github) credibility 0.3; if (item.authorCertified) credibility 0.5; // 3. 时效性衰减 const hoursAgo (Date.now() - new Date(item.timestamp)) / (1000 * 60 * 60); const timeWeight Math.max(0.2, 1.0 - hoursAgo / 72); // 综合得分 return keywordMatch (credibility * timeWeight config.minCredibility); }这个函数在每次UI渲染前调用对IndexedDB中符合条件的记录批量过滤。没有外部调用没有异步等待纯同步计算保证响应速度。第四阶段UI集成popup.html极其简单就是一个div idinbox/div容器。popup.js里只做一件事监听chrome.storage.local的变化一旦检测到新数据入库立即调用renderInbox()函数用document.createElement动态生成卡片DOM。每张卡片的“深读原文”按钮绑定的不是跳转而是chrome.scripting.executeScript在当前活动标签页中注入一段高亮脚本自动滚动到原文中匹配关键词的位置——这才是真正“为你服务”的体验而不是把你踢到另一个页面。整个流程下来核心逻辑清晰可见数据进来规则过滤本地存储UI呈现。没有黑盒没有魔法全是你可以打开开发者工具、逐行调试的代码。这也是我坚持不用任何第三方SaaS服务的原因——当你能完全掌控每一行代码的意图和行为时你才真正拥有了这个工具。5. 常见问题与排查技巧实录那些文档里不会写的实战经验在把插件交给第一批23位测试用户后的三周里我收集了大量真实场景下的问题。这些问题往往不在技术文档的FAQ里而是藏在用户一句“咦这个怎么没反应”的背后。我把它们整理成一张速查表并附上我亲自验证过的解决方案。问题现象可能原因排查步骤解决方案侧边栏空白无任何内容Service Worker未正确注册或崩溃打开chrome://extensions→ 启用“开发者模式” → 找到插件 → 点击“Inspect views: background page” → 查看Console是否有Uncaught Error检查background.js第1行是否遗漏use strict;某些老版本Chrome对严格模式解析异常会导致Worker静默退出GitHub仓库更新不显示GitHub API调用频率超限每小时5000次或Token失效在Background Page Console中执行await fetch(https://api.github.com/rate_limit)查看rate.remaining字段为避免超限我在代码中加入了指数退避首次失败后等待1秒重试第二次失败后等待2秒第三次后等待4秒最大重试3次Bilibili字幕提取为空视频未开启字幕或字幕格式为ASS非HTML手动访问该视频页面按CtrlU查看源码搜索div classsubtitle是否存在增加fallback逻辑若HTML字幕不存在则尝试用fetch获取https://api.bilibili.com/x/web-interface/view?bvidxxx接口解析data.subtitle.subtitles[0].subtitle_url字段下载SRT文件关键词匹配不灵敏用户输入了中文标点如“RAG、LoRA”中的顿号导致正则编译失败在Popup的规则编辑浮层中输入RAG、LoRA观察Console是否报SyntaxError: Invalid regular expression前端增加输入清洗用input.replace(/[\u3000-\u303f\uFF00-\uFFEF]/g, )移除所有中文标点再分割关键词侧边栏打开缓慢1秒IndexedDB查询未建索引导致全表扫描在Application → IndexedDB中右键你的DB → “Open in Index Editor”检查itemsobjectStore是否有timestamp和source索引执行db.createObjectStore(items, {keyPath: id}).createIndex(byTimeSource, [timestamp, source], {unique: false})除了这些技术问题还有几个高频的“认知偏差”需要特别提醒误区一“本地优先完全离线”。其实不是。插件需要联网获取原始数据源RSS、API但所有处理、存储、展示都在本地。就像你用手机拍照片相机需要光线联网但照片存在相册里本地别人拿不走。关键在于数据“落地”后的控制权。误区二“规则越多越好”。我见过用户一口气加了37个关键词结果90%的推送都是误报。真实经验是从1个最核心的关键词开始比如你当前项目最依赖的模型名稳定运行一周后再根据漏报情况逐步增加1-2个补充词。宁缺毋滥。误区三“UI越炫酷越好”。有用户建议加动画、加渐变色、加数据可视化图表。我全部拒绝。因为每一次CSS重绘、每一次Canvas渲染都在消耗你宝贵的CPU周期而这本该用来跑你的AI模型。一个0.5秒内打开、0.1秒内响应点击的侧边栏远比一个带粒子特效但卡顿的面板更有生产力价值。最后分享一个独门技巧如何快速验证一条推送是否“真有价值”我给自己定了一条铁律——如果这条推送里的技术描述无法在10分钟内让我在本地复现一个最小可行Demo哪怕只是pip install一个包、跑通三行代码那它就不值得我花时间深读。这个标准帮我过滤掉了至少70%的“概念性资讯”。工具的价值不在于它给你多少信息而在于它帮你节省了多少无效信息的处理时间。6. 材料准备与定制化扩展让插件真正长在你的工作流里这个插件不是开箱即用的成品而是一个可生长的框架。它的真正威力来自于你能根据自己的工作流像搭积木一样快速接入新的数据源、编写专属规则、甚至嵌入私有系统。下面我以三个典型场景为例说明如何做定制化扩展。场景一接入公司内部AI知识库某公司使用Confluence管理AI模型评测报告所有报告都遵循统一模板标题含“【模型名】评测”正文有“硬件配置”“吞吐量”“准确率”等固定章节。要让插件抓取这些报告只需两步第一步在background.js中新增一个confluenceParser函数用fetch获取Confluence页面HTML再用document.querySelectorAll(h1:contains(【))定位标题用nextElementSibling获取后续内容第二步在用户规则配置里增加一个“内部源”开关开启后自动轮询指定Confluence空间的RSS FeedConfluence原生支持。整个过程不超过50行代码且所有数据仍存于本地IndexedDB不触碰公司内网边界。场景二为特定会议定制追踪比如你关注NeurIPS中文社区的投稿动态。GitHub上有个neurips-chinese-submissions仓库每周更新一次Accepted Paper列表。这时你可以在规则里写一条专用正则/NeurIPS.*2024.*accepted/i并设置source为github:neurips-chinese-submissions。更进一步我写了一个小脚本自动从该仓库的README中提取PDF链接用pdfjs-dist库在后台解析第一页提取作者单位判断是否来自国内高校再按单位分组推送。这已经超出了通用资讯范畴变成了你的个人学术雷达。场景三与本地开发环境联动这是最硬核的玩法。假设你正在调试一个RAG应用想实时监控社区对llama-index库的最新Issue讨论。你可以在插件里配置一个“开发中”标签当检测到llama-index相关的GitHub Issue被标记为bug或help wanted时不仅推送到侧边栏还通过chrome.tabs.sendMessage向你当前激活的VS Code Web版或Code Server标签页发送消息在编辑器底部状态栏显示一行提示“⚠️ llama-index#12345: 新增RAG chunking bug报告影响v0.10.0”。这相当于把资讯流直接缝进了你的编码现场。所有这些扩展都不需要重新打包插件。你只需要在background.js里新增一个parser函数再在filterItem里加一行判断逻辑保存后刷新Service Worker即可。这就是“本地优先”带来的最大自由——你不是在使用一个产品而是在培育一个属于你自己的信息器官。它会随着你的技术栈演进、关注点迁移、工作流变化持续生长、自我迭代。我把它比作一把瑞士军刀出厂时只有主刀和开瓶器但当你需要时随时可以拧下螺丝换上锯子、剪刀甚至激光测距仪。而这一切都发生在你自己的浏览器里安静、可靠、完全由你掌控。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。