$npx -y skills add QFIN-tech/model-evo --skill uplift-model-result-comparison已有两个或更多 experiment_ids 或底层 candidate_result_paths 时,用于在同一任务和评估 split 下先生成比较方案,用户确认后做确定性模型比较,输出比较表、摘要报告和推荐模型 path。不要用于训练、调参、最终报告或模型采用决策。
| 1 | # 多模型结果比较 |
| 2 | |
| 3 | ## 1. 输入依赖 |
| 4 | |
| 5 | 本 skill 读取显式候选 experiment 或底层 result path,规范化 baseline modeling 与 tuning winner 的指标,校验可比性,并在可公平比较且用户确认后给出推荐模型 path。 |
| 6 | |
| 7 | 已有两个或更多 `experiment_ids` 或底层 `candidate_result_paths` 后使用。 |
| 8 | |
| 9 | ## 2. 执行入口 |
| 10 | |
| 11 | 统一 CLI: |
| 12 | |
| 13 | ```bash |
| 14 | python <skill-dir>/scripts/run.py --input - --output-dir <output_dir> |
| 15 | ``` |
| 16 | |
| 17 | Windows 环境可按需将路径分隔符改为反斜杠。 |
| 18 | |
| 19 | `--output-dir` 必须是已存在的 `run_dir`;runner 不创建 run_dir,不扫描 `latest/current`。`draft_comparison_plan` 创建 comparison flow;正式 `compare` 应显式传入上一步 `outputs.flow_dir` 和 `outputs.comparison_plan_path` 复用该 flow。所有 stdout、result、manifest 和 log 中的持久化 path 都是 `run_dir` 相对路径。 |
| 20 | |
| 21 | 请求 JSON 必须通过 stdin 传入: |
| 22 | |
| 23 | ```json |
| 24 | {"action": "draft_comparison_plan", "payload": {"experiment_ids": ["exp-001-s_learner_baseline", "exp-002-t_learner_baseline"], "comparison_dataset_role": "test"}} |
| 25 | ``` |
| 26 | |
| 27 | 用户确认 comparison plan 后,再执行正式比较: |
| 28 | |
| 29 | ```json |
| 30 | {"action": "compare", "payload": {"flow_dir": "...", "comparison_plan_path": "..."}} |
| 31 | ``` |
| 32 | |
| 33 | runner stdout 是 JSON object。调用方只读取 stdout 或 result JSON 中的 `outputs.*` 字段,例如 `outputs.comparison_plan_path`、`outputs.recommended_comparison_mode`、`outputs.comparison_table_path`、`outputs.model_comparison_summary_path`、`outputs.recommended_candidate_result_path`、`outputs.report_path`。 |
| 34 | |
| 35 | 只接受显式 `*_path` / `*_paths` 字段。收到旧的 `*_ref` / `*_refs` 输入时,runner 返回 `needs_input`,并在 `issues` 与 `next_steps` 中给出对应替代字段。 |
| 36 | |
| 37 | ## 3. Actions 与参数说明 |
| 38 | |
| 39 | `draft_comparison_plan` |
| 40 | |
| 41 | - 输入:`experiment_ids`;底层调试或临时手动接力时可改用 `candidate_result_paths`。 |
| 42 | - 可选输入:`comparison_dataset_role`,支持 `test`、`oot`、`train`、`valid` / `validation`。 |
| 43 | - 输出: |
| 44 | - `comparison_plan_path` |
| 45 | - `recommended_comparison_mode` |
| 46 | - `requires_user_confirmation=true` |
| 47 | |
| 48 | `draft_comparison_plan` 只生成 comparison plan,不执行正式比较;返回 `status=needs_confirmation`。推荐使用 `experiment_ids`,runner 从 `{run_dir}/new-models/{experiment_id}/_experiment_manifest.json` 读取候选信息。`experiment_ids` 和 `candidate_result_paths` 二选一,不能混用。 |
| 49 | |
| 50 | `compare` |
| 51 | |
| 52 | - 推荐输入:`comparison_plan_path`,通常来自 `draft_comparison_plan` 的 `outputs.comparison_plan_path`。 |
| 53 | - 底层调试输入:`task_config_path`、`candidate_result_paths`。 |
| 54 | - 可选输入:`comparison_dataset_role`,支持 `test`、`oot`、`train`、`valid` / `validation`。 |
| 55 | - 输出: |
| 56 | - `comparison_table_path` |
| 57 | - `model_comparison_summary_path` |
| 58 | - `report_path` |
| 59 | - `recommended_primary_model_path` |
| 60 | - `recommended_candidate_result_path` |
| 61 | |
| 62 | `compare` 的主链路入口是已确认的 `comparison_plan_path`。`candidate_result_paths` 仅作为底层显式输入保留,用于调试、未注册候选或临时手动接力;不作为新体系推荐入口。后续应通过外部候选注册机制进一步弱化或剔除面向用户的裸 `candidate_result_paths` 用法。 |
| 63 | |
| 64 | `candidate_result_paths` 可以包含 `uplift-model-s-learner-modeling` 或 `uplift-model-t-learner-modeling` 的 `modeling_result_path`,也可以包含 `uplift-model-tuning` 的 S-Learner/T-Learner execute result path;必须至少两个。 |
| 65 | |
| 66 | comparison 从 `model_candidate.model_spec.model_type` 或 `outputs.learner` 识别 learner,不固定为 `s_learner`。 |
| 67 | |
| 68 | 以下候选会进入 comparison table,但不可推荐: |
| 69 | |
| 70 | - 指定 split 缺少 `split_evaluations`:`MISSING_SPLIT_EVALUATION` |
| 71 | - `metric_value = null` 或不可转成 finite number:`NON_RECOMMENDABLE_CANDIDATE` |
| 72 | - population fingerprint 或 dataset role 不一致:`EVALUATION_POPULATION_MISMATCH` |
| 73 | - `metric_name`、`metric_direction`、`auuc_version.package` 或 `auuc_version.version` 不一致:`EVALUATION_METHOD_MISMATCH` |
| 74 | |
| 75 | 候选缺少 `auuc_version` 或不是 `{"package": "scikit-uplift", "version": "0.5.1"}` 时不可比较。comparison 以 `outputs.split_evaluations.<split>` 作为 AUUC 结果主 contract,不再用旧 `outputs.modeling_metrics.splits` 绕过 split evaluation contract。 |
| 76 | |
| 77 | ## 4. 输出产物 |
| 78 | |
| 79 | 典型输出目录: |
| 80 | |
| 81 | ```text |
| 82 | {run_dir}/uplift-model-result-comparison/{timestamp}_model_comparison/ |
| 83 | inputs/0001_draft_comparison_plan.request.json |
| 84 | results/0001_draft_comparison_plan.result.json |
| 85 | artifacts/ |
| 86 | comparison_plan.v1.json |
| 87 | model_comparison.v1.csv |
| 88 | model_comparison_summary.v1.json |
| 89 | _flow_manifest.json |
| 90 | _flow_log.jsonl |
| 91 | report.md |
| 92 | ``` |
| 93 | |
| 94 | 报告保持轻量业务摘要形态,包含:最终推荐模型、模型产物索引、AUUC 对比、分箱性能对比、可比性与限制。 |
| 95 | |
| 96 | ## 5. 与其他 skill 的关联 |
| 97 | |
| 98 | | 方向 | Skill | 关系 | |
| 99 | |---|---|---| |
| 100 | | 上游 | `uplift-model-s-learner-modeling` / `uplift-model-t-learner-modeling` | 提供 baseline `experiment_ids` 或 `modeling_result_path` | |
| 101 | | 上游 | `uplift-model-tuning` | 提供 tuned winner `experiment_id` 或 `winner_model_result_path` | |
| 102 | | 下游 | `uplift-model-reporting` | 消费 `model_comparison_summary_path`、`recommended_candidate_result_path` 和报告证据 | |
| 103 | |
| 104 | ## 6. 执行约束 |
| 105 | |
| 106 | 本 skill 不训练模型,不调参,不重算上游指标,不生成最终建模报告,也不代表模型采用或部署。 |
| 107 | |
| 108 | `draft_comparison_plan` 只生成 comparison plan,不执行正式比较;返回 `status=needs_confirmation`。推荐使用 `experiment_ids`,runner 从 `{run_dir}/new-models/{experiment_id}/_experiment_manifest.json` 读取候选信息。`experiment_ids` 和 `candidate_result_paths` 二选一,不能混用。 |
| 109 | |
| 110 | `compare` 的主链路入口是已确认的 `comparison_plan_path`。`candidate_result_paths` 仅作为底层显式输入保留,用于调试、未注册候选或临时手动接力;不作为新体系推荐入口。 |
| 111 | |
| 112 | ## 7. 异常处理 |
| 113 | |
| 114 | ### 7.1 字段兼容与比较计划异常 |
| 115 | |
| 116 | 只接受显式 `*_path` / `*_paths` 字段。收到旧的 `*_ref` / `*_refs` 输入时,runner 返回 `needs_input`,并在 `issues` 与 `next_steps` 中给出对应替代字段。 |
| 117 | |
| 118 | `experiment_ids` 和 `candidate_result_paths` 二选一,不能混用;`candidate_result_paths` 必须至少两个。 |