关于 filtering-bot-traffic
用于在 PostHog 分析中识别和衡量机器人流量的技能,适合需要区分真人、爬虫、自动化和 AI Agent 流量的团队。它提供虚拟属性、HogQL 函数及自定义机器人规则的操作方法。
主要功能
- 01按流量类型和类别分类
- 02从分析中筛除机器人流量
- 03按名称或运营方拆分流量
- 04使用 HogQL 函数分析用户代理
- 05管理自定义机器人规则
适用场景
- 01统计页面访问中的机器人占比
- 02识别访问网站的爬虫及其运营方
- 03单独衡量 AI Agent 流量
- 04为未识别的爬虫添加分类规则
MCP 相关
该技能介绍通过 MCP 工具列出、创建和删除 PostHog 自定义机器人规则。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ posthog/ ai-plugin --skill filtering-bot-traffic安装后在 Claude Code 中输入/filtering-bot-traffic确认已加载。
详细介绍
筛选和衡量机器人流量
PostHog 会根据用户代理对每个请求进行分类,让你可以在 HogQL 运行的任何地方(SQL 编辑器、洞察、趋势和 Web 分析细分)区分真人、机器人、爬虫和 AI Agent。本技能将教你(Agent)如何使用这些分类来:
- 排除机器人,让分析结果仅反映真人流量
- 衡量自动化流量的规模,以及哪些机器人 / 运营方造成了这些流量
- 区分值得衡量的 AI Agent 流量与应当过滤掉的噪声
- 选择合适的界面:洞察构建器使用虚拟属性,原始 SQL 使用函数
对于实时(“当前”,最近 30 分钟)的机器人问题和 Live 标签页中的卡片,请改用 exploring-live-traffic 技能。本技能适用于历史时间段、已保存的洞察、仪表板和筛选。
何时使用本技能
当用户想要:
- 排除或筛选机器人(“移除我的页面浏览量中的机器人”“仅真人”)
- 量化自动化流量(“流量中机器人占比是多少?”“AI 爬虫流量有多少?”)
- 查找访问过他们网站的机器人(“哪些爬虫访问了我们的网站?”“ChatGPT 有没有读取我们的文档?”)
- 按流量类型或机器人名称细分趋势
- 专门衡量 AI Agent / AI 搜索流量(AEO / 答案引擎可见度)
不要将本技能用于 Live 标签页、实时数据或按分钟统计的机器人图表——这些请使用 exploring-live-traffic。
分类方式
有两种等效方式可以使用同一分类。在洞察构建器和筛选器中,优先使用虚拟属性;手写 SQL 或需要获取虚拟属性未提供的值时,则使用函数。
虚拟属性(洞察构建器、筛选器、细分)
这些属性会自动读取用户代理(优先使用 $raw_user_agent,不可用时回退到 $user_agent),因此无需传入任何值。凡是可以选择事件属性的地方,都可以使用这些属性。
| 属性 | 值 |
|---|---|
$virt_is_bot | 布尔值——机器人 / 爬虫 / 自动化流量为 true |
$virt_traffic_type | Regular、AI Agent、Bot 或 Automation |
$virt_traffic_category | 更细分的类别,例如 ai_crawler、ai_search、ai_assistant、search_crawler、seo_crawler、social_crawler、monitoring、http_client、headless_browser、no_user_agent、regular |
$virt_bot_name | 显示名称,例如 Googlebot、GPTBot、ClaudeBot |
$virt_bot_operator | 机器人所属公司,例如 Google、OpenAI、Anthropic |
HogQL 函数(原始 SQL)
显式传入用户代理。使用 coalesce(nullIf(properties.$raw_user_agent, ''), properties.$user_agent)
同时涵盖服务端($raw_user_agent)和 JS SDK($user_agent)采集的数据。nullIf
可避免空的 $raw_user_agent 遮盖真实的 $user_agent,导致其被误判为机器人——这与虚拟属性内部使用的表达式一致。
| 函数 | 返回值 |
|---|---|
isLikelyBot(ua) | 如果 UA 符合机器人/自动化模式,则返回 true(空 UA 也算机器人) |
getTrafficType(ua) | AI Agent / Bot / Automation / Regular |
getTrafficCategory(ua) | 子类别;人类用户为 regular |
getBotType(ua) | 返回相同的子类别,但人类用户返回空字符串——便于筛选 |
getBotName(ua) | 机器人名称;人类用户返回空字符串 |
getBotOperator(ua) | 运营方/公司;人类用户返回空字符串 |
流量类型——该保留还是排除
getTrafficType / $virt_traffic_type 会将每个请求归入四类。每类的默认处理方式各不相同——不要把它们全都当作噪声:
| 类型 | 说明 | 默认处理方式 |
|---|---|---|
Regular | 人类访客 | 保留 |
AI Agent | AI 爬虫、AI 搜索、AI 助手(GPTBot、ClaudeBot、PerplexityBot、ChatGPT-User) | 通常应衡量,而非排除——AI 工具会通过它们发现和引用内容 |
Bot | 搜索爬虫、SEO 工具、社交预览、监控工具(Googlebot、AhrefsBot、Pingdom) | 从人类用户指标中排除;单独跟踪 SEO 流量 |
Automation | HTTP 客户端和无头浏览器(curl、python-requests、Puppeteer) | 通常是噪声——排除 |
示例
在洞察中排除机器人(仅统计人类用户)
添加属性筛选条件 $virt_is_bot exact false:
{ "key": "$virt_is_bot", "value": ["false"], "operator": "exact", "type": "event" }
将其添加到任何 TrendsQuery / FunnelsQuery 等的 properties 中。访客、会话和
页面浏览量计数随后仅反映人类流量,不会更改已存储的数据。
若要排除范围更窄的一部分流量(例如保留 AI Agent,但排除监控和自动化流量),请改用
operator: is_not 筛选 $virt_traffic_type 或 $virt_traffic_category。
自动化流量占比
按 $virt_traffic_type 对页面浏览趋势进行细分:
{
"kind": "TrendsQuery",
"dateRange": { "date_from": "-30d" },
"series": [{ "kind": "EventsNode", "event": "$pageview", "math": "total" }],
"breakdownFilter": { "breakdown": "$virt_traffic_type", "breakdown_type": "event" },
"trendsFilter": { "display": "ActionsBarValue" }
}
哪些机器人/运营方正在访问我们的网站
筛选机器人,并按名称进行细分(若要按公司级别细分,则使用 $virt_bot_operator):
{
"kind": "TrendsQuery",
"dateRange": { "date_from": "-30d" },
"series": [{ "kind": "EventsNode", "event": "$pageview", "math": "total" }],
"properties": [{ "key": "$virt_is_bot", "value": ["true"], "operator": "exact", "type": "event" }],
"breakdownFilter": { "breakdown": "$virt_bot_name", "breakdown_type": "event", "breakdown_limit": 25 },
"trendsFilter": { "display": "ActionsBarValue" }
}
专门衡量 AI Agent 流量
筛选 $virt_traffic_type exact AI Agent,再按 $virt_bot_operator 细分,查看哪些工具(OpenAI、Anthropic、Perplexity、……)访问了你的网站,以及它们访问了哪些页面。
等效的原始 SQL
-- human pageviews only
SELECT count() AS human_pageviews
FROM events
WHERE event = '$pageview'
AND NOT isLikelyBot(coalesce(nullIf(properties.$raw_user_agent, ''), properties.$user_agent))
-- top bots by hits
SELECT
getBotName(coalesce(nullIf(properties.$raw_user_agent, ''), properties.$user_agent)) AS bot,
getBotOperator(coalesce(nullIf(properties.$raw_user_agent, ''), properties.$user_agent)) AS operator,
count() AS hits
FROM events
WHERE event = '$pageview'
AND isLikelyBot(coalesce(nullIf(properties.$raw_user_agent, ''), properties.$user_agent))
GROUP BY bot, operator
ORDER BY hits DESC
添加 PostHog 尚未识别的机器人
内置列表仅包含 PostHog 已知且自行声明的 user agent。如果某个爬虫对项目很重要,但尚未被检测到——例如内部负载测试、合作伙伴集成或小众爬虫——请添加自定义机器人规则,而不是等待内置列表更新。规则会扩展相同的分类范围,因此无论在哪处运行 HogQL,Is bot(isLikelyBot)、Bot name 和 Traffic category 都会反映这些规则。
规则会匹配一个事件属性——默认为 user agent,也可以是 $ip、$lib、$host、$pathname、$current_url、$browser、$os、$browser_language、$screen_width、$screen_height、$geoip_country_code、$referrer 或 $referring_domain——并使用 contains(不区分大小写的子字符串)、regex(RE2)或 cidr(IP 范围,仅适用于 $ip)进行匹配。将 name 设为 Bot name 显示的标签,也可以将 category 设为 ai_crawler 之类的内置类别,以重新标记流量类型。
管理规则有三种方式:
- 设置界面 — Settings → Environment → Custom bots。
- MCP 工具 —
web-analytics-bot-rules-list、web-analytics-bot-rules-create、web-analytics-bot-rules-destroy。通过 Agent 操作 PostHog 时,优先使用这些工具。 - REST API —
GET/POST /api/projects/{project_id}/web_analytics_bot_rules/和DELETE /api/projects/{project_id}/web_analytics_bot_rules/{id}/。
项目成员可以查看规则;创建和删除规则则需要项目管理员权限(因为这些操作会修改仅限管理员的 modifiers 团队设置)。如果规则的模式无法运行,保存时会遭到拒绝,因此错误规则永远不会导致项目的分类查询失败。
查看不运行 JavaScript 的机器人
大多数爬虫和 AI Agent 从不执行 JS,因此 posthog-js 不会为它们触发 $pageview——它们对客户端分析不可见。若要衡量它们的活动,项目必须将服务器访问日志作为携带 $raw_user_agent 的 $http_log 事件转发。如果用户问“我明明知道 GPTBot 正在抓取,为什么看不到它?”,答案几乎总是:没有摄入 $http_log。在构建机器人洞察之前,请引导他们使用服务端采集(Vercel logs 来源、边缘工作器或采集 API)。
注意事项
- 必须采集到 user agent。 分类会在查询时根据事件的
$raw_user_agent/$user_agent计算,因此适用于任何历史事件——无需限制dateRange.date_from。唯一的要求是采集到了 user agent;从未设置 user agent 的来源所产生的事件无法分类(空 UA 会归为下文所述的Automation/no_user_agent)。 isLikelyBot表示“很可能”。 检测基于 user-agent 启发式判断——有些机器人会伪装成真实浏览器 UA,有些合法工具则会使用类似机器人的 UA。请将其视为尽力而为的判断,而非确凿事实。- 空 user agent = 机器人。 没有 UA 的请求(服务器到服务器请求、配置错误的 SDK)会归类为
Automation/no_user_agent,因此isLikelyBot会返回true。 - 不要悄悄移除主机筛选条件。 如果用户的范围限定在某个域名,请在
properties中沿用$host——省略它会改变查询结果。 - 机器人定义会变化。 检测到的机器人列表会随时间改变,因此稍后重新运行同一查询时,旧事件的分类结果可能不同。