不止于过滤列表:基于大语言模型(LLM)的广告拦截新思路
自诞生以来,广告拦截器始终面临着一个重大挑战,即过滤列表的局限性及其繁重的维护需求。这种维护工作大多是手动的,且极其繁琐。
在这项研究中,我将首先探讨当今广告拦截的工作原理,回顾此前利用机器学习实现自动化的尝试。然后,我将转向自己将大语言模型(LLM) 应用于广告拦截的实验,讨论这一方法的未来方向,并展示一个可供下载测试的可实际运行的浏览器扩展原型。
我知道大家可能已经迫不及待想了解 LLM 实验并试用这个扩展了。但首先,让我们从背景开始。
当今广告拦截的工作原理
当前所有广告拦截器的核心都是由社区维护的过滤列表。这些列表包含成千上万条规则,主要分为两大类:网络规则与修饰符规则。
网络规则:第一道防线
作用:拦截、重定向或修改网络请求。
示例:||evil-ads.com^ —— 此规则会拦截 evil-ads.com 网站及其所有子域名。
网络规则在内容到达用户的浏览器之前,就会对第三方广告服务器的请求进行拦截,这是一种快速高效的方法。这些规则可以阻止、重定向或修改请求。

但网络规则无法拦截所有内容。例如,有些广告与网页内容来自同一个域名,在网页加载前拦截它们会导致网站异常。此时便需要修饰符规则登场。
修饰符规则:清理页面残留
作用:使用 CSS 选择器直接在页面上隐藏不需要的元素,或应用自定义样式。
示例:example.com##.ad-banner —— 隐藏 example.com 网站上所有 CSS 类名为 “ad-banner” 的元素。
CSS(层叠样式表)是一种样式表语言,用于定义 HTML 或 XML 文档的视觉呈现效果。它规定了元素在设备屏幕上的显示方式。
修饰符规则主要用于清理那些简单的网络规则无法拦截的残余广告元素。

不止于 CSS:脚本规则
作用:修改或禁用页面上的特定脚本功能。
示例:example.com#%#//scriptlet('abort-on-property-read', 'alert') —— 当 example.com 上的脚本试图访问 alert 这类特定的浏览器功能时,该规则会阻止该脚本执行。
当 CSS 不足以应对复杂的脚本(例如广告重新注入)时,我们会使用脚本。脚本是由广告拦截器注入的小型 JavaScript 代码片段,用于阻止或修改不良行为。
脚本已成为过滤器开发者的得力工具,因为它们解决了 CSS 和网络规则无法处理的问题。
优势与局限
我们已经简要了解了过滤列表的工作原理。它们功能强大,在处理已知模式时表现出色,但也存在一些局限性。它们难以应对原生广告、需要持续更新,且在 Manifest v3 环境下更新变得更加困难。
这些限制引发了一个根本性的深层探讨:如果我们能彻底摒弃过滤列表呢? 如果广告拦截器能自行决定拦截什么,会怎样?
想象一下:没有过滤器、无需更新、不再追赶广告网络。没有手动调整,也没有猫鼠游戏。说到底,这不正是用户对广告拦截器的自然期待吗?“安装即可”,享受清爽的网络,无需再为广告拦截器费心。这也正是早期机器学习实验想要实现的目标。
带着这个动机,让我们看看企业和研究人员是如何尝试用机器学习来解决这些问题的。
广告拦截中机器学习简史
让我们回顾一下过去各种尝试用机器学习替代过滤列表的努力。这将帮助我们理解为什么这尚未成为现实,至少目前还没有。
eyeo 的 Moonshot 项目
目标:大规模实现修饰符规则过滤的自动化。
方法:
- 基于页面结构(DOM、HTML、CSS)训练机器学习模型
- 使用现有的过滤列表作为数据标签
- 直接在浏览器扩展内部分析页面
eyeo 的 Moonshot 项目曾在 2021 年的广告过滤开发者峰会上展示。他们使用过滤列表作为标签,基于页面结构训练了一个模型。该模型在浏览器扩展内部运行,用于预测并隐藏广告元素。它虽然能够工作,但面临着挑战:数据不平衡、部署困难以及持续重新训练的需求。
核心思路:基于页面结构而非图像做出决策。
成果:预测并隐藏广告元素,与网络规则拦截形成互补。
挑战:数据不平衡、部署摩擦、需要持续重新训练。
Brave 的 AdGraph
目标:实时拦截广告和跟踪器。
方法:
- 构建连接页面所有活动(DOM、网络、JavaScript)的关系图
- 根据资源在关系图中的上下文进行分类

另一个机器学习项目 AdGraph 由 Brave 浏览器开发,同样在 2019 年的广告过滤开发者峰会上首次介绍。他们构建了一个关系图来追踪页面上所有元素的连接方式(DOM、网络、JavaScript),然后根据上下文对资源进行分类。
AdGraph 通过追踪脚本回连到广告服务器(即使服务器使用随机名称)实现了高精度拦截。但它需要深度浏览器集成和持续维护。
核心思路:基于因果关系而非静态 URL 模式做出决策。
成果:极高的准确率(约 95–98%),并能有效对抗混淆技术。
挑战:需要深度浏览器集成和持续维护。
Brave 的 PERCIVAL
目标:实时拦截广告图片。
方法:
- 使用紧凑的卷积神经网络(CNN)对图像进行分类
- 将其直接嵌入浏览器的图像渲染管道中

2020 年,Brave 展示了另一种称为 PERCIVAL 的机器学习方法,专注于拦截广告图片。他们将一个紧凑的神经网络直接嵌入浏览器的渲染管道中,以便在图像加载时对其进行分类。结果令人印象深刻:通过直接分析图像内容,他们达到了 97% 的准确率。但它也有其局限性:易受对抗性图像攻击,且仅对图片的广告有效。
核心思路:分析图像的视觉内容,而非仅仅依赖其 URL 或元数据。
成果:约 97% 的准确率,且渲染开销低。
挑战:易受对抗性图像攻击;仅适用于基于图片的广告。
AutoFR(学术研究)
目标:从零开始自动生成过滤规则。
方法:
- 使用强化学习(一种试错系统)测试规则
- 分析页面内容以避免破坏网站功能
除了业界的努力,学术研究者也加入了寻找更好解决方案的行列。其中一个有趣的项目是 AutoFR,其目标是自动生成过滤规则。
AutoFR 由 Hieu Van Le 在 AFDS 2022 和 AFDS 2023 上展示。
它生成 URL 模式和 CSS 选择器,测试它们,并从结果中学习,同时避免破坏网站。其结果相当可观:AutoFR 达到了 86% 的有效性(与 EasyList 相比),且规则能在几分钟内生成。
核心思路:自动生成规则,并具备网站破坏感知能力。
成果:约 86% 的拦截效果;规则在数分钟内生成。
SINBAD(学术研究)
目标:检测并精确定位由广告拦截引起的网站功能破坏。
方法:
- 使用“网页视觉显著性”来识别重要的视觉元素
- 比较开启和关闭广告拦截器时的页面版本,以找出被破坏的部分

另一个学术项目是 SINBAD。它专注于检测过滤规则何时破坏了网站功能。这个项目很有价值,因为网站功能破坏是用户放弃使用广告拦截器的主要原因之一。该项目由当时在伦敦帝国理工学院的 Sandra Siby 在 AFDS 2023 上展示。
通过分析大小、位置和对比度,它可以识别出视觉上突出的元素(如标题和按钮),然后测试它们是否被破坏。SINBAD 在检测功能破坏方面实现了高准确率,其具体报告能精确显示什么被破坏以及是哪条规则导致的。
核心思路:关注用户可见的影响,以更快地发现和修复问题。
成果:更高的功能破坏检测准确率,并提供具体、可操作的报告。
总结:机器学习为何未能普及
至此,我们已经了解了所有这些实验和研究项目。但问题是,尽管做了这么多工作,这些基于机器学习的工具都未能获得广泛应用。因此,一个合乎逻辑的问题是:为什么机器学习没有取代过滤列表?
原因有以下几点:
- 标准极高:人工维护的过滤列表已经非常有效且成熟。要与其效果相匹配并非易事。
- 成本高昂:创建和维护大规模、高质量的数据集成本不菲,而大多数过滤列表由社区免费维护。
- 易于规避:专用模型可能容易受到对抗性攻击。
因此,事实证明,从头开始构建专用模型不仅进展缓慢、成本高昂,而且不够灵活。这就是为什么机器学习方法至今未能普及,我们仍然依赖着“历史悠久”的过滤列表。但这种情况即将改变吗?
进入大语言模型时代:庞大、昂贵… 但与众不同
就在这时,大语言模型闪亮登场,并开始改变世界。它们是否也有可能改变广告拦截呢?让我们探索如何将 LLMs 用于浏览器扩展的广告拦截。但首先,让我快速介绍一下 LLMs 的一些关键特性。
用 LLMs 重新构想拦截:快速原型开发的力量
大语言模型(英文:Large Language Models,简称:LLM)虽然仍是新近发展的事物,但其进展速度却异常迅猛。现在通过 API 即可广泛使用,开发者能以极小的成本将基于 LLM 的能力集成到他们的产品中。许多模型都提供云端和本地部署两种版本,用户可以根据需求灵活选择。
LLMs 的能力范围广泛,从生成高质量文本到数据分析、创建图像和视频、编写代码,以及支持复杂的工作流。这使它们对许多行业都极具价值,并受到数百万人的青睐。但也并不是完美的,其运行或调用这些模型的成本可能很高,尤其是在大规模应用时,这是在许多领域采用 LLMs 的一个实际问题。
但最重要的是,LLMs 使我们能够非常快速地测试各种想法。所以,请允许我最终向大家展示我将 LLM 应用于浏览器扩展广告拦截的实验。
实验一:基于语义的拦截
我第一个实验的想法是,看看 LLM 是否能即时区分不同的内容类型。
方案如下:
- 立即模糊所有帖子内容
- 通过 LLM 分析其内容
- 如果是安全内容则取消模糊,否则保持模糊
我决定在 X(原 Twitter)的信息流上进行测试。我抓取每个帖子的代码,发送给 LLM,询问它是否与政治相关。由于 LLMs 处理速度稍慢,我首先立即模糊所有帖子,借助 LLM 进行分析,然后如果是内容安全则取消模糊。

成功了!
这证明了一种全新的、基于语义的内容过滤方式是可行的。并且,我只用了几个小时就制作出了这个扩展的原型。如果使用传统机器学习方法,这可能需要数月时间。
下面让我为大家快速演示一下:
大家可以看到它的工作原理。帖子出现后立即模糊,LLM 随之进行分析,如果安全则取消模糊,否则保持隐藏。用户可以手动查看任何被模糊的帖子。
在 X 上进行实验时,我注意到一些帖子因为没有被拦截,主要是因为它们以图片为主。这促使我进行了第二个实验。
实验二:基于视觉语义的拦截
在这个实验中,我将教广告拦截器怎么看。
方案如下:
- 立即模糊帖子内容
- 视觉 LLM 分析包含帖子的截图
- 如果是安全内容则取消模糊,否则保持模糊
帖子通常只包含很少的文字。这里正好有一个例子说明了这个问题:一个几乎没有任何文字、只有图片的 Facebook 帖子。

但这不仅仅是关于无文字帖子的情况。即使存在文字,网站也经常使用混淆的 HTML 来隐藏它。例如,看一下开发者工具中的这个截图——你可以看到「Sponsored」标签被隐藏在随机化的 HTML 中。

这就是为什么我们必须停止分析代码,转而分析用户实际看到的内容。因此,思路与第一个实验相似,但现在我们分析的不是元素背后的代码,而是用户在页面上实际看到的内容。所以,我们截取帖子的屏幕截图,发送给具备视觉能力的 LLM,并询问它是否与政治相关。
它再次成功了!核心想法的原型制作只花了一个小时左右。但接下来是真正的挑战:通过浏览器扩展进行截图。这里的结果不尽人意。
让我解释一下原因。我尝试的一种方法是 Debugger API。Debugger API 允许捕获任何元素,甚至是视口(屏幕上当前可见的区域)之外的元素,但它会导致页面闪烁,这可能对用户造成困扰。请看下面的演示:

另一种方法是使用 chrome.tabs.captureVisibleTab。这是用于截取屏幕截图的标准 Chrome 扩展 API。这种方法不会导致闪烁。然而,它只能捕获当前在视口中可见的内容,并且 Chrome 限制了每秒可以截取的屏幕截图数量。

因此,如果您有多个元素需要分析,必须等待,并且只能检查已经显示在屏幕上的帖子。
这些实验表明,LLM 可以分析帖子并决定是否拦截它们。这是否意味着我们可以完全取代过滤列表?答案是否定的,我们仍然需要它们来知道需要检查什么。一个网页有数千个元素,分析所有元素会很慢且成本高昂。
实验三:扩展过滤列表:一种新的基础功能
如果我们仍然需要知道哪些元素需要检查,那么合乎逻辑的步骤就是将 LLM 与过滤列表连接起来,并将 LLM 的强大功能泛化为可供过滤器列表作者重复使用的工具。但这里的问题是,为每个语义任务编写一个新的自定义扩展是不可扩展的——我们需要一个更通用的解决方案。
灵感来源:扩展 CSS 伪类 :contains。
提出的问题:如果我们可以检查语义含义,而不仅仅是文本呢?
结果:三个新的实验性伪类:
selector:contains-meaning-embedding('criteria')
selector:contains-meaning-prompt('criteria')
selector:contains-meaning-vision('criteria')
为了创建这个通用解决方案,我从 AdGuard 的扩展 CSS 库中获得了灵感。扩展 CSS 是一个 JavaScript 库,它添加了额外的伪类,以扩展原生 CSS 之外的可能性。
它有一个 :contains() 伪类,可以隐藏包含特定文本的元素。我决定我们可以升级这种方法,以检查语义含义而不仅仅是关键词。这产生了三个原型:embedding、prompt 和 vision。
:contains-meaning-embedding
工作原理:比较文本与标准之间的语义相似度
优点:速度非常快,成本低廉
缺点:需要设定阈值,并且处理多种语言时存在困难
让我从 :contains-meaning-embedding 开始。这条规则使用嵌入模型,将文本转换为代表含义的数字向量。我们计算元素文本与给定标准之间的相似度,并判断它们是否匹配。优点是速度快,缓存后成本低。缺点是需要调整阈值,并且可能难以处理多种语言。
:contains-meaning-prompt
工作原理:询问 LLM 内容是否匹配标准
优点:更准确,无需设定阈值,与语言无关
缺点:速度较慢,成本更高
接下来是 :contains-meaning-prompt。这些规则使用一个简单的提示 API,我们直接询问某些元素的内容是否符合标准。这种方法更准确,无需设定阈值,并且适用于各种语言。缺点是比嵌入方法更慢且成本更高。
:contains-meaning-vision
工作原理:询问 LLM 截图是否匹配标准
优点:能捕获文本和嵌入方法遗漏的内容
缺点:用户体验复杂
最后一种方法是 :contains-meaning-vision。它截取所选元素的屏幕截图,然后询问具备视觉能力的 LLM 截图是否符合标准。之后,它的工作方式与 :contains-meaning-prompt 相同。这种方法的关键优势在于它能检测到基于文本的方法无法察觉的视觉内容。缺点是用户体验复杂,可能存在屏幕闪烁问题。

因此,这三条规则可以为过滤器开发者提供灵活的工具。他们可以根据需要选择:嵌入速度、提示准确性或视觉洞察力。为了缓解分析延迟,一个解决方案是首先模糊元素,然后根据结果决定是取消模糊还是保持隐藏。
性能与成本分析
现在我们有了这三个原型,最重要的问题出现了:它们实用吗?这能在实际生产环境中运行吗?为了回答这个问题,我分析了每种方法的性能和成本。
Embeddings
让我从嵌入方法开始。最初,我使用 OpenAI 的云端模型启动了扩展,老实说,结果并不理想。但后来我决定尝试一个小型的本地模型,结果让我惊讶。它速度更快,完全免费,并且在测试中达到了 100% 的准确率。这表明对于某些任务,小型本地模型实际上可以超越大型云端 API。

Prompts
接下来,让我们看看提示方法。这里的情况有所不同。云端 API 表现最佳,有些在不到一秒的时间内达到了 100% 的准确率。有些则需要超过四秒钟,这对于良好的用户体验来说太慢了。在这种情况下,本地模型根本无法达到云端的准确性。

Vision
最后,我们来谈谈视觉方法。这是最有趣的部分。准确率非常高,即使是本地模型也表现良好。视觉方法通常是最准确的。它的主要优势在于它处理的是图像而非文本,能捕获其他方法遗漏的广告。然而,这里存在一个重大的权衡:延迟。10 到 15 秒的延迟对于实时拦截来说是不切实际的。

方法对比
综合比较所有方法,视觉分析能提供极高的准确率,但其延迟也非常显著。提示词方法在速度和准确性之间取得了良好平衡,特别是使用云端 API 时。而本地嵌入方法则带来了惊喜——它不仅非常快速且高效,尽管其适用范围仅限于特定任务。总而言之,每种方法都有其优势和局限。

未来发展前景
Vision: 目前速度过慢,但会随时间逐步改进。
Embeddings: 在浏览器扩展中实用性有限,若能作为内置浏览器 API 则将非常理想。
Local LLM prompts: 仍处于实验阶段,需要进一步提高准确性。
这对未来意味着什么?在我看来,视觉分析目前的速度还难以满足实时需求。在浏览器扩展中使用嵌入模型不太实用,但如果作为浏览器内置 API 则可能表现良好。而利用 Chrome 的 Prompt API 进行本地 LLM 提示实验,是实现一个真正可交付的实验成果最有希望的路径。此外,如何改善用户体验也是一大挑战,目前先模糊元素再分析的方式并非最佳方案。随着模型速度的提升,我们可以缩短模糊时间,或许还能构想出完全不同的解决方案。
我们学到了什么? 首先,大语言模型使我们能够超越简单的模式匹配,真正理解网页内容的含义。这为过滤技术开辟了一条全新的、基于语义的道路。其次,大语言模型为我们带来了快速原型验证的能力。过去需要数月工程开发才能验证的想法,现在几个小时就能完成测试。尽管仍有实际挑战待解决,但这种新方法促使我们重新思考内容过滤领域的可能性。
希望本文能为大家带来关于内容过滤的新思路。大家可以亲身体验本文探讨的所有内容,直接从 Chrome 应用商店下载 AI AdBlocker。
完整的源代码也已发布于 GitHub。如有任何问题或建议,欢迎随时联系!