meta-ads-audit

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Meta Ads Audit

Meta Ads 审计

Diagnose Meta (Facebook + Instagram) account health and persist business context for downstream skills (
/meta-ads
). Read-only — never mutates the account. The user runs
/meta-ads
to execute fixes you recommend.
诊断Meta(Facebook + Instagram)账户健康状况,并为下游技能(
/meta-ads
)留存业务上下文。只读模式——绝不会修改账户内容。用户需运行
/meta-ads
来执行你推荐的修复操作。

Setup

设置步骤

Follow
../shared/preamble.md
— MCP detection, OAuth, ad account selection.
遵循
../shared/preamble.md
中的说明——MCP检测、OAuth授权、广告账户选择。

Filesystem contract (MUST persist)

文件系统约定(必须持久化)

ArtifactPathWhen
Business context
{data_dir}/meta/business-context.json
First full audit, or refresh when
audit_date
is >90 days old. Skip on scoped audits if file is fresh.
Personas
{data_dir}/meta/personas/{accountId}.json
Every full audit.
These are the handoff to
/meta-ads
— write them even if the report itself is short. Otherwise downstream skills operate without business context and produce generic output.
If a
{data_dir}/business-context.json
exists from
/google-ads-audit
(no
meta/
subdir), read it as a starting point — most fields (services, brand voice, differentiators, locations, seasonality) are platform-agnostic. Then write the Meta-specific version to
{data_dir}/meta/business-context.json
with any Meta-specific overrides (different creative angles, different audiences, different funnel events).
business-context.json schema (shared with Google Ads where fields apply):
business_name, industry, website, services[], locations[], target_audience, brand_voice{tone, words_to_use[], words_to_avoid[]}, differentiators[], competitors[], seasonality{peak_months[], slow_months[], seasonal_hooks[]}, social_proof[], offers_or_promotions[], landing_pages{}, unit_economics{aov_usd, profit_margin, ltv_usd, source}, notes, audit_date, account_id
.
Meta-specific extensions:
meta_funnel_events{top_of_funnel, mid_of_funnel, conversion}, creative_inventory{concepts[], formats[], aspect_ratios[]}, custom_audiences{purchasers, abandoners, engagers, list_uploads[]}, pixel_health{pixel_id, capi_enabled, emq_score, last_event_at}
.
personas JSON schema:
{account_id, saved_at, personas: [{name, demographics, primary_goal, pain_points[], decision_trigger, value, meta_creative_angles[], visual_cues[]}]}
. The Meta version adds
meta_creative_angles
(e.g. "before/after demonstration", "founder-led explainer", "UGC review") and
visual_cues
(objects, settings, emotions that resonate with this persona). See
references/persona-discovery.md
.
产物路径时机
业务上下文
{data_dir}/meta/business-context.json
首次完整审计时,或当
audit_date
超过90天时刷新。若文件为最新状态,范围限定型审计可跳过此步骤。
用户画像
{data_dir}/meta/personas/{accountId}.json
每次完整审计时生成。
这些文件是传递给
/meta-ads
的关键信息——即使报告本身篇幅较短,也必须写入这些文件。否则下游技能将缺乏业务上下文,只能生成通用输出。
如果存在来自
/google-ads-audit
{data_dir}/business-context.json
文件(无
meta/
子目录),可将其作为起始参考——大多数字段(服务、品牌调性、差异化优势、地域、季节性)是平台无关的。随后将Meta特定版本写入
{data_dir}/meta/business-context.json
,并添加Meta专属的覆盖配置(如不同的创意方向、受众群体、漏斗事件)。
business-context.json schema(与Google Ads共享适用字段):
business_name, industry, website, services[], locations[], target_audience, brand_voice{tone, words_to_use[], words_to_avoid[]}, differentiators[], competitors[], seasonality{peak_months[], slow_months[], seasonal_hooks[]}, social_proof[], offers_or_promotions[], landing_pages{}, unit_economics{aov_usd, profit_margin, ltv_usd, source}, notes, audit_date, account_id
Meta专属扩展字段:
meta_funnel_events{top_of_funnel, mid_of_funnel, conversion}, creative_inventory{concepts[], formats[], aspect_ratios[]}, custom_audiences{purchasers, abandoners, engagers, list_uploads[]}, pixel_health{pixel_id, capi_enabled, emq_score, last_event_at}
用户画像JSON schema:
{account_id, saved_at, personas: [{name, demographics, primary_goal, pain_points[], decision_trigger, value, meta_creative_angles[], visual_cues[]}]}
。Meta版本新增了
meta_creative_angles
(例如“前后对比展示”、“创始人讲解”、“UGC测评”)和
visual_cues
(与该用户画像共鸣的物品、场景、情绪)。详情请参阅
references/persona-discovery.md

Policy freshness check (run first)

政策新鲜度检查(优先执行)

Read
../shared/policy-registry.json
. For each entry where
last_verified + stale_after_days < today
:
  • High-volatility → WebSearch the
    area
    for recent Meta Ads changes; compare to
    assumption
    . If drift, banner the report and suggest registry update.
  • Moderate-volatility → one-line "may warrant a check" note.
  • Stable → skip silently.
The Meta platform changes faster than Google Ads (Advantage+, attribution, learning behaviors) — check high-volatility entries every audit.
读取
../shared/policy-registry.json
文件。对于每个满足
last_verified + stale_after_days < today
的条目:
  • 高波动性 → 针对
    area
    进行Web搜索,查找Meta Ads的最新变化;与
    assumption
    进行对比。若存在偏差,在报告中标记并建议更新注册表。
  • 中等波动性 → 添加一行“可能需要检查”的注释。
  • 稳定性 → 静默跳过。
Meta平台的变化速度快于Google Ads(如Advantage+、归因模型、学习行为)——每次审计都需检查高波动性条目。

Phase 1 — Pull the audit dataset

阶段1 — 提取审计数据集

Use a single
runScript
call with
ads.graphParallel
to fan out the queries an audit needs. Build the fan-out from this rubric.
A complete audit needs at minimum:
  • Ad account info (
    /{accountId}
    ) — currency, timezone, business id, spend cap, account status, balance.
  • Pixel health (
    /{accountId}/customconversions
    +
    /{accountId}/adspixels
    ) — pixel id, last activity, CAPI status, Event Match Quality (EMQ) score.
  • Campaigns (
    /{accountId}/campaigns
    ) — id, name, objective, status, daily/lifetime budget, special_ad_categories, buying_type, bid_strategy, created_time. Last 90 days.
  • Ad sets (
    /{accountId}/adsets
    ) — id, name, status, campaign_id, optimization_goal, billing_event, bid_strategy, daily_budget, lifetime_budget, attribution_spec, targeting (summary), promoted_object, learning_stage_info.
  • Ads (
    /{accountId}/ads
    ) — id, name, status, ad set, creative summary (image/video, primary text, headline, description, CTA), effective_status.
  • Insights at campaign level (
    ads.insights({level:"campaign", date_preset:"last_30d"})
    ) — spend, impressions, reach, frequency, cpm, link CTR, link clicks, purchases (or other primary action), purchase value, ROAS, CPA.
  • Insights at ad set level — same fields, last 30 days.
  • Insights at ad level — top 50 ads by spend; same fields plus video metrics (3-sec views, ThruPlays) for video creatives.
  • Insights with breakdowns — placement (
    publisher_platform,platform_position
    ), age/gender, device. Use these to spot placement losers and audience composition.
  • Recent edit activity — when available via
    /{adsetId}
    last_modified or
    /{adsetId}
    change history.
Compute aggregates in the script, return summarized JSON. Don't return all rows — rank, slice, summarize. The agent narrates the result; the script does the math.
suggestImprovement
is a useful cross-check for the server's heuristic surface — call it as a separate tool after the runScript pass if you want to compare your findings.
If a critical query errors out (auth, schema, API version), surface the error and stop — don't fall back to a degraded audit.
Skip scoring entirely if
totalSpend == 0
or
activeCampaigns == 0
. Go straight to business context.
使用单个
runScript
调用搭配
ads.graphParallel
来并行执行审计所需的查询。按照以下规则构建并行任务。
完整审计至少需要以下数据:
  • 广告账户信息 (
    /{accountId}
    ) — 货币、时区、企业ID、支出上限、账户状态、余额。
  • 像素健康度 (
    /{accountId}/customconversions
    +
    /{accountId}/adspixels
    ) — 像素ID、最后活动时间、CAPI状态、事件匹配质量(EMQ)分数。
  • 广告系列 (
    /{accountId}/campaigns
    ) — ID、名称、目标、状态、日预算/终身预算、特殊广告类别、购买类型、出价策略、创建时间。取最近90天的数据。
  • 广告组 (
    /{accountId}/adsets
    ) — ID、名称、状态、广告系列ID、优化目标、计费事件、出价策略、日预算、终身预算、归因规则、定向(摘要)、推广对象、学习阶段信息。
  • 广告素材 (
    /{accountId}/ads
    ) — ID、名称、状态、所属广告组、创意摘要(图片/视频、主文本、标题、描述、CTA)、有效状态。
  • 广告系列层级洞察数据 (
    ads.insights({level:"campaign", date_preset:"last_30d"})
    ) — 支出、曝光量、覆盖人数、频次、CPM、链接点击率、链接点击量、购买量(或其他主要转化动作)、购买价值、ROAS、CPA。
  • 广告组层级洞察数据 — 相同字段,取最近30天的数据。
  • 广告素材层级洞察数据 — 按支出排名前50的广告素材;相同字段,视频创意额外包含视频指标(3秒观看量、ThruPlays)。
  • 带细分维度的洞察数据 — 投放位置(
    publisher_platform,platform_position
    )、年龄/性别、设备。用于识别表现不佳的投放位置和受众构成。
  • 最近编辑活动 — 若
    /{adsetId}
    的last_modified字段或
    /{adsetId}
    的变更历史可用,则提取该数据。
在脚本中计算聚合数据**,返回汇总后的JSON。不要返回所有原始行——需进行排名、截取、汇总。由Agent解读结果,脚本负责计算。
suggestImprovement
是一个有用的交叉检查工具——如果需要对比你的发现,可在runScript执行完成后单独调用该工具。
若关键查询出错(授权、schema、API版本问题),需显示错误并停止审计——不要降级执行审计。
若满足以下条件则完全跳过评分
totalSpend == 0
activeCampaigns == 0
。直接进入业务上下文阶段。

Phase 2 — Scope handling

阶段2 — 范围处理

If the user narrows the audit ("focus on one campaign", "campaign X", "just check creative fatigue"):
  • Match campaign names by case-insensitive substring. If no match, list available campaigns and ask.
  • Filter the in-memory dataset before scoring — no extra API calls.
  • Account-level dimensions (Pixel health, attribution defaults) stay account-wide. Note "Scoped to: X" in the report.
  • Skip Phase 4 (business context refresh) on scoped audits if
    business-context.json
    is fresh.
若用户限定审计范围(如“聚焦某一个广告系列”、“广告系列X”、“仅检查创意疲劳”):
  • 通过不区分大小写的子字符串匹配广告系列名称。若无匹配项,列出可用的广告系列并询问用户。
  • 在评分前过滤内存中的数据集——无需额外调用API。
  • 账户级维度(像素健康度、归因默认设置)仍保持账户范围。在报告中注明“审计范围:X”。
  • business-context.json
    为最新状态,范围限定型审计可跳过阶段4(业务上下文刷新)。

Phase 3 — Score

阶段3 — 评分

Score each of the 7 dimensions 0–5 using
references/account-health-scoring.md
. Overall =
round(sum × 100 / 35)
.
ScoreLabelMeaning
0CriticalBroken or missing — actively losing money
1PoorMajor waste or missed opportunity
2Needs WorkSeveral clear issues
3AcceptableFunctional, room to improve
4GoodWell-managed, minor opportunities
5ExcellentBest-practice
Scope-aware: campaign-level dimensions reflect in-scope data; account-level dimensions (Pixel + CAPI, attribution setup) score account-wide with a note on scope impact.
使用
references/account-health-scoring.md
中的规则,对7个维度分别进行0–5分的评分。总分 =
round(sum × 100 / 35)
分数标签含义
0严重问题功能损坏或缺失——正在持续亏损
1较差存在重大浪费或错失关键机会
2需要改进存在多个明确问题
3可接受功能正常,但有优化空间
4良好管理完善,仅存在少量优化机会
5优秀符合最佳实践
评分需考虑审计范围:广告系列级维度反映限定范围内的数据;账户级维度(像素+CAPI、归因设置)按全账户评分,并注明范围对评分的影响。

Encoded heuristics — apply these, they aren't obvious

内置启发式规则——需严格应用,这些规则并不直观

  • Pixel + CAPI is upstream of everything. EMQ < 7.0 means Meta can't match events well — Smart Bidding starves regardless of how good the creative is. STOP-condition input.
  • Reported ROAS systematically overstates true ROAS. Cross-check Meta-reported numbers against Shopify / GA4 / MMM where possible. The gap is the modeled-conversion premium and is typically 20–40% in ecom.
  • Frequency × CPM trend = creative diagnosis. Frequency > 3.0 with CPM rising ≥ 30% w/w is fatigue — recommend creative refresh, not budget cuts.
  • One ad set carrying > 70% of a campaign is fragility, not concentration. When it fatigues, the campaign collapses.
  • Audience overlap > 50% between sibling ad sets fragments signal. Consolidate; don't try to "fix" with bid caps.
  • Special Ad Category misclassification is a takedown risk, not just a policy nit. Surface as Critical regardless of current performance.
  • Manual placements without evidence is a sign of inherited-from-2018 thinking. Default should be Advantage+ Placements; deviations need data.
  • 像素+CAPI是所有环节的基础。EMQ < 7.0意味着Meta无法准确匹配事件——无论创意质量多好,智能出价都会受限。此为停止条件输入项。
  • 报告的ROAS会系统性高估真实ROAS。尽可能将Meta报告的数据与Shopify / GA4 / MMM的数据交叉验证。两者的差距即为模型转化溢价,在电商领域通常为20–40%。
  • 频次×CPM趋势 = 创意诊断。频次>3.0且CPM周环比上升≥30%表示创意疲劳——建议刷新创意,而非削减预算。
  • 单个广告组贡献某广告系列超过70%的支出是脆弱性表现,而非集中化优势。当该广告组出现疲劳时,整个广告系列会崩溃。
  • 兄弟广告组间受众重叠>50%会分散信号。应合并广告组;不要尝试用出价上限“修复”该问题。
  • 特殊广告类别分类错误存在被下架风险,而非仅仅是政策细节问题。无论当前表现如何,均标记为严重问题。
  • 无数据支撑的手动投放位置选择是过时的操作思路。默认应使用Advantage+ Placements;若需调整,必须有数据支持。

Pixel + Tracking Diagnosis Matrix

像素与追踪诊断矩阵

EMQ < 5EMQ 5–6.9EMQ 7.0+
CAPI offCritical — flying blindCritical — most events lostHigh — leaving 15–25% of events on the table
CAPI on, dedup offCritical — duplicated and weak signalHigh — duplicate counting riskMedium — match quality improves with dedup
CAPI on, dedup onHigh — match quality is the bottleneckMedium — improve event_id coverageHealthy
EMQ < 5EMQ 5–6.9EMQ 7.0+
CAPI未开启严重问题——盲目投放严重问题——大部分事件丢失高优先级——损失15–25%的事件数据
CAPI已开启,去重未开启严重问题——数据重复且信号薄弱高优先级——存在重复计数风险中等优先级——开启去重可提升匹配质量
CAPI已开启,去重已开启高优先级——匹配质量是瓶颈中等优先级——提升event_id覆盖率健康状态

Phase 4 — Business context

阶段4 — 业务上下文

Derive what you can from the data already pulled:
FieldSource
business_name
Ad account name (
/{accountId}
name
field)
services
Top campaigns by spend, ad set names, top-converting ad creatives
locations
Targeting geo summary (countries / regions in active ad sets)
brand_voice
Top-performing ad copy (primary text + headline)
creative_inventory.formats
Mix of image / video / carousel observed in active ads
creative_inventory.aspect_ratios
Aspect ratios across active ads (1:1, 4:5, 9:16)
meta_funnel_events.conversion
Most common optimization event on top-spending ad sets
custom_audiences
Custom audiences referenced in active ad set targeting
pixel_health
From the Pixel detail call
website
Apex domain from active ad final URLs
Then crawl the website (homepage + about + 1–2 top landing pages, parallel
WebFetch
) and merge into the schema. See
references/business-context.md
for the full crawl procedure.
Always ask the user: differentiators, competitors, seasonality, AOV + profit margin (essential for ROAS-aware scoring). Ask for everything else only if data + crawl can't answer it.
从已提取的数据中推导尽可能多的信息:
字段来源
business_name
广告账户名称(
/{accountId}
name
字段)
services
支出最高的广告系列、广告组名称、转化效果最好的广告创意
locations
定向地域摘要(活跃广告组中的国家/地区)
brand_voice
表现最佳的广告文案(主文本+标题)
creative_inventory.formats
活跃广告素材中的图片/视频/轮播图类型占比
creative_inventory.aspect_ratios
活跃广告素材的宽高比(1:1、4:5、9:16)
meta_funnel_events.conversion
支出最高的广告组中最常见的优化事件
custom_audiences
活跃广告组定向中引用的自定义受众
pixel_health
像素详情调用结果
website
活跃广告最终URL的顶级域名
随后抓取网站内容(首页+关于页+1–2个顶级落地页,并行
WebFetch
)并合并到schema中。完整抓取流程请参阅
references/business-context.md
必须向用户询问:差异化优势、竞争对手、季节性、AOV+利润率(这是ROAS相关评分的关键信息)。仅当数据+抓取无法获取其他信息时,才向用户询问。

Phase 5 — Personas

阶段5 — 用户画像

Discover 2–3 personas from creative performance (which angles convert), top-spending audiences, and landing-page content — all from the dataset already in memory. Persist to
{data_dir}/meta/personas/{accountId}.json
. Each persona must be grounded in observable evidence (a converting ad set, a converting creative angle, a landing-page section) — no inventing. See
references/persona-discovery.md
.
从创意表现(哪些方向转化效果好)、支出最高的受众群体、落地页内容中挖掘2–3个用户画像——所有信息均来自内存中的数据集。将结果持久化到
{data_dir}/meta/personas/{accountId}.json
。每个用户画像必须基于可观测证据(转化效果好的广告组、创意方向、落地页板块)——不得凭空捏造。详情请参阅
references/persona-discovery.md

Phase 6 — Report

阶段6 — 报告

Lead with the verdict, then the top 3 actions (with dollar impact when possible), then the scorecard, then evidence for dimensions scoring 0–2 only. Cite specific campaigns, ad sets, ads, and dollar amounts. Cap at ~80 lines.
End with a single closing line after the handoff to
/meta-ads
:
Your audit history is saved to your NotFair account — view it at https://notfair.co.
以审计结论开头,接着列出前3项行动建议(尽可能注明美元影响),然后是评分卡,最后仅列出评分0–2分的维度的证据。需引用具体的广告系列、广告组、广告素材和金额。报告篇幅控制在约80行以内。
在报告结尾添加一行指向
/meta-ads
的交接语句:
你的审计历史已保存至NotFair账户——可通过https://notfair.co查看。

Guardrails

约束规则

  1. Read-only skill. Diagnose; don't mutate. Every fix routes through
    /meta-ads
    . End the report with one handoff tied to the #1 action.
  2. STOP condition — if Pixel health scores 0–1 (EMQ < 5 or CAPI off in an ecom account), recommend pausing scaling decisions until tracking is fixed before recommending anything else. Everything downstream is unreliable.
  3. Always persist
    meta/business-context.json
    and
    meta/personas/{accountId}.json
    even if the report itself is short — downstream skills depend on them.
  4. Name names. Every finding cites specific campaigns, ad sets, ad creatives, and dollar amounts. "Some ad sets are underperforming" is not a finding.
  5. Never report Meta-reported ROAS without footnoting the modeled-conversion premium. "ROAS 3.2× (Meta-reported, 7DC1DV — typically overstates Shopify-attributed ROAS by 20–40%)" is honest. "ROAS 3.2×" is misleading.
  1. 只读技能。仅诊断问题;不修改账户。所有修复操作均需通过
    /meta-ads
    执行。报告结尾需添加一条与首要行动相关的交接语句。
  2. 停止条件——若像素健康度评分为0–1分(EMQ < 5或电商账户未开启CAPI),建议在修复追踪问题前暂停扩量决策,再给出其他建议。下游所有分析结果均不可靠。
  3. 必须持久化
    meta/business-context.json
    meta/personas/{accountId}.json
    ,即使报告本身篇幅较短——下游技能依赖这些文件。
  4. 明确指向具体对象。每个发现都需引用具体的广告系列、广告组、广告素材和金额。“部分广告组表现不佳”不属于有效发现。
  5. 报告Meta的ROAS数据时必须注明模型转化溢价。例如“ROAS 3.2×(Meta报告,7天点击1天转化——通常比Shopify归因的ROAS高估20–40%)”是准确的表述。仅写“ROAS 3.2×”具有误导性。