fix: pipeline排序/runDic映射/label-master repeatable/达标优先级

- pipeline items 按 first_ts 自然时间排序,去掉 hardcoded section_order
- augment step-detail 去掉 R{n-1} 偏移,直接用本轮 runDic(与 resolve_run_ids.sh 实际行为对齐)
- 加 BundledSkill.repeatable 字段,label-master 标记 repeatable:true 跳过 duplicate detection
- SKILL.md/program.md: 目标集≥95%最高优先级,未达标前其他集合轻微下降不回滚
- SKILL.md/program.md: 禁止正则脚本替代 label-master 语义复核
- program.md: 每轮 SFT 前必须展示训练数据组成
- resolve_run_ids.sh: 修正注释(SFT_RUNDIC = 当轮 eval workflow id)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
wangsenhao
2026-05-26 14:10:32 +08:00
parent d2bb525e38
commit a09d4afacd
7 changed files with 103 additions and 32 deletions
+1
View File
@@ -4,6 +4,7 @@ description: 标签大师:读取和使用中控标签知识库,辅助标签
when_to_use: 当用户要求判断 query 应该归属哪个标签、解释标签边界、校验数据生成目标中的 target、整理标签知识或分析标签混淆时使用。
aliases: label-knowledge, 标签大师, 标签知识, label, 标签体系
allowed_tools: read_file, write_file, edit_file, grep_search, glob_search, ask_user_question, python_exec, bash
repeatable: true
---
使用这个 skill 作为“标签知识理解和标签边界分析”的入口。它不直接把标签判断收敛成一个黑盒分类工具,而是指导 Agent 逐步阅读知识、比较候选、解释依据,并在不确定时向用户确认。
+13 -3
View File
@@ -65,6 +65,13 @@ when_to_use: |
- [ ] **`step:"hypothesis"` entry 写在当前 roundR{n})名下**——不要写成 R{n+1}。后端把 hypothesis 归类为 analysis 类,是 R{n}·Baseline / R{n}·Analysis 的最后一张卡,不是 R{n+1}·Train 的开头。这样 gateHuman Check / Review)会插在 hypothesis 卡之后、R{n+1}·Train 之前,**用户看到假设内容再拍板是否进 train**。
- [ ] **`hypothesis=complete` 之前,必须 append `iteration_log.jsonl` 一条 R{n} entry**schema 至少包含 `iteration:n / runDic:<本轮编号> / timestamp / results:{<指标 key>:<float>...} / hypothesis`。**前端 metrics 折线图唯一数据源就是这个文件**,没写 → 图表彻底空白(state file 写得再全也不行)。已踩坑:R0 走完 dist-analysis + hypothesis 但漏了 iteration_log,前端 metrics 卡看不到任何点,指标空了一整轮。`results` 必须用 program.md 「§iteration_log schema」里固定的 metric key`req_set_car / dapan_car / specific_test / triage_err_rate / bvt_nav / talkable_controllable` 等),key 拼错前端按缺失处理。
### Step 3 → Step 4 / gate 边界(**CRITICALhypothesis=complete 后禁止空手结束 turn**
- [ ] **`hypothesis=complete` 写入 program-state.jsonl 之后,当前 turn 绝对不允许结束**——必须在同一轮里做下面两件之一(二选一,不能都不做):
- (A) 如果命中 HiTL 信号(§HiTL 阈值):写 `human-check` gate entryrunning)→ chat reply 给用户选项 → 然后才可以让 turn 自然结束(gate=running 会让 UI 显示 "waiting" 卡片)
- (B) 如果不命中 HiTL(候选量 ≤ 50 全自动路径):直接写 `augment=running` → 开始执行增强
- [ ] **"turn 预算不够"不是合法理由**——50 turns 里跑完 hypothesis 最多用 15~20 turns,剩余空间远够写一条 gate entry 或启动 augment。如果你真的接近上限,也必须**先写 gate entry 再结束**,不能空手结束。
- [ ] **"下一轮 wake 继续"不存在**——没有自动 wake 机制。你结束了就是结束了,session 不会被再次调起,用户只看到 pipeline 卡在 hypothesis=complete 不动。
### Step 1 → Step 3 边界(**NEVER STOP 硬连接**R0 / R1+ regression 都适用)
- [ ] dist-analysis 算完 deltanew_fail / new_fix / persistent / 子集分布)那一刻起,**同一轮 bash 不许结束**:紧接着写 `results/workflow<runDic>.md`(包含完整指标表 + 病灶定位 + 假设 + 回滚/继续建议)→ append `iteration_log.jsonl` R{n} entry`results` 字段填本轮 metric`hypothesis` 字段填下一动作)
- [ ] **regression 场景同样适用**:哪怕 R1 出现导航bvt 纯劣化、可聊可控大幅 -25 这种"必须回滚"信号,**先把分析落到 workflow<runDic>.md 和 iteration_log,再用 chat reply 给人回滚选项**。文件先落、聊天再发——顺序不能反。
@@ -81,6 +88,7 @@ when_to_use: |
- [ ] §4.0.1 Step C:备份 `.bak` 文件
- [ ] §4.1 输入准备 / §4.2 GPT 调用 / §4.3 sanity check / §4.4 写入
- [ ] **§4.5 label-master 标签复核(落盘后必做,强制)**:H1 `modified_samples.jsonl` 只跑层 1(格式)—— 语义已在 §4.0.1 Step A.5 完成;H2 `augment_<runDic>.jsonl` 跑两层(`validate_label_output.py` 格式 + Skill 调用 `label-master` 语义),**逐条 1:1 全量覆盖**(`augment` 多少行 `label_master_review.jsonl` H2 部分就多少行,禁止抽样 / spot-check / X/X pass 外推),verdict 写 `results/data_clean_<runDic>/label_master_review.jsonl`,**不通过必须 = 0**(任何不通过必须修正后重新 review 直到全 pass 才能进 Step 5
- [ ] **§4.5 层 2 语义复核必须调用 `Skill(skill="label-master")`,禁止正则/规则脚本替代**:层 2 的本质是"用 label-master 知识体系对每条 (query, label) 做独立语义判定"。label-master 已标记 `repeatable: true`,可在同一 run 内多次调用。**禁止**:纯正则/关键词匹配脚本、"target 都一样所以直接 pass"逻辑、批量写 pass 不看 query 内容。已踩坑:R1 agent 写了个正则脚本充当"layer 2",完全没走语义判断。
### Step 4 → Step 5 边界(**NEVER STOP 硬连接**,反复踩坑)
- [ ] 写完 `augment=complete` 那一刻,**同一轮 bash 不许结束**:紧接着跑 §4.5 label-master 复核 → 写 `sft=running` → 调 `submit_sft.sh` → 挂 watcher(评测在 SFT `_SUCCESS` 落盘后的下一轮单独用 `submit_cml_eval.sh` 起,不要在 SFT bg 里串接评测)
@@ -418,9 +426,11 @@ echo '{"log":{"ts":"11:55:10","iter":"R1","text":"Step 1 dist-analysis: 写 work
## 达标条件
- **需求集合** ≥ 95%(最高优先级)
- **大盘集(车载)** 降幅 ≤ 0.3%
- **specific test** 降幅 ≤ 1%
- **需求集合(目标集)** ≥ 95%**最高优先级,一切以此为准**
- **大盘集(车载)** 降幅 ≤ 0.3%(次要,目标集未达 95% 前不因大盘微降而回滚/停训)
- **specific test** 降幅 ≤ 1%(次要,同上)
⚠️ **优先级铁律**:目标集上 95% 是主线任务。只要目标集还没到 95%,其他集合的轻微下降(大盘 ≤1%、specific ≤2%)**不构成回滚理由**,继续迭代。只有目标集已达标后,才需要关注并修复其他集合的 regression。
## 主流程
+31 -8
View File
@@ -178,13 +178,17 @@ for k in prev:
3. **specific test**
**达标条件**
- 需求集合 ≥ 95%
- 大盘集(车载)降幅 ≤ 0.3%
- specific test 降幅 ≤ 1%
- 需求集合(目标集) ≥ 95%**最高优先级**
- 大盘集(车载)降幅 ≤ 0.3%(次要)
- specific test 降幅 ≤ 1%(次要)
⚠️ **优先级铁律**:目标集上 95% 是主线任务。只要目标集还没到 95%,其他集合的轻微下降(大盘 ≤1%、specific ≤2%)**不构成回滚理由**,应继续迭代优化目标集。只有目标集已达 95% 后,才需要关注并修复其他集合的 regression。
**决策**
- 全部达标 → 部署(`python modules/cloudml_deploy.py <rl_checkpoint>`),记录,循环结束
- 达标 → 在 Step 1 内继续做问题分析(见下文),**分析顺序:需求集合 → 车载大盘 → specific test**
- 目标集未达标 → 继续迭代(即使其他集合有轻微下降也不回滚)
- 目标集已达标但其他集合超限 → 微调修复其他集合
- 分析顺序:**需求集合 → 车载大盘 → specific test**
> **首次评测差异**:由于新旧模型相同,"降幅"和"vs 基线"无意义(均为 0)。此轮只记录各集合的**绝对准确率**作为 baseline,不做达标/不达标判定,不触发部署。直接在 Step 1 内分析基准模型的错误分布,为后续迭代建立对照基准。
@@ -655,6 +659,12 @@ for r in b_rows:
> 若 Step 1 显示全部达标 → 跳过 Step 3–5,直接部署。
> ⛔ **CRITICAL: hypothesis=complete 后禁止空手结束 turn**。写完 hypothesis 到 program-state.jsonl 之后,当前 turn 内必须做下面两件之一(不能都不做就结束):
> - 命中 HiTL → 写 `human-check` gate entry (running) → chat reply 给用户选项
> - 不命中 HiTL → 写 `augment=running` → 开始 Step 4
>
> **"turn 预算不够"不是合法理由**——没有自动 wake 机制,turn 结束 = session 永久停止。已踩坑:agent 在 R0 hypothesis=complete 后误判"turn 用满"而空手结束,用户看到 pipeline 卡在 hypothesis 不动、无任何后续(session `qf1ni1jh`25/50 turns 实际只用一半)。
### 4. 数据生成(GPT-5.4 从 badcase 增强)
**只在 §2.4 归因为 `data` 时做。** 其他归因直接跳过 Step 4,按下表路由:
@@ -743,18 +753,19 @@ with open(out_csv, 'w', encoding='utf-8-sig') as fp:
候选阶段(246 条等量级)的 CSV 必须写到 `output/relabel_candidates_<runDic>.csv` 让分析卡片可读;确认修改阶段(用户审核后落盘的 135 条)写入 `results/data_clean_<runDic>/modified_samples.jsonl` 让数据增强卡片可读。**不要混落**——把候选 CSV 写到 `/tmp/` 或 `data_clean_/` 都会让 UI 看不到。
> **runDic 命名语义(backend 已对齐,改 backend 时勿 revert**augment 类产物(`data_clean_<N>/`、`augment_raw/augment_<N>_raw.jsonl`、`zk_intent/augment_<N>.jsonl`、`label_master_review.jsonl`)的 `<N>` 永远是**「源轮次的 runDic」**,也就是 `R{n-1}.runDic`——agent 在 R{n} 跑 augment 时处理的是 R{n-1} 评测落地的错例,文件命名沿用 R{n-1} 的 workflow id。Backend step-detail 端点 (`server.py` 内 `_step_artifact_paths('augment', ...)` 调用方) 在 `step=='augment'` 时也是查 `R{n-1}` 的 runDic,跟落盘命名一一对应。其他 stepcml / dist-analysis / hypothesis / gold-drift)的产物按本轮自己的 runDic 命名,没有偏移。**不要把 augment 产物改名成 R{n} 的 runDic**——会同时打破历史归档和 backend 解析
> **runDic 命名语义(backend 已对齐)**augment 类产物(`data_clean_<N>/`、`augment_raw/augment_<N>_raw.jsonl`、`zk_intent/augment_<N>.jsonl`、`label_master_review.jsonl`)的 `<N>` = `$SFT_RUNDIC` = **当轮 eval 落盘后 `resolve_run_ids.sh` 取到的 max(已落盘 workflow)**。由于 resolve 是在当轮 eval 的 `lark_template.json` 落盘之后调用的,此时 max 就是当轮 eval 自身的 workflow id。Backend step-detail 端点对 augment 也直接用本轮(`per_round[R{n}]`的 runDic 去读。其他 stepcml / dist-analysis / hypothesis / gold-drift)的产物同理按本轮自己的 runDic 命名。
>
> ⚠️ **runDic 不许手算**augment 落盘、SFT yaml、归档目录、cml workflow run 用的 runDic **必须**从 `scripts/resolve_run_ids.sh` 取,不准 agent 自己 `ls workflow5 | tail -1` 然后心算 +1。规则简单到没必要靠模型:
>
> ```bash
> eval "$(./scripts/resolve_run_ids.sh)"
> # 现在 shell 里有:
> # $SFT_RUNDIC = R{n-1}.runDic augment 落盘 / yaml / 归档全用这个,不 +1)
> # $EVAL_RUNDIC = R{n-1}.runDic + 1 (仅 cml workflow run 时使用,唯一一次 +1)
> # $SFT_RUNDIC = max(已落盘 workflow) = 当轮 eval 的 workflow id
> # augment 落盘 / yaml / 归档全用这个
> # $EVAL_RUNDIC = SFT_RUNDIC + 1(仅下一轮 cml workflow run 提交时使用)
> ```
>
> 已踩坑:R2 augment 把 `data_clean_<N>/` 写成了 `EVAL_RUNDIC`(多 +1 一次),跳过了 R1.runDic 整段命名空间,前端 augment 卡片直接读不到。**写 augment / SFT / 归档脚本时一律用 `$SFT_RUNDIC`,不要写 `${RUNDIC}` 也不要写 `${EVAL_RUNDIC}`**。
> **写 augment / SFT / 归档脚本时一律用 `$SFT_RUNDIC`,不要写 `${RUNDIC}` 也不要写 `${EVAL_RUNDIC}`**。
>
> 🚨 **调用时序(CRITICAL**`resolve_run_ids.sh` **只能在当轮 CML eval 的 `lark_template.json` 已落盘之后调用**。禁止在 eval 提交前或 watcher 等待期间预先调用——此时 max workflow 仍是上一轮的值,会导致 SFT_RUNDIC 偏移 -1(已踩坑:R0 workflow17823 评测中提前 resolve 得到 17822augment 文件全部错位)。正确时序:`cml step=complete` → `resolve_run_ids.sh` → augment/SFT。每次进入 augment/SFT 步骤前**必须重新调用**,不许复用之前缓存的值。
@@ -1262,6 +1273,8 @@ python skills/label-master/scripts/validate_label_output.py \
**层 2:语义复核(Skill 调用 label-master Agent,仅 H2**
**禁止用正则/规则脚本替代 LLM 语义判断**。层 2 不是格式校验,是"该 query 在 label-master 知识体系下是否应该标成这个 label"的语义问题。**唯一合法实现方式是调用 `Skill(skill="label-master")`**label-master 已标记 `repeatable: true`,可在同一 run 内多次调用)。已踩坑:R1 agent 写了个检查 hist 里有没有导航触发词的正则脚本充当"layer 2",完全没走语义判断,导致错误样本全量混入训练集。
H1 在 §4.0.1 Step A.5 已经过 label-master 推荐覆盖,这里**不再重跑**。H2 仿写是 §4.2 GPT 新增的样本,没经过 Step A.5,必须在此补一次语义判定:
🚨 **覆盖率硬规则**`label_master_review.jsonl` 里 H2 部分的行数**必须等于** `augment_<runDic>.jsonl` 的行数(1:1 全量覆盖)。**禁止抽样、禁止"前 N 条 spot-check"、禁止"5/5 pass 推 100 OK"**——§5.0 准入门会用 `wc -l` 拦。已踩坑:R17817 跑了 5 条样本就上报"100 条 pass",被 §5.0 退回。
@@ -1485,6 +1498,16 @@ python prepare_and_train_sft.py prepare --regen_from_csv --output_dir ./sft_data
> 验证集文件名不能含 `valid`/`test`/`eval`HF datasets 会推断错误的 split),脚本自动重命名为 `part-0.jsonl`。
⚠️ **每轮 SFT 前必须在 log 中展示训练数据组成**
`prepare_and_train_sft.py` 会 glob 目录下**所有** `augment_*.jsonl`。agent 在每轮 SFT 前必须在 program-state log 中列出最终参与训练的文件及行数:
```jsonl
{"log":{"ts":"...","iter":"R3","text":"SFT 数据组成: all_train.jsonl(35379) + augment_17829.jsonl(210) = 35589 条 | 排除: augment_17828.jsonl(150) rename .pre_R3R2 pattern 导致导航 bvt 劣化)"}}
```
必须展示:(1) 参与训练的所有文件及行数 (2) 被排除的旧轮文件及排除原因(如果有)。
#### 5.2 启动训练(cml 任务,R29 起统一走这条路径)
R23-R28 期间用本地 `nohup python3 prepare_and_train_sft.py train ...` 启动,会因登出/网络/会话退出而中断,并占用本地工作机 8 卡 GPU。**R29 起统一改为 cml custom_train submit 提交训练任务**,由 CloudML 调度到 `bj-nlp` 队列的 h20-96g 8 卡,本地零占用。
@@ -1,11 +1,12 @@
#!/bin/bash
# resolve_run_ids.sh —— SFT/EVAL runDic 单一可信来源
#
# 规则(与 program.md §746 + §5.2 对齐):
# 规则(与 program.md §756 对齐):
# SFT_RUNDIC = workflow5/ 下「已落盘」(含 metric_diff/lark_template.json)的最大 runDic
# 即 R{n-1}.runDic —— augment 落盘、SFT yaml、modified_samples 归档全用这个值
# = 当轮 eval 自身的 workflow id(因为 resolve 在 eval 落盘后调用)
# augment 落盘、SFT yaml、modified_samples 归档全用这个值
# EVAL_RUNDIC = SFT_RUNDIC + 1
# 仅 cml workflow run 提交本轮评测时使用
# 仅下一轮 cml workflow run 提交时使用
#
# 用法:
# eval "$(./scripts/resolve_run_ids.sh)"