关于 ai tag debugger
ai tag debugger 是用于网站分析和广告追踪 QA 测试的开源 AI Agent,可通过真实浏览器流程进行检查。它捕获追踪请求和 dataLayer 活动,依据测量计划与同意设置检查数据,并生成问题说明和修复建议。
主要功能
- 01使用 Playwright 执行浏览器流程
- 02捕获追踪请求和 dataLayer 推送
- 03按测量计划检查事件
- 04在独立浏览器中测试同意选项
- 05用确定性规则评估捕获数据
- 06生成问题说明和修复建议
适用场景
- 01发布前检查结账追踪
- 02检查不同选择下的同意行为
- 03查找缺失或重复的分析事件
- 04比较不同广告平台的购买金额
MCP 相关
项目可通过支持 MCP 的 AI 聊天应用使用,由该应用的模型驱动审计。它提供 `start_audit` 和 `run_audit` 工具,并支持选择要检查的平台。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
7收录的工具列表 · 更新于 2 天前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| site | string | 是 | 要打开的页面,例如 https://staging.example.com/ |
| journey | string | 否 | 预设旅程(purchase、add_to_cart、sign_up、lead、search、decline_cookies),包含目标和预期事件;也可以是自定义旅程的简短名称,例如 newsletter。 |
| viewport | enum | 否 | 默认桌面视口。desktop | mobile |
| providers | array | 否 | 要检查的跟踪服务提供商。默认包括 ga4、google_ads、meta、tiktok,以及网站发送请求的任何其他已知平台。指定此项时,发往其他平台的请求仍会在本地响应,但只计数,不显示或检查。 |
| allowed_hosts | array | 否 | 旅程中可能访问的其他主机,例如托管式结账服务 checkout.example-payments.com。除此之外,浏览器会停留在网站自身的主机及其子域名中。 |
详细介绍
English | Türkçe
AI Tag Debugger
一款开源 AI Agent,可对网站的分析和广告跟踪进行 QA 测试。
AI 模型会像真实访客一样,通过真实浏览器访问关键用户流程(商品 → 购物车 → 结账、潜在客户表单)。浏览过程中,ai-tag-debugger 会记录每个跟踪请求(GA4、Google Ads、Meta Pixel、TikTok 以及约十几个其他平台)和每次 dataLayer 推送。随后,它会根据测量计划和 Consent Mode 设置检查这些记录,并用通俗易懂的语言撰写报告,说明哪些地方出了问题以及如何修复,支持英语或土耳其语。
可通过两种方式使用:
- 在终端或 CI 中,使用你自己的 Anthropic(Claude)、OpenAI、Google Gemini 或任何兼容 OpenAI 的 API 密钥(Kimi、GLM、DeepSeek、OpenRouter、本地 Ollama 等)。
- 在 AI 聊天应用中(Claude、ChatGPT、Gemini 及其他支持 MCP 的应用)。由应用自身的模型执行审计,因此你无需单独的 API 密钥。
由 Analitik İşler 构建。采用 MIT 许可证。
▶ checkout (mobile)
Accept cookies
Open the first product
Add to cart
Open the cart
Go to checkout
…
Place the order
✓ All scripted steps completed. · 20 tracking hits captured
2 broken · 1 risk · 1 warning · 4 ok
Report: reports/demo/localhost/runs/2026-10-16_0800/report.html
为什么要用
跟踪可能会悄无声息地失效。改版时按钮名称被更改,新模板漏掉一个字段,或者同意横幅更新后像素过早触发。没有人会收到警报。等到广告平台已经基于错误的转化数据完成优化,几周后你才会发现问题。
手动进行标签 QA 可以发现这些问题,但过程繁琐,因此很少有人会在每次发布后都进行检查。ai-tag-debugger 将其变成可在 CI 中运行的命令。
检查内容
| 检查项 | 发现示例 |
|---|---|
| 缺少事件 | 在结账流程中从未触发 purchase |
| 缺少参数 | 在移动设备上发送的 purchase 未包含 value 和 currency |
| 无效的购买金额 | 发送的 purchase 中,value 为 0、负数或 "free" 之类的文本 |
| 无效的购买币种 | 发送的 purchase 使用了 usd 或 TL,而不是 USD 或 TRY 等 3 位 ISO 代码 |
| 购买商品列表为空 | 发送的 purchase 中,items 列表为空 |
| 购买数据不一致 | 对于同一订单 ID,GA4 发送的 value 为 120,Meta 发送的为 115 |
| 重复发送 | 一次点击发送了两次 add_to_cart |
| 同意状态 | 访客接受 Cookie 前触发了 Meta PageView,Consent Mode 默认设置缺失或设置过晚,缺少 Consent Mode v2 信号(ad_user_data、ad_personalization),同意前设置了跟踪 Cookie,在 decline_cookies 流程中拒绝横幅后标签或 Cookie 仍处于活动状态,拒绝按钮不起作用 |
| 个人数据 | 以纯文本形式向广告平台发送电子邮件地址 |
| 未计划的事件 | 触发了衡量计划中没有的事件 |
| 计划覆盖情况 | 将每个计划中的事件分类为已实施、缺失、缺少参数、值错误或未检查(参见计划与网站) |
| 广告系列参数 | 重定向丢弃了落地页地址中的 utm_campaign 或 gclid,或报告中的请求所对应的页面地址缺少这些参数。该次访问会被归因于直接流量 |
| 服务端跟踪 | 同一个事件 ID 用于两个不同的事件,或者 Meta 事件 ID 与服务端容器转换为 Conversions API 事件的 GA4 请求中的 event_id 不匹配 |
支持的平台:GA4(包括服务端 GTM 端点以及网站自有域名上的 Google tag gateway 路径;发往服务端容器的请求会标记为服务端请求,并可识别 Stape 和 Elevar 请求)、Google Ads 转化、Meta Pixel、TikTok Pixel、基本的 X Pixel 事件、LinkedIn Insight Tag、Microsoft Advertising UET、Criteo OneTag,以及 Pinterest、Snapchat 和 Klaviyo 事件。也会读取 Adobe Analytics、Matomo 和 Piwik PRO 事件(页面浏览、链接、目标、站内搜索和电商订单),而 Microsoft Clarity 和 Hotjar 标签加载会标明项目或网站 ID。
当 GA4 请求发往另一主机上的服务端容器,或其加载器由另一主机提供时,报告会添加一条信息提示:这些事件转发到广告平台时不会经过浏览器,因此在此处不可见。
使用 gtm_container 导出内容时,每个有问题的事件还会指出发送该事件的 GTM 标签及其触发条件,或者说明没有标签发送该事件。随后会针对每个标签说明其触发条件是否在该流程中触发;如果未触发,还会说明原因:标签已暂停、没有 dataLayer 推送携带该触发条件的事件、触发条件未满足(并显示推送中的值,该值从累计 dataLayer 中读取,方式与 GTM 的 Data Layer Variables 相同)、例外触发条件阻止了标签,或事件触发时所需的同意状态未获批准。如果所有条件都已触发,但请求仍有问题,报告会指出这一点,并指向标签本身的设置。点击、表单、可见性和计时器触发条件由页面中的 GTM 评估,因此除非其 gtm.click 之类的事件已到达 dataLayer,否则会报告为无法评估。所有这些评估都基于捕获的 dataLayer,不使用 AI 模型。
选择要检查的平台
默认情况下,审计会检查 GA4、Google Ads、Meta 和 TikTok,以及网站实际使用的其他任何平台。从平台发出首个请求时便会检查,无需设置。选择平台后会关闭此项检测。通过 --platforms ga4,meta,x、配置中的 "providers",或 MCP start_audit 和 run_audit 工具上的 providers,指定固定的平台列表。可从 ga4、google_ads、meta、tiktok、x、linkedin、microsoft_ads、pinterest、snapchat、criteo、klaviyo、adobe、matomo、piwik_pro、clarity、hotjar、doubleclick 和 adsense 中选择。GA4、Google Ads、Meta、TikTok、X、LinkedIn、Microsoft Ads、Pinterest、Snapchat、Criteo、Klaviyo、Adobe Analytics、Matomo 和 Piwik PRO 的事件都会被解析。Clarity 和 Hotjar 会显示其标签加载情况,其他平台则显示其网络请求。--providers 仍可作为 --platforms 的旧名称使用一个小版本,并会显示提示。
对未选择平台的请求仍会在本地处理,因此不会到达相应平台账号。它们不会列入时间线、CSV 和检查结果,只会计数:报告会列出这些请求及其数量(例如,“跳过了 61 个范围外请求:Microsoft Clarity、DoubleClick”),每个步骤也会说明跳过了多少个请求。如果未设置 --platforms,测量计划中提及或网站实际发送请求的平台都会加入默认列表。对于你排除的平台,计划中的事件会集中列在一条信息性发现中,而不会报告为缺失。标签管理器和同意管理平台的请求始终会显示。
同意情景
每次审计还会针对每种同意选择,在全新浏览器中各打开一次起始页:全部接受、全部拒绝,以及仅接受分析。若 OneTrust、Cookiebot、Usercentrics 或 Didomi 等同意管理平台提供专用 API,就会通过该 API 执行选择;否则会点击横幅按钮。报告随后会显示每种选择后各标签发送的命中数。“仅接受分析”适用于 OneTrust 和 Cookiebot;对于其他平台,该列会显示“此处不支持”。全部拒绝后仍发送数据的标签会被标记,但无 Cookie 的 Consent Mode ping 除外。仅接受分析后发送数据的广告标签也会被标记,除非发送时广告存储已被拒绝。该表位于 Journeys 标签页顶部,以及 report.md 中发现项的上方。如果页面没有该工具能够响应的横幅,或正在重放已保存的网站,则会跳过此项。不会调用 AI 模型,但会额外访问起始页三次。在配置中将 "consent_scenarios": false 设为关闭此功能。
工作原理
- 浏览: AI 模型会收到一个自然语言目标(“将任意商品添加到购物车,并使用测试付款完成结账”)和页面的文本视图。它通过 Playwright 一次执行一步,使用两个工具:
browser_action(goto、click、fill、select、scroll、wait)和finish。 - 采集: 每个发往跟踪端点的请求都会被解析为规范化的命中数据,并标记触发该请求的步骤。每次 dataLayer 推送都会通过初始化脚本记录,包括
gtag('consent', ...)命令。默认情况下,该工具可以解析的所有平台(GA4、Google Ads、Meta、TikTok、X、LinkedIn、Microsoft Ads、Pinterest、Snapchat、Criteo、Klaviyo、Adobe Analytics、Matomo 和 Piwik PRO)的采集请求,以及 Google 的转化、再营销和同意状态 ping 请求,都会在本地得到响应,因此测试流量不会发送到这些真实账户。标签加载请求以及发往该工具只能通过主机名识别的供应商(例如 Clarity 和 Hotjar)的请求仍会发出;时间线中的网络部分会显示每次调用及其是否在本地得到响应。 - 检查: 确定性规则会将命中数据与测量计划进行比较。这一环节无需调用 API,因此结果可复现。
- 说明: 模型会读取检查结果、每个步骤的命中数据,以及(可选的)GTM 容器导出文件。它会针对每个问题说明可能的原因和修复方法,并指出涉及的标签和触发器。
AI 提供商
使用你自己的 API 密钥。ai-tag-debugger 使用各提供商的官方 SDK:
| 提供商 | API 密钥变量 | 默认模型 |
|---|---|---|
| Anthropic(Claude) | ANTHROPIC_API_KEY | claude-opus-5-5 |
| OpenAI | OPENAI_API_KEY | gpt-5.5 |
| Google Gemini | GEMINI_API_KEY | gemini-pro-latest |
| Cloudflare Workers AI | CLOUDFLARE_API_TOKEN 和 CLOUDFLARE_ACCOUNT_ID | @cf/meta/llama-3.3-70b-instruct-fp8-fast |
如果不指定 --provider,则按以下顺序使用找到的第一个配置:OPENAI_COMPATIBLE_BASE_URL、Vercel AI Gateway(AI_GATEWAY_API_KEY)、Cloudflare Workers AI、Anthropic、OpenAI、Gemini。使用 --provider anthropic|openai|gemini|vercel|cloudflare 或在配置中设置 "provider",即可明确选择提供商;使用 --model 选择其他模型。--model cheap 会为各提供商选择小型、低成本的模型,适合在 CI 中进行常规运行:Vercel 上的 claude-haiku-5-5、gpt-5.5-mini、gemini-flash-latest 或 anthropic/claude-haiku-5.5。Cloudflare 的模型列表中只有一个模型,因此其 cheap 和默认选项相同。为降低运行成本,导航过程使用低推理力度;说明过程则使用高推理力度,并输出结构化 JSON。
任意兼容 OpenAI 的 API:Kimi、GLM、DeepSeek、OpenRouter、Ollama 等
许多提供商都提供与 OpenAI API 类似的接口。使用接口地址和模型 ID,即可将 ai-tag-debugger 指向该接口:
export OPENAI_COMPATIBLE_API_KEY=... # leave unset for a local Ollama
ai-tag-debugger run --site https://yourshop.com --journey add_to_cart \
--provider openai-compatible --base-url <API address> --model <model id>
| 提供商 | --base-url |
|---|---|
| Moonshot(Kimi) | https://api.moonshot.ai/v1 |
| Z.ai(GLM) | https://api.z.ai/api/paas/v4 |
| DeepSeek | https://api.deepseek.com |
| Mistral | https://api.mistral.ai/v1 |
| Groq | https://api.groq.com/openai/v1 |
| OpenRouter(数百种模型) | https://openrouter.ai/api/v1 |
| 运行在本机上的 Ollama | http://localhost:11434/v1 |
请使用提供商文档中的模型 ID。你也可以改为设置 OPENAI_COMPATIBLE_BASE_URL 和 OPENAI_COMPATIBLE_MODEL,而不使用这些参数;或在配置中设置 "provider"、"base_url" 和 "model"。如果 API 无法返回严格的 JSON Schema,说明将退回普通 JSON 模式。
Vercel AI Gateway
一个密钥即可使用多种模型。从 Vercel 控制面板获取 AI_GATEWAY_API_KEY 并进行设置,然后以 <provider>/<model> 的格式选择模型:
export AI_GATEWAY_API_KEY=...
aitd run --site https://yourshop.com --journey purchase --model google/gemini-3.6-flash
如果不指定 --model,则会使用 anthropic/claude-opus-5.5。用量和费用会显示在 Vercel 的 AI Gateway 控制面板中,并由 Vercel 计费。若要查看本次运行将使用的 AI,请运行 aitd:最后一行会显示类似 AI: vercel (anthropic/claude-opus-5.5) · also set: anthropic (pick with --provider) 的内容。
Cloudflare AI Gateway
要查看每次 AI 调用的日志、费用和速率限制,请通过 Cloudflare AI Gateway 发送调用。你的服务商密钥保持不变:
export AI_GATEWAY_URL=https://gateway.ai.cloudflare.com/v1/<account id>/default
export AI_GATEWAY_TOKEN=... # only if the gateway has authentication on
这适用于 anthropic、openai 和 gemini。请在网关中关闭缓存,这样每次运行都会访问实时网站。若要直接在 Cloudflare 上运行模型,请参阅 Cloudflare Workers AI。
关于模型选择。 AI 会通过逐步调用工具来浏览,每次浏览需要 5 到 30 步。不同模型在可靠完成这些操作方面差异很大:较小的模型和本地模型可能会点错内容、陷入循环,或提前停止。无论模型表现如何,检查结果都保持准确,因为它们来自捕获到的命中记录;但如果浏览流程没有完成,就无法显示后续事件。如果模型表现不佳,可以尝试更大的模型、目标简短的现成浏览流程,或使用 --max-steps。Anthropic、OpenAI 和 Gemini 的默认模型均经过测试。
Cloudflare Workers AI
Cloudflare 网络上的开放模型,按使用量向 Cloudflare 付费。创建一个具有 Workers AI 权限的 API 令牌,并在 Cloudflare 控制面板中找到你的账户 ID:
export CLOUDFLARE_API_TOKEN=...
export CLOUDFLARE_ACCOUNT_ID=...
aitd run --site https://yourshop.com --journey purchase
未指定 --model 时,将使用 @cf/meta/llama-3.3-70b-instruct-fp8-fast。当这两个变量都已设置时,会优先选择 Cloudflare,而不是 Anthropic、OpenAI 和 Gemini;若要使用其中之一,请传入 --provider。
添加原生服务商时,需要在 src/providers.js 中实现两个函数:一个用于工具调用对话,另一个用于结构化 JSON 调用。
快速开始
需要 Node 20+。
npm install -g @analitikisler/ai-tag-debugger
npx -y [email protected] install chromium # the browser version this release uses
export ANTHROPIC_API_KEY=... # or OPENAI_API_KEY, or GEMINI_API_KEY
ai-tag-debugger run --site https://staging.yourshop.com --journey add_to_cart --headed
全局安装还会添加一个简短别名 aitd:aitd run --site … --journey add_to_cart 效果相同。
也可以不安装,直接运行:npx -y @analitikisler/ai-tag-debugger run --site … --journey add_to_cart。
运行 aitd --help 查看命令;运行 aitd run --help(或 plan、replay、mcp)查看各命令的选项。如果运行不正常,aitd doctor 会检查 Node、Chromium、AI 密钥和数据文件夹,并说明如何修复。
试用演示商店(从源码运行)
仓库中包含一个演示商店,其中故意设置了三个追踪错误:
git clone https://github.com/analitikisler/ai-tag-debugger.git
cd ai-tag-debugger
npm install
npx playwright install chromium # run again after upgrading, so the browser matches Playwright
npm run demo:serve # in one terminal: http://localhost:4321
node src/cli.js run --config examples/demo.config.json --data-dir reports/demo
open reports/demo/localhost/runs/*/report.html
还没有 API 密钥?无需 AI 模型即可重放固定步骤:
node src/cli.js run --config examples/demo.config.json --scripted --no-ai --data-dir reports/demo
直接提出需求
你不必先了解各项选项。用引号括起一句普通的话,aitd 就会将其转换为匹配的命令、打印该命令,并在运行任何操作前询问 Run this? (Y/n):
aitd "check my google analytics tags"
# aitd run --platforms ga4
# Run this? (Y/n)
| 你输入 | aitd 运行 |
|---|---|
"检查我的 google analytics 标签" | aitd run --platforms ga4 |
"自上次运行以来,我的网站有哪些变化" | aitd run(每次运行都会报告变化) |
"将我的网站与计划进行比较" | aitd run --against latest |
"我的网站需要哪些自定义事件" | aitd plan --topic custom-events |
"结账时我的 Meta 像素会触发吗?" | aitd run --platforms meta --goal "reach checkout" |
"测试订阅新闻简报" | aitd run --goal "sign up for the newsletter" |
"我的购买事件发送的收入金额正确吗?" | aitd run --journey purchase |
"为 example.com 制定追踪计划" | aitd plan --site https://example.com |
"网店应该追踪哪些电商事件?" | aitd plan --topic ecommerce |
"检查联系表单上的 TikTok 和 Google Ads" | aitd run --platforms google_ads,tiktok --goal "submit the contact form" |
添加 -y 可跳过提问:aitd -y "check my google analytics tags"。
如果句子遗漏了信息,aitd 会提出一个简短问题,而不是猜测:是制定计划还是运行检查、要检查哪个网站,或要测试什么。目前无法通过句子筛选报告(输入 "Show me only the errors from the last report" 时会对此进行说明)。没有 AI 密钥时,会使用小型关键词匹配器处理常见短语。使用 AI 密钥时,AI 能理解任意措辞,但只能选择已有选项,因此不会编造标志。
先制定计划,再进行审计
一次运行会检查网站发送的内容是否符合计划:你预期的事件、参数和用户属性。分为三个步骤:
# 1. Draft a plan. The AI explores the site and proposes what should be tracked.
aitd plan --site https://yoursite.com
# 2. Optional: edit it in a spreadsheet, then save the edited copy as a new plan.
aitd plan export latest --site https://yoursite.com # writes plan.xlsx next to the plan
aitd plan import plan.xlsx --site https://yoursite.com # saves a new plan; the old one is untouched
# 3. Audit the site against the plan.
aitd run --site https://yoursite.com --against latest
拟定计划无需追踪代码。AI 会探索每种类型中的一个页面:主页、分类页、产品页、购物车、结账的第一步、搜索页,以及任何注册或联系表单。它不会付款,也不会提交含有个人信息的表单。--provider、--model 和 --max-steps(默认值为 25,即 AI 步骤数上限)的用法与 run 相同。输出会显示“发现的页面类型”和“此网站上不存在”,方便你查看 AI 到达了哪些页面类型。只有 2 个页面的小型网站也没问题。
若只想为一种事件拟定计划,请添加 --topic:custom-events、ecommerce、forms 或 consent。计划便只涵盖这些事件,其他计划格式保持不变:
aitd plan --site https://yoursite.com --topic ecommerce
计划会以 measurement-plan.json 和易读的 plan.html 格式,保存在新文件夹 aitd/<domain>/plans/<id>/ 中。每个事件都会列出:
name和platform。网站特有的事件(例如尺码指南或门店定位器)会标记为custom: true。description和trigger:页面类型和触发事件的元素可见标签。parameters:每个参数都附有说明和示例值。自定义参数会标记出来。required_params列出必须存在的参数。user_properties:建议的用户属性(例如customer_type),每项都附有说明和示例。
网站已发送的事件会标记为 "seen": true。
使用计划前请先检查。示例和建议根据 AI 看到的页面生成,因此请确认每个事件都符合你的业务。检查时会忽略额外字段。
电子表格导入和导出。 aitd plan export <plan> --site <url> 会在计划旁写入 plan.xlsx,其中 events 工作表每个事件参数占一行(event, platform, parameter, required, example, trigger, description),user_properties 工作表每个用户属性占一行。添加 --format csv 可改为生成 events.csv 和 user_properties.csv;CSV 无需额外的软件包。.xlsx 使用一个小型库 fflate,它作为可选依赖项随工具安装。aitd plan import <file> --site <url> 会读取电子表格(从 Google Sheets 导出时,选择“文件 > 下载 > Microsoft Excel (.xlsx)”,也可以将每个工作表分别下载为 CSV:Shop plan - events.csv 会与旁边的 Shop plan - user_properties.csv 一起导入,复选框单元格可识别为是/否),并将其保存为新的计划文件夹。导入绝不会修改现有计划。未知列会被忽略并显示警告;出错时会指出工作表、行和修复方法,例如 events, row 7: "required" must be yes or no (found "maybe").
measurement-plan.json 的格式如下:
{
"consent_mode": true,
"events": [
{ "platform": "ga4", "name": "add_to_cart", "required_params": ["currency", "value", "items"] },
{ "platform": "ga4", "name": "purchase", "journeys": ["checkout"], "required_params": ["transaction_id", "currency", "value", "items"] },
{ "platform": "meta", "name": "Purchase", "journeys": ["checkout"], "required_params": ["value", "currency"] }
]
}
platform 可设为 ga4、google_ads、meta 或 tiktok。journeys 用于限定预期事件出现的旅程(默认值:所有旅程)。对于每次操作都可能合理地触发多次的事件,请设置 allow_multiple: true。
事件名称采用宽松匹配,因此 dl_add_to_cart(Elevar)、addToCart 和 Add To Cart 都会被视为 add_to_cart;transaction 或 order_completed 则会被视为 purchase。若要添加自定义名称,请在计划事件中设置 "aliases": ["my_event"]。必需参数也可以通过常见的其他名称识别:products 对应 items,revenue 对应 value,order_id 对应 transaction_id。
根据计划进行审计。 run --against <plan> 接受 latest(或 last)、first、计划 ID,或计划文件或其文件夹的路径。如果未指定 --site,则使用计划中的站点。还可以为运行指定一个 journey,此时只会遍历该流程,并仅检查其中预期的计划事件;计划的其余部分会报告为未检查,而不会报告为缺失。单独使用时,--against 会从计划中推导出最多六个 journey:按计划事件触发所在的页面分组,并为每个页面创建一个 journey,最多六个(最小的分组会合并到最后一个 journey),且不会额外调用 AI。选定的 journey 会在浏览器启动前打印出来。此后,每份报告的标题都会显示 Checked against plan <id>。
run 需要测试目标:--against、--journey、--goal,或配置文件中的 journeys。如果都没有,命令会在打开浏览器前停止,并显示 Nothing to test. Add --against latest, --journey <id> or --goal "<text>".,因此不会漫无目的地运行并消耗 API 用量。如果某个站点还没有计划,run --against 会显示 No plan yet for example.com. Draft one with: aitd plan --site https://example.com。
aitd plan list --site <url> 会按从旧到新的顺序列出该站点的计划 ID。
从首次运行中学习计划。 如果站点没有已保存的计划,且运行时未使用 --against 或 --out,则会列出该站点已发送的事件,并询问是否将其保存为计划:
No plan yet for this site. It already sends 3 events: ga4:page_view, ga4:purchase, meta:PageView
Save them as the site's plan? (Y/n)
确认后,后续运行即可使用 --against latest 对照该计划进行检查。每次事件触发时都会携带的参数会成为该事件的必需参数。不会复制任何值,因此访客输入的内容不会进入计划。在脚本或 CI 作业中,除非添加 --yes,否则不会保存任何内容;此时运行会打印用于起草更完整计划的 aitd plan --site 命令。
计划与站点
运行使用 --against 时,报告会包含 Plan vs. site 部分:该部分位于 report.md 的顶部,以及 report.html 的 Coverage 部分。每个计划事件都会归入以下类别之一:
| 类别 | 含义 |
|---|---|
| 已实现 | 已计划、已触发、包含所有必需参数,且没有值问题 |
| 缺失 | 计划用于本次运行已遍历的 journey,但从未触发 |
| 缺少参数 | 已触发,但缺少必需参数 |
| 值错误 | 已触发但存在值问题,检查方式与购买金额、货币和商品的检查相同 |
| 未计划 | 已触发,但不在计划中 |
| 未检查 | 已计划,但本次运行未涉及其 journey 或平台 |
覆盖率得分为已实现事件数除以可检查的计划事件数(除未检查事件外的所有事件),并显示整体和各平台的得分,例如 Coverage 7 of 11 (64%), 2 events not checked。相同条目也会写入 plan-check.json,每个计划事件对应一条记录,并标明其类别。退出代码不会改变:--fail-on 仍会依据发现项的严重程度进行判断。未使用 --against 时,报告与之前完全相同。
如果该计划不是站点的第一个计划版本,标题会将其与之前保存的版本进行比较:Plan changed since 2026-10-01_0900: 1 added, 0 removed, 2 changed,或 Plan unchanged since 2026-10-01_0900。随后,report.html 和 report.md 中的标题会列出每项变更:新增事件用 + 表示,删除事件用 − 表示,修改事件用 ~ 表示,之后注明变更内容(必需参数、参数或 journeys)。第一个版本没有可供比较的版本;capture.json 则会在 planChanges 中保留相同的比较结果。
标签清单
每份报告还会包含一份 tag inventory:列出该站点发送请求的每个供应商,并标记为第一方(请求发送至站点自身域名)、第三方(请求发送至供应商),或两者。清单会显示在哪些页面上发现该供应商,以及与其关联的 Cookie。没有供应商归属的 Cookie 会单独列出,并标记为第一方或第三方。只记录 Cookie 名称,从不记录其值。该清单位于 report.html 的 Inventory 部分,并以表格形式显示在 report.md 中。
文件夹布局和计划 ID
计划和运行记录保存在你运行工具所在文件夹的 aitd/ 中:
aitd/
example.com/ the site's host, without www.
plans/2026-10-16_0900/ measurement-plan.json, plan.html, plan.xlsx (after an export)
runs/2026-10-16_0912/ report.html, report.md, timeline.csv, capture.json, steps.json,
junit.xml, summary.json and plan-check.json (with --against)
history.json a small summary of every saved run, for the trend (see below)
ID 使用本地时间,格式为 YYYY-MM-DD_HHMM。如果该分钟已被占用,则会添加秒数(_HHMMSS)。任何内容都不会被替换:每个草稿、导入项和运行记录都会获得一个新文件夹。使用 --data-dir <dir> 可将 aitd/ 文件夹存放在其他位置。replay 和 --save-site 文件夹不受影响。
每份报告都有一个“自上次运行以来的变化”部分,用于比较本次运行与 runs/ 中该站点上一次运行的结果,例如 2 个事件已修复,1 个新问题,并逐项列出:修复了什么(修复前是什么)、新增了什么,以及哪些问题仍未解决。如果两次运行都使用了 --against,则会比较计划覆盖情况(某事件从 Missing 变为 Implemented 即视为已修复);否则会比较健康检查结果。站点的首次运行会说明目前还没有可供比较的记录。无需设置任何标志。比较结果也会保存在 capture.json 的 changes 下。
各次运行的趋势
从第二次保存运行记录开始,工具还会汇总该站点最近 30 次运行的数据。在计数之后,CLI 会打印结论行和最多三行趋势信息:
2 broken · 1 risk · 1 warning · 0 info · 4 ok
Verdict: Fail · purchase tracking is broken on mobile · score 25/100
Trend over 5 runs (2026-10-01 → 2026-10-07): improving. Now 0 broken · 1 risk · 2 warning; 3 runs ago 2 broken · 1 risk · 0 warning.
Open longest: Meta PageView before_consent in 4 places since 2026-10-01 (5 runs); GA4 add_to_cart duplicate in 4 places since 2026-10-03 (3 runs).
Journeys that do not finish every time: checkout (mobile) 80%.
相同的行还会配上运行记录的文本迷你图(每次运行用一个字符表示;若该次运行的所有用户旅程都未完成,则用 · 表示),并显示在 report.md 和 report.html 的 Trend 部分。只要最近一次完成用户旅程的运行仍显示某个问题,该问题就计为未解决;用户旅程提前停止的运行无法证明任何情况,因此既不会修复问题,也不会重新引入问题。系统会列出反复出现的问题(出现、消失、再次出现),因为这类问题通常取决于时机,或取决于 AI 选择的产品,而非某项修复。趋势方向会将最近几次完整运行与此前的运行进行比较。
aitd history --site <url> 可单独打印趋势:每次运行占一行,包含计数和评分(3·broken + 2·risk + warning,越低越好)、迷你图以及上文所述的趋势信息。--limit <n> 只读取最新的 n 次运行(默认 30),--lang tr 会将信息切换为土耳其语,--json 会打印趋势序列、每项检查结果的时间线(首次出现、最后出现、未解决起始时间、修复时间、反复出现情况),以及脚本的用户旅程完成率。
摘要保存在 aitd/<domain>/history.json 中,每次运行约占用 2 KB;每次保存运行记录后,都会在写入其 capture.json 后更新此文件。该文件是一个缓存:若运行文件夹不在其中,则会从其 capture.json 读取;已删除的文件夹会在下次更新时从缓存中移除;删除此文件始终是安全的。发送到 --out 的运行记录和回放不属于历史记录。
选择要测试的内容
开始时不需要配置文件。你可以选择现成的用户旅程、用自然语言描述自己的旅程、根据计划进行检查,并将检查范围缩小到你关注的事件:
# Check the site against its latest saved plan.
aitd run --site https://staging.yourshop.com --against latest
# Ready-made journeys come with a goal and the GA4 and Meta events to expect.
ai-tag-debugger run --site https://staging.yourshop.com --journey purchase --journey sign_up
# Describe a journey in your own words. The events you name are expected on it.
ai-tag-debugger run --site https://yoursite.com --goal "Subscribe to the newsletter in the footer" --events newsletter_signup
# Only check some events.
ai-tag-debugger run --config ai-tag-debugger.config.json --events purchase,add_to_cart
| 现成的用户旅程 | AI 执行的操作 | 预期事件 |
|---|---|---|
purchase(或 checkout) | 商品 → 购物车 → 结账 → 使用测试付款选项下单 | GA4 view_item、add_to_cart、begin_checkout、purchase;Meta AddToCart、InitiateCheckout、Purchase |
add_to_cart(或 cart) | 打开商品并将其加入购物车 | GA4 view_item、add_to_cart;Meta AddToCart |
sign_up(或 signup、register) | 使用测试数据创建账户 | GA4 sign_up;Meta CompleteRegistration |
lead(或 contact、form) | 填写并提交联系、报价或演示表单 | GA4 generate_lead;Meta Lead |
search | 搜索网站并打开一个结果 | GA4 search,包含 search_term;Meta Search |
--journey 也可以根据 ID 从你的配置中选择用户旅程。使用配置时,现成的用户旅程会将其事件添加到计划中。
不确定要测试什么?aitd plan --site https://yoursite.com 会起草一份测量计划,--against latest 则会根据该计划检查网站。
控制 API 使用量
每个浏览步骤都会调用一次模型,因此使用量会随着 旅程数 × 视口数 × 步骤数 增长,最后还会额外调用一次模型来解释结果。检查本身不会调用模型。
- 只运行需要的旅程。 这是节省用量最有效的方法:与完整的
purchase旅程相比,--journey add_to_cart只需几步,而不是十步或更多。 - 只运行一个视口。
--viewport mobile的调用次数是同时使用桌面和移动视口的一半。 - 限制步骤数。
--max-steps 15会在旅程漫无目的地进行时将其停止。 - 预期页面越复杂,成本越高。 每个步骤都会将页面视图(最多 250 个元素和 3,000 个字符的文本)发送给模型,因此,繁忙页面每步使用的令牌会比简单页面更多。
- 重复运行会从上次的路由开始。 某个旅程在网站上完成后,下次运行会按顺序将该次运行经过的页面提供给 AI,让它直接前往目标,而不是重新探索。只有在目标相同、运行版本为 0.14.0 或更高,且使用 AI 运行时才会重用路由。使用
--out或replay时不会使用路由。如果网站已更改,导致路由不再适用,AI 会改走其他路径。 - 使用
--events让报告聚焦重点。它不会缩短浏览过程,因此对用量几乎没有影响。 - 不使用 AI 进行回放。 每次完成运行后,都会将所执行的步骤保存为运行文件夹中的
steps.json;对于没有固定步骤的旅程,--scripted --no-ai会重复上次已完成运行的步骤。先使用 AI 运行一次旅程,然后在每次部署时回放。请参阅保存步骤并在不使用 AI 的情况下回放。 - 使用聊天应用。 通过 MCP,聊天应用自己的模型会执行浏览,因此完全不需要 API 密钥。
- 临时故障不会消耗一次运行。 对于模型 API 的速率限制、过载响应或连接中断(429、529、5xx 等),最多会重试 3 次,并逐渐延长等待时间,同时遵循
retry-after。如果网络中断或超时导致页面加载失败,则会在 2 秒后重试一次。其他错误(例如密钥无效或页面拒绝访问)会立即失败。
运行时间则是另一回事:--concurrency 3 会同时运行最多三个旅程,每个旅程使用独立的浏览器,因此包含多个旅程和视口的运行会快得多。模型调用次数不变,只是调用时间更集中,所以如果服务提供商对你实施速率限制,请将其设为 1 或 2。
使用保存的网站检查新版本
--save-site <dir> 还会保存网站发送的所有响应和执行过的步骤。随后,replay 会离线重新审查相同页面,无需网络和 AI 模型,因此不产生费用。它会列出与已保存运行相比新增或消失的发现:
npx @analitikisler/ai-tag-debugger run --site https://www.yourshop.com --journey purchase --save-site saved/yourshop
npx @analitikisler/ai-tag-debugger replay saved/*
✗ https://www.yourshop.com (saved/yourshop): 0 new, 1 gone
- warning duplicate purchase desktop ga4 page_view
首次运行的发现会成为预期结果。如果某项更改是正确的,例如修复了误报,可使用 replay --update 将新发现设为预期结果。你可以用它来检查工具的新版本在熟悉的网站上的表现,或检查网站相对于上次良好运行的变化。保存的网站通常有几 MB。保存内容不包括跟踪请求、图片和视频、HttpOnly 和登录 Cookie、浏览器发送的 Cookie、授权标头、表单数据,以及地址中包含电子邮件或其他用户数据的请求。保存内容仍包含网站页面和脚本,因此请勿将自己不拥有的网站放入公共仓库。
保存步骤并在不使用 AI 的情况下重放
每次运行完成后,都会将每个旅程执行的步骤保存到其运行文件夹 aitd/<domain>/runs/<id>/steps.json 中。使用 --scripted --no-ai 运行时,系统会对自身没有 steps 的每个旅程重复这些步骤:它会选取站点上最近一次完成该旅程的运行;如果有相同视口的运行,就选用该运行,否则选用其他视口的运行,并在旅程的 ▶ 行下方说明正在重放哪个运行。因此,每个旅程只需使用一次 AI,之后的每次运行都无需花费:
ai-tag-debugger run --site https://www.yourshop.com --journey purchase
ai-tag-debugger run --site https://www.yourshop.com --journey purchase --scripted --no-ai
如果站点发生变化,保存的步骤无法再找到对应元素,旅程就会以未完成状态结束,并附注说明该运行的步骤已不再适用;再使用 AI 运行一次,之后的重放就会使用新步骤。若某个旅程从未在该站点上完成,运行会在启动浏览器前停止。系统只会重放保存在 aitd/ 中的运行:通过 --out 将运行结果保存到其他位置,或通过 MCP 执行的运行,虽然也会写入 steps.json,但下次运行不会在那里查找。步骤会按执行时的原样保存,包括输入的值(例如,输入表单的电子邮件地址会按输入内容保存在 steps.json 中,因为重放时必须再次输入),因此请在旅程中使用测试数据,并将运行文件夹排除在版本控制之外。
若要将步骤改为保存在代码库中,--save-steps <file> 会将步骤写入配置文件的 journeys[].steps。如果文件不存在,就会创建;如果配置中没有运行计划,也会保存本次运行的计划。之后使用同一配置,即可在不调用 AI 模型且无需 API 密钥的情况下重复该旅程:
ai-tag-debugger run --site https://www.yourshop.com --journey purchase --save-steps ai-tag-debugger.config.json
ai-tag-debugger run --config ai-tag-debugger.config.json --scripted --no-ai
如果某个旅程在两个视口上都运行过,只会保留第一个视口的步骤。每次部署时运行第二条命令,即可在不调用任何模型的情况下检查同一旅程。
接受已知问题
--fail-on 会在发现某个级别的问题时使构建失败。如果某个问题已知且近期不会修复,例如某个供应商像素在用户同意前触发,可以使用基线让后续运行只因新问题而失败。使用 --update-baseline 运行一次,将当前所有问题写入文件,检查文件内容,然后提交该文件:
ai-tag-debugger run --config ai-tag-debugger.config.json --scripted --no-ai --baseline baseline.json --update-baseline
ai-tag-debugger run --config ai-tag-debugger.config.json --scripted --no-ai --baseline baseline.json --fail-on warning
文件中每个问题对应一个条目,其中 key 是运行用于匹配的键(检查项、平台、事件、旅程、视口,以及对于缺失参数,具体缺失哪些参数),其余内容供阅读者查看。删除某个条目即可让系统再次因该问题而失败;也可以添加 "note",说明接受该问题的原因;下次使用 --update-baseline 时,备注仍会保留。已接受的问题仍会显示在报告中,并标记为“Accepted”,但不会计入数量或 AI 说明,也不会触发 --fail-on。数量之后,运行会打印已接受的问题数量,以及已过期的基线条目数量(即不再出现的问题),以便精简文件。如果某个问题只在部分视口或旅程中被接受,报告会将其标记为部分接受,并仍计入数量;如果基线是为其他站点编写的,则会打印警告。在配置中设置 "baseline": "baseline.json"(相对于配置文件的路径),即可保存该选项,无需每次传入;MCP 的 run_audit 工具也接受 baseline 参数。
配置站点
ai-tag-debugger.config.json:
{
"site": "https://staging.yourshop.com",
"plan": "measurement-plan.json",
"gtm_container": "GTM-XXXX_workspace.json",
"viewports": ["desktop", "mobile"],
"journeys": [
{
"id": "checkout",
"goal": "Accept cookies, add any product to the cart and complete checkout using the test payment method."
}
]
}
| 字段 | 含义 |
|---|---|
site | 基础 URL。条件允许时使用暂存环境。 |
plan | 测量计划:文件路径或内联对象(见下文)。使用现成旅程时可选。使用 --against 的运行会改用该计划。 |
gtm_container | 可选的 GTM 容器导出文件(Admin → Export container)。之后,每个有问题的事件都会指出发送该事件的标签及其触发条件(或说明没有标签发送该事件),并说明该触发条件是否在旅程中触发,以及未触发的原因(标签已暂停、未随事件推送数据、条件不满足并附上检测到的值、存在阻止触发条件、同意状态被拒绝)。这些信息基于捕获的 dataLayer 数据评估,不使用 AI 模型。 |
viewports | desktop 和/或 mobile。 |
concurrency | 默认为 1。同时运行的旅程(及同意场景)数量,每个旅程各自在独立的浏览器中运行,最多为 8。等同于 --concurrency。 |
journeys | 使用 --journey 选择现成旅程、使用 --goal 描述旅程,或使用 --against 对照计划检查时可选。 |
journeys[].goal | 用通俗语言描述 AI 应执行的操作。 |
journeys[].start | 可选的起始路径(默认为 /)。 |
journeys[].steps | --scripted 运行的可选固定步骤:{ "action": "click", "selector": "#add-to-cart" }。如果未设置,--scripted 会重复该网站上该旅程最近一次已完成运行的步骤。 |
allowed_hosts | 旅程可访问的其他主机,例如托管结账页面时可设为 ["checkout.payments-provider.com"]。否则,浏览器只会访问 site 主机及其子域名。等同于 --allow-host。 |
providers | 要检查的跟踪平台,例如 ["ga4", "meta"]。默认值为 ["ga4", "google_ads", "meta", "tiktok"],此外还会检查此项未设置时网站发送数据到的其他平台。等同于 --platforms。 |
campaign_checks | 默认为 true。每次运行都会像点击广告一样打开第一个页面(使用 UTM 参数、gclid、fbclid,或起始地址中已有的参数),并检查这些参数是否在重定向后保留且传递到请求中。设为 false 则打开不带参数的地址。 |
block_hits | 默认为 true。设为 false 则允许请求发送到真实端点。 |
consent_scenarios | 默认为 true。设为 false 则跳过同意场景,即不再针对每种同意选择各访问一次起始页面。 |
baseline | 可选的已接受问题基准文件路径,相对于配置文件所在目录。等同于 --baseline。请参阅接受已知问题。 |
language | 报告语言,en(默认)或 tr。等同于 --lang。 |
keep_bodies | 默认为 false。设为 true 则按原样存储跟踪请求,不对用户数据进行脱敏。等同于 --keep-bodies。 |
branding | 默认为 true。设为 false 则在报告中隐藏 Analitik İşler 徽标和“Generated by AI Tag Debugger · analitikisler.com”一行。等同于 --no-branding,也可在 MCP finish_audit 和 run_audit 工具中设置 branding: false。 |
report | 可选的白标设置:{ "name": "Acme", "logo": "logo.png", "color": "#0a7d5a", "pdf": true }。logo(PNG、JPG、WebP、GIF 或 SVG,最大 512 KB,相对于配置文件所在目录)和 name 会替换 HTML 报告中的 Analitik İşler 品牌标识(小型“by AI Tag Debugger”徽标和署名仍会保留);color 用于设置强调色;pdf: true 还会在 report.html 旁生成 report.pdf。 |
provider | 可选值:anthropic、openai、gemini、vercel、cloudflare 或 openai-compatible。等同于 --provider。 |
base_url、model | 可选的 API 地址和模型 ID,例如用于 openai-compatible。分别等同于 --base-url 和 --model。 |
notify | 每次保存运行结果后的可选提醒:slack(Webhook URL,或设为 true 以读取 SLACK_WEBHOOK_URL)和 email(一个地址或地址列表)。请参阅提醒。 |
配置和计划会在读取后立即检查,浏览器启动前就会完成。发生错误时会指出字段;对于固定选项,还会列出允许的值,例如 viewports[1]: must be one of desktop, mobile (got "tablet") 或 journeys[0].steps[2].action: must be one of goto, click, fill, select, scroll, wait。工具不认识的键会被忽略,并显示建议最接近的键的警告(Unknown key "viewport" ... Did you mean "viewports"?),因此文件中的额外注释不会阻止运行。aitd plan 保存的计划以及从电子表格导入的计划也会接受相同检查。 |
提醒
每次运行保存后,notify 都会将“与上次运行相比的变化”差异发送给团队,这样网站发生变化时,无需打开报告就能收到通知:
"notify": {
"slack": "https://hooks.slack.com/services/...",
"email": ["[email protected]"]
}
- Slack 需要提供 Webhook URL。
"slack": true会改为从SLACK_WEBHOOK_URL环境变量读取该 URL,因此 URL 不会写入文件。 - 电子邮件 需要提供一个地址或地址列表。邮件通过
SMTP_URL中的服务器发送,例如smtps://user:[email protected]:465。SMTP_FROM设置发件人(默认为第一个收件人)。请使用smtps://,它会从连接开始时就加密。普通的smtp://URL 会以未加密的方式发送登录信息和邮件,并且不支持 STARTTLS。
只有保存的运行(而非发送到 --out 的运行)存在可供比较的较早运行,且自上次运行以来确实有变化时,才会发送提醒。主题会先显示结果,然后是计数和摘要:shop.example: Fail · 2 new problems · purchase tracking is broken on mobile。正文会重复结果行,接着列出已修复的问题(以及修复前的情况)和新增问题;每个新增问题都附有严重程度和负责人;然后是带迷你趋势图的趋势行、反复出现的问题,以及问题持续打开 5、10、20 次运行后(此后每 10 次)显示的“仍未解决,已持续 N 次运行”,以免每封消息都重复相同的未解决问题列表:
shop.example
Verdict: Fail · purchase tracking is broken on mobile · score 25/100
1 problem fixed, 1 new problem. Compared with run 2026-10-15_1000, by health findings (2026-10-16_1000).
- Fixed: GA4 page_view (was: Sent before consent)
- New: Meta Purchase · Broken · "Purchase" was sent without "value". · Developer
Trend over 5 runs (2026-10-12 → 2026-10-16): worsening. Now 2 broken · 1 risk · 0 warning; 3 runs ago 0 broken · 1 risk · 0 warning. `▃▃·▅█`
趋势本身不会触发提醒。如果某个渠道发送失败,运行会打印原因并继续执行。退出代码仍由 --fail-on 决定。
CLI
aitd "<sentence>" [-y]
aitd plan --site <url> [--topic <name>] [--headed] [--provider <name>] [--model <id>] [--max-steps <n>] [--data-dir <dir>]
aitd plan list --site <url> [--data-dir <dir>]
aitd plan import <file> --site <url> [--data-dir <dir>]
aitd plan export <plan> --site <url> [--format xlsx|csv] [--data-dir <dir>]
aitd run --site <url> (--against <plan> | --journey <id> | --goal "<text>") [--config <file>] [--events <names>]
[--max-steps <n>] [--viewport desktop|mobile] [--concurrency <n>] [--platforms <list>] [--data-dir <dir>]
[--provider anthropic|openai|gemini|openai-compatible] [--model <id>] [--lang en|tr] [--headed]
[--fail-on broken|risk|warning|never] [--baseline <file>] [--update-baseline]
[--scripted] [--no-ai] [--save-site <dir>] [--save-steps <file>]
aitd replay <dir>... [--update] [--out <dir>]
aitd mcp [--http] [--port <n>] [--host <addr>] [--token <secret>] [--public-url <https url>] [--reports <dir>]
[--allow-private-network]
aitd doctor [--site <url>] [--data-dir <dir>]
aitd history --site <url> [--limit <n>] [--json] [--lang en|tr] [--data-dir <dir>]
aitd 是 ai-tag-debugger 的简短别名,接受相同的命令和选项。运行 aitd <command> --help 可查看各命令的基本选项。
所有选项
| 选项 | 命令 | 含义 |
|---|---|---|
--site <url> | plan, run, doctor, history | 网站。plan 和 history 必填;对于 run,除非指定 --against 或配置文件提供网站,否则必填。doctor 只会检查地址是否为 http(s),以及能否解析其主机名。 |
--against <plan> | run | 根据计划进行检查:latest(或 last)、first、计划 ID,或计划文件或文件夹的路径。 |
--journey <id> | run | 预设旅程(可重复指定)。 |
--goal "<text>" | run | 用自然语言描述的旅程(可重复指定)。 |
--config <file> | run | 从配置文件中读取网站、旅程和计划。 |
--events <names> | run | 只检查这些事件,例如 purchase,add_to_cart。 |
--viewport <name> | run | desktop 或 mobile(可重复指定)。 |
--concurrency <n> | run | 同时运行的旅程数,每个旅程使用独立浏览器:1(默认值)到 8。并行运行时,每个旅程的日志行都以 [journey/viewport] 开头;--headed 会打开相应数量的浏览器窗口。等同于配置文件中的 concurrency。 |
--platforms <list> | run | 要检查的平台,例如 ga4,meta。用于替代 --providers;后者仍可使用一个小版本。 |
--max-steps <n> | plan, run | 每个旅程最多执行的 AI 步数(plan 的默认值为 25)。 |
--lang <code> | run, history | 报告语言:en 或 tr。对于 history,指定趋势线的语言。 |
--fail-on <level> | run | 达到此级别时以代码 1 退出:broken(默认值)、risk、warning 或 never。 |
--baseline <file> | run | 包含已接受问题的文件。这些问题仍会报告,但不会计入 --fail-on。请参阅接受已知问题。 |
--update-baseline | run | 运行结束后,将本次运行发现的所有问题写入基线文件;如果文件不存在,则创建该文件。 |
--headed | plan, run | 显示浏览器窗口。 |
--provider <name>, --model <id> | plan, run | AI 提供商和模型。默认值:已设置 API 密钥对应的提供商和模型。 |
--scripted | run | 重放每个旅程的固定步骤,不使用 AI 导航。没有步骤的旅程会重复使用该网站上次已完成运行的步骤。 |
--no-ai | run | 完全不使用 AI 模型。隐含启用 --scripted。 |
--save-site <dir> | run | 保存网站的响应,供 replay 使用。 |
--save-steps <file> | run | 将每个旅程执行的步骤写入配置文件。 |
--data-dir <dir> | plan, run, doctor, history | aitd/(计划和运行记录)的存放位置。默认值:./aitd。用于替代 run --out。 |
--limit <n> | history | 趋势读取的网站最近运行记录数量。默认值:30。 |
--json | history | 以 JSON 而非文本形式输出趋势序列、问题时间线和旅程稳定性。 |
--format xlsx|csv | plan export | 电子表格格式。默认值:xlsx。 |
--update | replay | 将此次重放发现的问题设为预期问题。 |
--out <dir> | replay | 重放报告的写入位置。对于 run,--out 仍可作为隐藏别名使用一个小版本,并会输出提示;请改用 --data-dir。 |
--base-url <url> | run | OpenAI 兼容提供商的 API 地址。 |
--allow-host <host> | run | 旅程可以访问的另一个主机(可重复指定)。等同于 allowed_hosts。 |
--keep-bodies | run | 按原样存储跟踪请求,不对用户数据进行脱敏。 |
--no-branding | plan, run | 从报告和 plan.html 中移除徽标和署名行。 |
--http, --port, --host, --token, --public-url, --reports, --allow-private-network | mcp | 请参阅下方的 MCP 部分。 |
0.10.0 中已移除:plan --from、plan --out 和 plan --force。起草计划时始终会保存到新文件夹中;使用已移除的标志时,会显示替代命令。
当发现数量达到 --fail-on 阈值(默认为 broken)时,退出代码为 1,因此可用于阻止部署。已在基线中接受的发现不计入其中。有关在每次部署后运行的示例,请参阅 examples/github-actions/ai-tag-debugger.yml。
**CI 中的测试结果。**每次运行还会生成 junit.xml,其中每个旅程都是一个测试套件,每项发现都是一个测试用例;当发现达到 --fail-on 阈值时,该测试用例会失败,因此 GitHub Actions、GitLab 和 Jenkins 会将这些发现显示为测试失败。在 GitHub Actions 中,上传该文件并将其交给 JUnit 报告器 action:
- run: aitd run --config ai-tag-debugger.config.json --data-dir tracking-report
- uses: actions/upload-artifact@v6
if: always()
with:
name: junit
path: tracking-report/**/junit.xml
# Optional: any JUnit reporter action turns the file into annotations on the run.
- uses: dorny/test-reporter@v2
if: always()
with:
name: tracking
path: tracking-report/**/junit.xml
reporter: java-junit
在 GitLab 中,将 artifacts: reports: junit: 指向相同的路径。同目录下的 summary.json 包含计数、判定结果(status:fail、attention 或 pass,以及 headline 键,例如 fail_broken)、数据质量 score(0 到 100)、已保存运行的趋势 direction、各个旅程、每项发现(检查项、严重程度、平台、事件、旅程、视口、标题、消息)、运行文件夹名称(run),以及其他文件的名称(files,相对于该文件夹),这样脚本无需解析 capture.json 即可读取结果;其中的任何内容都不依赖运行所在的机器:
jq '.counts.broken' aitd/example.com/runs/*/summary.json
jq -r '.verdict.status + " " + (.score | tostring)' aitd/example.com/runs/*/summary.json
**定时运行。**若要按计划进行审计,而不是在每次部署后运行,请使用 examples/github-actions/scheduled-run.yml(默认每周运行一次,可修改 cron 行)。它会在缓存中保存各次运行之间的历史记录,因此在全新运行器上也能继续使用“自上次运行以来的变更”。在自己的服务器上,examples/cron/ 提供了实现相同功能的脚本和 crontab 行。
输出:
report.html:单文件,每次聚焦一个屏幕。左侧可折叠侧栏列出七个部分;每个部分、筛选条件和卡片都有各自的 URL,可供收藏或分享;从一个部分点击链接,可在另一个部分打开对应卡片(例如,某条发现中的“位置”标签会在其所属步骤中打开该命中)。- 摘要:以圆环显示数据质量评分,低于 50 为红色,50 至 89 为琥珀色,90 起为绿色;显示结论及其标题,并用最多三行说明扣分原因(满分时不显示);状态标签可打开按严重程度筛选的发现;还有六张运行信息卡:已检查的供应商、各旅程及其检测到的平台、已检查的事件、同意状态、AI 提供方和运行本身。
- 发现:筛选栏(严重程度、负责人、平台、旅程、视口、搜索)可筛选三个分组:失败、未验证和通过。每行默认折叠,展开后显示 证据、修复、位置 和 验证 标签页:影响、可能原因、标出缺失参数的证据、编号修复步骤、问题发生的步骤,以及用于检查修复效果的工具,例如 Tag Assistant、GA4 DebugView、Meta Test Events 或 TikTok Pixel Helper。如果网站有更早的运行记录,分组上方会显示 自上次运行以来的更改。
- 旅程:每次显示一个旅程和一个视口。左侧按页面分组列出步骤,步骤名称取自页面(如“打开首页”“添加到购物车”),并显示每个步骤产生的命中;右侧显示所选步骤及其 命中、数据层 和 请求 标签页。每个命中都会显示事件、关键参数和同意状态,展开后可查看解码后的参数、商品卡片和原始请求。对于批量发送的 GA4 请求,会显示其中的每个事件。页面默认打开第一个存在问题的步骤。
- 同意状态:每个平台各占一行,显示其在用户选择前、接受后和拒绝后收到的内容、Consent Mode 默认值和更新及其时间,以及同意场景表格。
- 覆盖情况:显示每个计划事件是否在每条旅程中发送、仍缺少的参数、转化完整性,以及使用
--against时显示的计划与网站对比分组。 - 清单:标签清单,每个平台占一行,展开后显示其主机、页面和 Cookie。
- 运行:运行信息(网站、版本、AI 提供方和模型、计划、旅程、视口、平台、时间、文件);如果网站有更早的运行记录,还会显示 趋势。
除“摘要”外,每张卡片初始时均处于折叠状态;每个部分都有“全部展开”和“全部折叠”按钮。页面包含一个小型脚本,其哈希值已获页面内容安全策略许可,用于控制侧栏、筛选器、标签页和深层链接;没有 JavaScript 时,各部分会依次排列成一份文档,这也是打印版式。键盘操作:按
[折叠侧栏,按1–7跳转到相应部分。Logo 已嵌入页面,不会从互联网加载任何内容。--no-branding会移除 Analitik İşler Logo 和署名行。
timeline.csv:与报告相同的时间线,每次命中、dataLayer 推送和网络调用各占一行,可直接用于 Excel 或 Google Sheets。report.md:Markdown 格式的报告,适用于拉取请求评论、Slack 消息或邮件;四条用户旅程的运行结果约 100 行,不超过 8 KB。标题即结论(# shop.example: purchase tracking is broken on mobile),后接一行元数据、包含数据质量评分的状态,以及各项计数。随后按此顺序呈现:自上次运行以来的变化和趋势(当网站有更早的运行记录时);计划与网站对比(使用--against时);优先事项(按负责人列出的待办事项:Developer、Tag Manager、Marketing);问题发现(最多五个完整条目,包含位置、影响、原因、证据、其他正常项、负责人、修复方法、验证方法以及指向report.html的链接;其余问题在其他部分各用一行列出);同意管理(Consent Mode 时序说明,以及每个单元格均注明原因的场景表);已通过的检查;用户旅程(每次运行一行,之后仅列出存在问题的步骤);未检查项(列出本次运行无法判断的内容,以及用于启用相应检查的配置键);以及标签清单。文件中不包含逐次命中的时间线;时间线见timeline.csv。capture.json:包含捕获的所有内容,供你自行分析,包括工具version、ai提供方以及计算得出的metrics(结论、评分、计划覆盖率、漏斗、平台一致性、同意管理合规性、转化完整性、时序、优先事项)。plan-check.json:使用--against时,为每个计划事件提供一个条目,并标明其类别。junit.xml:以 JUnit 测试结果格式呈现问题发现,每条用户旅程和每种视口各一个测试套件,供 CI 系统将其显示为测试失败(见上文)。summary.json:用一个小型文件汇总本次运行的计数、结论、评分、趋势方向、用户旅程、问题发现和文件名,供脚本使用。plan.html(位于计划文件夹中):以易读页面展示计划中的事件、参数和用户属性。
报告以署名行结尾:“Generated by AI Tag Debugger · analitikisler.com”,其中域名为普通链接(没有图片、跟踪或 referrer,因此不会泄露报告 URL)。--no-branding 会同时移除署名行和 Logo。
使用 --lang tr 生成土耳其语报告。问题发现文本、标题、模型的解释和修复建议均以土耳其语撰写,Agent 也会用土耳其语描述其步骤。
在 AI 聊天应用中使用(MCP)
aitd mcp 会启动一个 Model Context Protocol 服务。随后,聊天应用的模型会自行执行审计:你只需询问“检查 staging.myshop.com 结账流程中的跟踪情况”,它就会打开浏览器、逐步点击操作,并在聊天中解释发现的问题。无需 API 密钥,因为由应用自身的模型进行分析。
该服务提供的工具:
| 工具 | 功能 |
|---|---|
make_plan | 为网站拟定跟踪计划(应跟踪哪些内容),与 aitd plan --site 相同。传入 topic(custom-events、ecommerce、forms、consent)可将范围限制为一种事件。计划会保存,其 ID 可作为 against 传给 finish_audit。该工具使用运行服务的计算机上配置的 AI 提供商,耗时几分钟。 |
what_changed | 仅返回网站“自上次运行以来”的差异:最新保存的运行(aitd run)中已修复的问题和新增问题,与之前的运行进行比较。不使用浏览器,也不使用 AI。传入 language 可获取土耳其语回答。 |
start_audit | 在某个 URL 上打开一个全新的浏览器,并开始记录所有跟踪数据。传入预设用户旅程(purchase、sign_up,等等)可获取其目标和预期事件;传入 providers 可选择要检查的平台。助手会先询问你要检查哪些平台。 |
browser_action | 执行一次点击、填写、选择、跳转、滚动或等待操作。返回页面以及该步骤发送的跟踪请求。 |
get_page | 显示当前页面。 |
finish_audit | 根据测量计划(JSON)、作为 against 传入的已保存计划(latest、first、计划 ID;在本地服务上也可以是路径),或预设用户旅程的事件检查所有内容;也可仅检查你指定的 events,并生成包含时间线的完整 HTML 报告。网站信息来自审计。 |
run_audit | 端到端运行配置文件。传入 against 后,会将运行结果与已保存计划进行比较;如果配置中没有用户旅程,还会遍历根据该计划推导出的用户旅程。concurrency 设置同时运行的用户旅程数量,每个旅程使用独立浏览器(默认值为 1);baseline 指定一个用 --update-baseline 写入的、包含已接受发现项的文件(默认值为配置中的 baseline;参见接受已知发现项)。仅本地支持文件路径。 |
against 的可接受值与 CLI 的 --against 相同。通过 HTTP 调用时,只能传入 latest、first 或计划 ID,不能传入路径。计划是通过 aitd plan --site <url> 或 make_plan 保存的计划。想了解应该跟踪什么时,就请求制定计划;想了解网站发送了什么时,就请求执行审计。
浏览器会在运行服务的计算机上运行,因此能够访问你的预发布环境和 localhost 网站。跟踪请求照常在本地得到响应。
启动本地服务的应用:Claude Desktop、Gemini CLI、Cursor、VS Code、Claude Code
将服务添加到应用的 MCP 配置中。对于 Claude Desktop,请前往“设置 → 开发者 → 编辑配置”(claude_desktop_config.json):
{
"mcpServers": {
"ai-tag-debugger": {
"command": "npx",
"args": ["-y", "@analitikisler/ai-tag-debugger", "mcp"]
}
}
}
首次运行审计时,浏览器(Chromium)会自行下载,约需一分钟,只需下载一次。要提前下载,请运行:npx -y [email protected] install chromium。
一键和单行设置:
- Claude Code:
claude mcp add ai-tag-debugger -- npx -y @analitikisler/ai-tag-debugger mcp - Cursor:添加到 Cursor
- VS Code:在 VS Code 中安装,或运行
code --add-mcp '{"name":"ai-tag-debugger","command":"npx","args":["-y","@analitikisler/ai-tag-debugger","mcp"]}' - **Claude Desktop、Gemini CLI 等:**使用上面的 JSON 代码块。Gemini CLI 在
~/.gemini/settings.json中使用相同的mcpServers代码块。
重启应用后,ai-tag-debugger 工具就会显示。如果应用找不到 npx,请使用其完整路径(例如运行 which npx;在安装了 Homebrew 的 Mac 上,路径可能是 /opt/homebrew/bin/npx)。报告会写入 ~/ai-tag-debugger-reports。
如果要从克隆的仓库运行,请使用 "command": "node" 和 "args": ["/path/to/ai-tag-debugger/src/cli.js", "mcp"]。
连接到 URL 的应用:ChatGPT、Gemini
这些应用通过 HTTPS 连接 MCP 服务(在 ChatGPT 中通过开发者模式连接器连接,具体取决于你的套餐)。以 HTTP 模式启动服务,并通过隧道公开服务:
cloudflared tunnel --url http://localhost:8787 # or: ngrok http 8787; note the https address it prints
npx -y @analitikisler/ai-tag-debugger mcp --http --port 8787 --public-url https://<your-tunnel-address>
服务会输出一个带有随机密钥路径的 URL,例如 https://<your-tunnel-address>/mcp/<secret>。将该 URL 添加为应用中的连接器。任何拥有此 URL 的人都可以使用你机器上的浏览器,因此请妥善保密,并在完成后停止服务。自定义密钥(--token)必须至少为 16 个字符。
在 HTTP 模式下,服务的限制比本地模式更严格:
- 它不会读取磁盘上的测量计划或配置(请在聊天中以 JSON 文本传入计划,或通过
against: latest、first或其 ID 指定已保存的计划),且不会提供run_audit。它只会提供自己生成的报告。 - 浏览器只会打开
http和https页面,并会拒绝localhost和私有网络地址(例如192.168.x.x或169.254.169.254),因此无法通过该 URL 查看你的网络。包括 WebSockets 在内的所有浏览器流量都会经过内置的小型代理;代理会解析每个主机一次,并且只连接已检查的地址,因此 DNS 响应即使在审计过程中发生变化,也无法绕过检查。若要以这种方式审计本地暂存站点,请使用--allow-private-network启动服务。 - 保持打开 15 分钟的审计会被关闭,且请求正文大小限制为 1 MB。
Analitik İşler Cloud 版本包含托管服务,无需使用隧道。
安全
- 系统会要求 Agent 使用明显的测试数据,绝不输入真实的支付信息。如果某个流程需要真实支付或账户,Agent 会停止并报告。
- 默认情况下,会在本地响应发往工作原理中所列平台的跟踪请求,因此这些分析和广告账户不会收到测试转化数据。
- 浏览器仅访问经过审计的网站及其子域名,以及任何
allowed_hosts。它只会打开http和https页面。 - 系统会告知模型,页面内容是数据,而非指令。提示词规则无法保证模型绝不会受误导,因此上述导航限制可限制模型受误导后能采取的操作。
- 浏览器运行环境中不包含你的 API 密钥及其他机密信息。
- 用于广告匹配的用户数据会在存储到
capture.json或显示在报告中之前进行脱敏:包括 GA4 和 Google Ads 增强型转化中的电子邮件、电话号码、姓名、地址和用户 ID(em、ph、uid等),Meta 高级匹配中的数据(ud[*]、udff[*]),TikTok 的context.user,以及网站为增强型转化推送到 dataLayer 的user_data。任何看起来像电子邮件地址的值都会被脱敏,无论其字段名称是什么;但审计网站自身在mailto:链接或链接字段(link_url、link_text、gtm.elementUrl等)中的地址除外,例如 GTM 点击事件中的联系链接,因为这并非访客数据。每个值都会替换为类似[redacted: 64 chars, looks hashed]的标记;未经过哈希处理的值会被报告为个人数据风险。--keep-bodies("keep_bodies": true)会按原样存储请求内容,以便调试。 - 存储的请求内容每个请求最多为 32 KB,每个流程最多为 2 MB。超出限制时,报告会注明未存储请求内容。
- 仅在你拥有或获准测试的网站上运行。
- 如果要为他人托管 HTTP 服务?还应在网络层阻止私有地址范围和云元数据地址范围(使用出口防火墙或隔离网络),作为纵深防御措施。
路线图
- Consent Check:针对 GDPR/KVKK 深入审计 Cookie 横幅和 Consent Mode v2。
- Measurement Plan:根据 URL 起草计划和 dataLayer 规范。
- 托管版本支持定时运行、部署 Webhook、托管 MCP 服务,以及面向代理机构的多站点仪表盘,详见 analitikisler.com。
开发
npm run setup # checks Node, installs the dependencies and Chromium, says whether an AI provider key is set
npm test # parsers, checks, each AI provider and the MCP server, end to end against the demo shop
npm run test:unit # only the tests that need no browser, in about ten seconds
npm run lint # ESLint, the recommended rules only: undefined names, unused imports and the like
此代码库还提供开发容器(.devcontainer/devcontainer.json)。使用 VS Code 和 Dev Containers 扩展,或在 GitHub Codespaces 中打开它,即可自动运行 npm run setup,其中包含 Chromium 的系统库。若要在其中使用 AI 模型,请将密钥添加为 Codespaces secret,或在容器终端中导出密钥。
端到端测试使用虚拟模型客户端,因此无需 API 密钥即可运行。
托管版本
有关托管运行、定时任务和代理机构仪表盘,请访问 analitikisler.com。
许可证
MIT © Analitik İşler
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。