大模型下的深度强化学习的多智能体渗透测试(4)
PenGym 单智能体 izumi 当日进展报告:MaskablePPO 主线稳定跑通,并通过 reward shaping 突破旧平台,形成新的 DRL 基线
一、这篇文章要说明什么
这份记录只描述今天真实完成的事情,不描述理想路线,也不把尚未完成的 LLM、多智能体部分写成已经完成。
今天最重要的结果可以概括为六点:
- 已确认当前单智能体学习型
izumi的主线应收敛到MaskablePPO,而不是继续在 D3QN/DDQN、PPO、RPPO 之间来回横跳。 - 已分清
run.py中的规则型izumi入口和真正的 DRL 入口,避免继续在错误入口上浪费时间。 - 已修复训练与评估不一致、动作掩码接错、成功动作循环、空掩码崩溃等关键工程问题,使 MaskablePPO 单智能体链路真正稳定。
- 已得到
maskable_ppo_izumi_tiny_20k.zip这一可复现、可多轮 deterministic eval 的 DRL 单智能体基线。 - 已在
tiny_20k基线上做继承训练,并通过更强 reward shaping(reward2)把训练回报从旧平台约 180 拉升到新平台约 430。 - 已成功保存新的模型
prototype/models/maskable_ppo_izumi_base_200k.zip,可作为接入 LLM 之前的底层 DRL 单智能体基线。
因此,今天最准确的阶段判断是:
- MaskablePPO 单智能体 DRL 工程链:已稳定跑通
- 单智能体策略质量:明显优于旧平台,并已经具备可继续封装与展示的价值
- 后续最合理的方向:先固化当前 DRL 基线,再接入 LLM 解释/规划层,而不是继续长期无脑拉步数
二、今天的工作目标
今天的目标不是继续扩展规则版 izumi 的固定路径,也不是继续在多个 DRL 算法之间不断切换,而是完成两件基础但必须先打通的事:
1. 明确当前单智能体学习型 izumi 的真实主线
也就是说,今天聚焦的是:
- 找到真实主工程目录;
- 分清规则入口与学习型入口;
- 确认当前最适合的单智能体 DRL 主线算法;
- 把训练与评估链做一致;
- 得到一个真正能继续迭代的单智能体基线。
2. 让策略质量真正突破旧平台
此前虽然已经能训练,但依然会长期陷入:
- 非法动作循环;
- 成功动作刷分循环;
- 训练脚本与评估脚本不一致;
- 长训后仍然卡在一条固定高分路径上。
因此,今天真正要解决的,不再是“脚本能不能跑”,而是:
如何让当前单智能体 DRL 从旧的局部高分路径中跳出来,学会更高覆盖率、更高收益的新策略。
三、今天实际确认和修改了什么
1. 确认真实工程目录
今天首先确认,真正的工作目录是:
1 | /home/test1/lab/pengym_lab/PenGym-main |
而不是最开始解压出来的临时副本目录。
这一步很关键,因为如果继续在错误副本上装依赖、改脚本、跑训练,就会一直出现“改了代码但主工程没变化”的假象。
2. 确认 run.py 中的 izumi 仍然是规则入口
今天通过查看 run.py 关键逻辑,确认了:
run.py -a izumi走的仍然是build_izumi_path()/run_deterministic_agent(...);- 当前
run.py中的izumi不是学习型主入口; - 因此继续围绕
run.py打转,不会直接得到 DRL 单智能体。
这一步直接避免了后续大量无效排查。
3. 确认学习型主线实际位于两个目录中
今天已经明确:
prototype/drl_izumi/
主要对应:
valid_actions.pystate_encoder.pytrain_ddqn.pyeval_ddqn.py- 以及此前构建的 D3QN / DDQN 分支
prototype/rl/
主要对应:
train_maskable_ppo.pyeval_maskable_ppo.pytrain_izumi_rppo.pytrain_bc.py- 以及 PPO / MaskablePPO / RecurrentPPO / BC 主线
经过今天的排查与实验,当前单智能体主线已经明确收敛到:
优先走
MaskablePPO,不再继续把主要精力投入到 D3QN/DDQN。
4. 环境选择:最终回到项目原 .venv
今天还确认了一件很关键的事:
- 新建的独立
.venv虽然更干净,但不一定最匹配当前工程; - 项目原本自带的
.venv才是当前最稳定、最能直接跑通学习型链路的环境; - 因此后续统一使用:
1 | /home/test1/lab/pengym_lab/PenGym-main/.venv |
这一步避免了“能 import 但训练/评估接口不匹配”的隐性问题。
四、今天修复了哪些关键问题
1. 修复训练脚本的动作掩码接法错误
今天定位到 MaskablePPO 训练脚本里原本直接使用:
1 | env.get_action_mask() |
但当前 wrapper 栈下,这种调用方式并不稳定,容易导致:
- wrapper 取值错层;
- 新环境下直接报
AttributeError; - 训练和评估时拿到的动作约束逻辑不一致。
今天已把它统一改成通过:
1 | get_valid_action_mask(env) |
并把 prototype/drl_izumi/valid_actions.py 作为统一的合法动作约束入口。
2. 修复静态动作约束过松的问题
今天的 valid_actions.py 不再只是“有 native mask 就直接用,没 mask 就放开”,而是继续加强了:
- 利用
service/os约束 exploit; - exploit 与 native mask 做交集;
- 对已
compromised的目标不再无限重复 exploit; - 对已经没有新发现空间的
subnet_scan做收紧; - 防止一部分重复成功动作无意义刷分。
虽然这并没有一次性解决所有循环,但已经把大量显而易见的坏动作挡在了外面。
3. 修复“成功动作循环”问题
今天最关键的现象之一,不再只是失败动作循环,而是:
- 已经成功过的 exploit / scan 仍会继续重复执行;
- 从 MDP 视角看,它们仍然是“高收益按钮”;
- 因而策略会倾向于持续刷同一个成功动作,而不是去探索新路径。
针对这个问题,今天增加了:
SuccessActionMemoryWrapper
它的核心作用是:
- 在同一 episode 内记住已经成功过、且没有新增信息价值的动作;
- 在后续 mask 中优先屏蔽这些动作;
- 避免 agent 持续刷同一个 exploit / scan / subnet_scan。
这一步让训练从“刷同一高分按钮”转向“继续寻找新收益来源”。
4. 修复训练与评估环境不一致的问题
今天还确认了此前一个非常关键的“假坍塌”来源:
- 训练脚本已套上新的 wrapper 与 mask;
- 但
eval_maskable_ppo.py还没有同步; - 因此模型在 eval 时失去训练时的动作约束,表面上看像“训练好了、评估坏了”。
这个问题修复后,deterministic eval 立即恢复正常,不再退化成单动作死循环。
这说明此前一部分所谓“模型坍塌”,本质是:
训练脚本与评估脚本工程实现不一致。
5. 修复“全掩码崩溃”问题
在继续加强 repeat guard 后,训练曾一度在约 56k 左右崩溃。根因是:
- repeat mask 与 base mask 相交后,某些状态下会出现全 False;
MaskablePPO在构造分类分布时,遇到“全动作被屏蔽”的 batch 会直接报错。
今天这一问题也已修复,具体做法是:
- 先求
base mask - 再求
repeat mask - 只有交集仍有合法动作时,才真正使用交集
- 否则退回
base mask - 最后再加一层全 True 兜底
这一步让训练真正具备了稳定长跑能力。
五、今天最重要的阶段成果
1. 已得到可复现的 tiny_20k 稳定基线
今天先在 MaskablePPO 路线下得到:
1 | prototype/models/maskable_ppo_izumi_tiny_20k.zip |
这个模型的重要意义在于:
- 它不是“能训练但评估就坏”的假结果;
- 在多轮 deterministic eval 中能够稳定复现一条有效攻击路径;
- 它说明当前
MaskablePPO + mask + wrapper这条链已经不是空壳。
因此,今天之后,tiny_20k 成为了:
当前单智能体 DRL 的真实可用基线。
2. 已完成继承训练,而不是重新冷启动
在得到 tiny_20k 之后,今天没有继续从 0 开始盲目长训,而是做了:
- 新建
base_200k训练脚本; - 先确认它一开始其实在重新
new MaskablePPO(...),属于冷启动; - 之后修正为:
1 | MaskablePPO.load(BASE_MODEL_PATH, env=env) |
也就是说,今天已经把长训改造成真正的:
在
tiny_20k基线上继续训练,而不是重新来过。
这一步非常关键,因为它避免了大量无意义的时间损耗。
3. 已完成更强 reward shaping(reward2)
今天最大的策略层变化,不在于再换算法,而在于承认:
- 旧 reward 已经让策略卡进局部最优;
- 继续长训不会自然跳出来;
- 必须改 reward,重新定义“什么叫更聪明”。
因此,今天正式对 train_maskable_ppo_base_200k.py 增加了:
ProgressRewardWrapper
这一步的思路不是“轻微加减分”,而是更明确地鼓励:
- 新主机发现;
- 首次拿到 USER;
- 首次拿到 ROOT;
- 更高覆盖率;
同时更明确地惩罚:
- 无新发现的
subnet_scan; - 无新增权限的 exploit / privesc;
- 成功但无新进展的重复扫描。
也就是说,今天已经把训练目标从:
最短高分老链
改成了更偏向:
更高覆盖率 / 更多新进展的新链
4. reward2 之后,训练平台被真正突破
这是今天最重要的策略层结果。
在旧平台阶段,训练长期停在大致:
ep_rew_mean ≈ 180
后来在继续实验中,reward2 初期就已经把结果推到:
ep_rew_mean ≈ 260- 再到
360+ - 最后在完整 200k 训练结束时达到:
1 | ep_rew_mean = 432 |
同时训练日志最终打印:
1 | saved model to: prototype/models/maskable_ppo_izumi_base_200k.zip |
因此,今天最重要的结果不是“又训了一个模型”,而是:
reward2 确实把单智能体 DRL 从旧平台里拉了出来,并形成了新的高收益稳定基线。
六、今天好的地方是什么
今天真正做对、而且值得保留的地方,主要有以下几点:
1. 没有继续陷在“修接口就是进展”的错觉里
今天虽然修了不少工程问题,但真正的主线已经从:
- 找路径
- 装依赖
- 修单个报错
转成了:
- 修训练与评估一致性
- 修动作约束
- 修局部循环
- 修 reward 目标
这是方向上的进步。
2. 算法路线收敛了
今天没有继续在:
- D3QN
- DDQN
- PPO
- RPPO
- BC
之间反复摇摆,而是明确收敛到:
当前竞赛阶段的单智能体主线优先采用
MaskablePPO。
这个收敛本身,就是效率提升。
3. 工程问题与策略问题第一次真正分离开了
今天已经很清楚地看出:
- 前一阶段的大量问题属于工程实现问题;
- 当前阶段的主要问题已经转成真正的策略质量问题;
- 后续提高智能体,不再只是修接口,而是要改训练目标和学习条件。
4. 产出了一个可继续向上封装的真实基线
今天不只是得到一个“训练脚本能跑”的结果,而是得到了:
1 | prototype/models/maskable_ppo_izumi_base_200k.zip |
这意味着:
- 后续接入 LLM 时,不再是空壳 agent;
- LLM 上层可以建立在一个真实可用的 DRL 单智能体之上;
- 当前项目已经从“实验想法”推进到“可继续封装的原型系统”。
七、今天不好的地方是什么
今天虽然总体进展明显,但也必须老实承认当前仍存在若干问题。
1. 当前仍然只是单智能体,不是多智能体
今天所有进展都集中在:
- PenGym 单智能体
izumi MaskablePPO- reward shaping
也就是说:
- 多智能体协同并没有开始真正落地;
- 语义通信也没有开始接入;
- 这仍然是多智能体路线之前的单智能体基础阶段。
2. 当前还没有接入 LLM
今天虽然在 DRL 层突破了平台,但:
- LLM 解释层还没接;
- LLM 规划层还没接;
- LLM 与 DRL 的接口设计还没有落地到代码。
因此,今天的模型虽然更强了,但仍然只是:
不带 LLM 的单智能体 DRL 基线。
3. 当前结果仍然主要建立在一个场景上
虽然今天突破了旧平台,但当前高收益结果主要来自:
1 | medium-multi-site |
这意味着:
- 泛化能力还没有被证明;
- 现在还不能说“已经学会通用渗透策略”;
- 更准确地说,是在这个场景和当前 reward 设定下学到了一套更好的单智能体策略。
4. 当前 reward2 虽然有效,但还没有完成系统化对照实验
今天已经看到:
- reward2 明显优于旧 reward;
但当前仍然缺少:
- reward v1 / v2 / v3 的系统化对照;
- 不同 shaping 分量的消融;
- 更严格的 episode 成功率、覆盖率统计。
所以,今天能说:
reward2 有效
但还不能说:
当前 reward2 已经是最终版本。
5. 当前训练脚本仍然带有明显实验性
虽然今天已经能稳定跑通,但代码风格上仍保留明显实验痕迹,例如:
- 强依赖当前目录结构;
- 训练 / 评估 / wrapper 修改还集中在脚本层;
- checkpoint、统一配置化、统一评估输出等工程能力仍不完善。
这意味着后续在做提交版封装时,还需要进一步整理。
八、今天到底完成到了哪一步
如果只用一句话准确描述今天阶段,最合适的表述是:
今天已完成 PenGym 单智能体
izumi的 MaskablePPO 主线稳定化工作,修复了训练/评估不一致、动作掩码接错、重复动作循环、空掩码崩溃等关键问题,并在tiny_20k基线之上通过继承训练与更强 reward shaping 成功突破旧平台,最终得到新的高收益单智能体模型maskable_ppo_izumi_base_200k.zip。但当前阶段仍然是单智能体、无 LLM、单场景强化结果,尚未进入多智能体与 LLM 上层封装阶段。
这句话比“已经做成最终智能体”更准确,也比“只是训练了个模型”更符合今天的真实完成度。
九、今天的阶段性成果总结
今天已经真实完成的内容包括:
1. 工程层
- 找到真实主工程与真实环境;
- 分清规则入口与学习型入口;
- 把训练脚本与评估脚本统一到一致 wrapper 栈;
- 修复动作掩码接法、重复动作屏蔽与空掩码崩溃;
- 建立稳定的
MaskablePPO单智能体主线。
2. 训练层
- 已产出
tiny_20k可复现基线模型; - 已完成继承训练,而不是继续冷启动重训;
- 已通过 reward2 突破旧平台;
- 已在 200k 完整训练结束后成功保存:
1 | prototype/models/maskable_ppo_izumi_base_200k.zip |
3. 评估层
- 已证明模型不是“只会训练日志好看”;
- deterministic eval 已能说明策略是可执行的;
- 当前单智能体已经具备继续封装、继续解释、继续接入 LLM 的价值。
十、当前还没有完成的部分
今天虽然已经突破很多,但以下内容仍未完成:
1. 没有做系统化 eval 报告
当前虽然已经看到:
- deterministic eval 可跑;
- 训练回报显著提升;
但尚未整理成:
- 成功率统计;
- 平均步数统计;
- 覆盖率统计;
- 不同模型版本横向对比表。
2. 没有把 reward 设计抽成独立配置
当前 reward 仍主要嵌在训练脚本 wrapper 中,后续若继续迭代:
- reward v3
- reward ablation
- reward 对照实验
还不够方便。
3. 还没有进入 LLM 封装层
也就是说,当前还不能说:
- “已经完成 LLM+DRL 单智能体系统”
更准确的说法仍应是:
- 已经完成了 LLM 接入前最重要的一层:强于旧平台的 DRL 单智能体基线。
十一、下一步最合理的推进方向
今天之后,下一步最合理的顺序不是继续无脑长训,而是:
先固化当前 DRL 基线,再进入 LLM 上层接入阶段。
1. 先备份并冻结 base_200k
这是当前最重要的阶段性成果,必须作为:
- 回滚点;
- 对照组;
- 后续 LLM 接入前的底层基线。
2. 再做 deterministic eval 与指标整理
要把当前结果进一步变成:
- 可展示;
- 可报告;
- 可对比;
就必须整理出更清晰的 eval 输出。
3. 之后进入 LLM 解释/规划层
在当前时点,再继续大量时间投入到纯 DRL 重训的收益已经开始下降。更合理的方向是:
- 让 LLM 负责状态解释;
- 让 LLM 负责攻击路径自然语言总结;
- 再逐步尝试更高层规划或语义辅助。
这样,后续提交时就可以形成更清晰的“LLM + DRL 单智能体渗透测试原型”。
十二、总结
当前最准确的当日总结是:
今天已完成 PenGym 单智能体
izumi的 MaskablePPO 主线稳定化工作,修复了训练/评估不一致、动作掩码接错、重复动作循环、空掩码崩溃等关键问题,使当前学习型izumi真正稳定下来;随后又在tiny_20k基线之上通过继承训练与更强 reward shaping 成功突破旧平台,最终得到新的高收益单智能体模型maskable_ppo_izumi_base_200k.zip。当前阶段的好处是:已经有了一个可继续接入 LLM 的真实 DRL 基线;当前阶段的问题是:仍然只是单智能体、无 LLM、单场景结果,且 reward 与评估体系还未完全系统化。下一步最合理的方向,应是先固化当前 DRL 基线,再进入 LLM 上层接入与提交版封装阶段。
