This commit is contained in:
hupenglong1
2026-05-22 19:48:47 +08:00
parent 20690cdef3
commit 5311e6d97c
31 changed files with 4620 additions and 472 deletions
+160 -31
View File
@@ -51,6 +51,23 @@ ssh -T git@git.n.xiaomi.com
# 打开 https://git.n.xiaomi.com/-/profile/keys 粘贴公钥
```
### Chat 工作区 bootstrap(首次启动时)
每个 chat session 一份独立工作区 `$AUTORESEARCH_CHAT_ROOT`(后端 jupyter 启动时自动注入这个 env)。该路径位于共享 NFS:`/mnt/wangsenhao/autoresearch-zk-users/<email_prefix>/<chat_session_id>/``<email_prefix>` 是用户登录的小米邮箱前缀(账号根目录),chat 二级隔离。**jupyter pod 与 SFT 训练 pod 共用这条 NFS**,所以训练 yaml 里 `cd $AUTORESEARCH_CHAT_ROOT` 不会再像旧版(jupyter pod 私有 `/root/zk_agent_workspaces/...`)那样在训练 pod 报 No such file。
`scripts/``results/``sft_output/` 由后端 mkdir + 推送 `prepare_and_train_sft.py`**ai-planning corpus 需要 agent 自己 git clone**(之前依赖全局共享,已废弃):
```bash
# 检测是否已 clone,没有就拉
[ -d "$AUTORESEARCH_CHAT_ROOT/ai-planning" ] || git clone -b autoresearch-v1 \
git@git.n.xiaomi.com:ai-service/ai-planning.git \
"$AUTORESEARCH_CHAT_ROOT/ai-planning"
```
之后所有训练数据读写都走 `$AUTORESEARCH_CHAT_ROOT/ai-planning/...`(包括 augment_<runDic>.jsonl 写入、近邻检索、训练集修改)。`prepare_and_train_sft.py``Path(__file__)/../ai-planning` 解析数据目录,因为脚本被推到了 `$AUTORESEARCH_CHAT_ROOT/scripts/` 旁边,自然落在 chat 副本上。
zk_trainer 的 clone 在首次 SFT 前进行(见 §5.0),目标也是 `$AUTORESEARCH_CHAT_ROOT/zk_trainer`
### cml 环境检查(每次评测前必做)
```bash
@@ -231,10 +248,11 @@ for k in prev:
当前瓶颈是需求集合,单独做一节:
1. **子集级表格**:每个需求子集 pass rate、距离 95% 的 gap、对比上轮、对比基线。
2. **失败 case 与训练数据的关联**:对每个失败 case 在 `ai-planning/data/train_set/zk_intent/` 下所有 `.jsonl`(包括历史增强 `augment_*.jsonl` 和原始种子训练文件,排除 `*_valid.jsonl`)里做近似检索(前 3 近邻),判断
- **数据缺失**:训练集中没有类似样本 → 补数据
- **数据充足但仍错**:训练集中有类似样本 → 数据质量 or 学不会,不是加数据的问题
3. **Reward 对齐检查**(抽样 10 条失败 case):用 `zk_reward_fn` 对"正确 label"和"实际输出"分别打分,验证 reward 方向是否和准确率一致。如果 reward 给错误输出的分更高 → reward 函数本身就有问题。
2. **失败 case 与训练数据的关联**:对每个失败 case 在 `ai-planning/data/train_set/zk_intent/` 下所有 `.jsonl`(包括历史增强 `augment_*.jsonl` 和原始种子训练文件,排除 `*_valid.jsonl`)里做近似检索(前 3 近邻),三档判定
- **无近邻**(最高相似度 < 阈值)→ 分布外,补数据
- **有近邻 + 近邻 label 与本 case gold 全部一致** → 训练数据正确,SFT 学不动 → 加 epoch / 改 reward
- **有近邻 + 任一近邻 label 与 gold 矛盾** ⚠️ → **训练集打错标**,必须**逐条列出该 mislabeled 训练样本**`{train_file:line, hash, 当前 label, 应改 label, 与失败 case 相似度, 违反的标签规则}`,进入下一轮的数据修订清单
3. **Reward 对齐检查**(全量失败 case,不抽样):用 `zk_reward_fn` 对"正确 label"和"实际输出"分别打分,验证 reward 方向是否和准确率一致。如果 reward 给错误输出的分更高 → reward 函数本身就有问题。
#### 2.4 根因归类
把发现映射到一类根因,**每个 pattern 必须归一类**(可并列,但要主次分明):
@@ -243,8 +261,9 @@ for k in prev:
|---|---|---|
| 分流错误占比高 (>30%) | reward 对 complex 误判惩罚不足 | 改 `zk_reward_fn` 加分流项 |
| 语义错误集中在少数 tag | 训练数据该类分布不足 | 定向补数据 |
| 需求集合失败 case 训练集近邻 | 数据质量 / 标签噪声 / SFT 学不动 | 审核数据 + 加大 SFT epoch |
| 需求集合失败 case 训练集近邻 | 分布外 | 补数据(最直接) |
| 需求集合失败 case 训练集近邻 **label 一致** | SFT 学不动 / reward 信号弱 | 加大 SFT epoch / 改 reward |
| 需求集合失败 case 训练集近邻 **label 矛盾**mislabeled ⚠️ | 训练集错标 | 按 §2.3 错标清单逐条修标,进 Step 4 数据修订 |
| 需求集合失败 case 在训练集**无近邻** | 分布外 | 补数据(最直接) |
| new/regressed case 多 | 上轮干预有副作用 | 回退 or 缩小干预范围 |
| 训练 prompt ≠ eval prompt | 格式不匹配(silent bug | 对齐模板,常常能"白捡"几个点 |
| 错误 query 含状态描述句但训练集标 Agent | 标签规则违反(R3) | 改训练集对应样本为 CT,按 4.3.1 规则检查 |
@@ -313,7 +332,14 @@ conflict_rate = len(conflicts) / len(query_to_golds)
| 子集 | 准确率 | 总数 | 错误数 | 距 95% gap |
### 失败 case 与训练数据关联
- <子集>: N 条失败中 X 条在训练集有近邻,Y 条无近邻 → 主要缺口: <数据缺失/质量>
- <子集>: N 条失败中 X 条**有近邻且 label 一致**、Y 条**无近邻**、Z 条**近邻 mislabeled** ⚠️ → 主要缺口: <分布外补数据 / SFT 学不动 / 训练集错标>
#### 训练集错标清单(逐条,对应 Z 条 mislabeled
| 失败 case query | 训练样本 file:line | hash | 当前 label | 应改 label | 相似度 | 违反规则 |
|---|---|---|---|---|---|---|
| <q1> | augment_<N>.jsonl:42 | <h1> | Agent | CT | 0.93 | R1(单 POI+多形容词) |
> 没有 mislabeled 时这张表省略;有则进入下一轮 Step 4 的修订清单。
## 设备维度(只分析车载)
| 设备 | 准确率 | 总数 | 错误数 |
@@ -332,7 +358,7 @@ query: ...
label: ...
模型输出: ...
归类: 分流/语义
训练集近邻: 有/无
训练集近邻: 有 label 一致 / 无 / ⚠️ mislabeledhash=xxx, 相似度 0.xx, 当前=Agent / 应改=CT
## 初始错误分布总结
| 根因类 | 错误数 | 占比 | 代表 pattern |
@@ -375,8 +401,15 @@ label: ...
> 准确率来自 lark_template.json(含 complex 门禁检查),B/G 数来自 CSV 的纯模型 GSB(不含 complex 门禁),两者口径不同。
### 失败 case 与训练数据关联
- <子集>: N 条失败中 X 条在训练集有近邻,Y 条无近邻 → 主要缺口: <数据缺失/质量>
- Reward 对齐抽样: N/10 条 reward 方向与准确率一致
- <子集>: N 条失败中 X 条**有近邻且 label 一致**、Y 条**无近邻**、Z 条**近邻 mislabeled** ⚠️ → 主要缺口: <分布外补数据 / SFT 学不动 / 训练集错标>
- Reward 对齐(全量): N/N 条 reward 方向与准确率一致
#### 训练集错标清单(逐条,对应 Z 条 mislabeled
| 失败 case query | 训练样本 file:line | hash | 当前 label | 应改 label | 相似度 | 违反规则 |
|---|---|---|---|---|---|---|
| <q1> | augment_<N>.jsonl:42 | <h1> | Agent | CT | 0.93 | R1(单 POI+多形容词) |
> 没有 mislabeled 时这张表省略;有则 Z 条样本自动进入下一轮 Step 4 的修订清单。
## 设备维度(只分析车载)
| 设备 | 基线准确率 | 新模型准确率 | 变化 | 旧对新错 |
@@ -421,7 +454,7 @@ label: xxx
旧: xxx # origin_predict_base
新: xxx # origin_predict_dev(保留 complex= 前缀)
归类: 分流/语义/两者 | 跨轮: persistent/new/regressed
训练集近邻: 有/无hash=xxx, 相似度 0.xx
训练集近邻: 有 label 一致(hash=xxx, 相似度 0.xx/ 无 / ⚠️ mislabeledhash=xxx, 相似度 0.xx, 当前=Agent / 应改=CT
```
> **重要**:对话历史从 input 字段的 `[对话历史]` 段提取,不能省略。很多错误(如短句闲聊被误判为 Agent)只有在多轮上下文中才能理解根因。
@@ -589,19 +622,33 @@ for f in glob.glob('ai-planning/data/train_set/zk_intent/*.jsonl'):
candidates.append((f, ln, q, d['output']))
# 3. 输出 csv 让人审核(不改文件)
import csv
with open(f'/tmp/candidates_r{RUNDIC}.csv', 'w', encoding='utf-8-sig') as fp:
# 必须写到 $AUTORESEARCH_CHAT_ROOT/output/ —— 这是 NFS 路径,前端「分层结果分析」
# 卡片从 chat_root/output/ 读这条;写到 jupyter pod 本地 cwd 会导致前端 not found。
import csv, os
out_csv = os.path.join(os.environ['AUTORESEARCH_CHAT_ROOT'],
'output', f'relabel_candidates_{RUNDIC}.csv')
os.makedirs(os.path.dirname(out_csv), exist_ok=True)
with open(out_csv, 'w', encoding='utf-8-sig') as fp:
w = csv.writer(fp)
w.writerow(['file','line','query','old_label','是否改(1/0)','建议新label'])
for c in candidates: w.writerow(list(c)+['',''])
```
**两阶段 UI 展示约定(强制)**
| 阶段 | 产物 | 落盘路径 | 前端卡片 |
|---|---|---|---|
| 阶段一:预计修改候选 | `relabel_candidates_<runDic>.csv` | `$AUTORESEARCH_CHAT_ROOT/output/`NFS | **分层结果分析(dist-analysis** |
| 阶段二:确认修改最终 | `modified_samples.jsonl` | `$AUTORESEARCH_CHAT_ROOT/results/data_clean_<runDic>/` | **数据增强(augment** |
候选阶段(246 条等量级)的 CSV 必须写到 `output/relabel_candidates_<runDic>.csv` 让分析卡片可读;确认修改阶段(用户审核后落盘的 135 条)写入 `results/data_clean_<runDic>/modified_samples.jsonl` 让数据增强卡片可读。**不要混落**——把候选 CSV 写到 `/tmp/``data_clean_/` 都会让 UI 看不到。
**Step B:量级判定(决定是否走人审)**
| 候选量 | 处理 |
|---|---|
| ≤ 50 条 | 程序化 sanity check + 自动改 |
| 51 ~ 200 条 | **必须**抽样 30~50 条到飞书 sheet 让人审 1/0,按抽样比例外推到全量 |
| 51 ~ 200 条 | **必须**全量导出到飞书 sheet 让人逐条审 1/0(不抽样) |
| > 200 条 | **强制 H-i-T-L 介入**(触发条件 #3),让人定更精细 pattern 收窄 |
**Step C:备份(强制,覆盖前必做)**
@@ -642,7 +689,7 @@ for f, edits in edits_by_file.items():
改完不能直接训:
1. **数据 sanity**`prepare_and_train_sft.py prepare`,对比合并后总数(旧总数 - 删除数 = 新总数)
2. **抽样人审**随机抽 5 条,看 query/label/instruction 符合预期
2. **全量人审**所有改动条目逐条过一遍,看 query/label/instruction 符合预期
3. **格式校验**:用 4.1.1 字段约束扫一遍改后 output
**Step F:删除 vs 修改的选择**
@@ -828,7 +875,7 @@ def gen_augment(badcase: dict, n: int = 8) -> list[dict]:
- **ground_truth 格式校验**`Agent(tag=...)` / `ComplexTask(...)` / `QA()` / `Chat()` 是否和测试集一致?GPT-5.4 偶尔会把 tag 改写或加空格,必须用 `zk_reward_fn` 里的 parser 过一遍,parse 失败的扔掉。
- **context 完整性**`context` 必须是 dict 且含 `location` / `rag` 两键(可为空字符串但不能缺);`prev_session` 必须是 list。结构不符的丢弃。
- **泄漏检测**:生成 `current_query` 与所有测试集(需求集合 + 大盘 + specific)做**精确匹配 + 近似匹配**MinHash or embedding cos > 0.9)。命中则整条丢弃。
- **Label 自洽**:生成的 `(current_query, prev_session, context) → ground_truth` 必须和原 badcase 的 ground_truth 语义一致。抽 10% 跑一次 GPT-5.4 自检("下面这条 current_query 的正确 ground_truth 是什么?"),和声明 ground_truth 不一致的丢弃。
- **Label 自洽**:生成的 `(current_query, prev_session, context) → ground_truth` 必须和原 badcase 的 ground_truth 语义一致。**全量**跑一次 GPT-5.4 自检("下面这条 current_query 的正确 ground_truth 是什么?"),和声明 ground_truth 不一致的丢弃。
- **Prompt 模板一致性**:并入训练前,把 `(prev_session, context, current_query)` 渲染成最终 SFT prompt,和 eval prompt 逐字段比对(`complex=true/false` 前缀、system prompt、function schema),不一致就对齐模板——常常能白捡几个点。
- **去重**:与 `ai-planning/data/train_set/zk_intent/` 下所有已存在的 `*_train.jsonl`(历史增强 + 原始种子训练文件)去重(`current_query` 精确 + 近似)。
@@ -1014,10 +1061,11 @@ def induce_rule(cluster_cases, all_test_rows, existing_rules):
### R{N} 自动归纳({runDic} 轮)
**规则**:含 pattern `{regex}` → {gold}
**置信度**c1={c1:.2f}(错例 {support_err}/{support_err_total} 一致), c2={c2:.2f}(全测试集 {full_majority}/{support_total} 一致)
**锚定 case**自动从测试集抽 3 条):
**锚定 case**列出该 pattern 在测试集命中的全部 case,不抽样):
- {case1}
- {case2}
- {case3}
- ...(共 {N} 条)
**自动检查正则**`{regex}`
```
@@ -1053,16 +1101,95 @@ ai-planning/data/train_set/zk_intent/augment_<runDic>.jsonl
JSONL 行里的 `sub_cate` 字段仅用于内部路由/去重,归档时丢弃不写入 CSV。因为 4.2 的输出 schema 已经和 CSV 列名对齐,归档就是把每个 `augment_<runDic>.jsonl` 行序列化成 CSV 单元格(`prev_session` / `context` 两列用 `json.dumps` 回写成字符串),没有字段重命名。
#### 4.5 label-master 标签复核(落盘后、SFT 前,**强制**)
任何写入训练目录的修改/新增样本都必须经 [label-master skill](../../label-master/SKILL.md) 复核**两层**:格式 + 语义。**没过这关不许进 Step 5。**
**复核范围**(两份必须全过):
| 文件 | 来源 | 复核什么 |
|---|---|---|
| `$AUTORESEARCH_CHAT_ROOT/results/data_clean_<runDic>/modified_samples.jsonl` | H1 改标(complex 翻转 / tag 改写等) | 改后的 `output` 字段 |
| `$AUTORESEARCH_CHAT_ROOT/ai-planning/data/train_set/zk_intent/augment_<runDic>.jsonl` | H2 仿写(新增训练样本) | `output` 字段 |
**层 1:格式校验(确定性,自动跑)**
```bash
cd /home/mi/zk-data-agent-wsh # 或 wherever skills 包在的项目根
# H1 改标
python skills/label-master/scripts/validate_label_output.py \
--file "$AUTORESEARCH_CHAT_ROOT/results/data_clean_<runDic>/modified_samples.jsonl" \
--field output_after
# H2 仿写
python skills/label-master/scripts/validate_label_output.py \
--file "$AUTORESEARCH_CHAT_ROOT/ai-planning/data/train_set/zk_intent/augment_<runDic>.jsonl" \
--field output
```
任一行 failtag 不存在 / Agent 包装错 / function 引用错)→ **必须修,不许直接跳过**。修完原地重跑直到全过。
**层 2:语义复核(Skill 调用 label-master Agent**
格式过了不代表标对了。每条修改/新增样本要用 label-master 做边界判断:
1. 抽出 `(query, output_after)``(query, output)` 对,按 `sub_cate` 分组(每组 ≤30 条作为一批)
2. 每批用 `Skill(skill="label-master", args=...)` 调用,args 里给:
- 全部 `(query, 当前 label)`
- 让 label-master 按 §决策流程 / §候选召回索引 / §高频混淆边界 判定每条
- 输出格式:每条 → `{verdict: 通过 | 不通过, 推荐标签, 排除理由, 易混淆边界}`
3. 收集 verdict,写入 `$AUTORESEARCH_CHAT_ROOT/results/data_clean_<runDic>/label_master_review.jsonl`,每行一条 verdict
**verdict 处置规则(自动)**
| 比例 | 处置 |
|---|---|
| 不通过 ≤ 5% | 自动丢弃这些样本(H2 → 从 augment_<N>.jsonl 删行;H1 → 回滚改动到 .bak+ 写明丢弃数到 iteration_log |
| 不通过 5%~20% | **触发 H-i-T-L #6**(gold 可疑),把不通过样本导出飞书 sheet 让人审 |
| 不通过 > 20% | **强制暂停**,Step 4 假设本身有问题,回 Step 3 重新形成假设 |
**写完复核报告才允许进 Step 5。**verdict 文件不存在 / 没跑层 2 → Step 5 拒绝启动(5.0 的准入检查会查 `label_master_review.jsonl` 存在)。
🚨 **注意**label-master 是"知识 + Agent 推理"型 Skill,不是黑盒分类器。批量调用时严禁要求它返回 1/0 标量;必须输出 `verdict + 推荐标签 + 排除理由` 三件套,便于人类回查。
### 5. SFT 训练
🚨 **Step 4 → Step 5 硬连接(NEVER STOP,反惯性反复强调)**
写完 `{"step":"augment","status":"complete",...}` 那一行**之后**,**同一轮 bash 不许结束、不许写"Step 4 完成"简报、不许等回调**。必须**紧接着**:
1. `echo '{"step":"sft","status":"running",...}' >> $SESSION_OUTPUT/program-state.jsonl`
2. 跑层 1 + 层 2 label-master 复核(§4.5
3. 如果复核全过:在 SAME bash turn 里调 `bash scripts/submit_sft_via_cml.sh <RUNDIC> <PREV_RUNDIC>` 并立刻挂 watcher(§5.2 的 cml custom_train + workflow chain
**反模式**(被反复踩坑,永远禁止):
- ❌ 写完 `augment=complete` → 写一份漂亮的"Step 4 完成"进度简报 → turn 结束 → 等下一次触发
- ❌ "augment 已完成,下一步等回调后续做 SFT" — 不存在等回调,augment 完成的那一刻就是 SFT 启动的那一刻
- ❌ 把 H2 后台任务的 stdout 当成"用户消息"处理完就 turn 结束 — bg 任务回调不是 turn 结束信号,augment=complete 也不是
**模型本能会想停("任务段落感"),SKILL NEVER STOP 压不住这个本能**——所以这里写成硬命令清单,照清单第一条到第三条机械执行,做完才允许 turn 结束。
使用 `prepare_and_train_sft.py` 完成数据组装和训练。
#### 5.0 环境准备
**准入检查(少一项不许进)**
```bash
# 克隆 zk_trainer(仅首次)
cd /mnt/wangsenhao/autoresearch-zk
git clone git@git.n.xiaomi.com:wangsenhao/zk_trainer.git
# 1. label-master 复核报告必须存在且全通过
REVIEW="$AUTORESEARCH_CHAT_ROOT/results/data_clean_${RUNDIC}/label_master_review.jsonl"
[ -f "$REVIEW" ] || { echo "label-master 复核未完成,回 §4.5"; exit 1; }
NOT_PASS=$(grep -c '"verdict":"不通过"' "$REVIEW" || echo 0)
TOTAL=$(wc -l < "$REVIEW")
if [ "$TOTAL" -gt 0 ] && [ $((NOT_PASS * 100 / TOTAL)) -gt 5 ]; then
echo "不通过比例 $NOT_PASS/$TOTAL > 5%,按 §4.5 处置规则走 H-i-T-L 或回 Step 3"
exit 1
fi
# 2. zk_trainer 仓库已 clone
cd "$AUTORESEARCH_CHAT_ROOT"
[ -d zk_trainer ] || git clone git@git.n.xiaomi.com:wangsenhao/zk_trainer.git
```
**训练配置**
@@ -1098,8 +1225,8 @@ git clone git@git.n.xiaomi.com:wangsenhao/zk_trainer.git
- `prepare_and_train_sft.py train` 命令行参数 `--model_path` 必须检查为 basemodel 路径
**反模式**
-`--model_path /mnt/wangsenhao/autoresearch-zk/sft_output`(继续训练)
-`--model_path /mnt/wangsenhao/autoresearch-zk/sft_output_r17776`(从历史轮 ckpt
-`--model_path $AUTORESEARCH_CHAT_ROOT/sft_output`(继续训练)
-`--model_path $AUTORESEARCH_CHAT_ROOT/sft_output_r17776`(从历史轮 ckpt
- ❌ 任何形式的 "增量 SFT"(除非显式声明是为了验证"从 X ckpt 继续是否更好"的对照实验,且单次性,log 要明确标记)
#### 5.0.1 训练产物备份(R23-R28 经验沉淀)
@@ -1127,13 +1254,15 @@ R29 起 SFT 走 cml custom_train submit(见 5.2),watcher 直接复用 `sub
```bash
# 预清理:必须在挂 watcher 之前执行
rm -f /mnt/wangsenhao/autoresearch-zk/sft_output/_SUCCESS
rm -f "$AUTORESEARCH_CHAT_ROOT/sft_output/_SUCCESS"
# Watcher 1:训练阶段 —— cml state 为主判据,_SUCCESS 辅助
# 注意:heredoc 用 'EOF' 防止外层 shell 展开,$AUTORESEARCH_CHAT_ROOT
# 在 watcher 子进程里运行时再展开(远端 bash 会自动注入这个 env)。
cat > /tmp/wait_train_<RUNDIC>.sh <<'EOF'
#!/bin/bash
JOB_ID=<t-xxx-xxx>
SUCCESS=/mnt/wangsenhao/autoresearch-zk/sft_output/_SUCCESS
SUCCESS="$AUTORESEARCH_CHAT_ROOT/sft_output/_SUCCESS"
export PATH=$HOME/.cloudml-cli/bin:$PATH
while true; do
sleep 60
@@ -1174,7 +1303,7 @@ EOF
# /tmp/auto_eval_after_train.sh —— 等本地训练 PID 结束 → 自动起 cml workflow
TRAIN_PID=$1
RUN_DIC=$2
MODEL_NEW=/mnt/wangsenhao/autoresearch-zk/sft_output
MODEL_NEW=$AUTORESEARCH_CHAT_ROOT/sft_output
MODEL_OLD=<基线模型>
while kill -0 $TRAIN_PID 2>/dev/null; do sleep 60; done
@@ -1217,7 +1346,7 @@ R23-R28 期间用本地 `nohup python3 prepare_and_train_sft.py train ...` 启
##### 一键提交脚本
```bash
cd /mnt/wangsenhao/autoresearch-zk
cd "$AUTORESEARCH_CHAT_ROOT"
./scripts/submit_sft_via_cml.sh <RUNDIC> [PREV_RUNDIC]
# 例:R29 训练(上一轮 R28
@@ -1333,7 +1462,7 @@ tail -f /tmp/r<RUNDIC>_logs/cml_watcher.log
| **跨子集净退步:目标子集 +X / 其他子集合计 -Y, 净 < 0.3pp** | **回退或缩小干预范围**(R27 经验:单看目标子集涨容易自欺)|
| **连续 3 轮目标子集净提升 ≤ 0.5pp** | **进入瓶颈期**:输出 SFT 天花板报告,触发 H-i-T-L #6 |
| **跨子集 gold 矛盾率 > 5%** | **结构性天花板**:触发 H-i-T-L #2,停 SFT 转 RL 或返工标注 |
| **要批改旧标签 > 50 条** | **触发 H-i-T-L #3**抽样人审,按比例外推 |
| **要批改旧标签 > 50 条** | **触发 H-i-T-L #3**全量人审 |
| **Gold drift ≥ 10 条** | **触发 H-i-T-L #1**,暂停迭代确认是否同步训练集 |
| 训练前未备份 sft_output | **强制 mv sft_output sft_output_r{prev}**,不允许覆盖 |
@@ -1347,7 +1476,7 @@ tail -f /tmp/r<RUNDIC>_logs/cml_watcher.log
|---|---|---|---|
| 1 | **Gold drift 检测到 ≥10 条** | 暂停迭代,让人确认是否同步更新训练集 | R23 100 条翻转 |
| 2 | **跨子集同形 query gold 矛盾率 > 5%** | 输出"结构性天花板"报告,让人选:硬推目标子集 / 接受 / 转 RL | 复杂导航 vs 可聊可控 矛盾 |
| 3 | **要批改旧标签 > 50 条** | 暂停,导出抽样 ≥30 条到飞书 sheet 让人逐条确认 | R28 改 230 条引发副作用 |
| 3 | **要批改旧标签 > 50 条** | 暂停,导出全量到飞书 sheet 让人逐条确认 | R28 改 230 条引发副作用 |
| 4 | **跨子集净退步**(目标 +X / 其他合计 -Y, 净 < 0.3pp) | 暂停,让人决策回退 / 接受 / 换策略 | R27 可聊可控 -1.34pp |
| 5 | **连续 3 轮目标子集净提升 ≤ 0.5pp** | 输出 SFT 天花板报告,让人选继续 SFT / 转 RL / 接受 / 换基模 | R25-R28 复杂导航 +0.7~3pp 递减 |
| 6 | **测试集错例里 gold 可疑(自相矛盾的同 pattern)** | 列出可疑 gold 让人确认 / 反馈标注团队 | R28「找+模糊属性」双向标注 |
@@ -1359,8 +1488,8 @@ tail -f /tmp/r<RUNDIC>_logs/cml_watcher.log
| # | 触发条件 | 应对动作 | 经验来源 |
|---|---|---|---|
| T1 | **单轮批改旧标签 > 50 条** | 抽样 30 条到飞书 sheet 逐条审;按抽样的"改/不改"比例外推全量 | R28 改 230 条引发跨子集副作用 |
| T2 | **单轮新仿写 > 100 条 OR 单类 (同 sub_cate / 同 pattern) > 50 条** | 抽样 20 条让人审风险,量级大要拆批 | R23 一次 670 条仿写过载,规则错全反 |
| T1 | **单轮批改旧标签 > 50 条** | 全量导出到飞书 sheet 逐条审,逐条标 1/0 | R28 改 230 条引发跨子集副作用 |
| T2 | **单轮新仿写 > 100 条 OR 单类 (同 sub_cate / 同 pattern) > 50 条** | 全量让人审风险,量级大要拆批 | R23 一次 670 条仿写过载,规则错全反 |
| T3 | **删除训练样本 > 30 条** | 列删除清单 + 删除原因,人确认后才执行(删比改更不可逆) | R26 删 23 P0 通用短词产生副作用 |
| T4 | **修改 `all_train.jsonl` 主集 > 20 条** | 核心训练集动一行都贵;列改动给人确认 | 主集影响所有 sub_cate,副作用范围最大 |
| T5 | **跨子集冲突 query:同结构 query 在 ≥3 条训练样本里 gold 不一致** | 让人定边界规则(如「沿途搜 X」是 Agent 还是 CT),不许两边都加 | R26 augment_17752 同 pattern 矛盾仿写 |
@@ -1396,7 +1525,7 @@ tail -f /tmp/r<RUNDIC>_logs/cml_watcher.log
2. **现状量化**:目标子集 +X / 其他子集 -Y / 大盘 ±Z
3. **2-4 个选项**(用 AskUserQuestion 工具):每个选项含预期收益 + 风险
4. **推荐选项**:基于经验给出推荐(标 "(推荐)"
5. **本地产物**抽样 / 错例 csv / 飞书 sheet 链接
5. **本地产物**全量错例 csv / 飞书 sheet 链接
### 介入后的恢复