大模型下的深度强化学习的多智能体渗透测试(6)
PenGym 单智能体 izumi 当日进展报告:medium family 统一接口打通,重复无增量动作约束显著改善泛化,但长训与强加权会导致分布偏置
一、今天这篇记录要说明什么
今天的主线不是继续讨论 reward3,也不是回到最初的单场景长训,而是围绕 medium family 的泛化 持续往下推进,并把“为什么泛化不稳定”一步一步拆出来。
今天真实完成并验证的事情可以概括为:
- 已实现 medium family unified observation adapter,并把
medium-multi-site、medium-single-site、medium统一映射到固定646维输入。 - 已验证 unified observation 下的
reset、step、smoke train、单局推理都能正常运行,说明“统一接口 + PPO”这条链已经真正打通。 - 已确认:仅做 unified observation + single-scenario training 并不足以稳定泛化。
- 已实现 medium family mixed training,把训练分布从单场景推进到 family-level。
- 已逐层定位 mixed training 中的主要失败模式:重复
process_scan、重复失败 exploit、重复失败os_scan/service_scan、repeat mask 接线失效、mask 不足以彻底阻断重复动作等。 - 已实现一套更完整的 repeat-action guard:
- 成功扫描动作 block
- 失败 exploit block
- 失败 scan block
- mixed env 中 repeat mask 接线修复
- step 侧硬拦截 blocked repeat
- 已拿到一版关键正结果:某个 50k mixed + repeat-guard 版本在多 seed × 多 episode 的评估下,对
medium-multi-site / medium-single-site / medium三个场景全部达到15/15成功。 - 已同时验证:更长训练(100k)或强加权采样(如
[1,1,4])并不天然更好,反而会造成偏科甚至整体崩坏。
今天最重要的阶段性结论不是“已经彻底解决泛化”,而是:
对 medium family 来说,真正显著提升泛化的关键,不是单纯继续堆 timesteps,也不是直接切 reward3,而是 在 unified observation + mixed training 的基础上,把 episode 内的重复无增量动作真正封死。
二、今天的核心目标
今天的目标可以拆成三层:
1. 把 medium family 的 unified observation adapter 真正写出来并跑通
也就是把昨天已经在思路上定下来的 canonical observation schema,真正落到代码里,并且完成 shape 对齐与 smoke 验证。
2. 在统一接口上重新训练 PPO,确认它到底能不能学,以及学成后能不能跨场景迁移
换句话说,不只是证明 wrapper“看起来没问题”,而是真正让 agent 在 unified observation 上训练和评估。
3. 如果 mixed training 仍然失败,就继续往下追,直到把 failure loop 定位到可改动的具体机制
今天后半段的大量时间,其实都花在这第三层:持续定位并修正反复出现的“无增量动作循环”。
三、今天具体做了什么
1. 实现并验证 medium-family unified observation adapter
今天首先完成了 medium family 的统一 observation wrapper。
按当前确定的 canonical schema,统一设计为:
- max subnet slots = 7
- max host slots per subnet = 16
- scalar fields = 6
- os slots = 1
- service slots = 5
- process slots = 3
因此每一行宽度固定为:
7 + 16 + 6 + 1 + 5 + 3 = 38
再结合当前 family 的总行数设计,最终固定输入变成:
17 × 38 = 646 dims
今天已经实际写出并运行了:
prototype/rl/adapters/unified_medium_obs.pyprototype/rl/check_medium_obs_shapes.py
对三个场景的 shape smoke test 结果是:
medium-multi-site原始 observation:493medium-single-site原始 observation:578medium原始 observation:459
统一后全部变成:
646
这一步说明:
unified observation 不是停留在思路层面的设计,而是已经完成了代码实现,并在 medium family 三个目标场景上真实跑通。
2. 验证 unified observation 下的基础交互链路
在 shape 对齐之后,继续验证 unified observation 是否会破坏最基本的环境交互。
今天实际做了:
- unified env
reset() - unified env
step() - 5k unified smoke train
- 单局 deterministic eval
最开始遇到过一些工程问题,例如:
- 把 Python 源码误直接敲进 shell;
prototype模块导入路径不对;nasim.make_benchmark()本地版本接口与预想不一致;flat action采样出来的是numpy.int64而不是 Pythonint。
这些问题今天都已逐步解决,最后确认:
- unified observation wrapper 不破坏
reset - unified observation wrapper 不破坏
step - PPO 能在 unified observation 上启动训练
- 模型也能在 unified observation 上正常推理
这一步把一个关键前提真正坐实了:
“统一输入接口以后还能不能继续用 PPO”——答案是可以。
3. 证明:single-scenario unified training 能学会,但 zero-shot 仍然不够
在 unified observation 的基础上,先做了 single-scenario 训练和评估。
结论是:
medium-multi-site在统一接口下可以学会;- 但把同一个模型直接拿去
medium-single-site和medium,依然会失败或表现明显不稳。
这说明:
unified observation 解决了输入空间不一致的问题,但没有自动带来 zero-shot 泛化。
换句话说,今天已经把问题进一步缩小到了:
- 不是 PPO 根本学不会;
- 不是 unified observation 完全没用;
- 而是 unified observation 只是必要条件,还不是充分条件。
4. 实现 medium family mixed training
在确认 single-scenario unified policy 无法稳定迁移后,今天继续把训练分布推进到了 family-level。
新建并改造了:
prototype/rl/train_maskable_ppo_medium_family_mixed.py
实现思路是:
- 通过
MixedScenarioEnv - 在每个
reset()时从 medium family 中抽一个场景 - 仍然保留已有 wrapper 链:
UnifiedMediumObservationWrapperIntActionWrapperProgressRewardWrapperSuccessActionMemoryWrapperActionMaskerMonitor
也就是说,今天已经从“统一 observation 的单场景 PPO”推进到:
统一 observation + medium family mixed training
这是后面所有泛化修复的真正训练载体。
5. 逐层定位 mixed training 中的真实失败根源
今天最有价值的一部分,不是第一次 mixed train 本身,而是后面一路往下追“mixed 为什么还是会崩”。
这个定位过程今天先后暴露出几个非常具体的 failure mode:
(1)重复 process_scan 循环
最早观察到 mixed training 容易被大量重复 process_scan 拖垮。
这说明 scan 类重复动作的约束不足,于是先把 process_scan 纳入 repeat block。
(2)重复失败 exploit 循环
修完 process_scan 后,又很快发现模型会在同一 host 上反复重试失败 exploit,例如反复 e_smtp、e_ftp。
这说明失败 exploit 没有被及时记忆并屏蔽,于是把:
connection_errorpermission_errorundefined_error
这几类失败下的 e_* / pe_* 也纳入 repeat block。
(3)重复失败 os_scan/service_scan 循环
继续向下看,又出现了大量失败的 os_scan 和 service_scan 循环。
于是继续扩展规则,把失败的:
service_scanos_scanprocess_scan
也一起加入 block。
(4)规则写了,但 repeat mask 在 mixed wrapper 链里没有真正接上
后面又发现一个更深的工程问题:
SuccessActionMemoryWrapper.get_repeat_block_mask()已经存在;- 但在 mixed env 的 wrapper 链里,
mask_fn()没有稳定拿到它; - 结果就是规则虽然写了,但最终 action mask 并没有真正用上 repeat block。
于是今天继续修:
- 给
MixedScenarioEnv显式暴露get_repeat_block_mask() - 把
mask_fn()改成通过get_wrapper_attr("get_repeat_block_mask")去拿 repeat mask
(5)mask 侧不够,step 侧还需要硬拦截
即便 repeat mask 接上之后,日志里仍然能观察到 blocked 动作偶尔真正落到了底层环境。
所以今天又继续做了更强的一步:
- 在
SuccessActionMemoryWrapper.step()里加入 step 侧硬拦截; - 如果当前动作 key 已经进入
_blocked_action_keys,就不再真的发到底层 env,而是直接返回缓存 observation + 负奖励。
一开始还因为底层 PenGymEnv 没有 get_observation() 而报错,后来改成 wrapper 内缓存 _last_obs,最终跑通。
今天这一整轮推进,把失败根因从“mixed training 看起来不太行”逐步压缩成了:
关键瓶颈并不是 mixed 这个训练框架本身,而是 episode 内重复执行无增量动作的行为没有被彻底封死。
6. 拿到一版关键正结果:三场景 15/15 全成功
在 repeat-guard 逐步完善后,mixed training 的训练表现明显回稳:
ep_len_mean显著下降ep_rew_mean回到正值- 训练日志不再被大量
process_scan / os_scan / failed exploit循环主导
随后今天新建了系统化评估脚本:
prototype/rl/eval_medium_family_mixed.py
评估设置为:
5个 seeds- 每个 seed
3个 episodes - 每个场景共
15局
在一版 50k mixed + repeat-guard 模型上,得到今天最关键的正结果:
medium-multi-site:15/15medium-single-site:15/15medium:15/15
这一步的意义非常大:
今天第一次不是只拿到“单次 rollout 成功”,而是拿到了 medium family 三场景在多 seed、多 episode 下全部成功的系统化评估结果。
这已经足够支撑一个比较有分量的阶段性正结论。
7. 同时验证:更长训练和强加权并不天然更好
在拿到上述关键正结果后,今天并没有停下,而是继续往前探索“能不能更进一步”。
(1)把 50k 拉到 100k
当 mixed + repeat-guard 从 50k 拉到 100k 时,出现了新现象:
medium-multi-site和medium-single-site进一步变强;- 但
medium.yml完全掉下去,出现0/15。
这说明:
更长训练可能会把策略推向某些子拓扑分布,导致选择性偏科,而不是均衡提升所有场景。
(2)尝试 weighted sampling
为了把 medium.yml 拉回来,今天又尝试了:
[1, 1, 2][1, 1, 4]
这种 scenario weighting。
得到的现象也很有价值:
[1,1,2]只能略微改善medium.yml的负回报,但不能恢复成功;[1,1,4]则直接把三个场景全练坏,三场景都掉到0/15。
这说明:
强行提高某个失败场景的采样权重,并不会线性地修复泛化,反而可能把整体训练分布拉歪。
所以今天又得到了一个重要负结论:
- 不是继续堆 timesteps 就会更好;
- 也不是把失败场景权重拉高就会更好。
四、今天做对了什么
1. 没停在 unified observation “能跑”这一层
今天不是写完 wrapper 就算结束,而是一路推进到:
- shape smoke
- step smoke
- train
- eval
- mixed env
- failure analysis
- repeat guard
- 系统化评估
这让 unified observation 真正进入了策略层的验证。
2. 对 failure loop 一层一层往下追
今天最大的亮点之一,是没有停在“mixed 还是会失败”的泛泛描述,而是持续向下拆成:
process_scanloop- failed exploit loop
- failed os/service scan loop
- repeat mask 接线问题
- step 侧硬拦截必要性
这使得后续修复都变成了可以落实到代码的小改动,而不是空泛猜测。
3. 拿到了多 seed × 多 episode 的关键正结果
今天最有分量的成果,不是某一局的 rollout,而是:
- 50k mixed + repeat guard 版本
- 在 medium family 三场景上全部
15/15
这已经把“可能有点效果”推进到了“有统计证据的阶段性突破”。
4. 证明了“更长训练 / 更强加权”不一定更好
今天的 100k 偏科现象与 [1,1,4] 的全面崩坏,都说明:
- 泛化问题不是简单继续训练就能解决;
- 训练分布和重复动作约束之间存在比较微妙的平衡。
这对后续研究方向判断很重要。
五、今天的问题与不足
1. 最优平衡版本没有第一时间固定保存
今天一度拿到了非常好的 50k balanced result,但当时没有立刻冻结成单独 checkpoint,就继续向更长训练和加权 sampling 往前试了。
这导致后面虽然看到了更多现象,但最稳的平衡版本没有及时单独归档。
2. 当前结论仍然局限在 medium family
虽然今天对 medium-multi-site / medium-single-site / medium 的 family-level generalization 推进很实质,但这并不代表:
- small family
- tiny family
- 更大范围场景
也已经具备同样的迁移能力。
今天的结论范围仍然应当严格表述为:
当前方法在 medium family 内部已经出现了可验证的跨场景泛化能力,但其更大范围的可迁移性尚未验证。
3. 当前最强机制仍然偏工程性约束
今天真正拉起结果的关键,是 repeat guard / hard blocking 这一类行为约束。
这说明当前 agent 的进步仍然很大程度依赖于:
- 合理的 action mask
- 合理的 anti-loop 机制
- 合理的 episode 内动作封锁
这不是坏事,但也说明当前的“通用策略能力”还没有强到完全脱离这些辅助约束。
六、今天得到的阶段性结论
今天真正能站住脚的结论有五条:
1. unified observation 对 medium family 是可行的
medium family 三个目标场景已经被成功统一到固定 646 维输入,并且 PPO 链路已经在这个统一输入空间上稳定运行。
2. 仅做 unified observation 并不足以自动带来泛化
single-scenario unified policy 依然会在 zero-shot 场景上失败,因此 observation unified 只是必要条件,不是充分条件。
3. medium family mixed training 是正确方向
把训练分布从单场景推进到 family-level 后,agent 的训练与评估问题才真正进入“泛化”层面,而不再只是单场景记忆。
4. 重复无增量动作约束是当前提升泛化的关键
真正显著提升结果的,不是 reward3,也不是简单长训,而是:
- 重复 scan 屏蔽
- 失败 exploit 屏蔽
- 失败 scan 屏蔽
- repeat mask 接线修复
- step 侧硬拦截
这些约束共同抑制了 episode 内的无意义动作循环。
5. 更长训练与强加权都可能导致子分布偏置
100k 训练和强加权采样都证明了:
- 泛化不一定随训练时长单调提升;
- 过强地向某个子场景补偿,会破坏整体分布平衡。
七、下一步最合理的推进方向
今天的结果已经足够说明:继续盲目堆 timesteps 或继续提高场景权重,并不是当前最优路线。
更合理的后续方向有三类:
1. 先把当前最优平衡版本管理好
把真正表现最均衡的 checkpoint 和训练脚本单独固定下来,避免后续实验覆盖最强平衡版本。
2. 在保持 current repeat-guard 机制的基础上,进一步研究“如何在不偏科的前提下继续提升”
例如:
- 更精细的 curriculum,而不是简单粗暴加权;
- 在 50k 附近找更稳的训练区间;
- 对不同 sub-topology 采用更细的阶段式训练。
3. 后续才考虑更大改动
例如:
- unified action abstraction
- 更抽象的 topology encoding
- 更高层策略结构
但这些都应该建立在今天已经验证出来的有效机制之上,而不是推翻重来。
八、今天一句话总结
今天最重要的推进不是“把一个 PPO 多训练了一会儿”,而是:
把 medium family 的统一输入接口真正打通,并通过 mixed training + repeat-action hard guard,第一次在系统化评估下实现了 medium family 三场景全部成功;同时也实证发现,更长训练与强加权会带来新的偏科与退化。
这使得当前研究从“agent 能不能学”正式推进到了:
agent 在 family-level 上如何稳定泛化,以及泛化为什么会被分布偏置破坏。
