关于 cja-executive-briefing
cja-executive-briefing 是一项 Customer Journey Analytics 技能,可将表现数据整理为面向管理层的叙述,并提供指标依据。它会选择 KPI、比较日历对齐的时段,并在可能时分析重大变化涉及的维度。
主要功能
- 01面向管理层的表现叙述
- 02确定性选择最多 6 个 KPI
- 03按日历规则对齐时段
- 04分析变化最大的两个指标的驱动因素
- 05列出指标 ID 以便审计
适用场景
- 01准备管理层表现简报
- 02比较当前结果与上一时段
- 03用维度数据解释 KPI 的重大变化
MCP 相关
使用 CJA MCP 工具读取数据视图上下文、识别指标、获取报告,并比较维度级别的驱动因素。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ adobe/ skills --skill cja-executive-briefing安装后在 Claude Code 中输入/cja-executive-briefing确认已加载。
附带文件evals/evals.json
详细介绍
高管简报(客户旅程分析)
生成一份精致、适合领导层阅读的绩效文档。高管不会阅读数据表——他们更关注能回答“我们在增长吗?”“发生了哪些变化?”以及“我们该怎么做?”的叙述。
此技能会将 CJA 数据转化为一份 VP 或 C-suite 领导者可在不到 3 分钟内读完的简报,并为希望深入了解的人提供支持数据。
语气:侧重业务影响,而非技术指标。应写“营收增长了 12%,这得益于付费搜索表现强劲的一周”,而不是“metrics/revenue 增加了 0.12 per metrics/sessions”。
使用的 CJA MCP 工具
describeCja(DATAVIEW_CONTEXT_GUIDE)— 了解数据视图的业务背景listComponentUsage— 确定北极星指标和辅助 KPIfindMetrics— 查询用户指定或发现的指标 IDfindCalculatedMetrics— 纳入自定义业务 KPIrunReport— 提取当前周期和对比周期的 KPI 数值searchDimensionItems— 确定维度值中的主要驱动因素
阶段 0 — 设置
- 调用
findDataViews列出可用的数据视图。 - 如果用户尚未指定数据视图,请展示列表并询问要使用哪一个。
- 使用所选 ID 调用
setDefaultSessionDataViewId。 - 确认报告周期(默认:过去 7 天)和简报的受众(高管、董事会、团队负责人)。
阶段 1 — 确定背景
1.1 加载数据视图背景
调用 describeCja("DATAVIEW_CONTEXT_GUIDE") 以了解:
- 数据视图代表的业务类型(电子商务、媒体、SaaS 等)
- 主要转化事件和营收指标
- 日历约定和时区。 记录这些值——它们是 1.2 中每次日期计算的输入:
WEEK_START_DOW— 每周开始的星期几(星期日、星期一,……)。 如果背景指南未指定,默认:星期一(ISO 8601)。FISCAL_YEAR_START_MONTH— 财年开始的月份。如果背景指南未指定,默认: 一月(日历年)。TIMEZONE— 例如,America/Los_Angeles。CALENDAR_SOURCE— 以下选项之一:"context guide"(值来自describeCja)、"default fallback"(背景指南未提供这些值,因而使用了上述默认值),或"user override"(用户明确指定了这些值)。
此背景决定了什么应被视为“北极星指标”,以及叙述中应使用什么措辞(例如,“订阅者”与“客户”或“用户”)。
1.2 确定报告周期
根据用户请求推断周期类型。不要停下来询问——立即继续。
原则
在相同的数据视图、周期类型和提示词下运行此技能两次,必须生成完全相同的 current 和 comparison 日期范围。确定性来自:(a) 读取 1.1 中的日历约定,而不是自行推测;(b) 对相应周期类型应用对齐规则,不凭主观判断。
周期类型 → 对齐规则
从用户请求中准确选择一种周期类型:
| 用户请求 | PERIOD_TYPE | 当前周期 | 对比周期 |
|---|---|---|---|
| “上周” / 未指定 | weekly | 截至今天之前最近一个完整周,按 WEEK_START_DOW 对齐(正好 7 天) | 紧邻的前一周,采用相同对齐方式 |
| “本月” / “MTD” | month-to-date | 当前月 1 日 → 今天 | 上个月 1 日 → 与今天相同的日号 |
| “上个月” | monthly | 上一个完整日历月(1 日 → 最后一天) | 再往前一个月 |
| “本季度” / “QTD” | quarter-to-date | 当前财季开始日 → 今天;根据 FISCAL_YEAR_START_MONTH 推导财季 | 上一财季中对应的相同天数 |
| “上季度” / “Q[N]” | quarterly | 上一个完整财季 | 再往前一个财季 |
| 自定义日期范围 | custom | 按指定范围 | 以 current.startDate 前一天为结束日的等长时间窗口 |
通用不变量(必须适用于每种周期类型)
调用 runReport 前,验证以下六项:
current.startDate < current.endDatecomparison.startDate < comparison.endDatecomparison.endDate < current.startDate(无重叠)comparison.endDate的次日等于current.startDate(连续)current和comparison的天数相同- 满足
PERIOD_TYPE的对齐规则:weekly:两个startDate都落在WEEK_START_DOWmonthly:两个startDate都落在每月 1 日month-to-date:两个startDate都落在每月 1 日;两个endDate的日相同quarterly:两个startDate都落在财务季度的第一天quarter-to-date:两个startDate都落在财务季度的起始日;两个endDate距季度起始日的天数相同custom:天数相同;日期连续
如果任一不变量不成立,请重新计算日期。切勿通过修改页脚来掩盖不匹配。
示例:今天是 2026 年 5 月 26 日,星期二
这些示例假设数据视图的上下文指南返回 WEEK_START_DOW = Sunday 和 FISCAL_YEAR_START_MONTH = January。使用其他日历时数字会有所不同——这正是重点。
| 用户请求 | PERIOD_TYPE | 当前周期 | 对比周期 |
|---|---|---|---|
| “上周” | weekly | 5 月 17 日(周日)– 5 月 23 日(周六) | 5 月 10 日(周日)– 5 月 16 日(周六) |
| “本月”/“MTD” | month-to-date | 5 月 1 日 – 5 月 26 日 | 4 月 1 日 – 4 月 26 日 |
| “上个月” | monthly | 4 月 1 日 – 4 月 30 日 | 3 月 1 日 – 3 月 31 日 |
| “本季度”/“QTD” | quarter-to-date | 4 月 1 日 – 5 月 26 日 | 1 月 1 日 – 2 月 24 日 |
| “上季度” | quarterly | 1 月 1 日 – 3 月 31 日 | 2025 年 10 月 1 日 – 12 月 31 日 |
| 自定义:“5 月 15–22 日” | custom | 5 月 15 日 – 5 月 22 日(8 天) | 5 月 7 日 – 5 月 14 日(8 天) |
如果 WEEK_START_DOW = Monday,则每周一行变为 May 18 (Mon) – May 24 (Sun) 与 May 11 (Mon) – May 17 (Sun)。其他行不变。
常见的 AI 失败模式
AI 可能会根据训练数据“知道”一周是周一至周日(ISO 8601),或者季度是 Q1=1 月至 3 月(日历季度)。擅自用这些默认值覆盖上下文指南,正是本节旨在避免的确定性错误。页脚的方法说明必须准确描述你计算出的日期——如果页脚写着“每周从周日开始”,但 current.startDate 是星期一,那就是日期计算有误,需要修正日期,而不是页脚。
1.3 受众假设
默认面向内部领导层(VP、总监、高级经理)。这意味着:
- 在叙述中包含具体的维度值(例如渠道名称)
- 同样直接地呈现正面和负面发现
- 读者了解你的业务,无需解释基本术语
如果用户说“外部”“董事会”或“投资者”,则转而关注更高层级的业务成果,删除可能敏感的内部渠道名称,并优先介绍最积极的发现。
第二阶段 — 发现北极星指标
提取使用最频繁的指标,以识别组织实际用什么来衡量成功。 并行运行两个调用——速度快,也为后续所有 KPI 决策奠定基础:
listComponentUsage(componentType: "metric")
listComponentUsage(componentType: "calculatedMetric")
确定性选择——不要自行发挥
对于相同的数据视图,KPI 集合在不同运行中必须可复现。同一时期运行两次此技能,必须得到相同的指标值,这就要求每次都选择相同的指标 ID。请严格遵循以下算法:
- 将两个
listComponentUsage结果合并为一个排名列表。 - 按
usageCount降序排序。若相同,则按指标 ID 的字母顺序排序(稳定的次级排序)。 - 使用
describeMetric或describeCalculatedMetric将指标 ID 解析为易读的显示名称。 - 从排序列表中取前 6 个指标 ID。这就是 KPI 集合。
不要按指标“类型”(流量、转化或收入)挑选,也不要因为某个替代指标的名称更适合叙述就换用它。不同运行分别选中 metrics/orders 和 metrics/orders_1_1,会导致数值大相径庭,并损害简报的可信度。
用户明确指定指标时
如果用户在请求中指定了指标(“给我一份关于收入、订单和转化率的简报”),请通过 findMetrics 将每个名称解析为一个具体的指标 ID。如果名称匹配到多个指标(例如,“Orders”同时匹配 metrics/orders 和一个名为“Orders”的计算指标),请选择 usageCount 最高的指标,并记录这一选择。
始终披露所用的指标 ID
在简报产物的页脚中加入一行简短的“包含的指标”,列出解析出的指标 ID(例如:metrics/orders_1_1、metrics/visits、metrics/page_views)。这样报告可供审计,用户也能确认重新运行时使用的是相同指标。
最多 6 个 KPI。更多只会带来噪声。
阶段 3 — 获取 KPI 数据
并行运行两份报告——当前时期和对比时期——并包含所有选定指标。使用日期维度(例如 variables/daterangeday),使报告返回整个时期的汇总总值。响应中的 summaryData.totals 数组包含所需的汇总值。
runReport(
startDate: "<current period start>T00:00:00",
endDate: "<current period end>T00:00:00",
dimensionIds: "variables/daterangeday",
metricIds: "metrics/visits,metrics/orders_1_1,metrics/revenue_1,...",
page: 0,
limit: 1
)
runReport(
startDate: "<prior period start>T00:00:00",
endDate: "<prior period end>T00:00:00",
dimensionIds: "variables/daterangeday",
metricIds: "metrics/visits,metrics/orders_1_1,metrics/revenue_1,...",
page: 0,
limit: 1
)
读取每个响应中的 summaryData.filteredTotals——这些值与 metricIds 中指定的指标顺序相对应。
针对每个 KPI 计算:
current值prior值delta= current − priorpctChange= delta / prior × 100direction:上升 / 下降 / 持平(采用 ±3% 阈值)polarity:若数值越高越好则为正向,若越低越好则为负向signal:绿色(有利)、红色(不利)、黄色(混合 / 持平)
阶段 4 — 找出变化的驱动因素
针对绝对百分比变化最大的 2 个 KPI,找出主要驱动因素:
并行运行当前时期和前一时期的细分报告:
runReport(
startDate: "<current period start>",
endDate: "<current period end>",
dimensionIds: "variables/marketing_channel",
metricIds: "<top-moved metric id>",
limit: 5
)
runReport(
startDate: "<prior period start>",
endDate: "<prior period end>",
dimensionIds: "variables/marketing_channel",
metricIds: "<top-moved metric id>",
limit: 5
)
比较各时期的渠道级数值,找出变化值最接近整体指标变化的维度值。这将成为叙述中的“驱动因素”表述。
仅针对变动最大的 2 个指标(按绝对百分比变化计算)运行维度细分。此限制的原因是:(a) 更多细分会增加延迟,却不会带来更多高管层面的价值;(b) 领导层首先会关注变动最大的两个指标。其余 KPI 通过叙述补充背景,无需归因。
如果 variables/marketing_channel 未返回有用的细分结果(例如,只有一个渠道有数据),请尝试使用 variables/page_type 或 variables/product_category 作为替代驱动维度。
第 5 阶段 — 撰写高管叙述
将叙述整理成 3–5 条要点。每条要点遵循以下结构:
[信号表情符号] [指标]:[值](较[上一时段][+/-百分比变化%])— [通俗易懂的背景说明]
指南:
- 以最重要的发现开头(影响最大的指标,无论正面还是负面)
- 使用业务语言:“收入”“客户”“转化”——不要写“指标/收入”
- 已知驱动因素时应明确指出:“由付费搜索带动”“产品页面优化带动”
- 如有必要,加入一条前瞻性说明:“应持续关注这一趋势……”
- 对于负面趋势,应直截了当,但不要危言耸听。建议调查原因,而不是惊慌失措。
写得好的要点示例:
- “上周收入达到 $1.24M,较前一周增长 8.2%——付费搜索带动了大部分增幅(+$82K)。”
- “转化率降至 2.1%(−0.4pp),主要出现在移动端。桌面端转化率保持稳定,为 3.4%。”
- “会话数持平于 540K(+1.1%)——自然流量和直接流量抵消了邮件营销活动发送量的减少。”
- “跳出率小幅上升至 43%(+2pp)。尚未发现单一驱动因素;值得持续关注至月底。”
第 6 阶段 — 生成 HTML 简报文档
直接生成简报。写入 /tmp/cja_executive_briefing_<YYYY-MM-DD_HHMMSS>.html。
这份文档应经过精心设计,达到可分享给管理层的水准,而不是看起来像
开发者工具的输出。
渲染规则 — 每次运行时一致应用
在相同数据视图和时段上运行此技能两次,渲染结果必须完全一致 (生成时间戳除外)。以下规则用于固定格式选择,避免 AI 在这些方面出现偏差。
数字格式
- KPI 值(每个卡片中的大号数字)——使用完整数字并添加
千位分隔符(
8,160、77,584、1,250,000)。即使数值很大,也不得使用K或M等 SI 后缀。高管需要精确数字,而不是缩写。 - 百分比变化(胶囊标签和叙述要点中)——始终保留一位小数,
按远离零方向舍入。例如,
−23.55%显示为−23.6%,绝不显示为−23.5%。基于完整精度的数值进行计算,只在 显示时舍入。 - 百分点变化(适用于转化率或跳出率等本身已是百分比的指标)——舍入规则相同,后缀为
pp。例如:+0.40 pp。 - 货币——以
$开头,使用千位分隔符;金额 ≥ $100 时不显示小数($1,240,000);金额 < $100 时显示美分($45.20)。
空值/缺失数据处理
KPI 卡片必须如实反映数据视图实际返回的内容。AI 不得悄悄替换为其他指标,也不得为了让简报更整洁而隐藏卡片。
- 对于已解析指标集中的某个指标,如果两个时段都返回
0或NULL:渲染卡片,kpi-value=Data unavailable,胶囊标签类名为flat,胶囊标签文本为⚠ N/A,prior文本 =Both periods returned no data — validate instrumentation。卡片必须保留在网格中,不得省略。 - 如果一个时段返回有效数据,另一个时段返回
0/NULL:渲染卡片,kpi-value使用有效值,胶囊标签类名为flat,胶囊标签文本为⚠ N/A,prior文本 =Prior {period_noun}: no data。 - 绝不得替换为派生指标(例如,收入返回 $0 时擅自添加“转化率”)。可见的 KPI 集合必须与页脚中披露的已解析指标 ID 一致。
- 如果收入/货币指标不可用,应在 KPI 网格上方显示
.callout.note,说明数据缺失情况。不得编造数值。
模板变量
按照以下规则填充下面 HTML 模板中的每个 {PLACEHOLDER}。
简报属于客户——绝不要在面向客户的字段中使用 Adobe、CJA 或任何供应商的措辞。
{ORG_NAME}— 客户的企业或品牌名称,根据第 1 阶段第 1.1 节中加载的数据视图上下文确定。移除— Prod、- Demo、Stage、Test、MCP等技术性/环境后缀。如果数据视图名称中没有清晰的品牌名称,则移除后缀后使用数据视图显示名称。不要编造名称,也不要替换为供应商名称。{PERIOD_TYPE}— 从Weekly、Monthly、Quarterly或Performance(默认)中选择,根据第 1 阶段第 1.2 节推断的周期确定。{LEDE_SENTENCE}— 严格使用以下模式,不得包含供应商名称:Leadership readout for the {period type lowercase} of {PERIOD_LABEL} compared to {COMPARISON_LABEL}.示例:Leadership readout for the week of May 12–18, 2026 compared to May 5–11, 2026.{DATA_VIEW}—findDataViews返回的数据视图显示名称。可以保留后缀——这一行是技术标识行,而非标题。{PERIOD_LABEL}/{COMPARISON_LABEL}— 易读的日期范围,例如May 12–18, 2026。{GENERATED_DATE}— 今天的日期,使用相同的易读格式,例如May 23, 2026。{METRIC_LABEL}/{FORMATTED_VALUE}/{PCT_CHANGE}/{PRIOR_VALUE}— 第 3 阶段中每项 KPI 对应的值。使用面向客户的指标显示名称,不要使用内部 ID。
HTML 模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Performance Briefing — {ORG_NAME} — {PERIOD}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@700;900&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--bg: #f5f4f1;
--surface: #ffffff;
--ink: #1a1a1a;
--ink-muted: #6b6b6b;
--border: #e5e2dc;
--header-bg: #0e0e10;
--header-warm: #3a1010;
--accent-red: #c8312f;
--accent-red-bright: #ff6b68;
--accent-red-soft: #fdecea;
--accent-green: #1f7a4d;
--accent-yellow: #d4a017;
}
body { font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
background: var(--bg); color: var(--ink); line-height: 1.5;
-webkit-font-smoothing: antialiased; }
/* === Header === */
header { background: linear-gradient(120deg, var(--header-bg) 0%, #1a0d0d 55%, var(--header-warm) 100%);
color: #fff; padding: 56px 56px 44px; position: relative; overflow: hidden; }
header::after { content: ""; position: absolute; right: -140px; top: -140px;
width: 460px; height: 460px;
background: radial-gradient(circle, rgba(200,49,47,.35) 0%, transparent 70%);
pointer-events: none; }
.header-inner { max-width: 1080px; margin: 0 auto; position: relative; z-index: 1; }
.eyebrow { display: inline-flex; align-items: center; gap: 8px;
padding: 6px 14px; border: 1px solid rgba(255,107,104,.55);
border-radius: 999px; color: var(--accent-red-bright);
font-size: 11px; font-weight: 600; letter-spacing: 1.2px;
text-transform: uppercase; margin-bottom: 24px;
background: rgba(200,49,47,.10); }
.eyebrow::before { content: ""; width: 6px; height: 6px;
background: var(--accent-red-bright); border-radius: 50%; }
header h1 { font-family: "Playfair Display", Georgia, serif;
font-size: 56px; font-weight: 700; letter-spacing: -1.5px;
line-height: 1.05; margin-bottom: 14px; }
header .lede { font-size: 16px; max-width: 560px;
color: rgba(255,255,255,.80); margin-bottom: 24px;
line-height: 1.55; }
header .meta { display: flex; flex-wrap: wrap; gap: 22px;
font-size: 13px; color: rgba(255,255,255,.60); }
header .meta span { display: inline-flex; align-items: center; gap: 6px; }
header .meta .icon { opacity: .8; }
/* === Tabs === */
nav { background: var(--surface); border-bottom: 1px solid var(--border);
padding: 0 56px; display: flex; gap: 28px;
position: sticky; top: 0; z-index: 50; }
nav a { display: block; padding: 16px 0; font-size: 14px;
color: var(--ink); text-decoration: none;
border-bottom: 2px solid transparent;
transition: border-color .15s ease; }
nav a:hover { border-bottom-color: var(--accent-red); }
/* === Container === */
.container { max-width: 1080px; margin: 0 auto; padding: 36px 56px 60px; }
/* === Callout === */
.callout { background: var(--accent-red-soft);
border-left: 4px solid var(--accent-red);
border-radius: 6px;
padding: 18px 22px; margin-bottom: 32px;
display: flex; gap: 14px; align-items: flex-start; }
.callout .warn-icon { font-size: 22px; line-height: 1; flex-shrink: 0;
color: var(--accent-yellow); }
.callout-title { font-weight: 700; color: var(--accent-red);
margin-bottom: 4px; font-size: 15px; }
.callout-body { font-size: 14px; color: #4a2222; line-height: 1.55; }
.callout.note { background: #fdf6e7; border-left-color: var(--accent-yellow); }
.callout.note .callout-title { color: #8a5a08; }
.callout.note .callout-body { color: #5a4108; }
/* === Section label === */
.section-label { font-size: 11px; font-weight: 700;
text-transform: uppercase; letter-spacing: 1.4px;
color: var(--ink-muted); margin-bottom: 14px;
padding-bottom: 10px; border-bottom: 1px solid var(--border); }
/* === KPI grid === */
.kpi-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 14px; margin-bottom: 36px; }
.kpi-tile { background: var(--surface); border-radius: 8px;
padding: 22px 22px 20px;
border-top: 3px solid #b9b6ae;
box-shadow: 0 1px 3px rgba(0,0,0,.05); }
.kpi-tile.down { border-top-color: var(--accent-red); }
.kpi-tile.up { border-top-color: var(--accent-green); }
.kpi-tile.flat { border-top-color: #b9b6ae; }
.kpi-head { display: flex; justify-content: space-between;
align-items: center; margin-bottom: 10px; }
.kpi-label { font-size: 11px; font-weight: 700;
text-transform: uppercase;
color: var(--ink-muted); letter-spacing: 1px; }
.kpi-value { font-family: "Playfair Display", Georgia, serif;
font-weight: 700; font-size: 38px;
line-height: 1; color: var(--ink);
margin-bottom: 12px; }
.pill { display: inline-flex; align-items: center; gap: 4px;
padding: 3px 9px; border-radius: 4px;
font-size: 12px; font-weight: 600; line-height: 1.4; }
.pill.down { background: var(--accent-red-soft); color: var(--accent-red); }
.pill.up { background: #ebf5ef; color: var(--accent-green); }
.pill.flat { background: #f1efea; color: var(--ink-muted); }
.prior { display: block; margin-top: 10px;
font-size: 12px; color: var(--ink-muted); }
/* === Narrative === */
.narrative-card { background: var(--surface); border-radius: 8px;
padding: 32px 36px;
box-shadow: 0 1px 3px rgba(0,0,0,.04);
margin-bottom: 24px; }
.narrative-card h2 { font-family: "Playfair Display", Georgia, serif;
font-size: 24px; font-weight: 700;
margin-bottom: 18px;
padding-bottom: 12px;
border-bottom: 1px solid var(--border); }
.bullet-list { list-style: none; }
.bullet-list li { padding: 14px 0; font-size: 15px; line-height: 1.65;
border-bottom: 1px solid #f1eeea; }
.bullet-list li:last-child { border-bottom: none; }
.bullet-list .signal { margin-right: 6px; }
.bullet-list .metric-highlight { font-weight: 700; }
.bullet-list .driver { color: var(--accent-red); font-style: italic; }
/* === Sections (collapsible tables) === */
.section { background: var(--surface); border-radius: 8px;
box-shadow: 0 1px 3px rgba(0,0,0,.04);
margin-bottom: 22px; overflow: hidden; }
.section-header { padding: 18px 28px; border-bottom: 1px solid var(--border);
display: flex; justify-content: space-between;
align-items: center; cursor: pointer; }
.section-header h2 { font-family: "Playfair Display", Georgia, serif;
font-size: 18px; font-weight: 700; }
table { width: 100%; border-collapse: collapse; font-size: 13px; }
thead th { background: #faf8f4; padding: 12px 22px;
text-align: left; font-weight: 600;
text-transform: uppercase; letter-spacing: .6px;
font-size: 11px; color: var(--ink-muted);
border-bottom: 1px solid var(--border); }
tbody td { padding: 12px 22px; border-bottom: 1px solid #f4f1eb; }
tbody tr:last-child td { border-bottom: none; }
.badge { display: inline-block; padding: 3px 9px; border-radius: 4px;
font-size: 11px; font-weight: 600; }
.badge.green { background: #ebf5ef; color: var(--accent-green); }
.badge.red { background: var(--accent-red-soft); color: var(--accent-red); }
.badge.yellow { background: #fef6e3; color: #b67a08; }
.badge.grey { background: #f1efea; color: var(--ink-muted); }
footer { text-align: center; padding: 32px 24px;
font-size: 12px; color: var(--ink-muted); }
/* === Print === */
@media print {
nav { display: none; position: static; }
header { padding: 36px 32px 28px; }
header h1 { font-size: 42px; }
.section-header { cursor: default; }
.kpi-row { page-break-inside: avoid; }
.kpi-tile, .narrative-card, .section {
box-shadow: none; border: 1px solid var(--border);
}
}
</style>
</head>
<body>
<header>
<div class="header-inner">
<div class="eyebrow">{PERIOD_TYPE} Performance Briefing</div>
<h1>{ORG_NAME} Performance</h1>
<p class="lede">{LEDE_SENTENCE}</p>
<div class="meta">
<span><span class="icon">📅</span> {PERIOD_LABEL}</span>
<span><span class="icon">📊</span> {DATA_VIEW}</span>
<span><span class="icon">🕔</span> Prepared {GENERATED_DATE}</span>
</div>
</div>
</header>
<nav>
<a href="#highlights">Highlights</a>
<a href="#narrative">Summary</a>
<a href="#data">KPI Detail</a>
<a href="#drivers">Drivers</a>
</nav>
<div class="container">
<div class="section-label">Key Performance Indicators</div>
<div id="highlights" class="kpi-row">
</div>
<div id="narrative" class="narrative-card">
<h2>Executive Summary</h2>
<ul class="bullet-list">
</ul>
</div>
<div id="data" class="section">
<div class="section-header" onclick="toggle('data-body')">
<h2>Full KPI Detail</h2>
<span id="data-body-icon">▾</span>
</div>
<div id="data-body">
<table>
<thead><tr>
<th>Metric</th>
<th>{PERIOD_LABEL}</th>
<th>{COMPARISON_LABEL}</th>
<th>Change</th>
<th>% Change</th>
<th>Signal</th>
</tr></thead>
<tbody>
</tbody>
</table>
</div>
</div>
<div id="drivers" class="section">
<div class="section-header" onclick="toggle('drv-body')">
<h2>What Drove the Movement</h2>
<span id="drv-body-icon">▾</span>
</div>
<div id="drv-body">
<table>
<thead><tr>
<th>Metric</th>
<th>Top Driver</th>
<th>Value This Period</th>
<th>Value Prior Period</th>
<th>Contribution</th>
</tr></thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
<footer>
Performance Briefing — {ORG_NAME} — Generated {GENERATED_DATE}<br>
<span style="opacity:.7">
Methodology: {PERIOD_TYPE}
· current {CURRENT_START_ISO}–{CURRENT_END_ISO}
· comparison {COMPARISON_START_ISO}–{COMPARISON_END_ISO}
· week starts {WEEK_START_DOW}
· fiscal year starts {FISCAL_YEAR_START_MONTH}
· tz {TIMEZONE}
· calendar source: {CALENDAR_SOURCE}
· metrics: {METRIC_IDS_CSV}
</span>
</footer>
<script>
function toggle(id) {
var el = document.getElementById(id);
var ic = document.getElementById(id + '-icon');
if (el.style.display === 'none') { el.style.display=''; ic.textContent='\u25be'; }
else { el.style.display='none'; ic.textContent='\u25b8'; }
}
</script>
</body></html>
第 7 阶段 — 交付简报
- 将 HTML 写入
/tmp/cja_executive_briefing_<YYYY-MM-DD_HHMMSS>.html - 使用
open /tmp/cja_executive_briefing_<YYYY-MM-DD_HHMMSS>.html打开 - 直接在聊天中输出叙述性要点,以便用户立即复制并粘贴到电子邮件或演示文稿中——HTML 是“附录”。
聊天中的格式:
Performance Briefing — Last Week vs Prior Week
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📈 Revenue: $1.24M (+8.2%) — Paid Search drove the majority of the gain.
📉 Conversion Rate: 2.1% (−0.4pp) — Mobile checkout declined; desktop stable.
➡ Sessions: 540K (+1.1%) — Essentially flat; organic offset email decline.
📈 Orders: 11,340 (+6.7%) — Product page improvements appear to be contributing.
⚠️ Bounce Rate: 43% (+2pp) — No clear driver identified; monitor next week.
Full briefing document: /tmp/cja_executive_briefing_<YYYY-MM-DD_HHMMSS>.html
语气和风格规则
- 写结果,不写活动。 写“收入增长了”,不要写“metrics/revenue 增加了”。
- 简洁地指出驱动因素。 写“付费搜索推动了增长”,不要写“Marketing Channel = Paid Search 在周期 A 的值高于周期 B”。
- 每条要点写一个句子。 最多两个句子。高管会快速浏览。
- 把最重要的发现放在开头。 不要层层铺垫才得出结论。
- 对坏消息直言不讳。 写“转化率下降了”,不要写“转化率出现了一些向下的变化”。
- 所有内容都要量化。 每条要点都必须包含数字。没有数据支撑的观点不属于高管沟通内容。
- 避免行话。 输出中不要出现“维度”“指标 ID”“数据视图上下文”或“MCP 工具调用”。
重要注意事项
- 仅限只读报告。 切勿修改指标、细分或项目。
- 使用业务语言,不要使用技术 ID。 将维度 ID(例如
variables/evar5)替换为其显示名称。叙述中绝不公开内部 ID。 - 始终醒目地注明日期范围。 高管需要了解背景——“上周”含义模糊;请写成“2026 年 4 月 7 日至 13 日”。
- 不要编造数据。 如果某项 KPI 不可用或报告未返回数据,请明确说明,而不是省略或估算。
- 简报只聚焦最重要的发现。 最理想的是 3–5 个 KPI 卡片和 2–3 条驱动因素;KPI 超过 8 项会削弱信息传达效果。
- 注明重要背景。 相关时,提及会影响指标的已知外部因素(营销活动、节假日、产品发布)。
- 呈现前验证数据。 如果 KPI 数值看起来异常,请通过第二次
runReport调用进行交叉核对。 - 使用客户品牌,不使用供应商品牌。 简报是客户关于自身业务的文档。在面向客户的简报中(标题、导语、叙述、表格、页脚或聊天内容),绝不要使用 “Adobe”、“CJA”、“Customer Journey Analytics” 或任何供应商/产品名称。红黑配色的页眉是报告中唯一允许使用的 Adobe 品牌元素。
交互示例
“为我撰写一份上周业绩的执行简报。”
- 设置: 使用
findDataViews确认数据视图。用户选择其主要数据视图。调用setDefaultSessionDataViewId。 - 范围: 确认报告周期(过去 7 天,即 2026 年 4 月 7 日至 13 日)和关键 KPI(收入、转化率、会话数、AOV)。
- 提取数据: 针对每项 KPI 运行
runReport,比较本周与上周,以及与去年同一周的数据。 - 起草叙述: 使用业务语言撰写 3–4 条高管要点:“收入为 240 万美元,环比增长 8%,这主要得益于付费搜索带来的转化量增长 15%。转化率下降 2 个百分点至 3.1%,这与 4 月 9 日推出的产品页面改版一致。”
- HTML 报告: 生成可直接打印的 HTML 简报,包含 KPI 卡片、叙述部分和驱动因素表格。打开文件。向用户提供 2 句话的摘要,并询问是否需要调整语气或范围。