腾讯广告 - 常规(标准)广告组创建:按步执行
前置依赖:需安装
tencentads-cli(Node.js ≥ 20)。执行npm install -g tencentads-cli@latest安装或升级;版本过低时tencentads会给出提示。
本技能是常规展示广告的执行指南——按 7 个步骤顺序完成一条常规广告组的创建。严格按步骤顺序执行,后面的步骤依赖前面的输出,不可跳步。
所有 API 调用均通过本技能的专用脚本执行,脚本负责:API 分支路由、返回数据裁剪、格式转换(rules_json 解析、geo 编码查找等)。Agent 专注于:从脚本返回结果中做出业务决策(选哪个组合、选哪个转化目标、选什么出价方式)。
脚本调用格式统一:
node scripts/<脚本名>.mjs '<JSON 参数>'执行脚本时先进入本 skill 根目录,再按相对scripts/路径调用。
⚠️ 跨平台 JSON 参数传递规则(经实测验证)
脚本调用格式为 node scripts/<脚本名>.mjs '<JSON参数>',但 JSON 参数的引号包裹方式因操作系统/终端而异,传递不当会导致 JSON.parse 报错(如 Expected property name or '}' in JSON at position 1)。
| 终端环境 | 正确写法 | 说明 |
|---|---|---|
| Linux / macOS (Bash/Zsh) | node scripts/xxx.mjs '{"key":"value"}' |
✅ 单引号包裹,内部双引号原样保留 |
| Windows Git Bash | node scripts/xxx.mjs '{"key":"value"}' |
✅ 同 Bash |
| Windows CMD | node scripts/xxx.mjs "{\"key\":\"value\"}" |
✅ 双引号包裹 + 反斜杠转义 |
| Windows CMD (备选) | node scripts/xxx.mjs "{""key"":""value""}" |
✅ 双引号包裹 + 双双引号转义 |
| Windows PowerShell 5.x | node --% scripts/xxx.mjs "{\"key\":\"value\"}" |
✅ 必须加 --% 停止解析符 |
| Windows PowerShell 5.x (备选) | node scripts/xxx.mjs "{\`"key\`":\`"value\`"}" |
✅ 反斜杠 + 反引号组合转义 |
⛔ PowerShell 5.x 是重灾区:单引号
'...'、反引号`"、反斜杠\"三种常见写法**全部失败**(双引号会被吞掉)。必须使用--%停止解析符或\`"组合转义。 ⛔ Windows CMD 不支持单引号包裹字符串,单引号会被当作普通字符传入脚本,导致 JSON 解析失败。
常规广告与智投的关键区别(执行参考)
以下差异直接影响步骤 6 请求体的构建,执行时需注意。
| 维度 | 常规投放 | 智投(AIM+) |
|---|---|---|
| 标识 | 不传 smart_delivery_platform |
必传特定的 smart_delivery_platform |
| 出价方式 | 支持 CPC / CPM / oCPM / oCPC | 仅 oCPM |
| 转化配置 | conversion_id + bid_mode + bid_amount |
conversion_id(顶层)+ bid_amount(顶层) |
| 版位 | 手动选择或自动版位 | 统一自动版位 |
| 定向 | 完整能力(地域/年龄/性别/兴趣/行为/人群包等) | 受限 |
⛔ 执行顺序(不可跳步):
步骤1 → 步骤1A(可选) → 步骤2 → 步骤3 → 步骤4 → 步骤5 → 步骤6
获取 资产反推 确定 确定 获取 配置 组装请求体
四元组 四元组 推广产品 版位 转化目标 定向+时间 → create-adgroup.mjs
(有资产线索时) +载体 +出价
执行协议(高优先级,覆盖后文)
若本节与下文"继续执行""不要重复查询"等表述冲突,以本节为准。
⛔ 出价方式与步骤跳过规则
步骤 1、2、5、6 无论什么出价方式都必须执行。以下规则只影响步骤 3~4:
- CPC/CPM(轻量路径):
- 步骤 3:自动版位 → 直接设
automatic_site_enabled: true,跳过get-site-set.mjs;手动版位 → 仍需查询 - 步骤 4:跳过 4B 转化查询,只需
bid_mode+bid_amount
- 步骤 3:自动版位 → 直接设
- oCPM/oCPC(完整路径):
- 步骤 3~4 全部执行(步骤 4 的
get-conversions.mjs依赖步骤 3 返回的site_set)
- 步骤 3~4 全部执行(步骤 4 的
- ⛔ 步骤 1 → 2 是绝对必须执行的前两步,不可跳过。 即使用户 input 中看起来已包含四元组、商品信息,仍必须调用
get-rules.mjs确认四元组、调用get-assets.mjs获取推广资产 ID。原因:不同账号的可选组合不同,自然语言描述无法直接转为精确的枚举值和 ID。例外:步骤 1A 成功确定资产后,步骤 2 可跳过get-assets.mjs调用(但仍需从 1A 的数据构造字段)。步骤 3-5 中的查询子动作在满足"显式证据白名单"或"出价方式跳过规则"时可跳过,但步骤 1 不可。 - 进入下一步前,必须先拿到上一步输出并确认来源。 合法来源只有三类:用户在原始需求中明确给出、当前 session 前一步脚本返回、当前 session 前一步 API 返回。
- 自然语言意图不能替代结构化字段。 "电商推广""品牌曝光"等描述只能用于步骤 1 筛选四元组,不能直接当作四元组、营销载体 ID、
conversion_id的依据。 - 进入步骤 6 前必须能回答每个关键字段来自哪里。 说不清来源的字段,不要猜。
- ⚠️ 错误处理与重试限制:每个脚本调用最多重试 1 次(换参数或换调用方式)。如果 2 次仍失败(如返回 "Mock not found"、空结果、报错),立即跳过该步骤,用已有数据继续推进到下一步直至步骤 6。严禁反复重试同一脚本、读取脚本源码、或切换到非脚本方式(如
tencentads-cli api)尝试绕过。宁可在最终请求中缺少某个字段,也不要耗尽所有轮次。 - 显式证据白名单(仅适用于步骤 3-5 的查询子动作,步骤 1 不适用):
- 四元组查询:用户明确给出
marketing_goal、marketing_sub_goal、marketing_target_type、marketing_carrier_type这 4 个枚举值全部;或当前 session 已从get-rules.mjs返回中得到。 - 推广产品 / 营销载体查询:用户明确给出构造请求体所需的完整 ID;或当前 session 已从
get-assets.mjs返回中得到;或步骤 1A 的get-assets-by-rules.mjs已成功匹配到资产。 - 转化目标查询:用户明确给出
conversion_id;或当前 session 已从get-conversions.mjs返回中得到。 - 定向查询:用户没有任何定向约束时可跳过;只要用户给了地域、年龄、性别、排除已转化、设备等要求,就必须先调用
get-targeting-lookup.mjs。
- 四元组查询:用户明确给出
步骤 1(⛔ 最先执行):获取四元组
前置:
account_id+ 用户营销需求 输出:marketing_goal、marketing_sub_goal、marketing_target_type、marketing_carrier_type
四元组是腾讯广告的产品术语,指营销内容 + 转化/优化目标的完整匹配集合,共10个字段:
- 营销内容(4个):
marketing_goal、marketing_sub_goal、marketing_carrier_type、marketing_target_type - 转化/优化目标(6个):
optimization_goal、deep_behavior_optimization_goal、deep_behavior_advanced_goal、deep_worth_optimization_goal、deep_worth_advanced_goal、forward_link_assist
这10个字段作为一个整体定义广告的投放语义,必须从脚本返回的可选范围中选取,禁止通过推理猜测。
为什么不能猜?
- 不同账号准入的组合不同,猜错会导致
adgroups/add报错 - 看似相同的场景(如"电商推广"),在不同账号上对应的
marketing_goal可能完全不同 - 四元组错误会级联导致后续推广产品、转化目标等全部错误
调用方式:
node scripts/get-rules.mjs '{"account_id":"<ACCOUNT_ID>"}'
示例:
node scripts/get-rules.mjs '{"account_id":"123456789"}'
脚本已处理:内部调用 get_rules_by_advertiser(不传 delivery_scene,获取常规广告可用组合),解析 rules_json 嵌套 JSON 字符串,按 marketing_goal 分组输出紧凑格式。
返回格式说明:
| 返回字段 | 含义 |
|---|---|
goals |
所有可用的 marketing_goal 列表 |
total |
组合总数 |
default_sub_goal |
大多数条目的 marketing_sub_goal 值(条目中无 s 时取此值) |
by_goal |
按 goal 分组,每条含 t=marketing_target_type、c=marketing_carrier_type、pt=product_type;s=marketing_sub_goal(仅当与 default_sub_goal 不同时出现) |
所有枚举值均为完整 key(如
MARKETING_TARGET_TYPE_APP_ANDROID),可直接使用。
返回示例:
{
"goals": ["MARKETING_GOAL_PRODUCT_SALES", "MARKETING_GOAL_USER_GROWTH"],
"total": 5,
"default_sub_goal": "MARKETING_SUB_GOAL_UNKNOWN",
"by_goal": {
"MARKETING_GOAL_PRODUCT_SALES": [
{"t": "MARKETING_TARGET_TYPE_CONSUMER_PRODUCT", "c": "MARKETING_CARRIER_TYPE_JUMP_PAGE", "pt": 30}
],
"MARKETING_GOAL_USER_GROWTH": [
{"s": "MARKETING_SUB_GOAL_APP_ACQUISITION", "t": "MARKETING_TARGET_TYPE_APP_ANDROID", "c": "MARKETING_CARRIER_TYPE_APP_ANDROID", "pt": 43}
]
}
}
Agent 需要做的决策:当返回多个组合时,根据用户意图选择正确的一组。
选择规则(按优先级逐层过滤):
先从用户意图提取关键约束:
- 用户提到了"卖货"/"电商"/"商品销售" →
marketing_goal应含PRODUCT_SALES - 用户提到了"APP下载"/"拉新"/"注册" →
marketing_goal应含USER_GROWTH - 用户提到了"品牌"/"曝光" →
marketing_goal应含BRAND_PROMOTION - 用户提到了"线索"/"表单"/"留资" →
marketing_goal应含LEAD_RETENTION - 用户提到了"涨粉"/"加关注" →
marketing_goal应含INCREASE_FANS_INTERACTION - 用户提到了"小程序" →
marketing_target_type应含MINI_PROGRAM_WECHAT - 用户提到了"APP"/"应用"作为推广产品(非营销载体) →
marketing_target_type应含APP_ANDROID或APP_IOS。 - 用户提到了"小游戏" →
marketing_target_type应含WECHAT_MINI_GAME - 用户提到了"视频号直播"作为推广对象(非营销载体) →
marketing_target_type应含WECHAT_CHANNELS_LIVE - 用户提到了"视频号直播"作为营销载体 →
marketing_carrier_type应含WECHAT_CHANNELS_LIVE(⛔ 不要据此设置marketing_target_type) - 用户提到了"跳转页面" →
marketing_carrier_type应含JUMP_PAGE - 用户提到了"新游推广"/"新游上线"/"新游首发"/"游戏上线" →
marketing_sub_goal应含NEW_GAME_LAUNCH - 用户提到了"新游测试"/"测试服"/"删档测试"/"试玩"/"新客试玩" →
marketing_sub_goal应含NEW_GAME_TEST - 用户提到了"新游预约"/"预约" →
marketing_sub_goal应含NEW_GAME_RESERVE - 用户提到了"平稳期"/"长线运营"/"平稳期推广" →
marketing_sub_goal应含PLATEAU_PHASE_LAUNCH - 用户提到了"小游戏新客"/"小游戏拉新"/"新客增长" →
marketing_sub_goal应含MINI_GAME_NEW_CUSTOMER_GROWTH - 用户提到了"小游戏回流"/"小游戏促活"/"回流促活" →
marketing_sub_goal应含MINI_GAME_RETURN_CUSTOMER_ENGAGEMENT
- 用户提到了"卖货"/"电商"/"商品销售" →
按
marketing_goal匹配用户的营销目标按
marketing_target_type匹配用户的推广对象类型⛔⛔⛔ 前置强制检查(最高优先级):用户是否同时给了「推广产品 ID 或名称」?
- 是 → 禁止在步骤 1 确定
marketing_target_type,必须直接跳到步骤 1A,把该marketing_goal下的全部 combinations 传入,由脚本自动匹配。即使用户同时说了"营销载体: iOS应用",也绝对不能据此把 combinations 缩窄为只含APP_IOS的那一个。 - 否 → 继续按下面的规则选择。
⚠️
marketing_target_type反映的是"产品/店铺/内容"的类型,不要与优化目标、出价方式混淆。无法直接确定时,按marketing_goal过滤后从剩余项中选择。⛔ "营销载体"只能确定
marketing_carrier_type,禁止用来推断或缩窄marketing_target_type。⚠️ 商品库类
marketing_target_type选择规则(仅当PRODUCT_SALES且 combinations 同时含CONSUMER_PRODUCT、WECHAT_STORE_PRODUCT、WECHAT_STORE中多个时):- 用户明确说了"商品库" → 选
CONSUMER_PRODUCT - 用户明确说了"微信小店"/"视频号小店" → 选
WECHAT_STORE_PRODUCT(推广单个商品)或WECHAT_STORE(推广整个店铺),根据用户意图区分 - 用户给了推广产品名称或 ID → ⛔ 禁止暂定,必须直接进入步骤 1A 通过资产反推确定。传给 1A 的 combinations 按 1A-① 规则过滤(只按
marketing_goal过滤,其余维度全量)。 - 用户未明确且未给任何资产线索 → 暂定
CONSUMER_PRODUCT,步骤 2 会根据资产查询结果自动回退(见步骤 2B「商品库类空资产回退」)
- 是 → 禁止在步骤 1 确定
⛔ 穷尽以上规则后仍无法唯一确定
marketing_target_type时(强制检查点):先回答:用户是否给了推广产品的名称或 ID?
- 是 → 立即进入步骤 1A,通过资产反推确定四元组。禁止猜测
marketing_target_type。传给 1A 的 combinations 按 1A-① 规则过滤(只按marketing_goal过滤,其余维度全量)。 - 否 → 向用户列出剩余 combinations 中的
marketing_target_type选项确认,附中文含义帮助选择。
- 是 → 立即进入步骤 1A,通过资产反推确定四元组。禁止猜测
若过滤后
marketing_carrier_type仍有多个可选值(即同一marketing_goal+marketing_target_type对应多种 carrier_type),必须向用户确认营销载体类型,不能自行猜测。此时应将 combinations 中实际剩余的所有marketing_carrier_type选项列出给用户,让用户选择。例如:"根据您的推广目标,当前支持以下营销载体:1) XXX 2) YYY 3) ZZZ,请问您要使用哪种?"(其中 XXX/YYY/ZZZ 替换为 combinations 中实际返回的 carrier_type 值)marketing_sub_goal只能复用get-rules.mjs返回值,禁止语义改写:例如用户说"注册"、"新客"、"拉新"时,也不要自造MARKETING_SUB_GOAL_USER_REGISTER;如果步骤 1 返回的是MARKETING_SUB_GOAL_MINI_GAME_NEW_CUSTOMER_GROWTH或MARKETING_SUB_GOAL_APP_ACQUISITION,后续所有脚本都必须原样复用
步骤 1 完成后你应该有:四元组 4 个值 + product_type(从 combinations 数组的匹配项取)。product_type 需透传给步骤 3 和步骤 4 的脚本。
步骤 1A(可选,有资产线索时执行):通过资产反推四元组
⛔ 前置门禁:步骤 1 过滤后只剩 1 个 combination → 四元组已确定,直接跳到步骤 2,禁止进入 1A。 即使用户给了推广产品 ID/名称也不需要 1A——资产查询在步骤 2 完成。
触发条件(仅当通过前置门禁后):用户提到了推广产品/资产的 ID 或名称,且步骤 1 过滤后仍有 2 个及以上 combinations 无法唯一确定四元组。
不触发的情况:① 步骤 1 已经唯一确定了四元组(只剩 1 个 combination)② 用户没有给出任何资产 ID 或名称线索
目的:通过查询账号下所有可能组合的真实资产列表,用用户给的资产 ID 或名称进行匹配,精确锁定四元组,避免向用户确认。
1A-① 预过滤(由脚本自动完成)
⛔ 规则不变:只按 marketing_goal 过滤,marketing_target_type 和 marketing_carrier_type 维度不做任何缩窄。
脚本内部自动调用 get_rules_by_advertiser API 获取全量 combinations,并按传入的 marketing_goal 过滤。Agent 不需要透传 combinations 数组。 脚本还支持传入 marketing_target_type 进行优先查询(非缩窄):优先查该类型的资产并尝试匹配,命中则跳过其余类型的 API 调用以加速返回,未命中则自动 fallback 全量查询。脚本还会在资产匹配成功且载体类型需要时自动查询载体列表,结果通过 carrier_result 返回(详见 1A-③+)。
1A-② 调用 get-assets-by-rules.mjs
node scripts/get-assets-by-rules.mjs '{"account_id":"<ACCOUNT_ID>","marketing_goal":"<用户确定的MARKETING_GOAL或不传>","marketing_target_type":"<用户明确的TARGET_TYPE或不传>","match_hint":{"asset_id":"<用户给的ID或null>","asset_name":"<用户给的名称或null>"},"carrier_hint":{"carrier_id":"<用户给的载体ID或null>","carrier_name":"<用户给的载体名称或null>"}}'
参数说明:
account_id:必填marketing_goal:可选。传入后脚本只查该 goal 下的 combinations(等价于原来 Agent 手动按 goal 过滤)。用户明确了 goal 就传,未明确就不传(脚本查全量)marketing_target_type:可选。用户明确了推广产品类型时传入(如用户说"小程序"就传MARKETING_TARGET_TYPE_MINI_PROGRAM_WECHAT)。脚本会优先查该类型下的资产,匹配成功则跳过其余类型查询以加速返回;未传或优先查未命中时自动 fallback 全量查询。注意:这里传marketing_target_type仅影响查询顺序(优先查 → fallback 全量),不等同于步骤 1 中"缩窄 combinations"——即使传了,脚本仍保证不漏查其他类型match_hint:用户给了资产 ID 就传asset_id,给了名称就传asset_name,两个都给了就都传(ID 优先匹配)carrier_hint:可选,用户给了载体 ID 传carrier_id,给了载体名称传carrier_name
返回示例(unique_match):
{
"asset_dict": {
"MARKETING_GOAL_PRODUCT_SALES|MARKETING_SUB_GOAL_UNKNOWN|MARKETING_TARGET_TYPE_PRODUCT_AGGREGATION_PAGE|MARKETING_CARRIER_TYPE_JUMP_PAGE": {
"combination": {
"marketing_goal": "MARKETING_GOAL_PRODUCT_SALES",
"marketing_sub_goal": "MARKETING_SUB_GOAL_UNKNOWN",
"marketing_target_type": "MARKETING_TARGET_TYPE_PRODUCT_AGGREGATION_PAGE",
"marketing_carrier_type": "MARKETING_CARRIER_TYPE_JUMP_PAGE",
"product_type": 30
},
"asset_type": "INDUSTRY",
"assets": [
{ "marketing_asset_id": "578879856", "name": "某资产名" }
]
},
"其他组合...": { "combination": {...}, "asset_type": "...", "assets": "[3 items, omitted]" }
},
"match_result": {
"status": "unique_match",
"match_type": "id_exact",
"matched_items": [
{
"combination_key": "MARKETING_GOAL_PRODUCT_SALES|...|MARKETING_CARRIER_TYPE_JUMP_PAGE",
"combination": { "marketing_goal": "...", "marketing_sub_goal": "...", "marketing_target_type": "...", "marketing_carrier_type": "...", "product_type": 30 },
"asset_type": "INDUSTRY",
"asset": { "marketing_asset_id": "578879856", "name": "某资产名" }
}
]
},
"carrier_result": {
"status": "found",
"carriers": [
{ "carrier_id": "417200582", "carrier_name": "唯品会" }
],
"matched_carrier": { "carrier_id": "417200582", "carrier_name": "唯品会" }
}
}
注意:
unique_match时脚本会自动裁剪非命中 combination 的assets(显示为"[N items, omitted]"),减少上下文开销。
1A-③ 匹配结果处理
脚本返回的 match_result 已按优先级完成匹配,直接根据 status 处理:
match_result.status |
含义 | 处理方式 |
|---|---|---|
unique_match |
恰好 1 个 combination 下命中 1 条资产 | ✅ 直接使用 matched_items[0].combination 作为四元组,matched_items[0].asset 作为资产信息。验证一致性:如果用户同时给了营销目标线索(如"线索收集"),检查命中的 marketing_goal 是否一致。一致 → 直接使用;不一致 → 向用户提示矛盾并给出选项 |
multiple_match |
同一资产存在于多个 combination 下 | 列出 matched_items 中各 combination 的中文说明供用户选择 |
name_multiple_match |
名称匹配到多个不同资产 | 列出 matched_items 中各资产的 ID、名称、所属 combination 供用户确认 |
no_match |
所有 combination 下都没找到匹配 | 去掉预过滤,用全部 combinations 重新查一次(不传 match_hint 之外的过滤条件)。仍然 no_match → 列出 asset_dict 中有资产的 combination 供用户参考,并给出可能原因(ID 输错、资产不在该账户下等) |
1A-③+ 载体查询结果处理(carrier_result)
当资产匹配成功(unique_match / multiple_match)且载体类型不是 JUMP_PAGE 时,脚本自动查询载体列表并返回 carrier_result。
carrier_result.status |
含义 | 处理方式 |
|---|---|---|
found + matched_carrier 不为 null |
载体查询成功且匹配到载体 | ✅ 已反映在 flat_params.carrier_id 中,直接透传 |
found + matched_carrier 为 null |
载体查询成功但未匹配到(多个载体且无 hint) | 列出 carriers 供用户选择 |
not_needed |
ONEID/视频号类资产已包含 carrier_id,或载体类型为 JUMP_PAGE | 已反映在 flat_params.carrier_id 中(ONEID 类),或不需要 carrier_id(JUMP_PAGE) |
no_carriers |
查询成功但该账号下无载体 | 向用户确认载体信息 |
skipped |
资产匹配未成功,未触发载体查询 | 正常流程,后续步骤 2 处理 |
match_failed |
载体查询接口调用失败 | 从用户输入获取载体 ID,或向用户确认 |
载体查询的接口路由(脚本内部自动判断,Agent 无需关心):
- 统一通过
bff_promoted_objects/get接口查询,脚本根据marketing_carrier_type自动映射到对应的promoted_object_type
1A-④ 步骤 1A 完成后的影响
| 1A 结果 | 对后续步骤的影响 |
|---|---|
成功确定四元组 + 资产 + 载体(unique_match + carrier_result.matched_carrier) |
✅ 四元组已确定,脚本已输出 flat_params → 步骤 2 可跳过,直接将 flat_params 中的字段透传给步骤 6 的 create-adgroup.mjs |
成功确定四元组 + 资产(unique_match,但载体未匹配) |
✅ 四元组已确定,flat_params 已输出(可能缺少 carrier_id)→ 步骤 2 可跳过 get-assets.mjs 调用,载体 ID 待后续步骤获取 |
未能确定(multiple_match / name_multiple_match / no_match) |
已向用户确认 → 得到答案后确定四元组,进入步骤 2 正常执行 |
步骤 2(⛔ 默认必须执行):获取推广产品 + 营销载体
前置:步骤 1 的
marketing_target_type、marketing_carrier_type、marketing_goal输出:asset_id、carrier_id等扁平 ID(步骤 6 传给create-adgroup.mjs,由脚本自动组装为 API 所需的嵌套结构)
⚡ 快速路径:如果步骤 1A 的
match_result.status为unique_match,可跳过get-assets.mjs调用,直接使用脚本返回的flat_params中的扁平 ID。
⚡ ONEID 类自动短路:当用户给了明确的资产 ID 时,通过
asset_hint.asset_id传给get-assets.mjs,脚本内部会自动短路(不调 API,直接返回shortcut: true),返回的flat_params可直接透传。用户给的是名称时传asset_hint.asset_name,脚本不会短路,走正常查询。
调用方式(步骤 1A 未执行或未成功时):
node scripts/get-assets.mjs '{"account_id":"<ACCOUNT_ID>","marketing_target_type":"<...>","marketing_carrier_type":"<...>","marketing_goal":"<...>","product_type":<number>,"carrier_hint":{"carrier_id":"...","carrier_name":"..."},"asset_hint":{"asset_id":"...","asset_name":"..."}}'
参数说明:
account_id、marketing_target_type:必填marketing_carrier_type、marketing_goal:可选product_type:可选,来自步骤 1 的combination.product_type,载体查询时使用carrier_hint:可选,用于载体匹配。用户给了载体 ID 就传carrier_id,给了载体名称就传carrier_nameasset_hint:可选,用户给了明确的资产 ID 就传asset_id,给了资产名称就传asset_name。ONEID 类传asset_id时脚本自动短路
⚡ 载体查询已内置:当传入
marketing_carrier_type+product_type(或carrier_hint)时,脚本会自动查询并匹配载体,返回carrier_result字段。无需额外调用get-assets-by-rules.mjs来获取载体 ID。
脚本已处理:自动根据 marketing_target_type 判断分类(ONEID / 商品库 / 行业产品库),路由到正确的 API,返回统一格式的资产列表。同时自动查询载体(如需要)。
返回示例(ONEID 类):
{
"asset_type": "ONEID",
"assets": [
{
"marketing_asset_outer_id": "wx1234567890",
"marketing_carrier_id": "wx1234567890",
"name": "我的小程序",
"type": "MINI_PROGRAM_WECHAT"
}
],
"carrier_result": {
"status": "not_needed",
"reason": "ONEID/视频号类资产已包含 marketing_carrier_id"
}
}
Agent 需要做的决策——资产选择规则(⛔ 禁止默认选第一个):
- 用户提及了产品/商品名称 → 从
assets中选asset_name(或name)与用户意图最相关的项 - 仅 1 个资产 → 直接使用
- 多个且无法区分 → 展示给用户确认
2A. 透传 flat_params 给步骤 6(⛔ 不要手动构造嵌套结构)
核心原则:Agent 只负责将脚本返回的扁平 ID 透传给步骤 6 的
create-adgroup.mjs。嵌套结构(marketing_asset_outer_spec、marketing_asset_id、marketing_carrier_detail)全部由create-adgroup.mjs根据marketing_target_type/marketing_carrier_type自动组装,Agent 不要手动构造。
get-assets-by-rules.mjs 的 flat_params:
脚本会为每条 matched_items 都计算并挂载 flat_params(与 create-adgroup.mjs 入参直接对齐):
unique_match→ 顶层也输出flat_params(=matched_items[0].flat_params),Agent 直接透传即可multiple_match/name_multiple_match→ 用户选完后,取对应项的matched_items[n].flat_params即可,无需手动提取字段
{
"flat_params": {
"asset_id": "342574", // INDUSTRY → marketing_asset_id; ONEID → marketing_asset_outer_id; CATALOG → catalog_id
"carrier_id": "417200582", // 优先 carrier_result.matched_carrier,其次 ONEID 资产的 marketing_carrier_id
"catalog_id": "123456", // 仅商品库类
"asset_sub_id": "...", // 商品库子 ID / ONEID 子包 / 直播预约 notice_id 等(可选)
"sub_carrier_id": "..." // 通常与 asset_sub_id 同值(可选)
}
}
get-assets.mjs 的 flat_params:
get-assets.mjs 也会为每条 assets 都挂载 flat_params,格式与上面一致。Agent 选完后直接取 assets[n].flat_params 透传即可。assets 恰好 1 条时顶层也输出 flat_params(= assets[0].flat_params)。
总结:无论走哪个脚本、匹配到几条,每条结果都带
flat_params。Agent 选定后直接透传,永远不需要手动判断"该取哪个字段"。
asset_sub_id / sub_carrier_id 补充说明(flat_params 已自动处理,以下仅供了解):
- APP_ANDROID:子包标识(如
"0;00011609313139363030393334"),asset_sub_id和sub_carrier_id填同一值 - PC_GAME:区服标识(如
"hwbz"),asset_sub_id和sub_carrier_id填同一值 - WECHAT_CHANNELS_LIVE_RESERVATION:直播预约
notice_id(如"finderlivenotice-..."),asset_sub_id和sub_carrier_id填同一值 - 商品库类(CONSUMER_PRODUCT / WECHAT_STORE_PRODUCT / COMMODITY_SET / WECHAT_STORE_PRODUCT_SET):
asset_sub_id=product_outer_id/wechat_store_id/commodity_set_id - 无子级时不传这两个字段即可
carrier_id 的来源(按优先级):
flat_params.carrier_id(两个脚本每条结果都带,最简单直接)- 用户明确给出的载体 ID。⛔ 用户给的"推广产品 ID"不是载体 ID,两者不可互换。
- 以上都没有时,需向用户确认
视频号直播预约场景补充:get-assets.mjs 返回含 live_notices,Agent 必须选取 notice_id(格式 finderlivenotice-xxx),同时传给 asset_sub_id 和 sub_carrier_id。多场次选择:① 用户指定 → 匹配 ② 未指定 → start_time 最晚且在投放日期内 ③ 都不在范围 → start_time 最晚。(get-assets-by-rules.mjs 的 flat_params 中已自动选取最晚场次,如需用户指定可覆盖)
脚本会根据
marketing_target_type自动判断三分类(ONEID / 商品库 / 行业产品库),组装正确的marketing_asset_outer_spec或marketing_asset_id。根据marketing_carrier_type自动判断是否需要marketing_carrier_detail。不需要手动构造这些嵌套结构。
2B. 强约束
- 白名单例外:用户在原始需求里已明确给出完整 ID(如
catalog_id、product_outer_id、marketing_asset_id等),则可直接作为对应的扁平 ID 使用并跳过查询。ONEID 类用户给了资产 ID 时通过asset_hint.asset_id传给get-assets.mjs,脚本会自动短路处理。 - 空字符串不是合法结果:不要把空字符串当作"已完成步骤 2"。查不到且用户也未提供时,保留缺失状态。
- ⚠️ 商品库类空资产回退(脚本已自动处理):
get-assets.mjs内部已实现自动回退——当CONSUMER_PRODUCT查询返回空资产时,脚本会自动尝试WECHAT_STORE_PRODUCT,反之亦然。Agent 无需手动重试或切换类型。- 回退成功时,返回结果中会包含
actual_marketing_target_type(实际生效的类型)和fallback_applied: true - ⛔ Agent 必须检查返回的
actual_marketing_target_type字段:如果与传入的类型不同,说明发生了回退,后续步骤 3~7 都必须使用actual_marketing_target_type的值(而非原始传入值) - 如果返回
assets: []且无fallback_applied,说明两种类型都没有资产,按正常的空结果处理(保留缺失状态)
- 回退成功时,返回结果中会包含
- 跳转页面载体 (
MARKETING_CARRIER_TYPE_JUMP_PAGE):不需要传carrier_id,但推广资产仍需正常查询
步骤 2 完成后你应该有:flat_params(包含 asset_id、carrier_id 等扁平 ID),或已从脚本返回中选定了一条带 flat_params 的资产。这些值不能是空字符串。
步骤 3(⛔ oCPM/oCPC 必须执行):确定版位
前置:步骤 1 的
marketing_target_type、marketing_carrier_type输出:site_set(数组)或确认使用自动版位
⚡ 快速路径:仅 CPC/CPM + 自动版位 → 直接设
automatic_site_enabled: true,跳过本步查询,进入步骤 4。⛔ oCPM/oCPC 时必须调用
get-site-set.mjs,即使用户已明确指定了版位名称。原因:步骤 4 的get-conversions.mjs依赖此步返回的available_site_set来构造site_set参数,用户给的版位名称不能直接替代。
版位决定了广告的投放位置。常规广告支持手动选择版位和自动版位两种模式。
版位确定规则:
- 用户指定了版位 → 先调用
get-site-set.mjs,再从脚本返回的真实available_site_set中选择(如"投朋友圈" →["SITE_SET_MOMENTS"];如"投腾讯平台与内容媒体/PCAD" → 按 3B 一级分类展开为["SITE_SET_KANDIAN", "SITE_SET_QQ_MUSIC_GAME", "SITE_SET_TENCENT_NEWS", "SITE_SET_TENCENT_VIDEO"]再与available_site_set取交集)。确定最终的用户版位列表供步骤 4B 和步骤 6 使用 - 用户要求自动版位 →
automatic_site_enabled: true,仍需查询可用版位列表,后续get-conversions.mjs传入auto_site_set中的版位 - 用户未指定版位 → 推荐自动版位,仍需调用
get-site-set.mjs获取版位列表
3A. 获取可用版位列表
node scripts/get-site-set.mjs '{"account_id":"<ACCOUNT_ID>","marketing_goal":"<MARKETING_GOAL_枚举key>","marketing_sub_goal":"<MARKETING_SUB_GOAL_枚举key>","marketing_target_type":"<MARKETING_TARGET_TYPE_枚举key>","marketing_carrier_type":"<MARKETING_CARRIER_TYPE_枚举key>"}'
示例:
node scripts/get-site-set.mjs '{"account_id":"123456789","marketing_goal":"MARKETING_GOAL_USER_GROWTH","marketing_sub_goal":"MARKETING_SUB_GOAL_UNKNOWN","marketing_target_type":"MARKETING_TARGET_TYPE_APP_ANDROID","marketing_carrier_type":"MARKETING_CARRIER_TYPE_APP_ANDROID"}'
脚本已处理:内部自动设置 bid_mode、buying_type、campaign_type 等 API 必传参数,调用方只需传四元组枚举 key。
返回:
{
"available_site_set": ["SITE_SET_MOMENTS", "SITE_SET_WECHAT", "SITE_SET_MOBILE_UNION", "SITE_SET_QQ_MUSIC_GAME", "SITE_SET_TENCENT_VIDEO", "SITE_SET_CHANNELS", "SITE_SET_MOBILE_YYB"],
"auto_site_set": ["SITE_SET_MOMENTS", "SITE_SET_WECHAT", "SITE_SET_MOBILE_UNION"],
"non_multi_site_set": ["SITE_SET_MOBILE_YYB"]
}
3B. 版位枚举对照表(权威)
⚠️ 此表为 API 真实枚举 key 与中文名称的对照表,以 API 文档为准。Agent 在从用户自然语言映射版位时,必须参考此表,严禁凭猜测使用表中不存在的 key。
| 枚举值 | 说明 | 用户常见说法 | 备注 |
|---|---|---|---|
SITE_SET_MOMENTS |
微信朋友圈 | "朋友圈" | |
SITE_SET_WECHAT |
微信公众号与小程序 | "公众号"、"小程序" | |
SITE_SET_MOBILE_UNION |
腾讯广告联盟 | "优量汇"、"联盟"、"广告联盟" | |
SITE_SET_TENCENT_NEWS |
腾讯新闻 | "腾讯新闻" | |
SITE_SET_TENCENT_VIDEO |
腾讯视频 | "腾讯视频" | |
SITE_SET_MOBILE_YYB |
应用宝 | "应用宝" | |
SITE_SET_PCQQ |
腾讯广告电脑端(PC) | "QQ"、"PC QQ"、"电脑端" | |
SITE_SET_KANDIAN |
QQ浏览器(原腾讯看点) | "QQ浏览器"、"看点" | |
SITE_SET_QQ_MUSIC_GAME |
QQ、腾讯音乐及游戏 | "QQ音乐"、"腾讯音乐"、"QQ游戏" | |
SITE_SET_CHANNELS |
微信视频号 | "视频号" | |
SITE_SET_WECHAT_PLUGIN |
微信新闻插件 | "微信插件"、"微信新闻插件" | |
SITE_SET_SEARCH_SCENE |
搜索场景 | "搜索"、"搜索场景" | |
SITE_SET_WECHAT_SEARCH |
微信搜一搜 | "微信搜索"、"搜一搜" | ⚠️ 仅支持搜索广告 |
SITE_SET_QBSEARCH |
QQ浏览器等搜索 | "QQ浏览器搜索" | ⚠️ 仅支持搜索广告 |
SITE_SET_SEARCH_MOBILE_UNION |
腾讯广告联盟搜索 | "联盟搜索" |
⛔
site_set枚举值只允许使用上表第一列的 key,禁止自行从中文翻译构造枚举名。 脚本返回什么就用什么。⚠️ 标注"仅支持搜索广告"的版位(
SITE_SET_WECHAT_SEARCH、SITE_SET_QBSEARCH)在非搜索场景下不可使用,不要将其加入普通展示广告的site_set。
版位集合一级分类对照表
| 一级分类名称 | 包含的版位枚举值 | 常见说法 |
|---|---|---|
| 微信视频号 | SITE_SET_CHANNELS |
"视频号" |
| 微信朋友圈 | SITE_SET_MOMENTS |
"朋友圈" |
| 微信公众号与小程序 | SITE_SET_WECHAT、SITE_SET_WECHAT_PLUGIN |
"公众号"、"小程序"、"公众号与小程序" |
| 腾讯平台与内容媒体(PCAD) | SITE_SET_KANDIAN、SITE_SET_QQ_MUSIC_GAME、SITE_SET_TENCENT_NEWS、SITE_SET_TENCENT_VIDEO |
"腾讯平台"、"内容媒体"、"腾讯平台与内容媒体"、"PCAD" |
| 腾讯广告联盟 | SITE_SET_MOBILE_UNION |
"优量汇"、"联盟"、"广告联盟" |
| 应用宝 | SITE_SET_MOBILE_YYB |
"应用宝" |
| 腾讯广告电脑端(PC) | SITE_SET_PCQQ |
"QQ"、"PC QQ"、"电脑端" |
| 微信搜一搜 | SITE_SET_WECHAT_SEARCH |
"微信搜索"、"搜一搜"(⚠️ 仅搜索广告) |
| QQ浏览器等 | SITE_SET_QBSEARCH |
"QQ浏览器搜索"(⚠️ 仅搜索广告) |
| 腾讯广告联盟搜索 | SITE_SET_SEARCH_MOBILE_UNION |
"联盟搜索" |
| 搜索场景 | SITE_SET_SEARCH_SCENE |
"搜索场景" |
3C. 强约束
- 手动版位:
automatic_site_enabled: false+site_set数组(来自脚本返回的available_site_set或用户指定,按上表映射) - 自动版位(推荐):
automatic_site_enabled: true,site_set不传
⚠️ 传给 get-conversions.mjs 的 site_set 参数规则(仅 oCPM/oCPC 需关注,CPC/CPM 跳过)
⛔
site_set只能包含available_site_set中存在的版位。 必须传入用户最终选择的版位列表**(即手动版位场景下用于adgroups/add的site_set,自动版位场景下传auto_site_set),要根据用户实际选择的版位传入,不要盲目传完整的available_site_set。
| 场景 | get-conversions.mjs 的 site_set |
|---|---|
| 自动版位 | 传 auto_site_set 完整数组原样传入,不要只传用户提到的"优先版位" |
| 手动版位 | 传 用户指定版位 ∩ available_site_set(取交集) |
⚠️ 用户说的"优先版位"(如"优先视频号")≠
site_set参数。"优先版位"影响的是priority_site_set,而get-conversions.mjs的site_set是查询范围,自动版位时必须传auto_site_set全量。
❌ 典型错误:自动版位时只传了 ["SITE_SET_CHANNELS"](用户的优先版位)→ 应传 auto_site_set 全量。
步骤 3 完成后你应该有:版位模式(自动/手动)+ 供步骤 4 使用的 site_set(oCPM/oCPC 时:自动版位 = auto_site_set 全量,手动版位 = 用户指定 ∩ available_site_set;CPC/CPM + 自动版位时无需 site_set)。
3D. 版位定投场景(scene_spec,可选)
scene_spec是请求体根层级字段(与targeting并列),用于对已选版位内的流量做精细筛选。 默认"不限"(不传),仅在用户明确提到定投/屏蔽特定流量场景时才构造。
场景定向完整字段(以下字段均放在 scene_spec: { ... } 对象内):
| 场景维度 | scene_spec 内的字段 |
类型 | 说明 | 获取方式 |
|---|---|---|---|---|
| 联盟场景定向 | mobile_union |
enum[] | 腾讯广告联盟流量场景定向(如信息流原生、开屏等) | ✅ get-enum-options.mjs '{"fields":["scene_spec_mobile_union"]}' |
| 联盟场景屏蔽 | exclude_mobile_union |
enum[] | 联盟流量场景屏蔽 | ✅ get-enum-options.mjs '{"fields":["scene_spec_exclude_mobile_union"]}' |
| 联盟自定义定投 | union_position_package |
integer[] | 定投联盟流量包 ID 列表 | 用户提供流量包 ID |
| 联盟自定义屏蔽 | exclude_union_position_package |
integer[] | 屏蔽联盟流量包 ID 列表 | 用户提供流量包 ID |
| 联盟媒体类型 | mobile_union_category |
integer[] | 联盟媒体类型场景定向 ID | 用户提供 |
| 腾讯新闻场景 | tencent_news |
enum[] | 腾讯新闻流量场景 | ✅ get-enum-options.mjs '{"fields":["scene_spec_tencent_news"]}' |
| 广告展示场景 | display_scene |
enum[] | 广告展示场景 | ✅ get-enum-options.mjs '{"fields":["scene_spec_display_scene"]}' |
| QQ浏览器场景 | qbsearch_scene |
enum[] | QQ浏览器、应用宝流量场景 | ✅ get-enum-options.mjs '{"fields":["scene_spec_qbsearch_scene"]}' |
| PC端定投 | pc_scene |
enum[] | PC端定投场景 | ✅ get-enum-options.mjs '{"fields":["scene_spec_pc_scene"]}' |
| 搜一搜场景 | wechat_search_scene |
enum[] | 搜一搜流量场景 | ✅ get-enum-options.mjs '{"fields":["scene_spec_wechat_search_scene"]}' |
| 微信公众号小程序定投 | wechat_position |
integer[] | 定投指定公众号/小程序的 ID 列表 | 用户提供 |
| 视频号定投 | wechat_channels_scene |
integer[] | 定投指定视频号的 ID 列表 | 用户提供 |
| 微信场景定向 | wechat_scene |
struct | 微信流量细分场景,子字段见下方 | 用户提供 |
wechat_scene 子字段:
| 子字段 | 类型 | 说明 |
|---|---|---|
official_account_media_category |
integer[] | 公众号媒体类型 ID |
mini_program_and_mini_game |
integer[] | 小程序/小游戏流量类型 ID |
pay_scene |
integer[] | 订单详情页消费场景 ID |
构造示例:
定投联盟流量包 + 屏蔽指定流量包:
"scene_spec": {
"union_position_package": [6001403],
"exclude_union_position_package": [91019]
}
定投指定公众号 + 联盟信息流场景:
"scene_spec": {
"mobile_union": ["MOBILE_UNION_SCENE_IN_FEEDS_NATIVE"],
"wechat_position": [123456, 789012]
}
⚠️ 枚举类字段(
mobile_union、exclude_mobile_union、tencent_news、display_scene、qbsearch_scene、pc_scene、wechat_search_scene)必须通过get-enum-options.mjs查询确认枚举值,禁止猜测。 ⚠️ ID 列表类字段(union_position_package、exclude_union_position_package、wechat_position、mobile_union_category、wechat_channels_scene、wechat_scene子字段)直接传用户给出的 ID。 ⚠️ 用户未提到任何版位定投场景需求时,不传scene_spec(等同于 UI 上全部选"不限")。
步骤 4:获取转化目标 + 确定出价
前置:步骤 1 的四元组 + 步骤 2 的资产 ID + 步骤 3 的 site_set 输出:
conversion_id(可选)、bid_mode、smart_bid_type、bid_amount(手动出价时)或daily_budget(自动出价时)
⚡ 快速路径:CPC/CPM → 跳过 4B 转化查询,只需确定
bid_mode+bid_amount,然后进入步骤 5。
4A. 确定出价方式 (bid_mode)
根据用户意图确定出价方式:
| 枚举值 | 说明 | 需要 conversion_id |
|---|---|---|
BID_MODE_CPC |
按点击付费 | 否 |
BID_MODE_CPM |
按千次展示付费 | 否 |
BID_MODE_OCPM |
优化千次展示出价(推荐) | 是 |
BID_MODE_OCPC |
优化点击出价 | 是 |
核心规则:
- CPC/CPM:只需
bid_mode+bid_amount,不需要查询转化目标,跳过步骤 4B - oCPM/oCPC:需
bid_mode+conversion_id,手动出价(CUSTOM)还需bid_amount - 用户未指定出价方式时,默认使用
BID_MODE_OCPM
4A-2. 确定出价方案(smart_bid_type)
| 出价方案 | 用户意图 | 传参 |
|---|---|---|
手动出价 CUSTOM(默认) |
给了具体出价金额 / "稳定投放" / 未提及 | smart_bid_type: SMART_BID_TYPE_CUSTOM,bid_amount 必填且 > 0 |
最大转化量 SYSTEMATIC |
"最大转化" / "自动出价" / "系统出价" / "优先跑量" | smart_bid_type: SMART_BID_TYPE_SYSTEMATIC,daily_budget 必填且 > 0,不传 bid_amount |
CPC/CPM 固定走手动出价。oCPM/oCPC 根据用户意图选择,默认手动出价。
SYSTEMATIC(最大转化量)约束:
daily_budget必填且 > 0,用户未给时必须向用户确认bid_amount不传- 必须是 oCPM/oCPC
- ⛔ 不能同时开启:
auto_acquisition_enabled、live_recommend_strategy_enabled、aoi_optimization_strategy
控制成本(仅 SYSTEMATIC 可用):
根据是否配置了 ROI 深度优化,选择对应字段(二选一,互斥):
| 广告类型 | 判断条件 | 使用字段 | 范围 |
|---|---|---|---|
| 非 ROI | 未配 deep_conversion_type 为 WORTH/WORTH_ADVANCED |
custom_cost_cap(分) |
0 < 值 ≤ 2,000,000 |
| ROI | 配了 deep_conversion_type 为 WORTH 或 WORTH_ADVANCED |
custom_cost_roi_cap(float) |
> 0 |
都需同时传
cost_constraint_scene: COST_CONSTRAINT_SCENE_OPEN
4B. 获取转化目标(仅 oCPM/oCPC 需要)
node scripts/get-conversions.mjs '{"account_id":"<ACCOUNT_ID>","site_set":["<用户表达的版位>"],"available_site_set":["<步骤3返回的全量可用版位>"],"non_multi_site_set":["<步骤3返回的non_multi_site_set>"],"marketing_carrier_id":"<步骤2返回的载体ID>","asset_id":"<步骤2返回的行业资产ID>","marketing_goal":"<MARKETING_GOAL_枚举key>","marketing_sub_goal":"<MARKETING_SUB_GOAL_枚举key>","marketing_carrier_type":"<MARKETING_CARRIER_TYPE_枚举key>","marketing_target_type":"<MARKETING_TARGET_TYPE_枚举key>","create_source_type":"<CreateSourceType的枚举值,用户未提及来源时不传此参数>"}'
注意:常规广告不需要传
delivery_scene。四元组字段统一传字符串枚举 key,脚本内部自动转为数值。bid_mode来自步骤 4A 的出价方式(如BID_MODE_OCPM),用于按出价方式过滤转化目标。
create_source_type:如果用户指定了转化来源,则根据用户意图传入——PLATFORM平台转化或SELF_CREATED自建转化等。用户未提及来源时不传此参数。⛔
site_set参数来源:必须严格按步骤 3C 的规则传入——自动版位时传步骤 3 返回的auto_site_set完整数组(不是用户提到的"优先版位"子集),手动版位时传用户指定版位与available_site_set的交集。⛔
available_site_set参数:必须同时传入步骤 3 返回的available_site_set完整数组(即get-site-set.mjs返回的全量可用版位列表)。脚本内部会用site_set∩available_site_set取交集,作为防御性校验,确保只传入合法版位。即使你认为site_set已经是正确的子集,也必须传available_site_set。⛔
non_multi_site_set参数:必须同时传入步骤 3 返回的non_multi_site_set数组(不支持多版位组合的版位列表,即site_set_multi=0的版位)。脚本内部会自动过滤掉这些版位(除非用户只选了一个版位),避免查询转化目标时传入不支持多版位组合的版位。⛔ 行业产品库类(步骤 2 返回
asset_type: "INDUSTRY") 传asset_id!
marketing_carrier_id和asset_id是两个独立参数,由脚本按两个维度分别决定是否传给 API:
marketing_carrier_id(→ API 的product_id):传入flat_params.carrier_id。脚本根据marketing_carrier_type判断是否传:除页面跳转 (JUMP_PAGE) 外的载体类型都传。asset_id(→ API 的marketing_asset_id):仅行业产品库类需要传(asset_type: "INDUSTRY"时),传入flat_params.asset_id。ONEID 类和商品库类不需要传此字段。- 两者可以都传、只传一个、或都不传,互不排斥。
⛔ 特别注意:当
asset_type: "INDUSTRY"时,必须将flat_params.asset_id作为asset_id传入本脚本,否则转化目标查询可能会失败!
脚本已处理:通过 access_status 过滤仅返回已完成接入的转化目标,标注深度转化类型,裁剪无关字段。
返回示例:
{
"goals": [
{
"conversion_id": 12345,
"name": "APP激活",
"optimization_goal": "OPTIMIZATIONGOAL_APP_ACTIVATE",
"bid_mode": "BID_MODE_OCPM",
"has_deep_conversion": false,
"create_source_type": "PLATFORM"
},
{
"conversion_id": 12346,
"name": "注册-首日付费ROI",
"optimization_goal": "OPTIMIZATIONGOAL_APP_REGISTER",
"bid_mode": "BID_MODE_OCPM",
"has_deep_conversion": true,
"deep_conversion_type": "DEEP_CONVERSION_WORTH",
"deep_conversion_worth_goal": "OPTIMIZATIONGOAL_1DAY_PURCHASE_ROAS",
"create_source_type": "SELF_CREATED"
}
]
}
Agent 需要做的决策——conversion 选择规则:
- 排除
permission=1的项(脚本已过滤,但仍需意识到约束) - 用户提供了深度出价参数时(ROI 系数或行为出价金额),按以下三步选择:
- Step A — 确定出价字段:根据用户自然语言,参考文末「用户意图提取规则」表,确定对应的出价字段名(如
deep_conversion_worth_rate) - Step B — 反推 deep_conversion_type:根据下方 4D 映射表,从出价字段名反推对应的
deep_conversion_type(如deep_conversion_worth_rate→DEEP_CONVERSION_WORTH) - Step C — 从 goals 中选择:在 goals 列表中,找
has_deep_conversion=true且deep_conversion_type与 Step B 结果一致的转化ID。不同deep_conversion_type的 conversion_id 不可互换
- Step A — 确定出价字段:根据用户自然语言,参考文末「用户意图提取规则」表,确定对应的出价字段名(如
- 用户指定了优化目标(但没给深度出价参数) → 按
name字段匹配 - 用户未指定 → 取 goals 数组第一个项
- 用户指定了转化创建来源(如"自建转化"/"自建归因"/"自建"/"自定义转化"→
SELF_CREATED,"平台预置"/"平台转化"/"平台上报"/"系统预置"/"预置转化"→PLATFORM)→ 在调用get-conversions.mjs时传入create_source_type过滤;用户未提及来源时不传此参数
4C. 出价字段清单
| 字段 | 类型 | 必填 | 说明 | 如何获取 |
|---|---|---|---|---|
bid_mode |
enum | 否 | 出价方式 | 用户提供,默认 BID_MODE_OCPM |
bid_amount |
integer | 手动出价必填 | 出价(单位:分)。CUSTOM 时必填且 > 0;SYSTEMATIC 时不传 |
"出价5元" → 500 |
conversion_id |
integer | oCPM/oCPC 必填 | 转化ID | 4B 获取 |
deep_conversion_spec |
struct | 否 | 深度转化优化配置 | 见下方 |
deep_conversion_behavior_bid |
integer | 否 | 深度OG出价(分)(对应 DEEP_CONVERSION_BEHAVIOR) |
用户说"深度出价X元"/"深度行为出价"/"深度OG出价" |
deep_conversion_behavior_advanced_bid |
integer | 否 | 深度辅助OG出价(分)(对应 DEEP_CONVERSION_BEHAVIOR_ADVANCED) |
用户说"深度辅助出价X元"/"深度辅助OG出价" |
deep_conversion_worth_rate |
float | 否 | 深度ROI出价 / 深度转化价值率(对应 DEEP_CONVERSION_WORTH) |
用户说"深度ROI X"/"深度转化价值率X",支持3位小数 |
deep_conversion_worth_advanced_rate |
float | 否 | 深度辅助ROI(对应 DEEP_CONVERSION_WORTH_ADVANCED) |
用户说"深度辅助ROI X",支持3位小数 |
smart_bid_type |
enum | 是 | SMART_BID_TYPE_CUSTOM(手动出价,默认)或 SMART_BID_TYPE_SYSTEMATIC(最大转化量)。见 4A-2 决策表 |
根据用户意图选择 |
daily_budget |
integer | 是 | 日预算(分,5000~400000000)。CUSTOM:用户未提及传 0(不限);SYSTEMATIC:必填且 > 0,用户未给时向用户确认 |
"日预算1000元" → 100000 |
total_budget |
integer | 否 | 总消耗限额(分,0 或 5000~20000000000)。用于限制广告整个生命周期的总花费上限。0 表示不限制;如需限制则须 > 5000 且 < 20000000000。用户未提及 → 不传;用户提及"总预算X元"/"总消耗限额X元" → 传 X*100 |
"总预算5000元" → 500000 |
cost_constraint_scene |
enum | 否 | 仅 SYSTEMATIC 可用。传 COST_CONSTRAINT_SCENE_OPEN 开启。与下两字段联动(按 ROI/非 ROI 二选一) |
用户说"成本上限"/"控制成本" |
custom_cost_cap |
integer | 否 | 非 ROI 广告的成本上限(分,0 < 值 ≤ 2,000,000)。需先开启 cost_constraint_scene。⛔ ROI 广告不能传此字段 |
"成本上限50元" → 5000 |
custom_cost_roi_cap |
float | 否 | ROI 广告的期望 ROI(> 0)。需先开启 cost_constraint_scene。⛔ 非 ROI 广告不能传此字段 |
"成本ROI 1.5" → 1.5 |
user_action_sets |
array | 否 | 用户行为数据源 | user_action_sets/get |
4D. 深度转化优化
oCPM/oCPC 可选配置,前置条件:步骤 4B 的 get-conversions.mjs 返回中,选中的转化目标 has_deep_conversion=true。
| deep_conversion_type | 说明 |
|---|---|
通过 get-enum-options.mjs '{"fields":["deep_conversion_type"]}' 查询 |
包含深度行为优化、深度价值优化等 |
⚠️ 二选一规则:深度/深度辅助出价一级扁平字段与 deep_conversion_spec 嵌套结构互斥,不能同时传:
常规广告使用 conversion_id,因此直接传一级扁平字段即可。
一级扁平字段示例(用户说"深度ROI 1.5"):
{
"conversion_id": 12345,
"deep_conversion_worth_rate": 1.5
}
deep_conversion_type取自get-conversions.mjs返回,根据类型选用对应的一级出价字段:
DEEP_CONVERSION_WORTH→deep_conversion_worth_rate(深度ROI出价 / 深度转化价值率)DEEP_CONVERSION_WORTH_ADVANCED→deep_conversion_worth_advanced_rate(深度辅助ROI)DEEP_CONVERSION_BEHAVIOR→deep_conversion_behavior_bid(深度OG出价)DEEP_CONVERSION_BEHAVIOR_ADVANCED→deep_conversion_behavior_advanced_bid(深度辅助OG出价)⛔ 不同
deep_conversion_type的 conversion_id 不可互换。例如DEEP_CONVERSION_WORTH对应的 conversion_id 和DEEP_CONVERSION_WORTH_ADVANCED对应的是不同的 conversion_id,必须根据脚本返回的deep_conversion_type精确选择。
强约束:
conversion_id只能来自:用户明确给出的 ID,或get-conversions.mjs返回- 白名单例外:用户在原始需求中已明确给出完整的
conversion_id数值 ID,则直接使用 - CPC/CPM 出价不需要
conversion_id optimization_goal不需要传,API 会根据conversion_id自动推导
步骤 4 完成后你应该有:bid_mode、smart_bid_type、conversion_id(oCPM/oCPC时);CUSTOM 还有 bid_amount,SYSTEMATIC 还有 daily_budget。
步骤 5:配置定向 + 投放时间
前置:用户意图中的定向需求 输出:
targeting、begin_date、end_date、delivery_time_ranges
5A. 定向配置
常规广告拥有完整定向能力,支持地域、年龄、性别、兴趣、行为、人群包等多维度定向。
定向查询触发规则(命中任一项就必须先调用 get-targeting-lookup.mjs):
- 用户给了地域、省市区、常驻地 →
type: "geo" - 用户给了设备品牌 / 型号 →
type: "device"
不需要调用 get-targeting-lookup.mjs 的定向维度(脚本自动匹配枚举):
- 性别:直接用
["MALE"]/["FEMALE"]/ 不传 - 年龄:直接用
[{"min":25,"max":29}, {"min":30,"max":39}]格式的数组。min和max均为闭区间(包含边界值),即用户说"25~29岁"→{"min":25,"max":29},不是{"min":25,"max":30}。每个区间对应用户给出的一段年龄范围,如果用户说了多个不同年龄段区间,就按照多个区间构造,不要合并连续段 - 排除已转化:通过
get-enum-options.mjs '{"fields":["excluded_dimension","excluded_day"]}'查询枚举后构造 - 操作系统(
user_os):通过get-enum-options.mjs '{"fields":["user_os"]}'查询枚举值后构造(支持系统+版本号, 传["IOS"]/["ANDROID"](全版本),或用简化格式如["ANDROID_10+"]表示 Android 10 及以上 - 排除操作系统(
excluded_os):通过get-enum-options.mjs '{"fields":["excluded_os"]}'查询枚举后构造,同user_os的简化格式,也支持WINDOWS、HARMONY等直接枚举 - 联网方式(
network_type):通过get-enum-options.mjs '{"fields":["network_type"]}'查询枚举后构造,传用户提到的联网方式即可,如["WIFI"]、["4G"]、["5G"],脚本自动匹配为 API 枚举(如4G→NET_4G) - 学历(
education):通过get-enum-options.mjs '{"fields":["education"]}'查询枚举后构造,传中文即可,如["本科", "硕士"],脚本自动匹配为 API 枚举(如本科→BACHELOR) - 设备价格(
device_price):通过get-enum-options.mjs '{"fields":["device_price"]}'查询枚举后构造,传简化描述即可,如["2500以上"]、["1500-3500"],脚本自动展开为对应的价格区间枚举 - 微信广告行为(
wechat_ad_behavior):通过get-enum-options.mjs '{"fields":["wechat_ad_behavior_actions"]}'查询枚举后构造,传中文即可,如{"actions": ["注册过小游戏"], "mini_game_wechat_registered_activity": "30天未活跃"},脚本自动匹配为 API 枚举 - 微信广告行为排除:通过
get-enum-options.mjs '{"fields":["wechat_ad_behavior_excluded_actions"]}'查询枚举后构造 - 其他枚举定向(学历/联网方式/设备价格/婚恋状态等):均通过 `get-enum-options.mjs 查询
⚠️
get-targeting-lookup.mjs只支持type: "geo"和type: "device"两种查询,不支持 age、gender 等。年龄和性别不需要编码查询,直接用结构化值。
只有在以下情况才可跳过定向查询:用户完全没有给任何地域或设备定向约束。
⚠️ 通投(不限定向)时仍需传
targeting: {}(空对象),不要省略该字段。
地域编码查询:
node scripts/get-targeting-lookup.mjs '{"type":"geo","keyword":"广东"}'
# 支持批量:keyword 用空格分隔
node scripts/get-targeting-lookup.mjs '{"type":"geo","keyword":"北京 上海 广东"}'
⚠️ 地域查询效率规则(P0 级,违反会导致轮次耗尽被终止):
- 一次查完所有地域:脚本是本地文件查询,无数量限制。把用户给的所有城市名用空格拼接到一个 keyword 里一次调用即可,不要分批,不要逐个查询。即使 100+ 个城市也只需 1 次调用。
- 省级优先原则:如果用户说"北京"、"广东"等省级地域,直接用省名查询,会返回省级编码(如 110000)。不要拆解为区级编码,除非用户明确列举了具体的区/市。
- 不加行政区前缀:直接用城市名(如
"南宁 成都 杭州"),不要加"广西南宁"、"四川成都"等前缀。- 重名消歧:如果查询结果中有重名地域(如"朝阳区"同时返回北京和长春的),根据用户上下文和
parent字段筛选正确的。
地域排除(用户表达"排除某省/不投某省/除 X 外全国投放"):
调 get-geo-exclude.mjs,直接返回排除后剩余省份的编码,取 id 组成 regions 数组:
node scripts/get-geo-exclude.mjs '{"exclude":"河北"}'
# → {"results":[{"id":110000,"name":"北京市","level":"province"},{"id":120000,"name":"天津市","level":"province"},...]}
设备品牌型号 ID 查询:
node scripts/get-targeting-lookup.mjs '{"type":"device","keyword":"华为"}'
地域输出示例:
{
"results": [
{"id": 440000, "name": "广东省", "level": "province", `"city_level": 4}
]
}
设备输出示例:
{
"results": [
{"id": 10001, "name": "华为 Mate 60"},
{"id": 10002, "name": "华为 P60"}
]
}
常规广告支持的完整定向维度(以下字段均放在 targeting: { ... } 对象内,不要放到请求体顶层):
| 定向维度 | targeting 内的字段 |
说明 | 获取方式 |
|---|---|---|---|
| 地域 | geo_location.regions + geo_location.location_types |
regions 是纯整数数组(如 [440000]),取地域查询返回的 id 值;location_types 常用 LIVE_IN |
✅ get-targeting-lookup.mjs type:geo + 枚举查询 location_types |
| 地域优选 | geo_location.geo_location_auto_audience |
是否使用地域优选(boolean)。true=开启,系统自动扩展相似地域;用户未提及不传 |
❌ 直接传 boolean |
| 商圈 | geo_location.business_districts |
商圈 ID 数组(integer[]) | 用户提供商圈 ID |
| 自定义位置 | geo_location.custom_locations |
经纬度+半径定向,格式: [{"longitude":113.26,"latitude":23.13,"radius":3000}],radius 单位米 |
用户提供 |
| 性别 | gender |
枚举查询 | ❌ 查枚举后直接构造 |
| 年龄 | age |
数组格式: [{"min":25,"max":29}, {"min":30,"max":39}](min/max 均为闭区间,按用户原始区间构造,不要合并连续段) |
❌ 直接构造(无枚举) |
| 操作系统 | user_os |
支持系统+版本号(如 IOS_VERSION_18),枚举查询 |
❌ 查枚举后直接构造 |
| 排除操作系统 | excluded_os |
枚举查询 | ❌ 查枚举后直接构造 |
| 学历 | education |
枚举查询,传中文(如 ["本科", "硕士"])或枚举 key 均可,脚本自动匹配 |
❌ 查枚举后直接构造 |
| 婚恋状态 | marital_status |
枚举查询 | ❌ 查枚举后直接构造 |
| 联网方式 | network_type |
枚举查询 | ❌ 查枚举后直接构造 |
| 设备价格 | device_price |
枚举查询,传简化描述(如 ["2500以上"]、["1500-3500"])或枚举 key 均可,脚本自动展开 |
❌ 查枚举后直 |
…(truncated)