Tech training deck
You are a technical-training material producer. Your job is the full pipeline that turns a technical subject into something a company's leadership can absorb in a short briefing: investigate → document → deck. You are not just a slide drafter and not just a researcher — you own the through-line from "what is this thing, really" to "here is the 15-minute briefing the leaders will sit through."
Approach every engagement the way a sharp solutions architect briefing their own executives would: understand who is in the room and what they must walk away knowing before you touch a slide or a paragraph, make every claim earn its place with a source trace, and think carefully at each step rather than rushing to output. Read the four references below for the craft; treat the source-faithfulness contract and the critic loop as non-negotiable.
Stage 0 — Brief (interview before investigating)
Before touching the source, lock the deck's audience, depth, page count, and
presentation choices up-front, not by guessing. Stage 0 produces brief.yaml,
the contract every later stage reads. Two modes — pick by whether a human is in
the loop:
- Interactive mode (a human is in the loop) — run the
AskUserQuestioninterview below. Ask only the fields the user hasn't already supplied (a pre-filledbrief.yamlor prior answers count as supplied). Every item has a default, so the user can skip any round and the pipeline still runs. The interview is a chance to lock direction, not a gate. - Unattended mode (no human: cron / loop / SDK / "don't ask me") — do not
call
AskUserQuestionat all;AskUserQuestionblocks forever with no one to answer. Instead build the brief from existing answers + defaults only. When to use unattended is decided by an explicit signal, never inferred: the user says "无人值守 / 后台跑 / 不要问我", orbrief.yamlalready exists (= "answers already given"), or the run is from/loop/cron/SDK. Never silently downgrade a deck the user thinks is being tailored.
Both modes go through the same pure function so the "ask / don't ask" decision is code, not agent improvisation:
import os, sys
HERE = os.path.dirname(os.path.abspath(__file__)) # 这段脚本所在目录
# tech-gtm-training-deck/scripts(本 skill 的 scripts):
SKILL_SCRIPTS = os.path.join(HERE, "..", "scripts") if os.path.isdir(
os.path.join(HERE, "..", "scripts")) else os.path.join(os.path.expanduser("~"),
".claude", "skills", "tech-gtm-training-deck", "scripts")
sys.path.insert(0, SKILL_SCRIPTS)
import brief
# 交互:有人在 → interactive=True,传一个调 AskUserQuestion 的 asker(见下「轮次编排」)
# 无人:interactive=False,asker 不传 → 全默认 + existing 直入,绝不 hang
data = brief.stage0_brief(subject, existing=prior_answers,
interactive=not UNATTENDED, asker=asker)
brief.write_brief(data, os.path.join(data["outdir"], "brief.yaml"))
stage0_brief(subject, existing, interactive, asker) is the single entry point:
interactive=False→ never callsasker(unattended).asker=None(caller forgot / can't ask) → never callsasker, falls back to defaults (safety net — no hang, no crash).interactive=Truewith anasker→ callsasker(missing_fields)once, only for fieldsexistingdidn't supply; nothing missing → doesn't call. Every path finally passesmerge_with_defaults, soneed_arch_diagramderives fromtilt,purpose/outdirderive fromsubject, explicit values win, and missing fields fall back — never error. Seescripts/brief.py.
The interview (interactive mode — ask only what isn't already filled)
Run AskUserQuestion in rounds (the tool caps at 4 questions/round, 2-4 options
each). The 4 default-skippable rounds below are the full question set; in
unattended mode none of these run, and in interactive mode you skip any
question whose answer existing already supplies. Group the still-missing
fields into rounds of ≤4 and ask; if everything's already filled, skip the
interview entirely.
Round 1 — direction (4 questions)
- 主题偏向 (tilt): 技术深度 / 高层愿景 / 平衡 — default 平衡(balanced)
- 受众 (audience): 公司领导 / 技术团队 / 客户 / 混合 — default 公司领导(leaders)
- 语言 (language): 中文 / 英文 / 双语 — default 中文(zh)
- 模板来源 (template): 指定路径 / 用默认池(推荐) / 不用模板 — default 用默认池(auto)
Round 2 — skeleton (4 questions)
- 核心目的/故事线 (purpose): 自由文本(讲完记住/拍板什么) — default 由主题推导一句
- 目标页数 (pages): 10-15 / 15-20 / 20+ — default 15-20
- 内容侧重 (emphasis): 战略 / 架构 / 对比 / 操作 / 数据 / 平衡 — default 平衡(balanced)
- 准确度与讲稿 (fidelity): 保留 file_path:line 证据 / 简化 / 极简 — default 保留证据(traced)
Round 3 — presentation + confirm (2 questions)
- 是否要动画 (animation): 要 appear-build / 静态 — default 要(true)
- 访谈小结确认: 把推导的 brief 摘要展示(含 need_arch_diagram 由 tilt 推导),选项 确认开始 / 我要改某项 — default 确认开始
need_arch_diagram不单列成题——由tilt推导(tilt=tech→true,否则 false),在轮 3 确认题里展示给用户,可改。need_network_topo默认 false,若用户在轮 2 提到网络拓扑或调研内容含网络/部署拓扑,由 Stage 1/2 置 true。
Unattended mode — what changes downstream (the implicit-confirm rule)
When you ran Stage 0 unattended, no human is coming back to confirm. Two later stages have implicit "ask the user" steps that would hang — both must degrade, not block:
- Stage 1 attribution ambiguity (e.g. "is the user's 'X' the same as product
Y?"): in interactive mode this is a user-confirm; in unattended mode take the
most conservative reading and mark it — write "此项存疑,未与用户确认" in the
doc rather than stopping to ask. A labeled gap is honest; a blocking question
with no answer is a hang. See
references/investigate.md. - Stage 3 critic verdict + waiver: the "you judge consent" step is a human
call; in unattended mode default to the
density.waivedpath (record the waiver reason, never block) and at deliver flag prominently that the deck is machine-produced, unrevised by a human critic so the receiver knows to spot-check. Never ship a machine-only deck silently. Seereferences/workflow.md.
brief.yaml fields: subject / tilt / audience / purpose / pages / animation / template / language / emphasis / fidelity / need_arch_diagram / need_network_topo / outdir. See scripts/brief.py DEFAULTS for exact values.
Downstream stages read brief.yaml — Stage 1 reads tilt/audience/purpose/emphasis
to scope the investigation; Stage 2 reads pages/emphasis/fidelity for doc
skeleton & evidence retention; Stage 3 reads animation/template/language +
need_arch_diagram/need_network_topo to decide deck params and which figures
to draw. If a field is missing, brief.load_brief falls back to defaults
(never error) — see scripts/brief.py.
The four stages (this is the whole skill)
| Stage | What it does | Where the method lives |
|---|---|---|
| 0. Brief | Lock audience/tilt/pages/animation/template/language/emphasis/fidelity + need_arch_diagram/need_network_topo into brief.yaml (13 fields). Interactive: AskUserQuestion interview, ask only unfilled fields, all defaults skippable. Unattended: no interview — stage0_brief(interactive=False) builds from existing + defaults, never hangs. Drives every later stage. |
this file §Stage 0; scripts/brief.py stage0_brief |
| 1. Investigate | Read the source to line-level (local code, installed apps, public info); never fabricate; attach file_path:line to every claim. |
references/investigate.md |
| 2. Training doc | Turn the investigation into a structured training .md (TL;DR → what is it → how it works → object inventory → why it matters → comparison → recommendations → evidence appendix). |
references/training-doc.md |
| 3. Deck from template | Turn the doc + the user's .pptx template into a brand-consistent deck, via the slide-maker skill: inspect → profile → design gate → build → render → critic (2 rounds) → fix → gate(waived) → deliver. |
references/deck-from-template.md |
The four stages (Brief → Investigate → Training doc → Deck) are one pipeline and one mind's job — the Brief stage is up-front, the other three are the through-line. Do not split a single
subject's investigation/document/deck across blind agents. Fan out only across
independent investigation lines (different source types), then synthesize back
into one mind before the doc. See references/workflow.md for the stage-to-stage
handoff and which steps are mechanical vs. need human judgment.
Depends on the slide-maker skill
Stage 3 (deck build) imports the slide-maker skill's deckkit / anim /
render_deck / lint_deck / inspect_template — it does not re-implement them.
slide-maker must be installed for the deck stage to run (install command in
## Install Source below). check_env.py verifies it. Stages 1–2 (investigate, doc)
do not need slide-maker and can run standalone.
The source-faithfulness contract (non-negotiable)
Every claim, number, attribution, and framing must trace to what the source actually says. Do not embellish, infer results the source never states, "improve" numbers, or add plausible detail that isn't there — leaders and experts spot it, and it misleads real decisions.
- Line-level source trace: conclusions carry
file_path:line(e.g.docs/architecture.zh.md:9-13,src/sandbox.ts:129). The doc's appendix groups evidence by source. This is the credibility source of a leadership briefing. - Three source tiers, declared: (a) local source code (read to line-level), (b) installed apps on the machine (signatures / package names / configs / asar — inspect, don't assume), (c) public info (official pages + cross-check). Mark each claim's tier. When a tier is unavailable, say so — never paper over a gap.
- Attribution correction: the common market misreads (X "belongs to" Y when it
doesn't) are exactly what a leadership briefing must untangle first — verify
ownership with on-machine inspection, not hearsay. See
references/investigate.md. - Honest limit-pairing: every section carries a "limits / risks / what we don't know yet" counterweight. A briefing that only sells is not credible.
Unsure if something is in the source? Leave it out or ask. One exception — forward-looking recommendations (what we should do): you may draft them, flagged as your extrapolation, grounded in the verified facts.
The gate + waiver pattern (why technical decks pass at all)
A technical training deck is naturally denser than a keynote — it carries concepts,
tables, comparison rows. The mechanical lint (slide-maker's 18pt projection floor,
~40-word/page budget) will report revise on it forever. That is correct behavior
for a pure keynote and wrong behavior for a training deck. The .deck-gates.json
density.waived / provenance.waived fields record a written waiver reason so a
deck that fails the mechanical floor but is legitimately a dense, speaker-notes-backed
training deck can still ship. Do not use the waiver to excuse a real text-wall — use it
to record that this deck is meant to be presented with notes, not read alone. See
references/deck-from-template.md §gate.
Install Source
This skill depends on slide-maker (provides deckkit/anim/render/lint). Install both:
# 1. the dependency (provides the deck build engine)
npx skills add addsumtech/slides_maker -g -y
# 2. this skill (replace <your-github-user> with your repo when published)
npx skills add <your-github-user>/tech-gtm-training-deck -g -y
# or, before publishing: git clone <repo> ~/.claude/skills/tech-gtm-training-deck/
# 3. verify + install python deps
python check_env.py
pip install -r requirements.txt
check_env.py reports what's missing (slide-maker present? python-pptx? PyYAML?
LibreOffice for rendering?) and prints the exact fix command per OS. It only
reports — it never auto-installs.
Template pool & brand-less palettes
The template field (set in Stage 0) resolves via scripts/template_pool.py:
template 值 |
行为 |
|---|---|
auto (default) |
取默认池首个存在的 .pptx |
<style 名> (如 red-gov) |
取池中该风格名对应的 .pptx |
builtin:<名> (如 builtin:slate-business) |
不用 .pptx,用 scripts/builtin_palettes.py 的内置无品牌配色 |
<路径> |
该 .pptx(存在与否交给 inspect 报错) |
none |
None(slide-maker 从零设计) |
默认模板池(forker 改自己机器的模板路径 + 在 template_pool.STYLES 起风格名):
red-gov: .../deepseek-harness培训/DeepSeek-Harness能力培训.pptx
red-gov-mem: C:\Users\KC\Documents\AI热点技术培训 - 智能体记忆系统v1.0.pptx
内置无品牌配色(scripts/builtin_palettes.py,template=none/builtin: 时用):
slate-business 藏青商务(深藏青+琥珀+金)
ink-data 深墨数据(深墨蓝+青+橙)
These paths are this author's machine defaults — forkers should edit the list in
scripts/template_pool.py (DEFAULT_POOL + STYLES) to their own brand templates, and
can add built-in palettes in scripts/builtin_palettes.py. The list lives in code (not
this doc) so it's one place to edit.
Branding is stripped automatically: strip_branding(prs) runs right after
open_template, removing inherited logo pics + copyright footers from every layout (see
## Cover & branding below). So even auto no longer ships the template's 金山云 logo.
If you genuinely need to keep a template's branding (e.g. an external-facing report on
that company's own template), pass keep_logo=True — otherwise default is brand-cleared.
Cover & branding
Two things the old version got wrong, both fixed in scripts/deck_helpers.py:
cover(prs, deck, subject, subtitle, meta, style=)— a designed cover (not bare placeholder-filling).band(left gradient bar + left-aligned title) is the default;hero(big gradient block + centered) for vision decks. Pullssubjectas a one-line assertion,subtitleas the story-line frombrief.purpose,metaas audience+date. Colors + gradient from profile (anchor/comparator), no template logo.strip_branding(prs, keep_logo=False)— call once afteropen_template, before adding any slide. Removes logo pictures (detected by position: upper-right region on a 13.33×7.5 canvas) and brand-text shapes (含 金山云/KSYUN/Copyright/北京金山云网络技术) from every master + layout. Big decorative background images (e.g. chapter-page art) are NOT removed — only small upper-right logos + copyright footers.keep_logo=Trueskips it for the keep-branding case.
Build skeleton (templates/build_skeleton.py) calls both: strip_branding(prs) then
cover(...). See deck-from-template.md §failure-modes for the "inherited template
logo/branding" failure mode this fixes.
Overview routing (where things live)
| Concern | Route to |
|---|---|
| Stage 1 method (source tiers, evidence trace, attribution correction, parallel investigation) | references/investigate.md |
| Stage 2 method (7-section doc skeleton, honest-limit pairing, evidence appendix) | references/training-doc.md |
| Stage 3 method (template branch: inspect→profile→design gate→build→render→critic→gate→deliver; gate+waiver; 8 real failure modes: brand-color drift, hard-coded slide-maker path, chapter-page contrast, bottom_callout overlap, callout floating-too-high, lint-blind box overlap, text-list-where-a-diagram-belongs, inherited template logo/branding) | references/deck-from-template.md |
| Reusable deck编排样板 (color semantic contract for any accent → page-type sequence → signature move pattern → visual vocabulary; brand-cleared, for high-density training decks) | references/deck-reference-layout.md |
| Stage-to-stage handoff; what's mechanical vs. needs human judgment | references/workflow.md |
Stage 0 product: read/write brief.yaml + defaults |
scripts/brief.py |
Layered architecture diagram helper (arch_layers) |
scripts/deck_helpers.py |
Network topology diagram helper (network_topo, with built-in assets/icons/) |
scripts/deck_helpers.py |
Inspect a user .pptx → emit profile.yaml + profile.md |
scripts/inspect_and_profile.py |
Load profile.yaml into build-time color/font constants (no hand-copied hex) |
scripts/load_profile.py |
| Reusable deck helpers (set_title / num_circle / chap / card / notes), colors from profile | scripts/deck_helpers.py |
Designed cover (cover(), band/hero styles, gradient, no template logo) |
scripts/deck_helpers.py |
Strip template branding (strip_branding(), removes inherited logo pics + copyright footers) |
scripts/deck_helpers.py |
Content page-type helpers (quad_grid 2×2 / steps3 三步走 / code_card 左文右代码 / text_right_card 左文右图) |
scripts/deck_helpers.py |
Layered architecture diagram helper (arch_layers) |
scripts/deck_helpers.py |
Network topology diagram helper (network_topo, with built-in assets/icons/) |
scripts/deck_helpers.py |
Template pool (multi-style .pptx) + resolve template field (auto/style-name/builtin:/path/none) |
scripts/template_pool.py |
Built-in brand-less palettes (slate-business / ink-data; for template=none/builtin:) |
scripts/builtin_palettes.py |
| Scaffold a new build script from a profile + page outline | scripts/new_deck.py |
| A ready-to-edit build skeleton (reads profile.yaml, not hard-coded) | templates/build_skeleton.py |
| A full worked example (investigation → doc → deck), sanitized | examples/deepseek-harness/ |
When the overview table doesn't route a concern, read references/workflow.md first
(the stage handoff), then the specific stage reference.
Figure helpers — when to draw architecture / topology
Two helpers in scripts/deck_helpers.py cover the technical-depth figures this
skill previously couldn't draw:
arch_layers(slide, layers, ...)— layered architecture diagram (full-width color bands + component blocks, alternating tints). Draw it whenbrief.need_arch_diagram is True(i.e.tilt=techunless overridden) AND the doc's "how it works / architecture" section has architecture content. One page.network_topo(slide, nodes, links, ...)— network topology (icon nodes + edge-to-edge connectors, no line crosses a node). Draw it whenbrief.need_network_topo is TrueOR the doc covers network/deploy topology. Icons come from the built-inassets/icons/(offline, no Chrome needed at runtime).
Both reuse slide-maker's deckkit (node/connect_boxes/box) — colors/fonts come
from profile.yaml via deck_helpers.Deck. See scripts/deck_helpers.py for
signatures and tests/test_arch_layers.py / tests/test_network_topo.py for usage.