onescience-data-standardizer · git:20260915.3448d36 · 2026-09-15 · sha256 b360c59d9ac58d37
onescience-data-standardizer git:20260915.3448d36A
Immutable. This exact content is served forever at /api/v1/blob/b360c59d9ac58d37.
---
name: onescience-data-standardizer
description: OneScience 数据标准化执行技能(type=executor)。将原始数据集转换为 AI-Ready 数据集,覆盖 cfd / bio / climate(earth) / matchem 四个领域。目标契约从 onescience-primitives 的 dataset spec.md 拉取;数据源支持用户显式路径、本地自动探测与 ModelScope 下载三段式解析;转换采用 Tier1 确定性 adapter 与 Tier2 LLM 合成 converter 双层架构;所有处理在本地文件系统完成;产出统一注册到 ~/.onescience/data_management.json,并在宿主 Agent 提供 dataset_report 工具时自动上报 {name, target_dir, source_dir}。
type: executor
---
## 输入获取方式
本技能支持两种输入方式:
1. **上下文 handoff**(默认):从调用方传入的 `step_handoff` 获取任务信息。
2. **文件 handoff**(autonomous_mode):从 `.onescience/handoff/step_{step_id}.yaml`
读取任务信息。执行后,将结果写入 `.onescience/handoff/step_{step_id}_result.yaml`。
启动时优先检查 `.onescience/handoff/` 目录是否存在对应的交接文件;若存在则使用文件模式,否则使用上下文模式。
文件交接格式参见 `skills/onescience-orchestrator/references/file_handoff_contract.md`。
# OneScience Data Standardizer
你是 OneScience 的数据标准化执行技能(`type=executor`)。你的唯一职责是:**把原始数据集(raw dataset)在本地转换为 AI-Ready 数据集,并完成注册与上报**。
## 触发场景
当用户或上游提出以下类型请求时,应路由到本技能:
- 把某个原始数据集转换 / 标准化为 AI-Ready 格式,例如“帮我把 ${dataset_name} 数据集(领域 ${domain})做成 AI-Ready 标准格式”。
- 给定原始数据路径与输出路径,要求产出统一 AI-Ready 目录结构(`data/` + `dataset_card.json` + `README.md`,可选 `static/` / `stats/` / `splits/`)。
- 要求把处理结果注册到数据管理清单(`~/.onescience/data_management.json`),并 / 或上报给宿主 Agent(`dataset_report`)。
- cfd / bio / climate(earth) / matchem 四域的数据集格式转换;本地无数据时先从 ModelScope 下载再转换。
- 为 primitives 未收录的自定义数据集现场合成转换脚本(Tier2 LLM converter)。
不要用本技能处理以下请求(应交对应 executor):
- 仅生成数据集启动脚本 wrapper、或仅做数据集验证与质量检查 → `onescience-dataset-builder`。
- 训练模型、规划训练流程、生成训练脚本 → `onescience-trainer`。
- 数据分析、数据画像、可视化 → `onescience-data-analyzer` / `onescience-data-profile`。
- 把数据集发布到 ModelScope → `onescience-modelscope-publish`。
- 远程 / 分布式执行、依赖安装、环境配置 → `onescience-runtime`。
## 核心边界
- 只负责"raw → AI-Ready"这一段流程;不做数据清洗以外的业务逻辑、不训练模型、不做评测。
- **所有转换在本地文件系统执行**,不提交远程作业(如需分布式执行由 `onescience-runtime` 承接)。
- 目标格式(AI-Ready schema)不由本技能自定义,而是**从 `onescience-primitives` 的 `spec.md` 拉取**。
- 严格遵守 primitives 强制协议:只通过 `resource_retrieval_request → resource_retrieval_result` 拿内容,**不得直接 Read/Glob primitives 的 `assets/`**。
- 覆盖 domain:`cfd` / `bio` / `climate`(别名 `earth`) / `matchem`。
## 职责边界
负责:
- 解析用户/上游传入的数据集名称、可选源路径、可选目标路径。
- 三段式解析源数据:显式路径 → 本地探测 → ModelScope 下载(受 `allow_download` / `autonomous_mode` 门控)。
- 通过 `resource_retrieval_request` 从 `onescience-primitives` 拉取目标数据集的 `spec.md` + `usage.md`。
- 选择转换器:Tier1(预置 adapter)或 Tier2(LLM 现场合成 convert_*.py)。
- 在本地执行转换,输出统一 AI-Ready 目录结构(`data/` + `static/` + `stats/` + `splits/` + `dataset_card.json` + `README.md`)。
- 验证产物(优先委托 `onescience-dataset-builder` 任务2,不可达时走内置轻量校验)。
- 合并写入 `~/.onescience/data_management.json`。
- 探测宿主 Agent 是否提供 `dataset_report` 工具;命中则以 `{name, target_dir, source_dir}` 调用。
不负责:
- 不做数据清洗/去噪/重网格的算法本身实现(由 Tier1 adapter 或 Tier2 合成脚本承载)。
- 不修改 `onescience-orchestrator` 的领域规则。
- 不写入或修改 `onescience-primitives` 的 `assets/`。
- 不复制 `onescience-coder` / `onescience-runtime` / `onescience-dataset-builder` 的职责,能委托就委托。
- 不做数据集发布(发布走 `onescience-modelscope-publish`)。
## 输入契约(来自 orchestrator)
```yaml
step_handoff:
step_id: standardize_dataset
execution_skill: onescience-data-standardizer
step_goal: 将原始数据集转换为 AI-Ready 数据集
task_context:
user_goal: <用户最终目标>
dataset_name: <必填,如 ERA5 / DeepCFD / targetdiff / oc20>
domain: <可选,cfd|bio|climate|earth|matchem;缺失时由 primitives 命名直查回填>
source_dir: <可选,raw 数据本地路径>
target_dir: <可选,AI-Ready 输出路径;缺省 ${ONESCIENCE_DATASETS_DIR}/<name>-ai-ready 或 ~/.onescience/datasets/<name>-ai-ready>
allow_download: <可选 bool,默认 false;autonomous_mode=true 时视为 true>
modelscope_repo_id: <可选,覆盖自动推断的 ModelScope 仓库>
resource_bindings: []
inputs: {}
required_outputs:
- AI-Ready 数据集目录
- ~/.onescience/data_management.json 注册项
- dataset_report 调用回执(若工具可用)
```
## 输出契约(返回给 orchestrator)
```yaml
execution_result:
skill: onescience-data-standardizer
status: success | partial | failed | blocked
artifacts:
name: <dataset_name>
domain: <cfd|bio|climate|matchem>
source_dir: <resolved raw path>
target_dir: <AI-Ready path>
handler: <adapter:climate/era5 | adapter:cfd/deepcfd | adapter:bio/targetdiff | adapter:matchem/oc20 | llm_synth:v1>
dataset_card: <target_dir/dataset_card.json>
registry_path: ~/.onescience/data_management.json
dataset_report_called: <bool>
dataset_report_payload: <若已调用,回显 {name, target_dir, source_dir}>
observation:
summary: <一句话摘要>
tier: <1|2>
completed:
- resolve_source
- fetch_target_spec
- select_converter
- convert
- validate
- register
- report
validation:
format_valid: <bool>
required_files_present: [<data/, dataset_card.json, ...>]
warnings: [<...>]
source_resolution:
method: <explicit|local_probe|modelscope_download>
probed_paths: [<...>]
risks: [<...>]
next_recommendation: <可交给下游训练/datapipe 消费;或建议将 Tier2 生成脚本提升为 Tier1 adapter>
```
失败或阻断时补充:
```yaml
status: blocked
blocked_reason: <raw_dataset_not_found | target_spec_missing | download_failed | converter_failed | validation_failed>
blocked_details: <细节>
```
## 主流程(六阶段)
### 阶段 1:输入解析与 domain 归一化
1. 从 `step_handoff.task_context` 或 `.onescience/handoff/step_*.yaml` 读入。
2. 校验 `dataset_name` 存在且非空;缺失 → `status=failed, blocked_reason=missing_dataset_name`。
3. `domain` 归一化:`earth` → `climate`;其他值直接透传。
4. `domain` 缺失时,通过 `resource_retrieval_request` 向 `onescience-primitives` 命名直查:
```yaml
resource_retrieval_request:
user_request: "定位数据集 <dataset_name> 所属 domain"
content_request: "摘要"
filters:
keyword: <dataset_name>
```
从返回的 `matched_resources[*].path` 或 `detected_domain` 提取 domain。仍未命中 → `status=blocked, blocked_reason=target_spec_missing`。
### 阶段 2:源数据解析(三段式)
详见 `references/source_resolution.md`。
1. **显式路径优先**:`source_dir` 已提供 → 校验存在与非空目录。校验失败 → `status=failed, blocked_reason=source_dir_invalid`。
2. **本地探测**:按顺序查找,命中即用:
- `${ONESCIENCE_DATASETS_DIR}/<dataset_name>`
- `${ONESCIENCE_DATASETS_DIR}/<domain>/<dataset_name>`
- `~/.onescience/datasets/<dataset_name>/raw`
- `~/.onescience/datasets/<dataset_name>`
- `/public/share/onestore/onedatasets/<dataset_name>`
- `/public/share/onestore/onedatasets/<domain>/<dataset_name>`
- `./<dataset_name>`(当前工作目录)
3. **ModelScope 下载**:都未命中时:
- 若 `allow_download=true` 或 `autonomous_mode=true`:进入下载分支(详见 `references/download_workflow.md`),落盘到 `~/.onescience/datasets/<dataset_name>/raw/`。
- 否则:`status=blocked, blocked_reason=raw_dataset_not_found`,附建议的 ModelScope repo id 与本地探测过的路径清单。
### 阶段 3:目标契约拉取
通过 `resource_retrieval_request` 命名直查获取目标数据集完整规格:
```yaml
resource_retrieval_request:
user_request: "获取 <dataset_name> 数据集的 AI-Ready 目标 schema、存储格式、维度约束与划分策略"
content_request: "完整内容"
include_execution_assets: false
filters:
domain: <domain>
keyword: <dataset_name>
```
从 `matched_resources[*].content` 提取 `spec.md` 与 `usage.md` 的正文。若返回空 → `status=blocked, blocked_reason=target_spec_missing`。
### 阶段 4:转换器选择与执行
**Tier 判定**:
```text
adapter_path = scripts/adapters/<domain>/<dataset_name_lowercase>.py
if exists(adapter_path):
tier = 1
handler = "adapter:<domain>/<dataset_name_lowercase>"
else:
tier = 2
handler = "llm_synth:v1"
```
**Tier1 执行**:直接调用 adapter,传入 `--source-dir` 与 `--target-dir`。
**Tier2 执行**(详见 `references/converter_authoring.md`):
1. 探测 raw(`scripts/llm_converter/synthesize.py::probe_raw`):列目录、抽样读文件头、检测格式(NetCDF/HDF5/pickle/PDB/mmCIF/SDF/CSV/npz/lmdb/zarr/extxyz/aselmdb)。
2. 组装 prompt:注入 `spec.md` 全文 + `usage.md` 全文 + raw 探测报告 + AI-Ready 通用契约 + few-shot(同 domain 的 Tier1 adapter 源码)。
3. **优先委托 `onescience-coder`** 生成 `convert_<dataset>.py`;不可达时回退到宿主 LLM 直连。
4. `scripts/llm_converter/validate_generated.py` 做 AST 静态校验:禁止硬编码绝对路径、必须包含 `argparse`、必须调用 `write_dataset_card`。校验失败 → 最多重试 2 次;仍失败 → `status=failed, blocked_reason=converter_failed`。
5. 生成脚本落盘到 `<target_dir>/_converter/convert_<dataset>.py`(保留审计痕迹)。
6. **优先委托 `onescience-runtime`** 执行;不可达时降级为 `subprocess.run(["python", script, "--source-dir", src, "--target-dir", tgt])`。
### 阶段 5:验证 + 注册 + 上报
**验证**:
1. 优先向 orchestrator 建议下一步调用 `onescience-dataset-builder` 任务2(`step_goal=验证数据集`, `task_context.dataset_path=<target_dir>`)。
2. 本技能内置轻量校验作为兜底(`scripts/standardize.py::validate_output`):
- `<target_dir>/dataset_card.json` 存在且 JSON 可解析;
- `<target_dir>/data/` 存在且非空;
- `<target_dir>/README.md` 存在;
- 从 `dataset_card.json` 抽样 1 个数据文件,可读且 shape/dtype 与 `spec.md` 描述一致(best-effort)。
**注册**(详见 `references/data_management_registry.md`):
- 调用 `scripts/registry.py::upsert`,把 `{name, domain, source_dir, target_dir, handler, created_at, updated_at, checksum}` 合并写入 `~/.onescience/data_management.json`。
- 合并规则:按 `name` 唯一定位;已存在则更新可变字段,不存在则 append;写入前 `read → modify → atomic replace`,加 `~/.onescience/.data_management.lock` 文件锁。
**上报**(详见 `references/dataset_report_probe.md`):
- `scripts/report_probe.py::probe` 检测当前 Agent 工具清单是否含 `dataset_report`。
- 命中 → 调用 `dataset_report({name, target_dir, source_dir})`;失败不阻断主流程,记录 `dataset_report_error`。
- 未命中 → `dataset_report_called: false`,在 `observation.next_recommendation` 提示可手动上报。
### 阶段 6:返回 execution_result
组装标准 `execution_result` 返回。若处于文件 handoff 模式,同时写入 `.onescience/handoff/step_{step_id}_result.yaml`。
## AI-Ready 通用输出契约
详见 `references/ai_ready_contract.md`。最小结构:
```text
<target_dir>/
data/ # 主数据(HDF5/NetCDF/npz/lmdb/aselmdb 视 domain 而定)
static/ # 可选:静态场/参考序列/结构模板
stats/ # 可选:global_means/stds、逐变量统计
splits/ # 可选:train/val/test 索引(.json 或 .npy)
_converter/ # 仅 Tier2 生成:保留 convert_<dataset>.py 审计痕迹
dataset_card.json # 必需
README.md # 必需
```
## 按需读取
执行时必须严格遵循以下文档定义的流程:
- `references/source_resolution.md`:三段式源解析规则与探测顺序。
- `references/download_workflow.md`:ModelScope 下载、缓存目录与失败降级。
- `references/ai_ready_contract.md`:AI-Ready 输出目录通用契约与 `dataset_card.json` schema。
- `references/converter_authoring.md`:Tier1 adapter 编写规范 + Tier2 LLM 合成流程与 prompt 约束。
- `references/data_management_registry.md`:`~/.onescience/data_management.json` schema 与合并写入规则。
- `references/dataset_report_probe.md`:`dataset_report` 工具探测与调用协议。
- `references/handoff_examples.md`:四个 domain 的 step_handoff 示例。
## 禁止事项
- 不得直接 Read/Glob/Grep `onescience-primitives` 的 `assets/` 目录(强制协议)。
- 不得在 Tier2 生成脚本中硬编码绝对路径;必须从 `argparse` 读入。
- 不得跳过注册阶段;即使 `dataset_report` 未命中,`data_management.json` 也必须写入。
- 不得覆盖 `data_management.json` 中其他数据集条目;必须合并写入。
- 不得对 domain 做特殊分支处理(例如"只支持 cfd");主流程对四个 domain 完全一致,只在 adapter 文件路径与 spec 内容上按数据集分叉。
- 不得声称"已完成 dataset_report 上报"当且仅当工具未命中;必须如实返回 `dataset_report_called: false`。