Files
zk-data-agent/skills/model-iteration/SKILL.md
T
hupenglong1 362321c460 修改
2026-05-22 20:56:57 +08:00

35 KiB
Raw Blame History

name, description, when_to_use
name description when_to_use
model-iteration 小爱中控模型自主迭代框架(autoresearch-zk)。用于对小爱同学中控理解调度模型进行假设驱动的自主 SFT+评测迭代循环。触发信号:用户发送"开始,需求集合名"(如"开始,icl_test")时,必须立即使用此 skill 启动迭代,不得自行发挥。任何涉及 cml 评测、zk 模型训练、数据增强、badcase 分析、augment_*.jsonl 生成的任务,也应使用此 skill。 用户表达以下任一意图时启用此 skill: - 直接的核心触发短语:「开始,<需求集合名>」(如「开始,icl_test」) - 自然语言的训练/迭代请求:「我要进行模型训练」「开始模型训练」「目标集合是 xxx」「跑一下需求集合 xxx」「迭代 xxx」「针对 xxx 做模型迭代」 - 平台运维:「评测当前模型」「分析 badcase」「Gold drift 检查」「数据增强 augment_*.jsonl」「提交 SFT 训练」「跑 CML workflow」「写 iteration_log」 - 关键词:CML 评测 / SFT / autoresearch / zk 中控理解调度 / requirement set / specific test / metric_diff / lark_template 无需用户严格按「开始,xxx」字面匹配;只要意图涉及小爱中控模型 SFT+评测迭代,就立刻使用此 skill。

autoresearch-zk — 小爱中控模型自主迭代框架

🚫 严禁问用户的事(违反任一条 = 违反 skill)

每次问用户都让用户烦。program.md 已经把"什么时候停"写得很死(17 类 HiTL 信号 + 用户主动打断),这之外一律不准停下来等确认。下面是被反复踩坑的"擅自暂停"模式,全部禁止

禁止说的话 正确做法
"要不要我做训练集近邻检索?" 这是 §2.3 分析必做项,直接做,做完把结果落 report
"下一步可以继续吗?" 永远不问。看 program.md 流程图自己判断
"我先把控制权交回,等你来问跑完了吗" watcher 接手 UI 同步,长任务用 bash(run_in_background=true, wait_for_completion=true) 提交后本轮主动结束;后端会在产物落盘后自动起新一轮把结果送回,直接进 Step 1
"这一步是关键决策点,需要你拍板" program.md 没写就不是。自主决策 + 落 iteration_log
"我把现状停在这里,把决策摘要给你 review" 不准。摘要可以写,但不准停
"Step 4 augment 完成 ,等回调后续做 SFT" augment=complete 那一刻就是 SFT 启动那一刻——同一轮 bash 紧接着跑 §4.5 label-master 复核 + 提交 SFT,不许写简报、不许等回调(详见 program.md "Step 4 → Step 5 硬连接"
"R1 评测发现 regression,先把诊断给你看,等你拍板再决定要不要回滚" dist-analysis 发现 regression 也算 dist-analysis 完成——同轮 bash 紧接着写 results/workflow<runDic>.md(包含完整 delta 表 + new_fail/new_fix 子集 + 病灶定位 + 回滚建议)+ append iteration_log.jsonl R{n} entry。文件落完了再用 chat reply 给人提回滚选项。不许把诊断只写在 chat 里、不落盘——前端「分层结果分析」卡片读的是 results/workflow<runDic>.md,你不写卡片永远停在上轮。

合法暂停只有

  1. program.md ## Human-in-the-Loop 时机 章节的 7 类迭代级信号
  2. ### 训练集调整专项 H-i-T-L 信号 的 T1-T10
  3. §4.0.1 Step B 量级判定的 HiTL 分支
    • 候选量 51-200 条 → 必须全量导出到飞书 sheet 让人逐条审 1/0(这就是一次合法暂停,不是擅自停;不再抽样外推
    • 候选量 >200 条 → 命中触发条件 #3,强制 HiTL 介入让人定更精细 pattern 收窄(仍然全量交付)
  4. 用户主动发消息打断

这之外所有"我觉得这事大、我先停"的本能都要压下来。命中合法暂停时,不要只是说"等你确认"——按 §4.0.1 把全量候选清单(不是抽样)/精细 pattern 的具体输出 dump 到飞书 / scratchpad 给人具体可审的东西,再停。

📋 每个 Step 的强制准入条件(少一项不准进下一步)

按 Step 编号,进入下一 Step 前必须把当前 Step 的准入清单全部完成并落到 state file / iteration_log,否则视为跳步违规。

Step 0 准入

  • cml 环境检查通过(which cml + cml config show
  • runDic 已分配(扫 run_history_dir 取 max+1
  • CML workflow 已提交(拿到 Execution ID
  • watcher 声明已写入 program-state.jsonl
  • cml workflow + 等 metric_diff 落盘已用 bash(run_in_background=true, wait_for_completion=true) 提交(不要在 bash 内 sleep+poll

Step 1 准入(dist-analysis

  • metric_diff/lark_template.json 提分层指标(specific / 大盘车载 / 目标专项)
  • metric_diff/specific_comparison.csv 提取 baseline 错误分布
  • §2.3 失败 case 与训练数据的关联:每条错例在 train_set/zk_intent/*.jsonl 做近邻检索(前 3 近邻),输出"有近邻 / 无近邻"分类
  • §2.3 Reward 对齐检查:全量失败 case 用 zk_reward_fn 验 reward 方向(不抽样)
  • §0.1 Gold drift 检查(如未做)

Step 2 准入(report

  • §2.4 根因归类表(每个 pattern 必归一类,可并列但要主次)
  • 写入 results/workflow<runDic>.md
  • error_registry 追加本轮错误

Step 3 准入(hypothesis — analysis 收尾,不是 train 开头

  • 写本轮假设到 iteration_log.jsonl 的 hypothesis 字段
  • 假设必须有依据(指向 §2.3 / §2.4 的具体发现)
  • 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

Step 1 → Step 2 → 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} entryresults 字段填本轮 metrichypothesis 字段填下一动作)
  • regression 场景同样适用:哪怕 R1 出现导航bvt 纯劣化、可聊可控大幅 -25 这种"必须回滚"信号,先把分析落到 workflow.md 和 iteration_log,再用 chat reply 给人回滚选项。文件先落、聊天再发——顺序不能反。
  • 不许"诊断只写聊天回复 / 等用户拍板再补盘":前端「分层结果分析」卡片读的是 chat_root/results/workflow<runDic>.md;你不写盘卡片永远显示上一轮,看不到 R1 结论。
  • runDic 推进:每轮新评测结果落盘后,append iteration_log.jsonl 一条新 entryrunDic 写新轮的值,比如 R0 是 17793R1 评测的 metric_diff 在 workflow17794,这条 entry 的 runDic 就写 17794),UI 卡片才会切到新一行。
  • 凡是要让用户拍板的检查点(R0 baseline 之后、R{n} regression 之后、>200 候选要定 pattern、Gold drift 复核 等),必须先 append step:"human-check"step:"human-review" running entry,再用 chat reply 提问禁止只在 chat 里问而不写 gate entry——UI 看不到拦截 = 视为没做这步,用户面板上看不到任何卡。详见下方 "Human-in-the-Loop 信号 → 写 gate 节点"。

Step 4 准入(augment,需要修改训练集才进)

  • §4.0 原始训练数据清洗(增强前必做)——按 4 种动作走完逐 pattern 判定
  • §4.0.1 Step A:候选定位输出 csv不直接改
  • §4.0.1 Step B:量级判定走对应支线(≤50 自动 / 51-200 全量人审 / >200 触发 #3,全量交付)
  • §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 + H2 augment_<runDic>.jsonl 跑两层(validate_label_output.py 格式 + Skill 调用 label-master 语义),verdict 写 results/data_clean_<runDic>/label_master_review.jsonl,不通过比例 ≤ 5% 才能进 Step 5

Step 4 → Step 5 边界(NEVER STOP 硬连接,反复踩坑)

  • 写完 augment=complete 那一刻,同一轮 bash 不许结束:紧接着跑 §4.5 label-master 复核 → 写 sft=running → 调 submit_sft_via_cml.sh → 挂 watcher
  • 不许写"Step 4 完成"进度简报后 turn 结束,不许"等回调后续做 SFT"
  • H2 后台任务回调([system] 后台任务 ... exit_code=0不是 turn 结束信号——它只是 augment 子流程的一个中间节拍,agent 必须在同轮里继续走完 §4.5 → Step 5

Step 5 准入(sft

  • §4.5 label-master 复核报告 label_master_review.jsonl 存在且不通过 ≤ 5%
  • 旧 sft_output 已 mv sft_output sft_output_r{prev} 备份
  • 训练参数从 config.yaml 读,model_path = basemodel不从上轮 ckpt 续训

Step 6 准入(log

  • iteration_log.jsonl 完整 schemahypothesis / intervention / prediction / results / verdict / root_cause_findings / error_delta / next_hypothesis

跳步检查

每次写 {step:"X","status":"running"} 前,先看 state file 上一条 step 是不是 complete。如果上一条还在 running 或者跳过了某个 Step回去补,不要往前走。

⚠️ Pipeline UI 同步约定(强制,必读)

平台用户实时盯着 pipeline UI 看你跑到哪一步。卡片状态完全靠你写 program-state.jsonl 驱动;你不写、卡片不动;你嘴上说 running、文件里写 failedUI 就显示 failed。所以下面这些是硬性纪律,不是建议

R1(最重要)— 每一次状态切换都必须先 echo 再做事

进入新 step 之前,第一件事就是 append 一行 running。完成后最后一件事是 append 一行 complete。失败时也必须 append failed永远不要"嘴上"宣布状态切换却没落盘

错误示范(你不许这样):

我现在开始 step 0,跑 CML 评测... [执行很多操作]... 已完成

正确示范:

echo '{"step":"cml","status":"running","ts":"'$(date -Iseconds)'"}' >> "$SESSION_OUTPUT/program-state.jsonl"

(然后才执行 step 0 的具体操作) ...

echo '{"step":"cml","status":"complete","ts":"'$(date -Iseconds)'"}' >> "$SESSION_OUTPUT/program-state.jsonl"

R1.5 — 推荐每条 state entry 带 run_id(让 UI 准确归位 round

新版 UI 按 R0 / R1 / R2 切分 sections。强烈建议每行加 run_id

echo '{"step":"cml","status":"running","run_id":"R0","ts":"'$(date -Iseconds)'"}' >> $S
echo '{"step":"hypothesis","status":"complete","run_id":"R0","ts":"..."}' >> $S    # hypothesis 跟当前轮(R0),不是 R1
echo '{"step":"augment","status":"running","run_id":"R1","ts":"..."}' >> $S        # augment 才是 R1·Train 起点

run_id 缺省时后端会按 iteration_log.jsonl 行数自动推断(analysis 类 step 含 hypothesis → R{count}train 类 step augment/verify/sft → R{count+1}),但显式写更准——尤其是并发跨轮、补写历史 entry、或要在 R0 强制注入 baseline 时。

R2 — 写入即生效,最后一行覆盖前面

后端按 step 字段取最后一条状态。如果你之前写过 failed、现在恢复了,必须 append 一条新的 running,否则 UI 永远停在 failed。

R3 — Step 之间不允许跳步骤而不留状态

进入 dist-analysis 前必须确认 cml 状态已写到 complete(或显式 failed 后用户决定继续)。

R4 — 中长任务用 progress 字段更新

CML 评测、SFT 训练这种几分钟以上的任务,每次轮询/心跳时附带 progress 字段写一条新的 running 行(旧 running 不需删,最后一行最新):

echo '{"step":"cml","status":"running","progress":0.4,"ts":"'$(date -Iseconds)'"}' >> "$SESSION_OUTPUT/program-state.jsonl"

UI 卡底部进度条会跟着动;不写就一直显示初始进度。

State 文件位置

<远端 workspace>/output/program-state.jsonl

bash 命令是在 远端 workspace 里跑的(一般 /root/zk_agent_workspaces/LOCALID_xxx),系统提示里的「当前会话目录」是 后端宿主机的本地路径不能直接拿来当 SESSION_OUTPUT——拿了等于在远端凭空建一条同名死路径,后端 sync 永远读不到,前端卡片就一直不动。

正确做法:用远端 cwd 派生(pwd 就是当前远端 workspace),目录确保存在:

SESSION_OUTPUT="$(pwd)/output"
mkdir -p "$SESSION_OUTPUT"

或者显式写远端绝对路径 SESSION_OUTPUT="/root/zk_agent_workspaces/LOCALID_<本会话 id>/output"绝对不要

  • 拷系统提示里的 /home/mi/zk-data-agent-wsh/.port_sessions/.../output(那是后端本地,远端没这条)
  • 写到 /mnt/wangsenhao/... 或项目根目录(多会话互相覆盖)

后端 _sync_remote_program_state 只读远端 {workspace_cwd}/output/program-state.jsonl —— 路径写错 = 前端死锁。

Step key 表(必须用这套 key,否则匹配不到卡片)

step key 对应卡片
cml CML 评测
gold-drift Gold Drift
dist-analysis 分层结果分析
report 问题分析 & 报告
hypothesis 形成假设
augment 数据增强
verify 修改返回验证
sft SFT 训练
log 记录迭代日志
next-round 下一轮评测(边界标记,不生成卡片,仅推进 UI 的 run_id 推断)
human-check Human CheckHiTL 网关;命中 HiTL 时 agent 显式写,UI 在对应 round section 后插入 gate 卡)
human-review Human Review(同上,多用于"建议人审 1/0"或"建议回滚"等需要人拍板的检查点)

KPI(你不要写,后端读权威源)

顶部 7 个 KPIRUN ID / VERSION / 目标集合 / 大盘车载 / SPECIFIC TEST / ITERATION / 耗时)由后端从权威源直接读取:

KPI 后端读取自
RUN ID RUN_HISTORY_DIR(默认 /mnt/xiaoai-zk-model-train-tj5/workflow5/)下 workflow<N>/ 取 max N
VERSION skills/model-iteration/assets/config.yamlcml_eval.version
目标集合 从 session 最新 user 消息里解析 "开始, <name>" 中的 name
大盘车载 / SPECIFIC TEST RUN_HISTORY_DIR/workflow<runDic>/metric_diff/lark_template.json
ITERATION $AUTORESEARCH_CHAT_ROOT/results/iteration_log.jsonl 行数(每 chat 独立)
耗时 program-state.jsonl 第一条 {step:"cml",status:"running"}ts 到现在

你不要再写 {"kpi":...}——写了也会被后端忽略,不显示。如果想让用户看到某个 KPI 的当前值,把它落到对应的权威源(比如改 config.yaml、写 iteration_log),后端会自动读到。

Watcher(长任务的 UI 状态副车,不是给你交回控制权的借口

CML 评测 / SFT 训练这类几分钟到几十分钟的长任务,声明 watcher 让后端自动检测产物文件并把 step=complete 写到 state file——这样 UI 的卡片状态不依赖你主动写 complete,watcher 替你写。

但你仍然必须留在当前迭代里继续干活,遵守 program.md 里的 NEVER STOP / 全程不打断用户 原则:

  • 不许给用户回"控制权交回 / 我先停下 / 等你来问"这种话
  • 不许主动结束本轮(除非命中 program.md 里写明的 H-i-T-L 阻断信号)
  • 长任务(cml 评测、SFT 训练)必须bash(run_in_background=true, wait_for_completion=true) 提交:把"提交远端任务 + 等产物落盘"打包成一个 bg 命令;本轮 agent 主动结束(不是交回控制权——是把等待这件事 detach 给后端),产物落盘后后端自动起新一轮,agent 收到 stdout 直接进 Step 1
  • 不许在 bash 里写 while true; do sleep 60; done 这种轮询循环——bash 命令有 30s 硬超时,会被切成几十个 step,把本轮 50 step 上限耗尽留不出做分析的预算

watcher 解决的是 UI 与 agent 异步UI 不用等 agent 写状态,watcher 替 agent 把 complete 落盘。它不是替你"放假"。

格式:

# 进入 step 时按规则写 running
echo '{"step":"cml","status":"running","ts":"'$(date -Iseconds)'"}' >> "$SESSION_OUTPUT/program-state.jsonl"

# 紧接着声明 watcher:当目标文件出现 → 后端自动写 cml=complete
echo '{"watch":{"step":"cml","kind":"file_exists","path":"/mnt/xiaoai-zk-model-train-tj5/workflow5/workflow17782/metric_diff/lark_template.json","interval":30,"timeout":3600,"run_id":"R0"}}' >> "$SESSION_OUTPUT/program-state.jsonl"

字段:

字段 必填 说明
step 跟卡片 step key 一致(cml / sft / augment ...
kind 当前只支持 file_exists
path 目标文件绝对路径。文件出现就视为 step 完成
interval 轮询间隔秒,默认 30,最小 2
timeout 整体超时秒,默认 3600,超时写 failed
run_id 写入 Live Log 时的 iter 标签

watcher 资源管理

  • 同一 (session, step) 已有 watcher 在跑时,重复声明被忽略
  • step 已经有 complete/failed 行后,watcher 声明会被忽略
  • 后端 scanner 5 秒扫一次所有会话的 state file

典型用法CML workflow用 bg 模式 + watcher):

长任务必须用 bash(run_in_background=true, wait_for_completion=true) 提交。bg 命令在远端 detach 跑、立刻返回 task_id;产物落盘后后端自动起新一轮把 stdout 作为 system 消息送回 agent不要在 bash 里 sleep+poll。watcher 仍然要声明——它驱动 UI 卡片状态,跟 bg 任务是两条独立的通道。

# 1. 写 running + watcher 声明(UI 卡片靠它)
echo '{"step":"cml","status":"running","ts":"'$(date -Iseconds)'"}' >> $S

# 2. 用 bg 模式:把"提交 cml + 等 metric_diff 落盘"一次封装
#    wait_for_completion=true(默认):进程结束后后端自动起新一轮把 stdout 送回
bash(run_in_background=true, command='''
  set -e
  RUNDIC=$(cml workflow run --workflow_id "$WORKFLOW_ID" ...)
  echo "RUNDIC=$RUNDIC"
  TARGET=/mnt/xiaoai-zk-model-train-tj5/workflow5/workflow$RUNDIC/metric_diff/lark_template.json
  while [ ! -f "$TARGET" ]; do sleep 60; done
  echo "EVAL_DONE runDic=$RUNDIC target=$TARGET"
''')

# 3. 紧接着声明 watcherUI 卡片切到 complete 靠它,runDic 在 bg 任务 stdout 里)
#    watcher path 用稍后从 bg stdout 拿到的 runDic 拼;如果先不知道 runDic
#    可以等 bg 任务返回 RUNDIC 后这一轮里再补声明 watcher。
echo '{"watch":{"step":"cml","kind":"file_exists","path":"'$ROOT/workflow$RUNDIC/metric_diff/lark_template.json'","interval":30,"timeout":7200,"run_id":"R'$N'"}}' >> $S

# 4. 跟用户简报一句"已提交,等产物落盘后会自动续",agent 这一轮主动结束
#    (不是交回控制权——是把等待这件事 detach 给后端)

# 5. 产物落盘后,后端起新一轮,agent 收到 stdout(含 RUNDIC + EVAL_DONE
#    → 立刻进入 Step 1,读 metric_diff、做分层分析、写报告……整轮 50 step 全用在分析上

为什么不能在 bash 里 sleep+pollbash 工具有 30s 硬超时,sleep 60 会被切成 sleep 25 + sleep 5 两个 step;评测跑 25 分钟 = ~50 step 全耗在等待上,留不出做分析的预算。bg 模式只占 1 个 step。

bg 任务排查agent 中途想看进度,可以 bash_status(task_id) 拿当前 stdout/exit_code 快照;想终止远端进程要 bash_kill(task_id)(前端按 stop 不会杀 bg 任务,那是 detach 的本意)。

Live log(可选)

要把日志推到 UI 底部那块黑色 Live Log 区,追加:

echo '{"log":{"ts":"11:55:10","iter":"R3","text":"Step 3 开始: 问题分析 & 报告生成"}}' >> "$SESSION_OUTPUT/program-state.jsonl"

不要做的事

  • 不要写 program.md(旧机制已废弃,写了也没用,平台现在不读它)。
  • 不要把 state 文件写到 /mnt/wangsenhao 或仓库根目录——只写当前会话的 output/program-state.jsonl
  • 不要用与上表不一致的 step key(比如 step:"评测"step:"step0"),UI 匹配不到。
  • 不要重写整个文件(每行只追加,append 即可),重写会导致 UI 闪。

快速参考

项目
触发信号 "开始,<需求集合名>"
评测 workflow f-20260408161444-wu3pz(版本见 config.yaml
训练基模 /mnt/wangsenhao/verl_zk/Qwen3-4B-Instruct-2507
工作目录 $AUTORESEARCH_CHAT_ROOT(每 chat 独立,由后端注入;位于共享 NFS:/mnt/wangsenhao/autoresearch-zk-users/<email_prefix>/<chat_session_id>/jupyter pod 与训练 pod 都能读写)
历史记录目录 /mnt/xiaoai-zk-model-train-tj5/workflow5/
需求集合位置 https://git.n.xiaomi.com/ai-service/ai-planning/-/tree/autoresearch-v1ai-planning/data/specific_test_set/

工作空间隔离(按用户 + 每 chat 二级隔离,落在 NFS)

每个 chat session 一份独立工作区 $AUTORESEARCH_CHAT_ROOT(后端在 jupyter 启动时自动注入这个 envagent 每次 bash 都能拿到)。该目录位于共享 NFS:

/mnt/wangsenhao/autoresearch-zk-users/<email_prefix>/<chat_session_id>/

<email_prefix> 是用户登录时的小米邮箱前缀(xxx@xiaomi.comxxx),用作账号根目录;同一用户跨 chat 共享根目录但 chat 之间完全隔离。

为什么放 NFS 而不是 jupyter pod 私有路径SFT 训练在独立的 pytorch pod 里跑,那个 pod 不挂载 jupyter pod 的 workspace;放共享 NFS 是双方都能 cd 进去的唯一选择。

所有写入路径都必须以 $AUTORESEARCH_CHAT_ROOT 开头,不要写 hard-coded /mnt/wangsenhao/autoresearch-zk/... 全局路径,也不要写 jupyter pod 本地路径(/root/zk_agent_workspaces/...),训练 pod 看不到。

资产 位置 隔离方式
prepare_and_train_sft.py $AUTORESEARCH_CHAT_ROOT/scripts/ 后端 bind 时从 skill bundle 推过来,每次刷新最新版
ai-planning/(含 corpus + augment $AUTORESEARCH_CHAT_ROOT/ai-planning/ 首次访问前你自己 git clone(见 program.md 「ai-planning bootstrap」)
zk_trainer/ $AUTORESEARCH_CHAT_ROOT/zk_trainer/ Step 5 首次 SFT 前你自己 git clone(见 program.md §5.0
results/iteration_log.jsonl $AUTORESEARCH_CHAT_ROOT/results/ 每 chat 独立累积;后端 KPI 也读这里
results/error_registry.jsonl 同上 每 chat 独立
results/workflow<runDic>.md / data_clean_<runDic>/ / augment_raw/ 同上 每 chat 独立
sft_output/ $AUTORESEARCH_CHAT_ROOT/sft_output/ 每 chat 独立,互不覆盖;训练 pod 走 NFS 直接写
augment_<runDic>.jsonl $AUTORESEARCH_CHAT_ROOT/ai-planning/data/train_set/zk_intent/ 写在 chat 自己的 ai-planning clone 内,下一次 SFT prepare 只合并本 chat 的增量

保持全局共享的资产(不要按 chat 拆):

  • runDic 计数:/mnt/xiaoai-zk-model-train-tj5/workflow5/max+1 是平台级唯一标识)
  • 训练基模:/mnt/wangsenhao/verl_zk/Qwen3-4B-Instruct-2507(只读模型权重)
  • metric_diff 输出:/mnt/xiaoai-zk-model-train-tj5/workflow5/workflow<runDic>/metric_diff/cml workflow 写)

每个 step 落产物时务必用 $AUTORESEARCH_CHAT_ROOT 作前缀(例如 cd $AUTORESEARCH_CHAT_ROOT && python scripts/prepare_and_train_sft.py ...,或 echo ... >> $AUTORESEARCH_CHAT_ROOT/results/iteration_log.jsonl)。

核心原则

  1. 评测优先"开始" 信号的第一个动作永远是评测当前模型,绝不直接训练
  2. 假设驱动:每轮必须能回答"这轮验证了什么?学到了什么?下一轮改什么?"
  3. NEVER STOP:全程不打断用户,循环直到达标或人类主动打断
  4. 从 basemodel 训练:每轮 SFT 的 --model_path 必须是 basemodel,禁止从上轮 ckpt 继续训

达标条件

  • 需求集合 ≥ 95%(最高优先级)
  • 大盘集(车载) 降幅 ≤ 0.3%
  • specific test 降幅 ≤ 1%

主流程

读取 references/program.md 获取完整的 Step 0-7 迭代循环规范。在任何操作前必须读取该文件。

每个 step 的执行模板(强制,配合上文「Pipeline UI 同步约定」R1):

1. echo '{"step":"<key>","status":"running","ts":"..."}' >> $SESSION_OUTPUT/program-state.jsonl
2. (执行该 step 的实际操作 / 调用工具 / 等结果)
3. 成功: echo '{"step":"<key>","status":"complete","ts":"..."}' >> ...
   失败: echo '{"step":"<key>","status":"failed","error":"...","ts":"..."}' >> ...

step key 跟 Step 编号映射:

Step step key 说明
Step 0 cml CML 评测当前模型
Step 0 (附带) gold-drift Gold drift 检查
Step 1 dist-analysis 分层结果分析
Step 2 report 问题分析 & 报告
Step 3 hypothesis 形成假设(写 iteration_log
Step 4 augment 数据增强 / 生成
Step (干预后) verify 修改返回验证
Step 5 sft SFT 训练
Step 6 log 记录迭代日志
循环 next-round 回 Step 0 评测新 ckpt
LOOP:
  Step 0: CML 评测(当前模型)+ Gold drift 检查
  Step 1: 分层结果分析(需求集合 → 大盘车载 → specific test
  Step 2: 问题分析 & 报告(根因归类 / 跨轮 diff / 天花板诊断)
  Step 3: 形成假设(写入 iteration_log.jsonl
  Step 4: 数据生成(仅 data 归因时做)
  Step 5: SFT 训练(submit_sft_via_cml.sh
  Step 6: 记录结果(iteration_log.jsonl / error_registry.jsonl
  → 回 Step 0

文件结构

references/
  program.md              # 完整迭代循环规范(必读,包含所有 Step 的详细说明)
  knowledge/
    navigation_routing_rules.md    # 地图导航 Agent/CT 分流规则
    travel_routing_rules.md        # 旅游 Agent/CT 分流规则
    multi_command_rules.md         # 多指令 vs ComplexTask 分流规则
    multiturn_continuity_rules.md  # 多轮对话 CT 继承规则

scripts/
  prepare_and_train_sft.py  # 数据组装 + SFT 训练脚本

assets/
  config.yaml              # 评估阈值 + CML workflow 配置

何时读取各文件

操作 读取
启动迭代前 references/program.md(完整流程,必读)
badcase 归类 / 数据增强标注时 references/knowledge/ 下对应规则文件
数据组装 / 训练前 scripts/prepare_and_train_sft.py(了解脚本参数)
评测阈值 / workflow 版本 assets/config.yaml

Human-in-the-Loop 信号(需暂停问人)

共 7 类迭代级信号 + 10 类训练集调整信号(T1-T10),详见 references/program.md 的"Human-in-the-Loop 时机"章节。

最常触发的

  • Gold drift ≥ 10 条(#1
  • 要批改旧标签 > 50 条(#3 / T1
  • 跨子集净退步(#4
  • 连续 3 轮目标子集净提升 ≤ 0.5pp(#5)

写 gate 节点(让 UI 显示 Human Check / Review 卡)

凡是要让用户拍板的检查点,必须 append 一条 gate entry 到 program-state.jsonl 用 chat reply 提问。UI 会在当前 round section 之后插入「Human Check」或「Human Review」横向卡片(IN PROGRESS 状态)。

禁止:只在 chat 里问用户、不写 gate entry。UI 看不到拦截 = 视为这一步没做——用户在面板里看不到任何卡,会以为流程卡死或还在自动推进。这是反复踩坑点:以前 agent 经常在 R0 baseline 跑完后聊天里问"要不要进 R1 train",但 program-state 一直在写 augment runningUI 里完全看不到 gate。

什么时候要写

需要用户拍板就写——不管 R0 还是 R{n≥1},触发条件都按 §HiTL 信号判:

时机 gate 类型 run_id
R0 baseline 分析完成、要让用户确认是否进 R1 train(命中 HiTL 信号 / 候选量大 / 目标子集偏低 / 第一次跑想让用户校方向 等) human-check R0
R{n≥1} analysis 完成、命中 §HiTL 信号(gold drift / regression / 跨子集退步 / 连续 3 轮无提升 等) human-review R{n}
§4.0.1 Step B:候选量 > 200 条命中触发条件 #3 human-check 当前 round
其他 HiTL 信号(要批改旧标签 > 50 条、Gold drift ≥ 10 条 等) human-check(开始前)/ human-review(结果后) 当前 round

判断标准就一条:只要你下一步打算 chat-ask 用户拍板,就先写 gate entry 再问

写法

强烈推荐结构化三段写法summary / proposal / ask)——UI 会渲染成"现状 / 提议 / 请选"三个带标签行,用户一眼看明白。reason 留作 fallback。

# R0 baseline 之后想让用户拍板是否进 train(推荐结构化)
echo '{"step":"human-check","status":"running","run_id":"R0",
  "summary":"R0 baseline 完成;复杂导航过召专项0511 = 58.89%(53/90)37 错全为 complex 误判",
  "proposal":"H1(标签纠错):把 7 条原标 complex=true 但实际是简单导航的样本改回 complex=false。 H2(数据增强):仿写 100 条 complex=false 的简单导航 query 补进训练集,平衡正负样本",
  "ask":"是否按 H1+H2 一起进 R1 train?还是先只跑 H1 验证一轮?",
  "ts":"'$(date -Iseconds)'"}' >> $S

# R1 评测发现 regression
echo '{"step":"human-review","status":"running","run_id":"R1",
  "summary":"R1 vs R0:导航bvt -3.2pp,可聊可控 -25pp,目标子集 +1.4pp",
  "proposal":"回滚到 R0 权重;下一轮把 H2 仿写量减半,避免对 complex=false 过拟合",
  "ask":"回滚 R0 还是继续跑 R2 看曲线?",
  "ts":"'$(date -Iseconds)'"}' >> $S

# fallback:只写 reason 也能跑(前端会启发式切分),但不如结构化清晰
echo '{"step":"human-check","status":"running","run_id":"R0","reason":"候选量 412 命中规则上限,需要人工定更精细 pattern 收窄","ts":"'$(date -Iseconds)'"}' >> $S

顺序不能反:先 echo gate entry → 再 chat reply 给用户。否则用户先看到聊天问话、UI 里却没卡,会困惑"流程是不是卡死了"。

字段说明

字段 必填 说明
step human-checkhuman-review
status 卡进入时写 running;用户回复后写 complete
run_id 当前所在轮次(决定 gate 插在哪个 section 后)
summary 🔼 现状一句话:跑了什么、关键数字。例:R0 baseline 完成;专项 58.89%(53/90)37 错全为 complex 误判
proposal 🔼 打算怎么干:每个 H 单独说"H? (类型):具体做什么"。详见下面规则
ask 🔼 让用户选什么:用问句给出 A/B 选项。例:是否按 H1+H2 进 R1 train?还是先只跑 H1 验证一轮?
reason 兜底用:没写 summary/proposal/ask 时前端会拿 reason 做启发式切分。但优先用结构化三段,别只写 reason
ts ISO 时间戳

🔼 = 强烈推荐写——三段都填 UI 会变成清晰的"现状/提议/请选"分块;都不填只填 reason 也能跑,但用户要自己抠语义。

proposal 写法规则(关键)

每个假设单独一句,结构 = H? (一两个字概括类型):具体动作 + 数量 + 目标。比如:

  • H1(标签纠错):把 7 条原标 complex=true 但实际是简单导航的样本改回 complex=false
  • H2(数据增强):仿写 100 条 complex=false 的简单导航 query 补进训练集
  • H1 修 7 条 mislabeled ← 用户要猜 mislabeled 是什么意思
  • H2 仿写 100 条 complex=false 简单导航 ← 没说补到哪、为啥补

不要写进 proposal 的内容

  • §X.X.X 规则引用(触发 §4.0.1 Step B命中条件 #3)—— 用户不关心你按哪条规则做的,只关心你要做什么
  • 流程自洽说明(需要人工逐条审 1/0走 sanity check过 label-master 复核)—— 这些是 agent 内部流程,对用户决策没用
  • 候选量区间括号注释(100~150 触发 51-200 区间)—— 数量 OK,区间归属归属是规则细节,删

写 proposal 时问自己:"这句话如果交给一个新加入的产品同学看,他能不能 5 秒内明白要干什么"。能 = ;得回头查 §X.X.X 才能懂 = ,重写。

用户拍板回复后append status:"complete" 同 step + run_id 一行,gate 卡变 COMPLETED;然后才继续往下走(继续/回滚/调参)。

两种 gate 的区分(约定)

  • human-check:偏"开始前的检查"——baseline → train 网关、>200 条候选定 pattern、Gold drift 复核
  • human-review:偏"结果出来要复核"——R{n} 评测出来发现 regression 要不要回滚、目标集合连续 3 轮无提升要不要换思路

实际差别在 UI 上不大(都是横向 dashed 卡),区分主要为了让用户从标题就大致知道是开始前还是结果后的检查点。

CML 配置(快速查阅)

# ~/.config/cloudml/config.yaml
default_config_context: cloudml5-config
xiaomi_cloudml:
  cloudml5-config:
    xiaomi_auth_type: key
    xiaomi_cloudml_endpoint: https://cnbj6-cloudml5.api.xiaomi.net
    xiaomi_cloudml_workspace_id: 10065

结果文件

文件 用途 前端卡片
results/iteration_log.jsonl 每轮假设/干预/判定完整记录 hypothesis / log
results/error_registry.jsonl 跨轮错误追踪(case_hash → 出错轮次) log
results/workflow<runDic>.md 每轮回归分析报告 dist-analysis / report
output/relabel_candidates_<runDic>.csv 阶段一:预计修改训练集候选清单(complex 翻转候选等) dist-analysis(分层结果分析)
results/data_clean_<runDic>/modified_samples.jsonl 阶段二:确认修改最终落盘(用户审核 1/0 后实际生效的改动) augment(数据增强)
results/data_clean_<runDic>/deleted_samples.jsonl 旧数据清洗存档(删除项)
results/augment_raw/augment_<runDic>_raw.jsonl GPT-5.4 仿写原始产物 augment
ai-planning/data/train_set/zk_intent/augment_<runDic>.jsonl 本轮合入训练集的增量(H1 重标 + H2 仿写) augment
results/gold_drift/drift_<runDic>.json Gold drift 检测结果 gold-drift
results/label_rules.md 已确立的标签规则集(R1~RN

两阶段训练集修改的展示约定:候选阶段(量级判定 + 人审 1/0 之前)写在 output/relabel_candidates_<runDic>.csv,前端「分层结果分析」卡片读取展示供人审;确认阶段(人审后落盘)写在 results/data_clean_<runDic>/modified_samples.jsonl,前端「数据增强」卡片读取展示最终改动。详见 references/program.md §4.0.1 Step A