广告创意审查 Agent
本页说明广告创意审查 Agent 如何在只读委托下读取广告平台或创意库中的草稿,对照版本化的品牌与合规规则给出待人确认的审查意见。读完本页,你能理解这个场景需要哪些模块、权限边界如何收窄,以及品牌与合规规则为什么应该放在规则库而不是 Memory。
适用场景
Marketing 团队需要在投放前检查图片、标题、描述、目标页面和 claims 是否符合品牌和合规要求。创意数量随渠道和 A/B 测试成倍增长,人工逐条比对品牌规则和平台政策容易遗漏;而给自动化脚本一个广告平台账号,它同时也拿到了改预算、提交投放的能力。
典型触发时机:
- 新 campaign 的一批创意进入投放前审查,需要在投放窗口前完成。
- 品牌规则或合规禁用词更新后,需要复查在库和待投的存量创意。
- 某条创意被平台拒审,需要排查同批次创意是否存在相同问题。
工程挑战
- 审查量随渠道与 A/B 测试成倍增长,而投放窗口固定:一批创意必须在窗口前审完,一条越界 claim 漏到线上就是平台拒审或合规事故。
- 意见必须可复核且前后一致:同一句文案在不同平台政策和目标页语境下结论不同,每条意见都要标明创意来源和依据的规则版本,否则既无法复查,批次之间的判定也会漂移。
- 借用投放账号权限过宽:能读草稿的账号通常也能改预算、提交投放——审查只需要"读取指定账户的草稿"这一件事,误触任何写操作都是真实资损。
模块组合
| 模块 | 角色 | 说明 |
|---|---|---|
| GenAuth | 核心 | 广告平台与创意库的只读委托、撤销与审计链;投放窗口内的审查任务用分钟级凭证。 |
| Web Agent | 核心 | 受控会话登录广告平台(Profiles 可复用登录态),逐条抽取素材、文案、目标页链接和 claims,每条留截图与来源。 |
| GUMem | 可选 | 仅保存审查者确认的长期偏好(例如意见措辞的口吻)。品牌与合规规则是版本化规则,放在你的规则库(policy store)按版本注入;历史拒审记录归档在你的审查系统。两者都不属于 Memory。 |
权限与委托边界
Agent 本身不持有任何固有权限。每次审查任务的实际权限是三个集合的交集:用户真实权限 ∩ 本次显式委托范围 ∩ 企业批准边界。落到这个场景:
- 委托范围只覆盖"读取指定广告账户的创意草稿、creative library 和投放规则",不包含提交投放、修改预算、编辑创意或下线广告。
- 委托凭证短时效,单次审查任务建议分钟级有效期,过期后需重新委托。
- 用户或管理员可随时撤销授权;撤销后新的草稿读取请求立即失败。
- 越权尝试(例如访问委托范围外的其他广告账户)会被拒绝并留痕——审计链覆盖全部尝试,不只是成功行为。
注意:SDK 示例申请的是产品级 scope(如 webagent.do_anything:read)。广告账户清单、页面范围和动作白名单这类细粒度边界由 GenAuth 的 Agent Profile 或策略层配置强制执行,不由任务 prompt 承担;本页示例未展示该配置。完整语义见 Delegate Token 与缩权。
工作流程
用户选择要审查的广告系列或创意草稿清单,并在 Qoni Console 确认本次交互式授权。
GenAuth 为本次任务签发最小权限的只读委托凭证。
应用从规则库读取当前版本的品牌与合规规则,连同平台政策要点注入任务描述。
Web Agent 登录广告平台或创意库,逐条抽取素材、文案、目标页链接和 claims,每条保留截图与来源。
检查点:广告平台出现登录墙、验证码或风控页时,Web Agent 应升级给人处理,而不是静默绕过。
Agent 对照规则逐条审查创意,标注风险项、疑似违规 claims 和与目标页不一致的表述,每条附创意 ID 和触发的规则编号。
应用侧校验输出契约:缺少创意 ID 或规则编号的意见直接丢弃。
Agent 输出审查意见:风险分级、修改建议和待确认 claims,附规则版本号与 audit id,交由人工确认;确认结果归档到你的审查系统。
检查点:每条风险项都应能回溯到具体创意来源和触发的规则版本;无来源支撑的结论不应进入交付物。
示例代码
下面的示例使用官方 Qoni SDK(@qoniai/qoni)把这个场景接到你的服务端:交互式委托(含完整回调)→ 从规则库读取品牌与合规规则 → 一次 doAnything.run() 完成逐条审查 → 解析并校验审查意见。
import { Qoni, QoniScopes } from '@qoniai/qoni'
const qoni = new Qoni({
accessKey: process.env.QONI_ACCESS_KEY!,
secretKey: process.env.QONI_SECRET_KEY!,
})
// 1. 交互式委托:涉及广告平台登录,让用户在 Qoni Console 确认授权
export async function startCreativeReview(userId: string, taskId: string) {
const { data: authorization } = await qoni.delegateToken({
mode: 'interactive',
agent: 'ad-creative-review',
scopes: [QoniScopes.DO_ANYTHING_READ, QoniScopes.DO_ANYTHING_MANAGE],
redirectUri: 'https://app.example.com/qoni/callback',
state: taskId,
user: { id: userId },
expiresIn: 900, // 单次审查任务给分钟级有效期
})
redirectUserTo(authorization.authorizationUrl)
}
// GET /qoni/callback —— 用户同意后在服务端兑换 grant,继续执行任务
export async function handleQoniCallback(request: Request) {
const query = new URL(request.url).searchParams
const { data: grant } = await qoni.completeDelegateToken({
grantId: query.get('grantId')!,
code: query.get('code')!,
state: query.get('state')!,
})
return runReviewTask(grant, await loadReviewTask(query.get('state')!))
}
async function runReviewTask(
grant: { token: string; auditId: string; grantedScopes: string[] },
task: { campaigns: string[] },
) {
// 2. 任务前:从你的规则库读取当前版本的品牌与合规规则(不是 Memory)
const policy = await loadCreativeReviewPolicy() // 例如 { version: '2026-08', forbiddenClaims: [...], brandVoice: ... }
// 3. 一次调用完成审查:登录平台、逐条抽取、只输出审查意见
const run = await qoni.doAnything.run({
token: grant.token,
prompt: `
Review the creative drafts in these campaigns: ${task.campaigns.join(', ')}.
Extract each creative's image, headline, description, landing page link
and claims, then flag risks against the policy below. Return findings as
a JSON array of { creativeId, risk, quote, ruleId, sourceUrl } objects.
Review only — never submit, change budgets, edit or take ads down.
Creative review policy (version ${policy.version}):
${JSON.stringify(policy)}
`,
capture: { screenshots: true },
})
const result = await run.wait({
// 登录墙 / MFA / 风控页:升级给人处理
onInteraction: (interaction) => notifyUserActionRequired(interaction),
})
// 4. 应用侧校验输出契约:缺创意 ID 或规则编号的意见直接丢弃
const opinions = parseOpinions(result.output).filter(
(o) => o.creativeId && o.ruleId,
)
return {
opinions, // 待人工确认;确认结果归档到你的审查系统
artifacts: result.artifacts,
policyVersion: policy.version,
audit: { auditId: grant.auditId, permissionBoundary: grant.grantedScopes },
}
}输出结构由任务描述约定:这里约定返回 { creativeId, risk, quote, ruleId, sourceUrl } 数组,应用侧 parseOpinions 负责解析与校验,任何缺少 creativeId 或 ruleId 的条目被直接丢弃。SDK 顶层只返回通用的 RunResult(runId、status、output、artifacts 等)。
数据与记忆边界
这个场景涉及四类数据,只有最后一类属于 GUMem:
- 版本化规则:品牌规范、合规禁用词、平台政策要点——放在规则库(policy store)里按版本管理,每条审查意见引用规则版本号。
- 业务状态:审查意见、人工确认结果、历史拒审记录——归档到你的审查系统,供后续批次对照与追溯。
- 审计记录:
grantId与auditId构成的委托与行为链——由 GenAuth 维护。 - 用户 Memory(可选):审查者确认的长期偏好(例如意见措辞的口吻)——这才是 GUMem 的位置;单次审查默认不召回也不写回。
失败处理
| 情况 | 推荐处理 |
|---|---|
| 广告平台登录态失效 | 任务挂起,通知用户重新登录,从断点继续。 |
| 创意库页面结构变化导致抽取失败 | 按失败处理并回放会话记录,不输出无证据的风险项。 |
| 委托范围外的广告账户请求 | 直接拒绝并记录,事后可在审计链中查到未遂访问。 |
| 输出条目缺少创意 ID 或规则编号 | 应用侧校验直接丢弃该条目,并在意见汇总中标注丢弃数量。 |
生产注意点
Agent 不应自动提交投放、修改预算或发布广告。高风险 claims 应交给人工确认。审查意见只作为投放决策的输入,不直接触发创意下线;每条意见都应带规则版本号,规则更新后旧意见不追溯改判。对广告平台的抽取频率应设置上限,避免触发平台风控。
下一步
- 阅读 快速开始 跑通 Agent 身份与委托的最短路径。
- 阅读 授权与浏览器沙盒 了解受控会话的安全边界。
- 继续查看 Landing Page Audit Agent 了解相邻场景。