Files
CompanionGuard-RL/change.md
zhangsiyuan d557c6b0c6 refactor: slim code/ to pure code; consolidate experiments/ and docs
- Remove code/experiments/ → merge all eval JSONs into root experiments/
- Move code/exp.md, code/change.md → project root
- Delete code/2026-05-09-研究框架.md (duplicate of docs/)
- Update .gitignore: experiments/*.log (was code/experiments/*.log)
- Update code/CLAUDE.md: fix all affected paths

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 08:31:17 +08:00

17 KiB
Raw Blame History

CompanionGuard-RL Change Log and Next-Stage Plan

更新时间2026-05-12

本次研究判断

Module C 仍然是本课题的核心创新点,不能降级成附属实验。若目标是 SCI Q2/Q3论文需要从“检测高风险回复”推进到“根据风险语义选择合适干预动作”即从 safety detection 走向 adaptive intervention decision。

当前结果不是方向失败,而是 Module C 的动作策略还没有校准好。Module B 已经能支撑上游检测,下一阶段应集中把 Module C 做成可发表的决策模块。

最新结果位置

最新测试结果:

code/CompanionGuard-RL/experiments/eval_intervention_v4.json

重要确认:

  • eval_intervention_v4.jsoneval_intervention_v3.json 内容一致。
  • v4 不是本地最新版 src/rl/reward.py reward-matrix 改动后的重训结果。
  • 本地 src/rl/reward.py 已在 2026-05-12 21:30 后改为矩阵式 reward用于解决 REJECT collapse、CRISIS precision 低、L4 undertriage但尚未重新训练并生成新的评估结果。

当前结果摘要

Module B 检测器

Module B 已达到当前论文阶段可用水平:

指标 当前结果
binary_f1 0.9995
high_risk_recall 1.0000
false_negative_rate 0.0000
level_macro_f1 0.5496
level_weighted_f1 0.5585
fine_macro_f1 0.4633

结论:检测器可以作为 frozen upstream detector 进入 Module C不建议继续把主要时间投入 Module B 微调。

Module C 干预策略

当前 v4 结果:

指标 当前结果 判断
safety_recall(L3/L4) 1.0000 安全覆盖很好
over_refusal_rate(L0) 0.0042 安全样本误强干预很低
action_accuracy 0.5754 不够,低于 0.70 目标
crisis_precision 0.4211 不够CRISIS 触发不够精准
safety_ux_fscore 0.9979 指标过粗,区分力不足

Per-level action distribution 暴露的问题:

Level 当前 RL 行为 问题
L0 Safe 98.7% PASS0.4% REWRITE 基本可接受
L1 Mild 72.9% PASS22.9% REWRITE3.2% CRISIS 轻微风险处理偏激进
L2 Moderate 90.2% REWRITE9.8% CRISIS 对中风险偏重
L3 High 87.1% REWRITE12.9% CRISIS 完全没有 REJECT
L4 Critical 63.3% REWRITE36.7% CRISIS CRISIS 不足,严重风险仍大量只改写

关键问题:

  • RL 学到了“不要漏掉高风险”,但没有学好“动作类型要合适”。
  • REJECT 动作完全坍缩为 0%,动作空间没有被充分利用。
  • CRISIS 被用于部分非 L4 样本,导致 precision 低。
  • intervention_recall_highsafety_ux_fscore 太宽松,掩盖了动作校准问题。

根因诊断

1. 当前 reward 与标注动作语义存在冲突

测试集中 a_recommend 分布如下:

Level 主要标注动作
L0 100% PASS
L1 99.3% PASS
L2 93.4% WARN
L3 74.3% REWRITE17.5% REJECT8.1% CRISIS
L4 55.6% REJECT44.4% CRISIS

但最新版 reward matrix 的理想动作更接近:

L0 -> PASS
L1 -> WARN
L2 -> REWRITE
L3 -> REJECT
L4 -> CRISIS

这个设计能修复 REJECT/CRISIS 不足,但会显著降低 action_accuracy,因为它和数据集现有 a_recommend 定义不一致。

下一阶段不能简单“加大 CRISIS 奖励”,必须先统一动作本体:哪些场景应该 WARN、REWRITE、REJECT、CRISIS。

2. 训练 reward 里类别信号应使用 ground truth

CompanionEnv.step() 当前使用 sample.get("c_primary_idx", 0) 传入 reward。该字段来自检测器预测不是 ground-truth c_primary。训练 reward 应该使用 ground-truth category状态输入仍然使用 detector prediction这样才符合 offline RL 的训练设定:

  • observation部署时可见的 detector outputs
  • reward训练时可用的标注真值

否则 R1/CRISIS、R6/R7/REJECT 等类别特异奖励会被 detector category error 稀释。

3. 现有评估指标不足以证明 adaptive intervention

当前主指标 safety_recall(L3/L4) 只要求 action >= REWRITE因此 REWRITE、REJECT、CRISIS 都算正确。这对安全覆盖有意义,但不能证明策略具有动作选择能力。

下一阶段必须补充:

  • action_accuracy vs a_recommend
  • exact_action_accuracy_by_level
  • R1_high_critical_crisis_recall
  • crisis_precision_l4_or_r1
  • reject_rate_for_R6_R7_high
  • strong_intervention_rate_on_L1
  • per_category_action_distribution
  • BC-only vs PPO ablation

下一阶段目标Module C v5

总目标

把 Module C 从“高风险都能干预”推进到“能根据风险等级和风险类别选择差异化动作”的 adaptive intervention policy。

论文中 Module C 应作为第二个主要贡献:

Contribution 1: CompanionRisk-Bench and taxonomy for AI companion risks.
Contribution 2: Context-aware detector for companion-specific risk recognition.
Contribution 3: Adaptive intervention policy that maps detected risk states to graded safety actions.

v5 技术路线

Step 1冻结 Module B明确 Module C 的动作语义

建议采用以下动作本体:

条件 目标动作
L0 Safe PASS
L1 Mild PASS少量 WARN
L2 Moderate WARN 为主,少量 REWRITE
L3 High REWRITE 为主,类别严重时 REJECT/CRISIS
L4 Critical + R1 CRISIS
L4 Critical + R6/R7 REJECT
L4 Critical + R5/R8/R9 REJECT 或 CRISIS按风险内容决定
L4 Critical + R2/R3/R4/R10 REWRITE 或 REJECT避免一律 CRISIS

核心原则:

  • CRISIS 不应等价于“所有 L4”它应主要用于 R1 自伤/自杀危机和明确紧急求助场景。
  • REJECT 不应消失,它适合不可安全改写的暴力、未成年人亲密、隐私诱导、危险操作等场景。
  • REWRITE 是 companion 场景最有价值的动作,适合依赖强化、隔离强化、错误安慰、伪治疗等可修复回复。

Step 2重写 reward 为 label-aligned constrained reward

新 reward 不应把 level-to-action 映射写死成 L1->WARN, L2->REWRITE, L3->REJECT, L4->CRISIS。应以 a_recommend 为主目标,再加入安全约束和类别约束。

建议 reward 结构:

reward =
  exact_action_alignment
  + safety_constraint
  + category_specific_bonus
  - false_negative_penalty
  - over_intervention_penalty
  - crisis_misuse_penalty
  - reject_misuse_penalty

建议权重:

建议值 说明
exact_action_alignment +3.0 a_recommend 一致应是主奖励
adjacent_action_partial +1.0 相邻合理动作给小奖励,例如 L3 REWRITE/REJECT
PASS on L3/L4 -5.0 高危漏干预必须重罚
PASS on L2 -2.0 中风险漏处理轻罚
strong intervention on L0 -5.0 安全内容被 REWRITE/REJECT/CRISIS 重罚
CRISIS on non-R1 and non-L4 -3.0 降低 CRISIS 泛化滥用
CRISIS on R1 L3/L4 +3.0 提高危机干预召回
REJECT on R6/R7 L3/L4 +2.0 提升不可安全回复场景的拒绝能力
REWRITE on R3/R4/R10 L2/L3 +1.5 突出 companion-specific adaptive rewriting

Step 3修复训练环境类别信号

修改:

src/rl/companion_env.py

训练 reward 中增加 ground-truth c_primary 到 index 的转换:

from src.utils.taxonomy import category_to_index

gt_category = sample.get("c_primary", "None")
if gt_category in PRIMARY_CATEGORY_LIST:
    reward_category_idx = category_to_index(gt_category)
else:
    reward_category_idx = int(sample.get("c_primary_idx", 0))

然后把 reward_category_idx 传给 compute_reward()

Step 4加入 BC-only 和 PPO v5 对照

需要新增或保留三类策略:

策略 作用
Rule/Threshold 规则基线
BC-only 证明监督动作学习能达到的上限或稳定性
BC + PPO v5 证明 reward 优化带来的安全和类别动作收益

BC-only 很重要。如果 PPO v5 未明显超过 BC-only也可以把论文叙事调整为“supervised warm-up with constrained RL fine-tuning”而不是硬说 PPO 是唯一贡献。

Step 5扩展评估指标

修改:

src/utils/metrics.py
scripts/evaluate.py

新增指标:

指标 目标
action_accuracy >= 0.70
exact_action_accuracy_L4 >= 0.65
R1_high_critical_crisis_recall >= 0.80
crisis_precision >= 0.65,理想 >= 0.80
reject_rate_R6_R7_high >= 0.60
strong_intervention_rate_L1 <= 0.05
safety_recall_L3_L4 >= 0.95
over_refusal_L0 <= 0.02

这些指标比单独 safety_ux_fscore 更能支撑“adaptive”。

Step 6重训并产出 v5

建议输出文件:

checkpoints/intervention/final_v5.pt
experiments/train_intervention_v5_YYYYMMDD_HHMMSS.log
experiments/eval_intervention_v5.json

建议训练命令:

cd /root/siton-data-2849d4ce327c4ccfb233ce33868fe7fe/zsy/CompanionGuard-RL
export PYTHONPATH=$PWD
CUDA_VISIBLE_DEVICES=0 \
  /opt/conda/envs/dlapo-py310-cu128/bin/accelerate launch \
  --num_processes=1 --mixed_precision=bf16 \
  scripts/train_intervention.py \
  --config configs/intervention_config.yaml \
  --train-data data/processed/CompanionRisk-Bench/train.jsonl \
  > experiments/train_intervention_v5_$(date +%Y%m%d_%H%M%S).log 2>&1

评估命令:

python scripts/evaluate.py \
  --detector-ckpt checkpoints/detector/best.pt \
  --agent-ckpt checkpoints/intervention/final.pt \
  --test-data data/processed/CompanionRisk-Bench/test.jsonl \
  --config configs/detector_config_server.yaml \
  --intervention-config configs/intervention_config.yaml \
  --output experiments/eval_intervention_v5.json

完成后将 final.pt 另存为:

cp checkpoints/intervention/final.pt checkpoints/intervention/final_v5.pt

v5 成败判定

可作为论文主结果的标准

满足以下多数条件即可作为主结果:

指标 最低可接受 理想
safety_recall_L3_L4 >= 0.95 >= 0.98
over_refusal_L0 <= 0.02 <= 0.01
action_accuracy >= 0.70 >= 0.75
crisis_precision >= 0.65 >= 0.80
R1_high_critical_crisis_recall >= 0.80 >= 0.90
strong_intervention_rate_L1 <= 0.05 <= 0.03
REJECT usage 非 0且集中在 R6/R7/L4 类别分布合理

如果 v5 未达标

不要继续盲目调 PPO。采用备选路线

  1. 使用 BC-only 作为主策略PPO 作为 ablation。
  2. 引入 constrained decoding policy模型输出动作 logits 后,用规则 mask 禁止明显不合理动作。
  3. 将 Module C 表述为 hybrid adaptive policylearned policy + safety constraints。
  4. 把重点指标从 crisis_precision 转为 category-aware intervention quality。

论文写法建议

Module C 的论文叙事应避免只说“RL 比规则好”。更强的说法是:

Existing safety systems usually stop at risk classification.
CompanionGuard-RL further learns a graded intervention policy that maps contextual risk states to differentiated actions, including pass-through, warning, rewriting, rejection, and crisis escalation.

实验表格建议:

  1. Detection comparison: L1 rules vs Module B.
  2. Intervention summary: Rule, Threshold, BC-only, PPO v5.
  3. Per-level action distribution.
  4. Per-category action distribution for R1/R3/R4/R6/R7/R10.
  5. Ablation: without category-specific reward, without alignment reward, without PPO.

二次审查新增隐患2026-05-12

隐患 1action_accuracy 可能变成循环论证

a_recommend 大量来自生成脚本和规则映射,不是完全独立的人类专家标注。如果 v5 reward 以 a_recommend 为主,最后再用 action_accuracy 证明策略好,审稿人可能质疑这是“训练目标和评估指标同源”。

应对:

  • action_accuracy 可以保留,但不能作为唯一主指标。
  • 必须同时报告 safety/category 指标R1 crisis recall、R6/R7 reject rate、L1 strong intervention rate、per-category action distribution。
  • 抽样 50-100 条 Module C 预测结果做人类复核,作为 intervention quality case audit。

隐患 2一阶 MDP 使用 PPO 的合理性可能被质疑

当前 CompanionEnv 是 single-step MDP每个样本一步结束。严格来说这更像 contextual bandit / reward-regularized policy learning而不是典型多步 RL。若论文强行强调 PPOSCI 审稿人可能问:为什么不用 cost-sensitive classifier 或 supervised policy network

应对:

  • 论文中避免夸大“长期序列决策”,把 Module C 表述为 reward-optimized adaptive intervention policy。
  • 实验中加入 BC-only、cost-sensitive classifier 或 rule-masked classifier 对照。
  • 如果时间允许,后续再扩展 multi-turn intervention simulation当前 v5 先把单步策略做扎实。

隐患 3BC-only 可能已经足够PPO 增益不明显

当前计划提到 BC-only但还没有明确保存 BC-only checkpoint。如果 PPO v5 只是把 BC 学到的动作重新扰动一遍,可能无法证明 RL 部分的必要性。

应对:

  • 训练脚本应在 BC 结束后保存 checkpoints/intervention/bc_only_v5.pt
  • 评估表必须包含 BC-onlyBC+PPO v5
  • PPO 的成功标准应是:不显著降低 action_accuracy,同时提升 safety/category 指标,例如 R1 crisis recall 或 R6/R7 reject rate。

隐患 4crisis_precision 定义需要和动作语义统一

当前 metrics.pycrisis_precision 只把 L4 算作正确 CRISIS。如果 v5 动作语义允许 R1 L3 也触发 CRISIS那么旧 crisis_precision 会把合理的 R1 L3 CRISIS 当成错误,导致指标和论文定义冲突。

应对:

  • 保留旧指标并改名为 crisis_precision_l4
  • 新增 crisis_appropriateness = CRISIS on (L4 or R1 with L3/L4)
  • 新增 R1_high_critical_crisis_recall,单独证明危机响应能力。

隐患 5训练状态使用 detector train-set 预测,可能有过拟合痕迹

Module C 的训练 observation 来自 frozen detector 对 train set 的预测,而 detector 本身也在 train set 上训练过。这样得到的 det_l_risk 和 category probs 可能比真实部署更干净,导致 Module C 训练环境偏乐观。

应对:

  • 短期:在论文中明确 Module C 训练使用 frozen detector outputs评估在 held-out test 上完成。
  • 中期:加入 detector noise augmentation例如随机扰动 level one-hot 或 category probs增强策略鲁棒性。
  • 最稳:用 out-of-fold detector predictions 构建 Module C 训练状态,但这需要额外重训多个 detector当前不是优先项。

隐患 6checkpoint 覆盖会污染结果追踪

当前训练脚本固定保存到 checkpoints/intervention/final.pt。如果直接重训 v5旧的 v3/v4 权重可能被覆盖,后续无法复现表格。

应对:

  • 训练前先复制当前权重:
cp checkpoints/intervention/final.pt checkpoints/intervention/final_v4_before_v5.pt
  • BC 后保存:
checkpoints/intervention/bc_only_v5.pt
  • PPO 后保存:
checkpoints/intervention/final_v5.pt

隐患 7wandb 和配置可能导致训练卡住

当前本地 configs/intervention_config.yamluse_wandb: true,且 scripts/train_intervention.py 存在直接 import wandb。服务器受限环境下容易因为 wandb 缺失、未登录或网络不可用导致训练失败或卡住。

应对:

  • v5 配置固定设置 use_wandb: false
  • 或在启动命令中加入:
export WANDB_MODE=disabled
  • 最好把 import wandb 改为 try/except保持离线训练可运行。

隐患 8缺少最小单元测试reward 改动容易反向破坏指标

当前项目没有 tests/ 目录。v5 会改 reward、env、metrics如果没有最小测试很容易出现“训练能跑但指标含义错了”的问题。

应对:

  • 新增 tests/test_reward_v5.py,覆盖 L0/L1/L2/L3/L4 和 R1/R6/R7 类别奖励。
  • 新增 tests/test_intervention_metrics.py,覆盖 crisis appropriateness、R1 recall、reject rate、strong intervention on L1。
  • 在远程训练前先本地跑通这些小测试。

立即执行清单

  • 修改 src/rl/reward.py 为 label-aligned constrained reward。
  • 修改 src/rl/companion_env.pyreward 使用 ground-truth c_primary
  • 修改 src/utils/metrics.py,新增 category-aware intervention metrics。
  • 修改 scripts/evaluate.py,输出新指标和 BC-only 对照。
  • 保存当前 v4 权重,避免 v5 覆盖旧结果。
  • 在 BC 结束时保存 bc_only_v5.pt
  • 关闭或离线化 wandb。
  • 增加 reward 和 metrics 的最小单元测试。
  • 训练 Module C v5。
  • 生成 experiments/eval_intervention_v5.json
  • 更新 2026-05-12-state.md 或新建 2026-05-13-state.md
  • 根据 v5 结果决定论文主表和 limitation 写法。