mcpField
A
ai tag debugger

ai tag debugger

本地服务
github.com/analitikisler数据与分析13 天前更新

关于 ai tag debugger

ai tag debugger 是用于网站分析和广告追踪 QA 测试的开源 AI Agent,可通过真实浏览器流程进行检查。它捕获追踪请求和 dataLayer 活动,依据测量计划与同意设置检查数据,并生成问题说明和修复建议。

主要功能

  1. 01使用 Playwright 执行浏览器流程
  2. 02捕获追踪请求和 dataLayer 推送
  3. 03按测量计划检查事件
  4. 04在独立浏览器中测试同意选项
  5. 05用确定性规则评估捕获数据
  6. 06生成问题说明和修复建议

适用场景

  1. 01发布前检查结账追踪
  2. 02检查不同选择下的同意行为
  3. 03查找缺失或重复的分析事件
  4. 04比较不同广告平台的购买金额

MCP 相关

项目可通过支持 MCP 的 AI 聊天应用使用,由该应用的模型驱动审计。它提供 `start_audit` 和 `run_audit` 工具,并支持选择要检查的平台。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"analitikisler-ai-tag-debugger": {
"command": "npx",
"args": [
"-y",
"@analitikisler/ai-tag-debugger"
]
}
}
}
启动命令npx -y @analitikisler/ai-tag-debugger

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@analitikisler/ai-tag-debugger0.20.0

工具

7

收录的工具列表 · 更新于 2 天前

参数类型必填说明
sitestring是要打开的页面,例如 https://staging.example.com/
journeystring否预设旅程(purchase、add_to_cart、sign_up、lead、search、decline_cookies),包含目标和预期事件;也可以是自定义旅程的简短名称,例如 newsletter。
viewportenum否默认桌面视口。desktop | mobile
providersarray否要检查的跟踪服务提供商。默认包括 ga4、google_ads、meta、tiktok,以及网站发送请求的任何其他已知平台。指定此项时,发往其他平台的请求仍会在本地响应,但只计数,不显示或检查。
allowed_hostsarray否旅程中可能访问的其他主机,例如托管式结账服务 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 设为关闭此功能。

工作原理

  1. 浏览: AI 模型会收到一个自然语言目标(“将任意商品添加到购物车,并使用测试付款完成结账”)和页面的文本视图。它通过 Playwright 一次执行一步,使用两个工具:browser_action(goto、click、fill、select、scroll、wait)和 finish。
  2. 采集: 每个发往跟踪端点的请求都会被解析为规范化的命中数据,并标记触发该请求的步骤。每次 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)的请求仍会发出;时间线中的网络部分会显示每次调用及其是否在本地得到响应。
  3. 检查: 确定性规则会将命中数据与测量计划进行比较。这一环节无需调用 API,因此结果可复现。
  4. 说明: 模型会读取检查结果、每个步骤的命中数据,以及(可选的)GTM 容器导出文件。它会针对每个问题说明可能的原因和修复方法,并指出涉及的标签和触发器。

AI 提供商

使用你自己的 API 密钥。ai-tag-debugger 使用各提供商的官方 SDK:

提供商API 密钥变量默认模型
Anthropic(Claude)ANTHROPIC_API_KEYclaude-opus-5-5
OpenAIOPENAI_API_KEYgpt-5.5
Google GeminiGEMINI_API_KEYgemini-pro-latest
Cloudflare Workers AICLOUDFLARE_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
DeepSeekhttps://api.deepseek.com
Mistralhttps://api.mistral.ai/v1
Groqhttps://api.groq.com/openai/v1
OpenRouter(数百种模型)https://openrouter.ai/api/v1
运行在本机上的 Ollamahttp://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 模型。
viewportsdesktop 和/或 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>rundesktop 或 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-baselinerun运行结束后,将本次运行发现的所有问题写入基线文件;如果文件不存在,则创建该文件。
--headedplan, run显示浏览器窗口。
--provider <name>, --model <id>plan, runAI 提供商和模型。默认值:已设置 API 密钥对应的提供商和模型。
--scriptedrun重放每个旅程的固定步骤,不使用 AI 导航。没有步骤的旅程会重复使用该网站上次已完成运行的步骤。
--no-airun完全不使用 AI 模型。隐含启用 --scripted。
--save-site <dir>run保存网站的响应,供 replay 使用。
--save-steps <file>run将每个旅程执行的步骤写入配置文件。
--data-dir <dir>plan, run, doctor, historyaitd/(计划和运行记录)的存放位置。默认值:./aitd。用于替代 run --out。
--limit <n>history趋势读取的网站最近运行记录数量。默认值:30。
--jsonhistory以 JSON 而非文本形式输出趋势序列、问题时间线和旅程稳定性。
--format xlsx|csvplan export电子表格格式。默认值:xlsx。
--updatereplay将此次重放发现的问题设为预期问题。
--out <dir>replay重放报告的写入位置。对于 run,--out 仍可作为隐藏别名使用一个小版本,并会输出提示;请改用 --data-dir。
--base-url <url>runOpenAI 兼容提供商的 API 地址。
--allow-host <host>run旅程可以访问的另一个主机(可重复指定)。等同于 allowed_hosts。
--keep-bodiesrun按原样存储跟踪请求,不对用户数据进行脱敏。
--no-brandingplan, run从报告和 plan.html 中移除徽标和署名行。
--http, --port, --host, --token, --public-url, --reports, --allow-private-networkmcp请参阅下方的 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

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。