siluzan-tso-cli 1.1.36 → 1.1.37-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/README.md +2 -1
  2. package/dist/index.js +2860 -746
  3. package/dist/skill/_meta.json +2 -2
  4. package/dist/skill/assets/google-period-report.schema.json +226 -0
  5. package/dist/skill/assets/pmax-create-template.md +7 -1
  6. package/dist/skill/references/accounts/accounts.md +3 -3
  7. package/dist/skill/references/accounts/finance.md +1 -1
  8. package/dist/skill/references/accounts/open-account-by-media.md +1 -1
  9. package/dist/skill/references/accounts/open-account-google-ui.md +1 -1
  10. package/dist/skill/references/analytics/rag.md +1 -1
  11. package/dist/skill/references/analytics/reporting.md +5 -5
  12. package/dist/skill/references/core/setup.md +5 -5
  13. package/dist/skill/references/misc/tso-home.md +2 -2
  14. package/dist/skill/references/report-templates/README.md +14 -14
  15. package/dist/skill/references/report-templates/REPORT-WORKFLOW.md +23 -15
  16. package/dist/skill/references/report-templates/bing-period-report.md +89 -23
  17. package/dist/skill/references/report-templates/google-period-report.md +55 -5
  18. package/dist/skill/references/report-templates/meta-account-diagnosis-report.md +144 -16
  19. package/dist/skill/references/report-templates/tiktok-period-report.md +112 -7
  20. package/dist/skill/report-templates/README.md +14 -14
  21. package/dist/skill/report-templates/REPORT-WORKFLOW.md +23 -15
  22. package/dist/skill/report-templates/bing-period-report.html +1343 -0
  23. package/dist/skill/report-templates/bing-period-report.md +89 -23
  24. package/dist/skill/report-templates/google-period-report.html +1314 -0
  25. package/dist/skill/report-templates/google-period-report.md +55 -5
  26. package/dist/skill/report-templates/meta-account-diagnosis-report.html +1124 -0
  27. package/dist/skill/report-templates/meta-account-diagnosis-report.md +144 -16
  28. package/dist/skill/report-templates/tiktok-period-report.html +1111 -0
  29. package/dist/skill/report-templates/tiktok-period-report.md +112 -7
  30. package/dist/skill/scripts/install.ps1 +3 -3
  31. package/dist/skill/scripts/install.sh +3 -3
  32. package/package.json +1 -1
@@ -2,9 +2,75 @@
2
2
 
3
3
  > 统计区间:`{startDate}` ~ `{endDate}`(**不可包含今天或昨天**,见下文)
4
4
  > 账户:`{mediaCustomerId}`(`{mediaCustomerName}`)
5
- > **默认交付**:**HTML**(Agent 脚本读落盘 JSON 生成;禁止仅 Markdown 摘要或纯 JSON 充当终稿)。用户指定 Excel 时 Agent 脚本写 xlsx,**无** CLI `render` 子命令。
5
+ > **默认交付物**:一份可打开的、带 ECharts 图表的 **HTML 文件**(`bing-period-report.html`)。
6
+ > 用户**未指定格式**时一律走下方 **标准四步流程**;**禁止** Agent 手写/拼接 HTML(语法错误会导致报告无法显示)。
7
+ > **用户明确要求 Excel / xlsx** 时:拉数步骤不变,改为 Agent 脚本写 `.xlsx`;**不要**调用 `bing-analysis render`;禁止假设存在内置 excel 子命令。
8
+
9
+ 数据块(Bing 实际支持的 9 类业务维度 + 总览):总览、设备、地域、受众(年龄/性别)、系列、广告组、广告、关键词、搜索字词。
10
+
11
+ | CLI `--sections` | 落盘形状(生产实测) | 报告 `tables.*` / KPI |
12
+ | --- | --- | --- |
13
+ | `overview` | 对象:`currentPeriod` / `previousPeriod` / `balance` / `averageDailyCost` … | → `meta` + `kpis`(环比、余额、日均) |
14
+ | `device` | `{ devices: Row[] }` | → `tables.devices[]` |
15
+ | `geographic` | `{ countries: Row[] }` | → `tables.geographic[]` |
16
+ | `audience-merged`(或 `age-audience`/`gender-audience`) | `{ data: { ageAudience.audience[], genderAudience.audience[] } }` | → `tables.audienceAge[]` / `audienceGender[]` |
17
+ | `campaigns` | **根节点数组** | → `tables.campaigns[]`;**本期 KPI 优先由此累加** |
18
+ | `ad-groups` | **根节点数组** | → `tables.adGroups[]`(含 `qualityScore`) |
19
+ | `ads` | **根节点数组** | → `tables.ads[]` |
20
+ | `keywords` | **根节点数组**(默认 limit=100) | → `tables.keywords[]` |
21
+ | `search-terms` | **根节点数组**(默认 limit=100) | → `tables.searchTerms[]` |
22
+
23
+ > Bing **没有** Google 的 `daily-metrics` / `dimension-summary`;报告模板也不渲染这两章。
6
24
 
7
- 数据块:总览、设备、地域、受众(年龄/性别)、系列、广告组、广告、关键词、搜索字词。
25
+ ---
26
+
27
+ ## 标准四步流程(默认 · 交付 HTML)
28
+
29
+ | 步骤 | 执行者 | 动作 |
30
+ | ---------------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
31
+ | **1. 拉数** | Agent 调 CLI | `bing-analysis -a <id> --start <s> --end <e> --json-out ./snap-bing`(见下方「日期规则」,全 11 维或 `--sections` 指定子集) |
32
+ | **2. 分析** | Agent | 用 **node/python 脚本**读落盘 JSON(勿用 Read 打开业务 `*.json`),把网关原始字段映射为下方 `tables.*` 契约,完成聚合与洞察 |
33
+ | **3. 写 JSON** | Agent | 撰写 `bing-period-report.json`:仅 `meta.accountId` + `narrative`(9 个分析小节)为必填;`kpis`/`tables` 可省略由 `--snapshot-dir` 自动合并 |
34
+ | **4. 渲染 HTML** | CLI | `bing-analysis render` — **校验 narrative 9 个分析小节必含字段**,缺项报错不生成 HTML;**禁止** Agent 手写/拼接 HTML |
35
+
36
+ ```bash
37
+ # 步骤 1
38
+ siluzan-tso bing-analysis -a <id> --start <s> --end <e> --json-out ./snap-bing
39
+
40
+ # 步骤 4(步骤 2~3 完成后)
41
+ siluzan-tso bing-analysis render \
42
+ --data ./bing-period-report.json \
43
+ --snapshot-dir ./snap-bing \
44
+ --out ./bing-period-report.html
45
+ ```
46
+
47
+ ### `bing-period-report.json` 顶层结构
48
+
49
+ - `meta`:`accountId`(必填)/ `accountName` / `currency` / `startDate` / `endDate`;可省略由 `--snapshot-dir` 从 `overview` 快照自动合并。
50
+ - `kpis`:账户级 KPI —— `spend`/`impressions`/`clicks`/`conversions`/`ctr`/`averageCpc`/`costPerConversion`/`averageDailyCost`/`balance`/`remainingAccountBudget`,含可选 `previousPeriod` 环比对象;可省略。**本期 KPI 优先对 `campaigns` 全系列累加并重算比率**;无 campaigns 时回退 `overview.currentPeriod`。余额/日均仍来自 overview。
51
+ - `tables`(可省略,由 `--snapshot-dir` 按上表形状自动映射):
52
+ - `devices[]`:`{deviceType, spend, impressions, clicks, ctr, averageCpc, conversions, costPerConversion}`
53
+ - `geographic[]`:`{countryOrRegion, spend, impressions, clicks, ctr, averageCpc, conversions, costPerConversion}`
54
+ - `audienceAge[]`:`{ageRange, spend, impressions, clicks, ctr, averageCpc, conversions}`
55
+ - `audienceGender[]`:`{gender, spend, impressions, clicks, ctr, averageCpc, conversions}`
56
+ - `campaigns[]`:`{campaignName, campaignStatus, campaignStatusDisplay, spend, impressions, clicks, ctr, conversions, costPerConversion}`
57
+ - `adGroups[]`:`{adGroupName, campaignName, qualityScore, spend, clicks, ctr, conversions, costPerConversion}`
58
+ - `ads[]`:`{adTitle, adGroupName, adType, spend, clicks, ctr, conversions}`
59
+ - `keywords[]`:`{keyword, matchType, qualityScore, spend, ctr, averageCpc, conversions, costPerConversion}`
60
+ - `searchTerms[]`:`{searchQuery, keyword, deliveredMatchType, spend, ctr, conversions, costPerConversion}`
61
+ - `narrative`(**Agent 必填,唯一由 Agent 撰写的叙事内容**):
62
+ - `executiveSummary[]`:≥1 段执行摘要
63
+ - `sections.{overview,devices,geographic,audience,campaigns,adGroups,ads,keywords,searchTerms}`:每个维度各 `{analysis[](≥1 条,含数字依据), suggestions[](≥1 条)}`
64
+ - `recommendations[]`:≥3 条跨维度优化建议汇总
65
+
66
+ ### 快照合并范围(`--snapshot-dir`)
67
+
68
+ `render` 传 `--snapshot-dir` 时,CLI 自动补全:
69
+
70
+ 1. `meta` / `kpis`(含余额、日均、环比;本期 KPI 优先 campaigns 累加)
71
+ 2. `tables.*`(按上表落盘形状映射;Agent 已填字段不覆盖)
72
+
73
+ Agent 只需撰写 `narrative`;**禁止手写 HTML**。`ctr` / `conversionRate` 落盘已为 0~1 小数。
8
74
 
9
75
  ---
10
76
 
@@ -18,11 +84,11 @@
18
84
 
19
85
  用户指定某一月份(如「6月份报告」「6月 Bing 月报」)且该月**已结束**时:
20
86
 
21
- | 项 | 规则 |
22
- | --- | --- |
23
- | `--start` | 当月 **1 日**(如 `2026-06-01`) |
24
- | `--end` | 当月**最后一天**(如 6 月 → `2026-06-30`,**禁止**写成 `06-29`) |
25
- | 报告首行 | `统计区间:YYYY-MM-01 ~ YYYY-MM-<末>` |
87
+ | 项 | 规则 |
88
+ | --------- | ---------------------------------------------------------------- |
89
+ | `--start` | 当月 **1 日**(如 `2026-06-01`) |
90
+ | `--end` | 当月**最后一天**(如 6 月 → `2026-06-30`,**禁止**写成 `06-29`) |
91
+ | 报告首行 | `统计区间:YYYY-MM-01 ~ YYYY-MM-<末>` |
26
92
 
27
93
  示例(7 月 8 日要 6 月报告):
28
94
 
@@ -103,9 +169,9 @@ CLI 落盘时会:overview 余额为 0 → 调 `GetMediaAccountInfo` → 写回
103
169
 
104
170
  Bing 网关常不返回 `averageDailyCost`、`activeDays`(或为 0)。CLI 落盘前会:① 缺 `totalCost` 时用 `currentPeriod.spend`;② 缺 `activeDays` 时用 `--start`~`--end` 含首尾日历天数;③ `averageDailyCost = totalCost / activeDays`(保留 2 位小数)。
105
171
 
106
- **数据呈现**:区间消耗、展示、点击、转化、CTR、CPC、CPA、日均消耗、**实时余额**(`balance`)、优化分;**有效** `previousPeriod` 时展示环比。
172
+ **数据呈现**:区间消耗、展示、点击、转化、CTR、CPC、CPA、日均消耗、**实时余额**(`balance`)、优化分;**有效** `previousPeriod` 时展示环比。写入 JSON `kpis`(可由 `--snapshot-dir` 自动合并)。
107
173
 
108
- **分析(必写)**:
174
+ **分析(必写)** → 写入 `narrative.sections.overview.{analysis,suggestions}`:
109
175
 
110
176
  - **总结**:本期 vs 上期消耗/点击/转化/CTR/CPC/CPA 变化(**仅当 previousPeriod 有数据**);展示份额(`searchImpressionShare`)及预算/排名丢失份额;余额与日均消耗可支撑天数(用 **`balance` / `remainingAccountBudget`**,非 overview 快照 0)。
111
177
  - **建议**:账户级预算或投放节奏(引用具体百分比或金额);若展示份额丢失高 → 预算或出价方向;1~3 条。
@@ -116,9 +182,9 @@ Bing 网关常不返回 `averageDailyCost`、`activeDays`(或为 0)。CLI
116
182
 
117
183
  - **CLI**:`bing-analysis --sections device` → `DeviceSectionData`(行在 `devices[]`)
118
184
 
119
- **数据呈现**:各 `deviceType` 的展示、点击、消耗、CTR、CPC、转化、CPA;建议附消耗占比。
185
+ **数据呈现**:各 `deviceType` 的展示、点击、消耗、CTR、CPC、转化、CPA;建议附消耗占比。写入 JSON `tables.devices[]`。
120
186
 
121
- **分析(必写)**:
187
+ **分析(必写)** → 写入 `narrative.sections.devices.{analysis,suggestions}`:
122
188
 
123
189
  - **总结**:主消耗设备、各设备 CPA/CPC 差异、高消耗低转化设备。
124
190
  - **建议**:设备出价调整或预算向高转化设备倾斜(写设备名 + 表中数字),1~3 条。
@@ -129,9 +195,9 @@ Bing 网关常不返回 `averageDailyCost`、`activeDays`(或为 0)。CLI
129
195
 
130
196
  - **CLI**:`bing-analysis --sections geographic` → `GeographicSectionData`(常见 `countries[]`,**以 outline 为准**)
131
197
 
132
- **数据呈现**:Top 国家/地区(建议 Top 10)消耗、点击、转化、CTR、CPC、CPA
198
+ **数据呈现**:Top 国家/地区(建议 Top 10)消耗、点击、转化、CTR、CPC、CPA。写入 JSON `tables.geographic[]`。
133
199
 
134
- **分析(必写)**:
200
+ **分析(必写)** → 写入 `narrative.sections.geographic.{analysis,suggestions}`:
135
201
 
136
202
  - **总结**:地域消耗集中度、高转化 vs 高消耗低转化国家/地区。
137
203
  - **建议**:地域加价/降价/排除或单独系列(写 `countryOrRegion` + 数据),1~3 条。
@@ -142,9 +208,9 @@ Bing 网关常不返回 `averageDailyCost`、`activeDays`(或为 0)。CLI
142
208
 
143
209
  - **CLI**:推荐 `bing-analysis --sections audience-merged`(年龄+性别合并 JSON);或分别 `--sections age-audience` / `--sections gender-audience`
144
210
 
145
- **数据呈现**:年龄段、性别的展示、点击、消耗、CTR、CPC(按 `data.ageAudience.audience` / `data.genderAudience.audience`)。
211
+ **数据呈现**:年龄段、性别的展示、点击、消耗、CTR、CPC(按 `data.ageAudience.audience` / `data.genderAudience.audience`)。写入 JSON `tables.audienceAge[]` / `tables.audienceGender[]`。
146
212
 
147
- **分析(必写)**:
213
+ **分析(必写)** → 写入 `narrative.sections.audience.{analysis,suggestions}`:
148
214
 
149
215
  - **总结**:主力年龄段/性别、转化或 CPA 更优的受众段、无效花费受众。
150
216
  - **建议**:受众出价\_modifier 或排除(引用 `audience` 字段 + 指标),1~3 条。
@@ -159,13 +225,13 @@ Bing 网关常不返回 `averageDailyCost`、`activeDays`(或为 0)。CLI
159
225
  | 广告组 | `bing-analysis --sections ad-groups` | `ad-groups-*.json` |
160
226
  | 广告 | `bing-analysis --sections ads` | `ads-*.json` |
161
227
 
162
- **数据呈现**:各表按消耗降序;系列含 `campaignStatus`;广告组可含质量分相关字段(以 outline 为准)。
228
+ **数据呈现**:各表按消耗降序;系列含 `campaignStatus`;广告组可含质量分相关字段(以 outline 为准)。写入 JSON `tables.campaigns[]` / `tables.adGroups[]` / `tables.ads[]`。
163
229
 
164
230
  **分析(必写,三个子块各写一段,不可合并为一句带过)**:
165
231
 
166
- 1. **系列分析 — 总结**:Top 系列及费用占比、暂停/活跃系列效果差异、合计 CTR/CPC/CPA。**建议**:预算增减、暂停或放量具体 `campaignName`,1~3 条。
167
- 2. **广告组分析 — 总结**:高消耗广告组、质量分或 CPA 异常组。**建议**:出价、暂停或结构优化(写 `adGroupName` + 数据),1~3 条。
168
- 3. **广告分析 — 总结**:Top 消耗创意、CTR/转化表现分化。**建议**:暂停低效广告、复制高效创意方向,1~3 条。
232
+ 1. **系列分析 — 总结**:Top 系列及费用占比、暂停/活跃系列效果差异、合计 CTR/CPC/CPA。**建议**:预算增减、暂停或放量具体 `campaignName`,1~3 条。→ 写入 `narrative.sections.campaigns.{analysis,suggestions}`
233
+ 2. **广告组分析 — 总结**:高消耗广告组、质量分或 CPA 异常组。**建议**:出价、暂停或结构优化(写 `adGroupName` + 数据),1~3 条。→ 写入 `narrative.sections.adGroups.{analysis,suggestions}`
234
+ 3. **广告分析 — 总结**:Top 消耗创意、CTR/转化表现分化。**建议**:暂停低效广告、复制高效创意方向,1~3 条。→ 写入 `narrative.sections.ads.{analysis,suggestions}`
169
235
 
170
236
  ---
171
237
 
@@ -176,18 +242,18 @@ Bing 网关常不返回 `averageDailyCost`、`activeDays`(或为 0)。CLI
176
242
  | 关键词 | `bing-analysis --sections keywords` | 默认 `limit=100`、`orderByCost=true` |
177
243
  | 搜索字词 | `bing-analysis --sections search-terms` | 同上 |
178
244
 
179
- **数据呈现**:Top 关键词/搜索词表(消耗、CTR、CPC、转化、CPA、质量分/匹配类型等,以 outline 为准)。
245
+ **数据呈现**:Top 关键词/搜索词表(消耗、CTR、CPC、转化、CPA、质量分/匹配类型等,以 outline 为准)。写入 JSON `tables.keywords[]` / `tables.searchTerms[]`。
180
246
 
181
247
  **分析(必写,两块各写一段)**:
182
248
 
183
- 1. **关键词 — 总结**:高转化词、高消耗低转化或零转化词、匹配类型分布。**建议**:暂停/降价/提价/改匹配(写 `keyword` + 数据),1~3 条。
184
- 2. **搜索字词 — 总结**:高意向词、应加为关键词的词、应否定的无关词(对比触发 `keyword`)。**建议**:加词、否词(写 `searchQuery` + 数据),1~3 条。
249
+ 1. **关键词 — 总结**:高转化词、高消耗低转化或零转化词、匹配类型分布。**建议**:暂停/降价/提价/改匹配(写 `keyword` + 数据),1~3 条。→ 写入 `narrative.sections.keywords.{analysis,suggestions}`
250
+ 2. **搜索字词 — 总结**:高意向词、应加为关键词的词、应否定的无关词(对比触发 `keyword`)。**建议**:加词、否词(写 `searchQuery` + 数据),1~3 条。→ 写入 `narrative.sections.searchTerms.{analysis,suggestions}`
185
251
 
186
252
  ---
187
253
 
188
254
  ## 7. 报告收尾(全账户)
189
255
 
190
- 在以上各 section 分析之后,可增加 **「优化建议汇总」**(3~5 条),跨 section 归纳优先级,**须与前面各 section 分析一致、不得矛盾**;可呼应对外客户话术(若用户需要)。
256
+ 在以上各 section 分析之后,须撰写 **「优化建议汇总」**(3~5 条,写入 JSON `narrative.recommendations[]`),跨 section 归纳优先级,**须与前面各 section 分析一致、不得矛盾**;可呼应对外客户话术(若用户需要)。
191
257
 
192
258
  ---
193
259
 
@@ -3,7 +3,57 @@
3
3
  > 统计区间:`{startDate}` ~ `{endDate}`
4
4
  > 账户:`{mediaCustomerId}`
5
5
 
6
- > **用户明确要求 Excel / xlsx**(且非 OKKI / 询盘话术)时:在拉数步骤不变的前提下,**另 Read 全文** `report-templates/google-period-report-excel.md`,并**先读齐**各维度 `*.outline.txt` 再写脚本;禁止加载宿主第三方 xlsx Skill。
6
+ > **默认交付物**:一份可打开的、带 ECharts 图表的 **HTML 文件**(`google-period-report.html`)。
7
+ > 用户**未指定格式**时一律走下方 **标准四步流程**;**禁止** Agent 手写/拼接 HTML(语法错误会导致报告无法显示)。
8
+ > **用户明确要求 Excel / xlsx**(且非 OKKI / 询盘话术)时:在拉数步骤不变的前提下,**另 Read 全文** `report-templates/google-period-report-excel.md`,并**先读齐**各维度 `*.outline.txt` 再写脚本;禁止加载宿主第三方 xlsx Skill;**不要**调用 `google-analysis render`。
9
+
10
+ ---
11
+
12
+ ## 标准四步流程(默认 · 交付 HTML)
13
+
14
+ | 步骤 | 执行者 | 动作 |
15
+ | ---------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
16
+ | **1. 拉数** | Agent 调 CLI | `google-analysis -a <id> --start <s> --end <e> --json-out ./snap-google --sections <见下方默认维度对应 CLI>` |
17
+ | **2. 分析** | Agent | 用 **node/python 脚本**读落盘 JSON(勿用 Read 打开业务 `*.json`),完成筛选、聚合、排序与洞察 |
18
+ | **3. 写 JSON** | Agent | 按 `assets/google-period-report.schema.json` 撰写 `google-period-report.json`:仅 `meta` + `narrative`(8 维度叙事)为必填,`kpis`/`charts`/`tables` 可省略由 CLI 自动合并 |
19
+ | **4. 渲染 HTML** | CLI | `google-analysis render` — **校验 narrative 8 维度必含字段**,缺项报错不生成 HTML;**禁止** Agent 手写/拼接 HTML |
20
+
21
+ ```bash
22
+ # 步骤 1
23
+ siluzan-tso google-analysis -a <id> --start <s> --end <e> --json-out ./snap-google \
24
+ --sections overview,daily-metrics,dimension-summary,campaigns,devices,geographic,keywords
25
+
26
+ # 步骤 4(步骤 2~3 完成后)
27
+ siluzan-tso google-analysis render \
28
+ --data ./google-period-report.json \
29
+ --snapshot-dir ./snap-google \
30
+ --out ./google-period-report.html
31
+ ```
32
+
33
+ `google-period-report.json` 顶层结构:
34
+
35
+ - `meta`:`accountId`(必填)/ `accountName` / `currency` / `startDate` / `endDate`;可省略由 `--snapshot-dir` 从 `overview` + manifest 自动合并。
36
+ - `kpis`:账户级 KPI(消耗/展示/点击/转化/CTR/CPC/CPA,含可选 `previousPeriod` 环比);可省略。本期 KPI 由 CLI 优先对 `campaigns` 全系列累加并重算比率(规避 overview/stats 相对 Google API 延迟);无 campaigns 快照时回退 `overview.currentPeriod`。环比仍来自 `overview.previousPeriod`。
37
+ - `charts.dailyTrend`:每日趋势(`dates`/`cost`/`conversions`/`cpa`);可省略由 `daily-metrics` 自动合并。
38
+ - `tables.{dimensionSummary,campaigns,devices,geographic,keywords}`:对应 §3~§7 表格数据;可省略由同名 `google-analysis` section 自动合并。
39
+ - `narrative`(**Agent 必填,唯一由 Agent 撰写的内容**):
40
+ - `executiveSummary[]`:≥1 段执行摘要
41
+ - `sections.{overview,dailyTrend,dimensionSummary,campaigns,devices,geographic,keywords}`:每个维度各 `{analysis[](≥2 条), suggestions[](≥1 条)}`,对应报告 §1~§7
42
+ - `recommendations[]`:≥3 条跨维度优化建议,对应报告 §8
43
+
44
+ 完整字段定义见 `assets/google-period-report.schema.json`。
45
+
46
+ **Excel 分支**(用户明确要 xlsx 时):
47
+
48
+ 1. 步骤 1~2 与 HTML 流程相同(拉数 → 分析)。
49
+ 2. 改为 Agent 执行 node/python 脚本按 `google-period-report-excel.md` 写出 `.xlsx`(先读齐 `*.outline.txt`)。
50
+ 3. **不要**调用 `google-analysis render`(除非用户同时要 HTML + Excel)。
51
+ 4. **禁止**假设存在 `siluzan-tso … excel` 子命令。
52
+
53
+ 模板源码:`report-templates/google-period-report.html`(结构与样式,ECharts 渲染逻辑已内联)。
54
+
55
+ `render` 会向输出目录写入 HTML,并注入 `window.__GOOGLE_PERIOD_REPORT__`。
56
+ 传 `--snapshot-dir` 时 CLI 自动从快照合并 KPI、每日趋势图表、周期汇总/系列/设备/地域/关键词表格(Agent JSON 中已有字段不覆盖)。本期 KPI 优先 `campaigns` 累加,勿用延迟的 `stats`/overview 手工填账户级消耗。
7
57
 
8
58
  ---
9
59
 
@@ -65,9 +115,9 @@ siluzan-tso google-analysis -a <id> --start <s> --end <e> --json-out ./snap-goog
65
115
 
66
116
  `campaigns-*.json` → `items[]` 每行含 CLI 注入的 **`campaignStatusDisplay`**(`投放中` / `已暂停` / `已移除`)。
67
117
 
68
- | 正确 | 错误 |
69
- | ---- | ---- |
70
- | 直接展示 `row.campaignStatusDisplay` | 读 `campaignStatus` 后自行 `MAP[s] \|\| '已移除'`(`Enabled` 未命中键时会全变「已移除」) |
71
- | 需要英文枚举时读 `campaignStatus` 或 `campaignStatusV2`,展示前 `.upper()` 再映射 | 用 `stats` / `list-accounts` 的账户 `status` 充当系列状态 |
118
+ | 正确 | 错误 |
119
+ | --------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
120
+ | 直接展示 `row.campaignStatusDisplay` | 读 `campaignStatus` 后自行 `MAP[s] \|\| '已移除'`(`Enabled` 未命中键时会全变「已移除」) |
121
+ | 需要英文枚举时读 `campaignStatus` 或 `campaignStatusV2`,展示前 `.upper()` 再映射 | 用 `stats` / `list-accounts` 的账户 `status` 充当系列状态 |
72
122
 
73
123
  原始枚举为 PascalCase(`Enabled`),与 `ad campaigns` 的 `statusDisplay`(有效/未投放/已结束使用)口径不同;周期报告「状态」列统一用 **`campaignStatusDisplay`**。
@@ -1,9 +1,9 @@
1
1
  # Meta(Facebook)账户 — 诊断报告(模板纲要)
2
2
 
3
- > 统计区间:`{startDate}` ~ `{endDate}`
3
+ > 统计区间:`{startDate}` ~ `{endDate}`
4
4
  > 账户:`{mediaCustomerId}`(`{mediaCustomerName}`)
5
5
 
6
- 在 **Facebook Ads 现有 7 个 Section** 内,尽量对齐 `google-account-diagnosis-report.md` 的章节结构;无接口的章节保留标题并写 `[ 本媒体接口未提供:{Google 维度名} ]`。
6
+ 在 **Facebook Ads 现有 7 个 Section** 内,尽量对齐 `google-account-diagnosis-report.md` 的章节结构;无接口的章节(健康度/系列类型/转化趋势/质量得分)在 JSON 中标注 `notAvailable: true` + `notAvailableReason`。
7
7
 
8
8
  拉数:**一次** `facebook-analysis`(建议全 7 维或默认 6 维 + 按需 `material`)。
9
9
 
@@ -11,64 +11,192 @@
11
11
  siluzan-tso facebook-analysis -a <id> --start <s> --end <e> --json-out ./snap-fb-diagnosis
12
12
  ```
13
13
 
14
+ **默认交付:HTML(`facebook-analysis diagnosis-render` 注入 Agent JSON 生成;禁止手写/拼接 HTML)**。用户指定 Excel 时 Agent 脚本写 xlsx。
15
+
16
+ ---
17
+
18
+ ## 标准四步流程(默认 · 交付 HTML)
19
+
20
+ | 步骤 | 执行者 | 动作 |
21
+ | ---------------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
22
+ | **1. 拉数** | Agent 调 CLI | `facebook-analysis -a <id> --start <s> --end <e> --json-out ./snap-fb-diagnosis`(全 7 维或默认 6 维 + 按需 `material`) |
23
+ | **2. 分析** | Agent | 用 **node/python 脚本**读落盘 JSON(勿用 Read 打开业务 `*.json`),做洞察与叙事;表格数字可由 `--snapshot-dir` 按 guide 根字段自动映射 |
24
+ | **3. 写 JSON** | Agent | 撰写 `meta-account-diagnosis-report.json`:仅 `meta.accountId` + `narrative` 为必填;`kpis`/`tables` 可省略,由 `--snapshot-dir` 自动合并 |
25
+ | **4. 渲染 HTML** | CLI | `facebook-analysis diagnosis-render` — **校验 narrative 11 个分析小节必含字段**(4 个媒体未覆盖小节可标 `notAvailable`),缺项报错不生成 HTML;**禁止** Agent 手写/拼接 HTML |
26
+
27
+ > `--snapshot-dir` 自动补全 `meta` / `kpis`(仅 overview;**禁止**用 ad-sets/creative 行 results 加总对比 overview)与 `tables.*`(按 `facebook-analysis-guide.md`:`adGroups`/`networks`/`countries`/`audiences`/`creatives`/`materials`)。Agent 已填字段不覆盖。
28
+
29
+ ### JSON 契约(`meta-account-diagnosis-report.json`)
30
+
31
+ ```jsonc
32
+ {
33
+ "meta": {
34
+ "accountId": "string(必填)",
35
+ "accountName": "string",
36
+ "currency": "string,如 USD/CNY",
37
+ "startDate": "YYYY-MM-DD",
38
+ "endDate": "YYYY-MM-DD",
39
+ "generatedAt": "ISO8601(可省略,render 自动写入)",
40
+ },
41
+ "kpis": {
42
+ "spend": "number",
43
+ "impressions": "number",
44
+ "clicks": "number",
45
+ "results": "number",
46
+ "ctr": "number(0~1 小数)",
47
+ "cpc": "number",
48
+ "costPerResult": "number",
49
+ "reach": "number",
50
+ "frequency": "number",
51
+ "previousPeriod": "同结构可选,用于环比",
52
+ },
53
+ "tables": {
54
+ "platform": "[{ publisherPlatform, platformPosition, spend, results, costPerResult }]",
55
+ "country": "[{ countryOrRegion, spend, results, costPerResult }]",
56
+ "audience": "[{ age, gender, spend, results, costPerResult }]",
57
+ "creative": "[{ creativeName, spend, impressions, clicks, ctr, results, costPerResult }]",
58
+ "material": "[{ materialName, spend, impressions, results }](DC 专用,标准账户常为空)",
59
+ },
60
+ "narrative": {
61
+ "executiveSummary": ["string,≥1 段"],
62
+ "sections": {
63
+ "accountProfile": { "analysis": ["string,≥1 条"], "suggestions": ["string,≥1 条"] },
64
+ "coreMetrics": { "analysis": ["…"], "suggestions": ["…"] },
65
+ "accountStructure": { "analysis": ["…"], "suggestions": ["…"] },
66
+ "healthGrade": {
67
+ "notAvailable": true,
68
+ "notAvailableReason": "gold-account",
69
+ "_comment": "或改为 { analysis, suggestions } 若有派生数据",
70
+ },
71
+ "campaignTypes": { "notAvailable": true, "notAvailableReason": "campaign-types" },
72
+ "keyComparisons": { "analysis": ["…"], "suggestions": ["…"] },
73
+ "conversionTrend": { "notAvailable": true, "notAvailableReason": "daily-metrics" },
74
+ "platformGeoAudience": { "analysis": ["…"], "suggestions": ["…"] },
75
+ "creative": { "analysis": ["…"], "suggestions": ["…"] },
76
+ "material": { "analysis": ["…"], "suggestions": ["…"] },
77
+ "qualityScore": { "notAvailable": true, "notAvailableReason": "ads-index" },
78
+ },
79
+ "recommendations": ["string 或 { title, content },≥3 条"],
80
+ "excludedChecks": [
81
+ "string,≥1 条,列出已排除的 Google-only 检查项(如 gold-account/daily-metrics/ads-index)",
82
+ ],
83
+ },
84
+ }
85
+ ```
86
+
87
+ > `healthGrade` / `campaignTypes` / `conversionTrend` / `qualityScore` 四节:Meta 无对应 API 时须写 `{ notAvailable: true, notAvailableReason: "<Google 维度名>" }`;若有派生数据(如用 `creativeType` 分布替代系列类型),则正常写 `{ analysis, suggestions }`,二者满足其一即可通过校验。
88
+
14
89
  ---
15
90
 
16
91
  ## 1. 账户画像
17
92
 
18
- - 账户名:`overview` → `accountName`;`list-accounts -m MetaAd -k <id>` 补 BM/状态(若有)。
19
- - **无** Google 式落地页 Section → 写 `[ 本媒体接口未提供:final-urls ]`。
93
+ **数据呈现**:账户名:`overview` → `accountName`;`list-accounts -m MetaAd -k <id>` 补 BM/状态(若有)。写入 JSON `meta.accountName`。
94
+
95
+ - **无** Google 式落地页 Section → 写 `[ 本媒体接口未提供:final-urls ]`
96
+
97
+ **分析(必写)** → 写入 `narrative.sections.accountProfile.{analysis,suggestions}`:
98
+
99
+ - **总结**:账户基本信息、投放状态。
100
+ - **建议**:账户结构或设置层面的优化,1~3 条。
20
101
 
21
102
  ## 2. 核心指标快照
22
103
 
104
+ **数据呈现**:本期 vs 上期:消耗、展示、点击、CTR、CPC、转化、CPA、results、costPerResult、reach、frequency。写入 JSON `kpis`(可由 `--snapshot-dir` 自动合并)。
105
+
23
106
  - **CLI**:`overview`
24
- - 本期 vs 上期:消耗、展示、点击、CTR、CPC、转化、CPA、results、costPerResult、reach、frequency。
107
+
108
+ **分析(必写)** → 写入 `narrative.sections.coreMetrics.{analysis,suggestions}`:
109
+
110
+ - **总结**:本期 vs 上期消耗/结果/CPL 变化(仅当 previousPeriod 有数据);覆盖与频次水平。
111
+ - **建议**:账户级预算或投放节奏(引用具体数字),1~3 条。
25
112
 
26
113
  ## 3. 账户结构
27
114
 
115
+ **数据呈现**:
116
+
28
117
  - **无** `resource-counts` / `conversion-actions` → 用 `ad-sets` + `creative` 行数简述:「共 N 个广告组、M 条在投创意(有 spend/impressions)」。
29
118
  - 按 `campaignName` 去重估算系列数(说明为派生,非 API 直出)。
30
119
 
120
+ **分析(必写)** → 写入 `narrative.sections.accountStructure.{analysis,suggestions}`:
121
+
122
+ - **总结**:账户结构规模、集中度。
123
+ - **建议**:结构精简或扩展方向,1~3 条。
124
+
31
125
  ## 4. 健康度 / 黄金账户
32
126
 
33
- - `[ 本媒体接口未提供:gold-account ]`
127
+ - `[ 本媒体接口未提供:gold-account ]` → 写入 `narrative.sections.healthGrade = { notAvailable: true, notAvailableReason: "gold-account" }`
34
128
 
35
129
  ## 5. 系列类型分布
36
130
 
37
- - `[ 本媒体接口未提供:campaign-types ]`;可用 `creative` 的 `creativeType` 分布作补充。
131
+ - `[ 本媒体接口未提供:campaign-types ]`;可用 `creative` 的 `creativeType` 分布作补充 → 写入 `narrative.sections.campaignTypes`(`notAvailable` 或补充 `analysis/suggestions`)
38
132
 
39
133
  ## 6. 重点维度对比(本期 vs 上期)
40
134
 
41
- - 总览已含环比;另可对 `ad-sets` / `country` / `platform` 做「本期排行」快照(无上期分维数据时不做分维环比)。
135
+ **数据呈现**:总览已含环比;另可对 `ad-sets` / `country` / `platform` 做「本期排行」快照(无上期分维数据时不做分维环比)。
136
+
137
+ **分析(必写)** → 写入 `narrative.sections.keyComparisons.{analysis,suggestions}`:
138
+
139
+ - **总结**:Top 广告组/国家/平台及其效率差异。
140
+ - **建议**:预算或出价调整方向(引用具体 `name` + 数据),1~3 条。
42
141
 
43
142
  ## 7. 转化成本趋势
44
143
 
45
- - `[ 本媒体接口未提供:daily-metrics ]`;勿用猜测曲线。
144
+ - `[ 本媒体接口未提供:daily-metrics ]`;勿用猜测曲线 → 写入 `narrative.sections.conversionTrend = { notAvailable: true, notAvailableReason: "daily-metrics" }`
46
145
 
47
146
  ## 8. 平台、地域、受众
48
147
 
148
+ **数据呈现**:
149
+
49
150
  - **CLI**:`platform`、`country`、`audience`
50
- - `platform` → `networks[]`:用 **`publisherPlatform`**(投放平台)+ **`platformPosition`**(版位);`network` 仅等于 `platformPosition`(兼容旧版,勿当平台列)。
51
- - 全表或 Top 表;与 Google `devices` / `geographic` / `audience` 对应说明。
151
+ - `platform` → `networks[]`:用 **`publisherPlatform`**(投放平台)+ **`platformPosition`**(版位);`network` 仅等于 `platformPosition`(兼容旧版,勿当平台列)。写入 JSON `tables.platform[]` / `tables.country[]` / `tables.audience[]`。
152
+
153
+ **分析(必写)** → 写入 `narrative.sections.platformGeoAudience.{analysis,suggestions}`:
154
+
155
+ - **总结**:主力平台/国家/受众段及其效率差异;与 Google `devices` / `geographic` / `audience` 对应说明。
156
+ - **建议**:版位/地域/受众定向调整(引用具体值 + 数据),1~3 条。
52
157
 
53
158
  ## 9. 创意(替代搜索词+搜索广告)
54
159
 
160
+ **数据呈现**:Top 创意、低效创意;**无** `search-terms` → `[ 不适用:搜索词 ]`。写入 JSON `tables.creative[]`。
161
+
55
162
  - **CLI**:`creative`
56
- - Top 创意、低效创意;**无** `search-terms` → `[ 不适用:搜索词 ]`
163
+
164
+ **分析(必写)** → 写入 `narrative.sections.creative.{analysis,suggestions}`:
165
+
166
+ - **总结**:Top 消耗创意、CTR/转化表现分化。
167
+ - **建议**:暂停低效创意或复制高效创意方向,1~3 条。
57
168
 
58
169
  ## 10. 素材
59
170
 
60
- - **CLI**:`material`(DC);否则指向 `creative`。
171
+ **数据呈现**:写入 JSON `tables.material[]`(DC 专用,标准账户常为空)。
172
+
173
+ - **CLI**:`material`(DC);否则指向 `creative`
61
174
  - **无** Google `extensions` → `[ 本媒体接口未提供:extensions ]`
62
175
 
176
+ **分析(必写)** → 写入 `narrative.sections.material.{analysis,suggestions}`:
177
+
178
+ - **总结**:素材表现(若为空,说明账户非 DC,改用 §9 创意结论)。
179
+ - **建议**:素材迭代方向,1~3 条。
180
+
63
181
  ## 11. 质量得分
64
182
 
65
- - `[ 本媒体接口未提供:ads-index ]`
183
+ - `[ 本媒体接口未提供:ads-index ]` → 写入 `narrative.sections.qualityScore = { notAvailable: true, notAvailableReason: "ads-index" }`
66
184
 
67
185
  ## 12. 总结与行动项
68
186
 
69
- - 优先:高消耗低效 Ad Set、版位、国家、人群、创意。
70
- - 列出已排除的 Google-only 检查项,避免读者以为漏查。
187
+ - 优先:高消耗低效 Ad Set、版位、国家、人群、创意。写入 JSON `narrative.recommendations[]`(≥3 条)。
188
+ - 列出已排除的 Google-only 检查项,避免读者以为漏查。写入 JSON `narrative.excludedChecks[]`(≥1 条,如 `gold-account`、`campaign-types`、`daily-metrics`、`ads-index`)。
71
189
 
72
190
  ---
73
191
 
74
192
  字段细则:`references/analytics/facebook-analysis-guide.md`。
193
+
194
+ ### 渲染 HTML
195
+
196
+ ```bash
197
+ siluzan-tso facebook-analysis diagnosis-render --data ./meta-account-diagnosis-report.json --snapshot-dir ./snap-fb-diagnosis --out ./meta-account-diagnosis-report.html
198
+ ```
199
+
200
+ - `--data`:Agent 撰写的诊断报告 JSON(必填)
201
+ - `--snapshot-dir`:可选,`facebook-analysis --json-out` 目录,自动补全 `meta` / `kpis` / `tables.*`
202
+ - `--out`:输出 HTML 路径(默认同 `--data` 目录)
@@ -1,38 +1,133 @@
1
1
  # TikTok 广告主账户 — 周期分析报告(模板纲要)
2
2
 
3
- > 统计区间:`{startDate}` ~ `{endDate}`
3
+ > 统计区间:`{startDate}` ~ `{endDate}`
4
4
  > 账户:`{mediaCustomerId}`(`{mediaCustomerName}`)
5
5
 
6
- 数据块:总览、系列/组/广告、视频素材、受众(含性别/年龄/兴趣合并)、地域与设备(**以 `--json-out` 实际字段为准**)。
6
+ 数据块:总览、系列/组/广告、视频素材、受众(含性别/年龄/兴趣合并)(**以 `--json-out` 实际字段为准**)。
7
+
8
+ **默认交付:HTML(`tiktok-analysis render` 注入 Agent JSON 生成;禁止手写/拼接 HTML)**。用户指定 Excel 时 Agent 脚本写 xlsx。
9
+
10
+ ---
11
+
12
+ ## 标准四步流程(默认 · 交付 HTML)
13
+
14
+ | 步骤 | 执行者 | 动作 |
15
+ | ---------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
16
+ | **1. 拉数** | Agent 调 CLI | `tiktok-analysis -a <id> --start <s> --end <e> --json-out ./snap-tiktok`(见下方「日期规则」,全 12 维或 `--sections` 指定子集) |
17
+ | **2. 分析** | Agent | 用 **node/python 脚本**读落盘 JSON(勿用 Read 打开业务 `*.json`),做洞察与叙事;表格数字可由 `--snapshot-dir` 按类型自动映射 |
18
+ | **3. 写 JSON** | Agent | 撰写 `tiktok-period-report.json`:仅 `meta.accountId` + `narrative` 为必填;`kpis`/`tables` 可省略,由 `--snapshot-dir` 按网关类型自动合并 |
19
+ | **4. 渲染 HTML** | CLI | `tiktok-analysis render` — **校验 narrative 6 个分析小节必含字段**,缺项报错不生成 HTML;**禁止** Agent 手写/拼接 HTML |
20
+
21
+ > `--snapshot-dir` 自动补全 `meta` / `kpis` / `tables.*`。网关形状见 `src/types/tiktok-analysis-api.ts`(对齐前端 `periodReport/tiktok.js`):`campaigns` 为 `{ campaigns:[] }`;ad-groups/videos/audience 为 `{ data.list[].metrics }`(snake_case);ads 为根数组。**本期 KPI 优先 campaigns 累加**。Agent 已填字段不覆盖。
22
+
23
+ ### JSON 契约(`tiktok-period-report.json`)
24
+
25
+ ```jsonc
26
+ {
27
+ "meta": {
28
+ "accountId": "string(必填,TikTok mediaCustomerId)",
29
+ "accountName": "string",
30
+ "currency": "string,如 CNY/USD",
31
+ "startDate": "YYYY-MM-DD",
32
+ "endDate": "YYYY-MM-DD",
33
+ "generatedAt": "ISO8601(可省略,render 自动写入)",
34
+ },
35
+ "kpis": {
36
+ "spend": "number",
37
+ "impressions": "number",
38
+ "clicks": "number",
39
+ "conversions": "number",
40
+ "ctr": "number(0~1 小数)",
41
+ "averageCpc": "number",
42
+ "costPerConversion": "number",
43
+ "previousPeriod": "同结构可选,用于环比",
44
+ },
45
+ "tables": {
46
+ "campaigns": "[{ campaignName, status, spend, impressions, clicks, ctr, conversions, costPerConversion }]",
47
+ "adGroups": "[{ adGroupName, campaignName, spend, clicks, ctr, conversions, costPerConversion }]",
48
+ "ads": "[{ adName, adGroupName, spend, clicks, ctr, conversions }]",
49
+ "videos": "[{ videoName, spend, impressions, clicks, ctr, conversions, costPerConversion }]",
50
+ "audienceGender": "[{ gender, spend, impressions, clicks, ctr }]",
51
+ "audienceAge": "[{ ageRange, spend, impressions, clicks, ctr }]",
52
+ "audienceInterest": "[{ interestCategory, spend, impressions, clicks, ctr }]",
53
+ },
54
+ "narrative": {
55
+ "executiveSummary": ["string,≥1 段"],
56
+ "sections": {
57
+ "overview": { "analysis": ["string,≥1 条"], "suggestions": ["string,≥1 条"] },
58
+ "campaigns": { "analysis": ["…"], "suggestions": ["…"] },
59
+ "adGroups": { "analysis": ["…"], "suggestions": ["…"] },
60
+ "ads": { "analysis": ["…"], "suggestions": ["…"] },
61
+ "videos": { "analysis": ["…"], "suggestions": ["…"] },
62
+ "audience": { "analysis": ["…"], "suggestions": ["…"] },
63
+ },
64
+ "recommendations": ["string 或 { title, content },≥3 条"],
65
+ },
66
+ }
67
+ ```
7
68
 
8
69
  ---
9
70
 
10
71
  ## 1. 执行摘要(总览)
11
72
 
12
- - 账户级消耗、展示、点击、转化、CTR、CPC 等(接口返回结构因版本可能略有差异)
73
+ **数据呈现**:账户级消耗、展示、点击、转化、CTR、CPC 等(接口返回结构因版本可能略有差异)。写入 JSON `kpis`(Agent 从 overview 快照映射填写)。
74
+
13
75
  - **CLI**:`siluzan-tso tiktok-analysis -a <mediaCustomerId> --sections overview [--start YYYY-MM-DD --end YYYY-MM-DD] --json-out <dir>`
14
76
 
77
+ **分析(必写)** → 写入 `narrative.sections.overview.{analysis,suggestions}`:
78
+
79
+ - **总结**:本期 vs 上期消耗/点击/转化/CTR/CPC/CPA 变化(若有 previousPeriod 数据)。
80
+ - **建议**:账户级预算或投放节奏(引用具体百分比或金额),1~3 条。
81
+
15
82
  ## 2. 广告结构(系列 / 广告组 / 广告)
16
83
 
17
- - 系列:`--sections campaigns` → `CampaignSectionData`(Query:`startDate`、`endDate`、`take`,默认 `take=100`)
18
- - 广告组:`--sections ad-groups` → `AdGroupReport`
19
- - 广告:`--sections ads` → `AdReport`
84
+ **数据呈现**:
85
+
86
+ - 系列:`--sections campaigns` → `CampaignSectionData`(Query:`startDate`、`endDate`、`take`,默认 `take=100`)。写入 JSON `tables.campaigns[]`。
87
+ - 广告组:`--sections ad-groups` → `AdGroupReport`。写入 JSON `tables.adGroups[]`。
88
+ - 广告:`--sections ads` → `AdReport`。写入 JSON `tables.ads[]`。
89
+
90
+ **分析(必写,三个子块各写一段,不可合并为一句带过)**:
91
+
92
+ 1. **系列分析 — 总结**:Top 系列及费用占比、暂停/活跃系列效果差异。**建议**:预算增减或暂停具体 `campaignName`,1~3 条。→ 写入 `narrative.sections.campaigns.{analysis,suggestions}`
93
+ 2. **广告组分析 — 总结**:高消耗广告组、CPA 异常组。**建议**:出价或结构优化(写 `adGroupName` + 数据),1~3 条。→ 写入 `narrative.sections.adGroups.{analysis,suggestions}`
94
+ 3. **广告分析 — 总结**:Top 消耗创意、CTR/转化表现分化。**建议**:暂停低效广告或复制高效创意方向,1~3 条。→ 写入 `narrative.sections.ads.{analysis,suggestions}`
20
95
 
21
96
  ## 3. 素材与创意(视频)
22
97
 
98
+ **数据呈现**:按消耗排序的视频素材表现(消耗、展示、点击、CTR、转化、CPA)。写入 JSON `tables.videos[]`。
99
+
23
100
  - **CLI**:`siluzan-tso tiktok-analysis -a <id> --sections videos [--start … --end …] [--take N] --json-out <dir>`
24
101
 
102
+ **分析(必写)** → 写入 `narrative.sections.videos.{analysis,suggestions}`:
103
+
104
+ - **总结**:高消耗低转化素材、Top 转化素材的共性(时长/形式/卖点)。
105
+ - **建议**:暂停低效素材、复制高效创意方向,1~3 条。
106
+
25
107
  ## 4. 受众分析
26
108
 
109
+ **数据呈现**:
110
+
27
111
  - 单维度:`--sections audience-<dimension>`,可选:`audience-gender` | `audience-age` | `audience-interest-category` | `audience-country-code` | `audience-platform` | `audience-language`
28
112
  - 三块合并:`--sections audience-merged`(**固定输出合并 JSON**,含 `gender` / `age` / `interest_category`;别名 `audience`)
29
113
 
114
+ 写入 JSON `tables.audienceGender[]` / `tables.audienceAge[]` / `tables.audienceInterest[]`。
115
+
116
+ **分析(必写)** → 写入 `narrative.sections.audience.{analysis,suggestions}`:
117
+
118
+ - **总结**:主力性别/年龄段/兴趣类目、转化或 CTR 更优的受众段。
119
+ - **建议**:受众定向调整或素材投放方向(引用维度值 + 指标),1~3 条。
120
+
30
121
  ## 5. 地域 / 兴趣辅助数据
31
122
 
32
123
  - 地区代码枚举:`tiktok-analysis areacode`(解析地域报表、对照名称,非 `--sections` 批跑维度)
33
124
  - 兴趣类目树:`tiktok-analysis interest-list -a <id>`(需配置 **`tiktokApiUrl`**)
34
125
 
35
- ## 6. 附录
126
+ ## 6. 报告收尾(全账户)
127
+
128
+ 在以上各 section 分析之后,须撰写 **「优化建议」**(3~5 条,写入 JSON `narrative.recommendations[]`),跨 section 归纳优先级,**须与前面各 section 分析一致、不得矛盾**。
129
+
130
+ ## 7. 附录
36
131
 
37
132
  - 日期规则:`--start` / `--end` **同传或同省略**;省略时默认**近 7 天(截至昨天)**,与 `report meta-overview`、`google-analysis` 一致。
38
133
  - 鉴权:与 TSO 其他接口相同(`config show` 中 `tsoApiBaseUrl` / Token)。
@@ -55,3 +150,13 @@
55
150
  | 受众(性别+年龄+兴趣) | `audience-merged`(别名 `audience`) |
56
151
  | 地区码 | 子命令 `tiktok-analysis areacode`(非 `--sections`) |
57
152
  | 兴趣列表 | 子命令 `tiktok-analysis interest-list -a <id>`(非 `--sections`) |
153
+
154
+ ### 渲染 HTML
155
+
156
+ ```bash
157
+ siluzan-tso tiktok-analysis render --data ./tiktok-period-report.json --snapshot-dir ./snap-tiktok --out ./tiktok-period-report.html
158
+ ```
159
+
160
+ - `--data`:Agent 撰写的报告 JSON(必填)
161
+ - `--snapshot-dir`:可选,`tiktok-analysis --json-out` 目录,自动补全 `meta` / `kpis` / `tables.*`
162
+ - `--out`:输出 HTML 路径(默认同 `--data` 目录)