fix: session resume, config_set schema, metrics chart, subagent logging

- Fix session resume: remove messages.length>1 guard so sessionStorage
  ID is used as resumeSessionId on first message (prevents new session
  creation when user sends "继续")
- Fix config_set tool schema: add missing `items: {}` to array type in
  oneOf (Azure OpenAI strict validation rejects it otherwise)
- Metrics chart: use actual target set filename from trigger text
  instead of generic "target_subset" key
- Add sub-agent skill call logging to agent_runtime.py (full
  prompt/response, no truncation)
- Various metric enrichment and dedup fixes in server.py

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
wangsenhao
2026-05-27 17:02:24 +08:00
parent 89e77140e7
commit 85ce8c0e69
8 changed files with 411 additions and 40 deletions
+36 -8
View File
@@ -87,8 +87,8 @@ when_to_use: |
- [ ] §4.0.1 Step B:量级判定基于 label-master 处理后的**残留候选量**走对应支线(≤50 自动按 label-master 推荐改 / 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` 只跑层 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",完全没走语义判断。
- [ ] **§4.5 label-master 标签复核(落盘后必做,强制H1+H2 都要**H1 `modified_samples.jsonl` **和** H2 `augment_<runDic>.jsonl` 都必须跑两层(`validate_label_output.py` 格式 + Skill 调用 `label-master` 语义),**逐条 1:1 全量覆盖**。§4.0.1 A.5 的预审是粗筛,**不能替代落盘前的 layer2 语义复核**。verdict 写 `results/data_clean_<runDic>/label_master_review.jsonl`,**不通过必须 = 0**(任何不通过必须修正后重新 review 直到全 pass 才能进 Step 5
- [ ] **§4.5 层 2 语义复核必须通过子 agent 调用 `Skill(skill="label-master")`,禁止主 agent 直接调、禁止正则/规则脚本替代**:主 agent 把待审列表写入 `scratchpad/lm_input.jsonl`,起子 agent`delegate_agent(prompt="...", allow_shell=true)`)逐条调 label-master,结果写 `scratchpad/lm_output.jsonl`,主 agent 读取汇总。子 agent prompt 里给**绝对路径**。**禁止**:主 agent 直接调 Skill(skill="label-master")、纯正则/关键词匹配脚本、"target 都一样所以直接 pass"逻辑、批量写 pass 不看 query 内容。
### 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 里串接评测)
@@ -128,17 +128,45 @@ when_to_use: |
> echo '{"step":"cml","status":"complete","ts":"'$(date -Iseconds)'"}' >> "$SESSION_OUTPUT/program-state.jsonl"
> ```
### R1.5 — 推荐每条 state entry 带 run_id(让 UI 准确归位 round
### R1.5 — 每条 state entry 必须带 run_id(让 UI 准确归位 round
新版 UI 按 R0 / R1 / R2 切分 sections。**强烈建议**每行 `run_id`
新版 UI 按 R0 / R1 / R2 切分 sections。每个 R{n>=1} 同时包含 **Train****Analysis** 两个 section。**必须**每行 `run_id`
⚠️ **核心规则:run_id 只在 hypothesis=complete 之后递增。** 一个完整迭代(augment → sft → eval → analysis → hypothesis)全程使用同一个 run_id。
完整示例(一轮完整迭代 R1):
```bash
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 起点
# ─── R0·Baseline ───
echo '{"step":"cml","status":"running","run_id":"R0"}' >> $S
echo '{"step":"dist-analysis","status":"complete","run_id":"R0"}' >> $S
echo '{"step":"hypothesis","status":"complete","run_id":"R0"}' >> $S
# ← hypothesis=complete → 递增 run_id
# ─── R1·Train ───
echo '{"step":"augment","status":"running","run_id":"R1"}' >> $S
echo '{"step":"augment","status":"complete","run_id":"R1","count":80}' >> $S
echo '{"step":"sft","status":"running","run_id":"R1"}' >> $S
echo '{"step":"sft","status":"complete","run_id":"R1"}' >> $S
# ─── R1·AnalysisSFT 后的 eval 仍然是 R1,不是 R2!)───
echo '{"step":"cml","status":"running","run_id":"R1"}' >> $S
echo '{"step":"cml","status":"complete","run_id":"R1"}' >> $S
echo '{"step":"dist-analysis","status":"complete","run_id":"R1"}' >> $S
echo '{"step":"hypothesis","status":"complete","run_id":"R1"}' >> $S
# ← hypothesis=complete → 递增 run_id
# ─── R2·Train ───
echo '{"step":"augment","status":"running","run_id":"R2"}' >> $S
# ...
```
run_id 缺省时后端会按 `iteration_log.jsonl` 行数自动推断(analysis 类 step 含 hypothesis → R{count}train 类 step augment/verify/sft → R{count+1}),但显式写更准——尤其是并发跨轮、补写历史 entry、或要在 R0 强制注入 baseline 时。
**错误(禁止)**eval 后递增 run_id,导致 train 和 analysis 分属不同 round
```
R1: augment+sft → R2: cml+analysis+hypothesis → R3: augment+sft → R4: cml+analysis ...
```
**为什么重要**:后端通过 `per_round[R{n}]` 从 R{n}·Analysis 的 watch/log entry 解析 runDic,再用这个 runDic 去找 R{n}·Train 的 augment 产物文件。如果 train 和 analysis 用了不同 run_idaugment 的产物文件找不到。
### R2 — 写入即生效,最后一行覆盖前面