skills/ppt-station-skill/reference/job-schema.md
wangyitong a65adcc2e5 Initial commit: merged, deduplicated, and vetted skill collection
Sources: extracted from two upstream archives (skill-repo, skills-main),
merged with the following policy:

- 15 broken symlinks (pointing to /Users/jameslee/.cc-switch/skills or
  ../../.agents/skills on a foreign machine) discarded
- 3 real name collisions with identical content (ai-pair, ifind-http-api,
  zhipu-websearch) kept as one copy
- Functional overlaps deduped keeping the strongest variant:
  - docx family: kept docx (official, full toolchain) + docx-cn
    (GB/T 9704 Chinese official-document constants),
    dropped docx_writer (no scripts, name collided with docx)
  - humanizer family: kept humanizer-zh (6 zh reference docs),
    dropped humanizer (en, redundant for CN workflow)
- Skills that only ran in a foreign environment removed:
  ablemind-ops, app-publish, hlb-design-system, openclaw-adj-skill,
  claude-driver
- alphapai excluded from this public repo because its SKILL.md hard-coded
  live credentials

Result: 25 skills, 572 files, ~7.5 MB.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 14:47:12 +08:00

439 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Job JSON 完整 Schema
Job JSON 是 PptEngine 的声明式配置格式,支持两种模式:
- **template 模式**(默认):基于 PPT 模板 + slides 配置进行占位符替换
- **composer 模式**(推荐):基于 PageComposer + pages 配置从零构建 PPT
## 顶层字段
| 字段 | 必填 | 说明 |
|------|------|------|
| `mode` | 否 | `"template"` (默认) 或 `"composer"` |
| `template` | 条件 | template 模式必填 |
| `slides` | 条件 | template 模式必填 |
| `theme` | 条件 | composer 模式用,默认 `"jp_finance"` |
| `pages` | 条件 | composer 模式必填 |
| `datasources` | 否 | 数据源配置(两种模式共用)|
| `transforms` | 否 | 数据转换配置(两种模式共用)|
| `params` | 否 | 自定义参数 |
| `output` | 是 | 输出配置 |
## Composer 模式 annotated skeleton
```json
{
"mode": "composer",
"theme": "jp_finance", // THEMES 中的名称
"datasources": {
"数据源名称": {
"type": "csv", // "csv" | "xlsx" | "tushare"
// ... 类型相关字段见下方
}
},
"transforms": { // 可选
"转换后名称": {
"from": "数据源名称",
"ops": [{"type": "sort", "sort_by": ["trade_date"]}]
}
},
"pages": [ // 页面列表(按顺序生成)
{
"layout": "title_dark", // LAYOUT_REGISTRY 中的布局名称
"data": { // 传给布局函数的 data dict
"title": "报告标题",
"date": "2026-02"
}
},
{
"layout": "chart_full",
"data": {
"title": "营收与利润",
"source": "revenue_df", // ← 引用 datasources/transforms 中的名称
"categories_col": "年度",
"series_config": [
{"key": "营收", "name": "营收(亿元)", "type": "bar", "axis": "primary"},
{"key": "利润", "name": "利润(亿元)", "type": "line", "axis": "secondary"}
],
"style_config": {"color_scheme": "jp_finance"},
"layout_config": {
"legend_config": {"font_size_pt": 9},
"value_axis_config": {"number_format": "#,##0"}
}
}
}
],
"output": {
"path": "output/report.pptx",
"overwrite": true,
"add_metadata": true
}
}
```
### source 引用解析规则
引擎在渲染时自动将 `source` 引用解析为实际 DataFrame
1. **顶层 source**`data.source` → `data.df`(替换为 DataFrame
2. **嵌套 source**`two_charts``data.left.source` / `data.right.source` → 各自的 `df`
3. 引用范围:可引用 `datasources``transforms` 中的任意 key
### style_config / layout_config 的 JSON 表达
- `style_config`:直接传 `StyleConfig` 构造参数的 dict`{"color_scheme": "jp_finance", "line_width_pt": 2.0}`
- `layout_config`:支持嵌套子对象:
- `legend_config``LegendConfig` 参数
- `value_axis_config` / `secondary_value_axis_config``ValueAxisConfig` 参数
- `category_axis_config``CategoryAxisConfig` 参数
- `date_axis_config` → 预设名字符串:`"daily"`, `"weekly"`, `"biweekly"`, `"monthly"`, `"quarterly"`, `"yearly"`
## Template 模式 annotated skeleton
```json
{
"template": {
"path": "aim/aim03.pptx", // 模板路径(相对于 ppt-st 项目根,或绝对路径)
"master": null, // 母版名称(可选)
"notes": null // 备注(可选)
},
"datasources": {
"数据源名称": { // 自定义名称,后续 source 字段引用
"type": "csv", // "csv" | "xlsx" | "tushare"
// ... 类型相关字段见下方
}
},
"transforms": { // 可选:数据转换
"转换后名称": {
"from": "数据源名称", // 字符串或数组(多源 concat
"ops": [ // 有序操作列表
{"type": "sort", "sort_by": ["trade_date"]}
]
}
},
"slides": [ // 幻灯片列表(按顺序对应模板页)
{
"id": "slide_1", // 唯一标识
"layout": null, // 版式名null 使用模板现有页)
"texts": [ // 文本替换
{"target": "文本框名", "value": "替换值(支持 Jinja2"}
],
"tables": [ // 表格渲染
{"target": "表格名", "source": "数据源名", "columns": ["col1"], "header": ["列1"]}
],
"charts": [ // 图表渲染
{
"mode": "update", // "create" | "update" | "excel_embedded"
"target": "图表名", // update 模式下模板中的图表名称
"source": "数据源名",
"categories": "日期列名",
"series": [
{"key": "列名", "name": "显示名", "axis": "primary"}
]
}
]
}
],
"params": {}, // 自定义参数(传入渲染上下文)
"output": {
"path": "output/report.pptx", // 输出路径
"overwrite": true,
"add_metadata": true // 是否添加生成信息到 PPT 元数据
}
}
```
## DataSource 字段表
### type: "csv"
| 字段 | 必填 | 说明 |
|------|------|------|
| `path` | 是 | CSV 文件路径(相对于 data_dir 或绝对路径)|
| `encoding` | 否 | 编码,默认 `utf-8` |
### type: "xlsx"
| 字段 | 必填 | 说明 |
|------|------|------|
| `path` | 是 | Excel 文件路径 |
| `sheet_name` | 否 | 工作表名,默认第一个 |
| `encoding` | 否 | 编码,默认 `utf-8` |
### type: "tushare"
| 字段 | 必填 | 说明 |
|------|------|------|
| `api_name` | 否 | API 接口名,默认 `index_daily`。支持 `index_daily`, `pro_bar` |
| `ts_code` | 是 | 股票/指数代码,如 `600519.SH`, `000300.SH` |
| `start_date` | 否 | 起始日期 `YYYYMMDD`,默认一年前 |
| `end_date` | 否 | 结束日期 `YYYYMMDD`,默认今天 |
| `fields` | 否 | 返回字段列表 |
前置条件: 环境变量 `TUSHARE_TOKEN``.env` 文件中配置。
## TransformOp 字段表
每个 op 是 `transforms[name].ops[]` 数组中的一项。
### type: "groupby"
| 字段 | 必填 | 说明 |
|------|------|------|
| `by` | 是 | 分组列名列表 |
| `agg` | 是 | 聚合方式 `{"列名": "sum/mean/count/..."}` |
### type: "pivot"
| 字段 | 必填 | 说明 |
|------|------|------|
| `index` | 是 | 行索引列名 |
| `columns` | 是 | 列索引列名 |
| `values` | 是 | 值列名 |
### type: "merge"
**未实现** — 会抛 `NotImplementedError`。用 `from: [src1, src2]` 做 concat 替代。
### type: "compute"
| 字段 | 必填 | 说明 |
|------|------|------|
| `expr` | 是 | pandas eval 表达式,如 `"close / close.iloc[0] - 1"` |
| `output_col` | 是 | 输出列名 |
### type: "filter"
| 字段 | 必填 | 说明 |
|------|------|------|
| `condition` | 是 | pandas query 表达式,如 `"close > 100"` |
### type: "sort"
| 字段 | 必填 | 说明 |
|------|------|------|
| `sort_by` | 是 | 排序列名列表 |
| `ascending` | 否 | 是否升序,默认 `true` |
### type: "rename"
| 字段 | 必填 | 说明 |
|------|------|------|
| `map` | 是 | 列名映射 `{"旧名": "新名"}` |
## SlideSpec
| 字段 | 必填 | 说明 |
|------|------|------|
| `id` | 是 | 唯一标识 |
| `layout` | 否 | 版式名称null 使用模板现有页面)|
| `texts` | 否 | 文本替换列表 `[{target, value}]` |
| `tables` | 否 | 表格渲染列表 `[{target, source, columns, header?, number_format?}]` |
| `charts` | 否 | 图表渲染列表(见 ChartSpec|
## ChartSpec
| 字段 | 必填 | 说明 |
|------|------|------|
| `mode` | 否 | `"create"` / `"update"` / `"excel_embedded"`,默认 `"update"` |
| `target` | 条件 | update 模式下的模板图表名称 |
| `target_placeholder` | 条件 | create/excel_embedded 模式下的占位符名 |
| `source` | 是 | 数据源名称(引用 datasources 或 transforms 的键)|
| `categories` | 是 | 分类列名 |
| `series` | 是 | 系列配置 `[{key, name, axis?}]` |
## ComposerPageSpeccomposer 模式)
| 字段 | 必填 | 说明 |
|------|------|------|
| `layout` | 是 | LAYOUT_REGISTRY 中的布局名称 |
| `data` | 是 | 传给布局函数的 data dict各布局字段见下表|
### 各布局的 data 字段
| 布局 | 必填字段 | 可选字段 |
|------|---------|---------|
| `title_dark` | `title` | `subtitle`, `date` |
| `title_light` | `title` | `subtitle`, `date` |
| `kpi_cards` | `title`, `cards: [{label, value}]` | `cards[].change`, `cards[].color` |
| `chart_full` | `title`, `source`, `categories_col`, `series_config` | `subtitle`, `style_config`, `layout_config` |
| `chart_text` | `title`, `source`, `categories_col`, `series_config`, `text_body` | `text_title`, `text_bullets`, `style_config`, `layout_config` |
| `two_charts` | `title`, `left: {source, categories_col, series_config}`, `right: {...}` | `left_title`, `right_title` |
| `comparison_table` | `title`, `headers`, `rows` | |
| `bullet_points` | `title`, `items: [{icon, label, desc}]` | |
| `section_divider` | `title`, `number` | |
| `conclusion_dark` | `verdict` | `items` |
### series_config 字段composer 模式)
| 字段 | 必填 | 说明 |
|------|------|------|
| `key` | 是 | DataFrame 列名 |
| `name` | 是 | 图表中显示的系列名称 |
| `type` | 否 | `"bar"`, `"line"`, `"area"`(默认按引擎决定)|
| `axis` | 否 | `"primary"` (左轴) 或 `"secondary"` (右轴) |
## 示例: Composer 模式完整版
```json
{
"mode": "composer",
"theme": "jp_finance",
"datasources": {
"revenue": {"type": "csv", "path": "data/revenue.csv"},
"stock": {
"type": "tushare",
"api_name": "pro_bar",
"ts_code": "600519.SH",
"start_date": "20240101",
"end_date": "20241231"
}
},
"transforms": {
"stock_sorted": {
"from": "stock",
"ops": [{"type": "sort", "sort_by": ["trade_date"]}]
}
},
"pages": [
{
"layout": "title_dark",
"data": {"title": "贵州茅台2024年度分析", "date": "2024-12"}
},
{
"layout": "kpi_cards",
"data": {
"title": "核心指标",
"cards": [
{"label": "营收", "value": "1,505亿", "change": "+17.2%"},
{"label": "净利润", "value": "747亿", "change": "+19.1%"},
{"label": "毛利率", "value": "91.5%", "change": "+0.3pp"}
]
}
},
{
"layout": "chart_full",
"data": {
"title": "营收与利润趋势",
"source": "revenue",
"categories_col": "年度",
"series_config": [
{"key": "营收", "name": "营收(亿元)", "type": "bar", "axis": "primary"},
{"key": "净利润", "name": "净利润(亿元)", "type": "line", "axis": "secondary"}
],
"style_config": {"color_scheme": "jp_finance"},
"layout_config": {
"legend_config": {"font_size_pt": 9, "font_name": "黑体"},
"value_axis_config": {"number_format": "#,##0"},
"secondary_value_axis_config": {"number_format": "#,##0"}
}
}
},
{
"layout": "two_charts",
"data": {
"title": "股价与成交量",
"left_title": "日收盘价",
"right_title": "日成交量",
"left": {
"source": "stock_sorted",
"categories_col": "trade_date",
"series_config": [{"key": "close", "name": "收盘价", "type": "line", "axis": "primary"}],
"layout_config": {"date_axis_config": "monthly"}
},
"right": {
"source": "stock_sorted",
"categories_col": "trade_date",
"series_config": [{"key": "vol", "name": "成交量(手)", "type": "bar", "axis": "primary"}],
"layout_config": {"date_axis_config": "monthly"}
}
}
},
{
"layout": "conclusion_dark",
"data": {"verdict": "茅台护城河坚固,品牌溢价持续"}
}
],
"output": {"path": "output/moutai_2024.pptx"}
}
```
## 示例: Template 模式最小版
```json
{
"template": {"path": "aim/aim03.pptx"},
"datasources": {},
"slides": [
{
"id": "cover",
"texts": [
{"target": "标题", "value": "2024年度报告"}
]
}
],
"output": {"path": "/tmp/minimal.pptx"}
}
```
## 示例: Template 模式完整版(含 Tushare + 变换 + 图表)
```json
{
"template": {"path": "aim/aim03.pptx"},
"datasources": {
"stock": {
"type": "tushare",
"api_name": "pro_bar",
"ts_code": "600519.SH",
"start_date": "20240101",
"end_date": "20241231"
},
"index": {
"type": "tushare",
"api_name": "pro_bar",
"ts_code": "000300.SH",
"start_date": "20240101",
"end_date": "20241231"
}
},
"transforms": {
"merged": {
"from": ["stock", "index"],
"ops": [
{"type": "sort", "sort_by": ["trade_date"]},
{"type": "rename", "map": {"close": "收盘价"}}
]
}
},
"slides": [
{
"id": "cover",
"texts": [
{"target": "标题", "value": "贵州茅台2024年度分析"},
{"target": "日期", "value": "2024-12-31"}
]
},
{
"id": "chart_page",
"charts": [
{
"mode": "update",
"target": "当年收益率走势图",
"source": "merged",
"categories": "trade_date",
"series": [
{"key": "收盘价", "name": "茅台收盘价", "axis": "primary"}
]
}
]
}
],
"params": {"year": 2024},
"output": {
"path": "output/moutai_2024.pptx",
"overwrite": true,
"add_metadata": true
}
}
```