前几天 Hacker News 上有一个挺受关注的 Show HN 项目:Teaching agents how to play Factorio (using RLM, GEPA)。标题翻译过来就是“教智能体玩《异星工厂》”,技术栈是 RLM 和 GEPA。前者应该是强化学习方向的组件,后者应该是进化计算方向的算法变体。它想做的不是写一个脚本操作按键,而是让智能体真正理解 Factorio 里的长周期决策——挖矿、冶炼、布局、科研、应对虫群。
这类项目最值得关注的地方,不是“AI 玩游戏”这个噱头,而是它同时踩中了三个技术点:游戏环境的程序化交互、长周期稀疏奖励的强化学习训练、以及进化算法与强化学习的组合方式。本文会从项目定位出发,拆解 RLM 和 GEPA 可能承担的角色,再给出一套可落地的复现流程,包括环境准备、启动方式、功能测试、批量实验和问题排查。适合正在做游戏 AI 研究、强化学习入门,或者想研究进化算法在复杂决策任务中如何落地的读者。下面先从核心能力速览开始。
1. 核心能力速览
由于 Hacker News 标题本身没有附带完整的 README 或者版本说明,下面这张表里凡是涉及具体数字的地方,都以“需要按实际项目确认”处理,避免为了凑参数而编造。
| 能力项 | 说明 |
|---|---|
| 项目类型 | 游戏智能体训练项目 |
| 训练对象 | Factorio(异星工厂)中的自动化建厂决策 |
| 核心技术 | RLM(强化学习相关组件)、GEPA(进化计算相关算法) |
| 主要功能 | 通过算法让智能体完成挖矿、冶炼、建造、科研等长周期任务 |
| 硬件门槛 | 小规模实验可以考虑 CPU,大规模训练建议 GPU,具体显存未确认 |
| 启动方式 | 大概率是命令行启动训练脚本,配合 Factorio 本体或 headless 服务 |
| 是否支持 API | 未确认,需要查看仓库源码 |
| 是否支持批量任务 | 可以采用配置矩阵方式批量跑实验,但项目自身是否内置未知 |
| 适合场景 | AI 研究、强化学习算法对比、进化算法优化、自动化游戏策略探索 |
从材料能确定的信息不多,所以这篇文章更多是围绕“这类项目怎么复现、怎么验证、怎么排错”展开。你拿到项目代码后,第一件事应该就是补全这张表:读 README,确认 RLM 和 GEPA 的准确缩写,确认训练入口脚本,确认依赖版本。
2. 为什么选 Factorio 当智能体训练场
很多 RL 项目都选 Atari、MuJoCo 这类环境,因为接口统一、单局时间短、奖励明确。Factorio 和这些环境完全不同,它更接近真实生产调度问题,这也是这类研究项目的价值所在。
2.1 状态空间大且结构复杂
Factorio 的地图是连续坐标,里面有矿石、树木、水域、虫群、玩家建筑。智能体的观测不只是当前帧画面,还包括背包、科技树、物流网络、电力系统。如果直接把屏幕像素作为输入,训练成本会非常高;如果做成结构化观测,又需要精心设计特征提取。这正是 RLM 里“记忆”和“表征”要解决的问题。
2.2 时间跨度长
一个完整的“从徒手采矿到自动化科研”流程,在游戏里可能要跑几千到几万个 tick。强化学习处理这种长时间跨度任务时,最大的问题是奖励延迟:前期所有动作都看不到反馈,智能体不知道造一个熔炉和最终产出科学包有什么关系。如果没有记忆机制或者奖励塑形,训练几乎无法启动。
2.3 动作空间是层级化的
Factorio 里的动作不是单一的“向左走”或者“按下扳机”,而是分层结构:
- 移动层级:走到指定坐标。
- 采集层级:选择目标矿石并采集。
- 建造层级:选择建筑类型,放置到指定格子。
- 配方层级:决定当前熔炉/组装机生产什么物品。
- 科研层级:选择下一个研究项目。
对智能体来说,这种动作空间比经典 RL benchmark 复杂得多。一个可行的做法是先做分层强化学习,低层负责原子动作,高层负责规划和调度。RLM 如果带有记忆模块,很可能就是在高层规划里发挥作用的。
2.4 奖励稀疏且多目标
Factorio 没有单一“赢”的目标。你可以追求产能、追求科研速度、追求防守稳定、追求布局美观。如果只看最终科学包产出,奖励会非常稀疏。项目如果想要训练效果可观察,大概率会引入奖励塑形,比如每生产一个铁板就给一个小奖励,每建造一台机器给一个小奖励,同时用 GEPA 去搜索这些奖励权重的最优组合。单纯靠一个固定奖励函数很难泛化。
从这些特性看,Factorio 是一个难度很高但更有研究价值的智能体训练场。它能检验一个算法是否真的能处理长期规划、资源约束和结构化决策,而不是只在短视的吃豆人式任务里刷分。
3. RLM 与 GEPA:两条技术路线的拆解
在没看到项目源码之前,RLM 和 GEPA 的准确含义只能靠推断。下面这段分析属于技术语义拆解,不是对项目的完整功能复述,你复现时一定要以仓库 README 为准。
3.1 RLM 可能承担的职责
从命名习惯看,RLM 可能有以下两种解释:
- Relational Latent Memory,关系潜在记忆,强调用记忆模块建模实体之间的关系。
- Reinforcement Learning Model,强化学习模型,泛指项目中的 RL 训练管线。
无论哪种解释,它在项目里大概率承担的职责是一样的:做一个可微分的策略训练组件,负责把游戏观测映射成动作概率分布。RL 的优势在于可以用梯度优化策略,能够处理高维连续输入,并且能在试错中逐步提升单步决策质量。
在 Factorio 场景里,RLM 会比较适合用来学习“在当前位置应该先采集铁矿石还是铜矿石”“距离不够时该往哪个方向移动”“当前熔炉空闲时该放什么配方”。这些都是短时间尺度的原子决策,用策略网络输出动作完全可行。但如果要它一口气规划“接下来十分钟的建厂顺序”,单纯的 RL 策略网络很难做到,这也是为什么要引入 GEPA。
3.2 GEPA 可能承担的职责
GEPA 的解释也有几种可能:
- Gene Expression Programming Algorithm,基因表达式编程算法,属于进化计算的一个分支。
- Genetic Evolutionary Programming Algorithm,遗传进化规划算法,泛指用进化策略优化程序或参数的算法。
GEPA 和 RLM 最大的区别在于:GEPA 不依赖梯度信息。它只需要一个适应度函数,就能在参数空间或者程序空间里搜索较优解。对于 Factorio 这种奖励形态复杂、奖励函数不可微、甚至不能端到端优化的任务,进化算法反而比梯度方法更稳。
具体到项目里,GEPA 可能做以下工作:
- 搜索最优奖励权重组合,给 RLM 提供更合理的训练信号。
- 直接演化高阶行为策略,比如“先发展电力,再建设自动化生产线”。
- 优化 RLM 的超参数,比如学习率、记忆长度、经验回放比例。
3.3 两者如何协同
一个比较聪明的组合方式是:RLM 负责微观执行,GEPA 负责宏观搜索。每轮训练时,GEPA 先生成一组高层任务描述或者奖励权重,RLM 在 Factorio 环境里执行这些任务并积累 rollout 数据。环境返回的累计产出作为 GEPA 的适应度评分,GEPA 据此更新下一轮的搜索方向。
这个过程可以用一个简化的循环来理解:
for generation in range(max_generations): # GEPA 搜索高层参数 reward_weights = gepa_search(history) # RLM 在环境中训练智能体 policy = rlm_train(reward_weights, environment) # 评估当前策略的实际表现 fitness = evaluate(policy, environment) # 回传给 GEPA gepa_update(fitness)这种“进化搜索 + 梯度训练”的组合,在文献里经常被称为双层优化或者元进化。它能缓解单个算法在复杂环境下的短板,但也引入了更大的计算开销。实际复现时,你要重点观察训练总耗时和每一层的收敛速度。
4. 适用场景与使用边界
明确一下这个项目到底适合什么人、不适合什么人。
4.1 适合的场景
- 高校实验室做游戏 AI 研究,需要找一个比 Atari 更有挑战性的长时间决策环境。
- 个人开发者研究强化学习和进化算法的结合方式。
- 算法工程师想对比“梯度方法”和“进化方法”在同一任务上的表现差距。
- 对 Factorio 本身有了解的程序员,想看看 AI 能不能解决自己熟悉的建厂难题。
这类项目很适合作为算法学习的载体,因为 Factorio 的规则是确定的,环境是可重复的,你可以用随机种子控制地图生成,能比较公平地对比不同算法。
4.2 不适合的场景
- 想在官方多人服务器上挂机刷成就或者自动生产:绝大多数游戏服务器禁止未经许可的机器人,Factorio 也不例外。
- 想直接把它用成“生产级排产工具”:游戏里的物流模型简化了大量现实约束,结果不能直接迁移到真实工厂。
- 硬件有限的用户:如果只有办公笔记本且没有独立显卡,长周期训练会非常痛苦,CPU 训练一个完整策略可能需要数天。
4.3 合规与安全边界
使用这个项目时必须注意几条边界:
- Factorio 是商业游戏,需要正版授权,不能为了训练模型使用破解版本。
- 自动化脚本只在本地测试环境或者自己开的服务器中使用,不要进入他人服务器。
- 如果后续发布论文、开源代码或者商用项目,要核对游戏 EULA、mod 协议和训练数据的版权来源。
- 游戏内行为不要涉及现实世界的任何对抗性或恶意行为。
简单说:你可以把 Factorio 当成一个很棒的算法训练沙盒,但别把游戏自动化和现实工业控制混为一谈,也别用它在多人游戏生态里干扰别人。
5. 复现项目前需要准备的环境
由于项目是 Hacker News 上的新仓库,没有确认的依赖清单,下面给出一套通用的环境准备流程。你拿到项目代码之后,对照 README 调整即可。
5.1 操作系统
建议在 Linux 环境下训练,尤其是 Ubuntu 20.04 或 22.04。Factorio headless 服务在 Linux 上运行稳定,Python 生态的依赖也更好装。Windows 可以用 WSL2,或者直接在 Windows 上跑 Python 训练端,但通信延迟和进程管理会稍微麻烦一点。
5.2 Factorio 本体
你需要有一个正版 Factorio 游戏本体。训练模式通常有两种方式:
- 启动 Factorio 客户端并加载自定义 mod。
- 使用 Factorio headless 服务,不渲染画面,只模拟游戏逻辑。
后者更省资源,适合大批量训练。headless 服务可以从游戏的官方渠道下载独立服务端文件,确认版本号和 mod 要求的版本一致。
5.3 Python 环境
推荐 Python 3.9 以上版本。建议用虚拟环境隔离依赖:
python3 -m venv factorio-ai source factorio-ai/bin/activate pip install --upgrade pip5.4 深度学习框架
如果项目基于 PyTorch,安装方式如下:
pip install torch torchvision如果使用 TensorFlow,则替换为:
pip install tensorflow不要混装两个框架,避免依赖冲突。安装完成之后先跑一个简单的 tensor 计算,确认 CUDA 能被识别:
import torch print(torch.__version__) print(torch.cuda.is_available()) print(torch.cuda.device_name(0) if torch.cuda.is_available() else "CPU mode")如果输出False,说明 PyTorch 没找到 GPU,后续训练会退回 CPU,速度会慢非常多。
5.5 磁盘空间
模型权重、训练日志、游戏存档、mod 文件加在一起,建议预留至少 30GB 空间。如果做大批量实验,还需要额外空间存 checkpoint 和评估结果。
6. 安装部署与启动流程
按照这类项目的通用结构,部署可以分为三步:拉取代码、安装依赖、启动训练环境。
6.1 拉取代码
git clone https://github.com/<user>/<repo>.git cd <repo>这里<user>/<repo>需要替换成项目的真实地址。如果项目已经在本地,可以直接跳过这一步。
6.2 安装依赖
pip install -r requirements.txt部分项目会把游戏环境依赖和模型训练依赖分开,例如requirements-env.txt和requirements-train.txt。如果 README 里这么组织,就分别安装。
6.3 启动 Factorio 环境
如果项目使用 headless 模式,先启动游戏服务:
./bin/x64/factorio --start-server ./saves/train-world.zip --mod-directory ./mods如果项目直接连客户端,则需要先打开 Factorio,加载指定地图,并启用训练 mod。注意观察游戏窗口或日志里打印的通信地址和端口。
6.4 启动 Python 训练端
通常训练脚本的入口是train.py或main.py:
python train.py --config configs/baseline.yaml如果项目没有提供配置文件,你可以用命令行参数替代:
python train.py --env-address 127.0.0.1 --env-port 34197 --epochs 1000注意端口必须和游戏端的 mod 配置一致。如果你看到的端口不是 34197,以项目 README 为准。
6.5 验证启动成功
启动后,重点看两类日志:
- 游戏端是否有连接成功的提示,比如
client connected。 - Python 端是否开始输出观测数据或者 reward。
如果 Python 端一直卡在waiting for connection,说明游戏端没起来或者网络配置不对,先检查端口和 mod 是否加载成功。
7. 功能测试与效果验证
跑通启动流程只是第一步,关键是要验证智能体真的“在学”。建议按下面的顺序做一轮功能测试。
7.1 环境连通性测试
测试目的是确认 Python 训练端和 Factorio 环境能正常交换数据。先写一个最小脚本:
import random def test_environment(env, steps=100): obs = env.reset() print("initial observation:", obs) for i in range(steps): action = env.action_space.sample() obs, reward, done, info = env.step(action) print(f"step {i}: reward={reward:.3f}, done={done}") if done: print("episode finished at step", i) break如果每一步都能返回 reward 和 observation,说明环境接口正常。如果卡住或者报错,问题大概率出在 mod 版本和游戏版本不匹配。
7.2 随机策略基线测试
在训练之前,先记录随机策略的得分。这个分数是后面判断算法是否有效的最重要基线。
def evaluate_random(env, episodes=5, max_steps=2000): total = 0.0 for _ in range(episodes): obs = env.reset() episode_reward = 0.0 for step in range(max_steps): action = env.action_space.sample() obs, reward, done, info = env.step(action) episode_reward += reward if done: break total += episode_reward return total / episodes print("random baseline:", evaluate_random(env))随机策略在 Factorio 里几乎不可能完成任何有效建设,所以它的总奖励通常会很低。如果你的随机策略奖励高到离谱,说明奖励函数可能设计得太宽,智能体不需要动脑也能刷分。
7.3 短任务训练测试
不要一开始就跑几百小时的长训练。先设置一个简单的子任务,比如“让智能体在 500 tick 内采集 20 个铁矿石”。
# 伪代码,具体接口需要按实际环境调整 config = { "task": "collect_iron_ore", "target_count": 20, "max_ticks": 500, "reward_weight": 1.0 } agent = train_agent(config) result = evaluate(agent, episodes=10) print("short task success rate:", result.success_rate)判断成功的标准不是看 reward 曲线是否完美,而是看成功率是否比随机策略有明显提升。如果训练 1000 回合之后成功率还是和随机相近,说明动作空间或者奖励设计有问题。
7.4 长周期任务训练测试
短任务跑通之后,再尝试完整的长周期任务,比如“从零开始研究到红瓶自动化”。这类任务对 RLM 的记忆能力和 GEPA 的规划搜索都是真正的考验。
训练过程中要记录这些指标:
- 每回合累计奖励。
- 铁板/铜板的产量曲线。
- 建筑数量随时间的变化。
- 是否成功完成目标 research。
- 每回合耗时。
判断训练是否有效的标准是:训练后期应当出现稳定的“产量爬坡”,而不是长期停在原地。如果奖励曲线在某个点后长时间震荡,先降低学习率或者增加记忆长度再试。
7.5 模型保存与恢复测试
训练中途断电、服务器重启是常态。你必须要确认:模型能够保存 checkpoint,并且能从 checkpoint 恢复继续训练。
# 保存 agent.save_checkpoint("checkpoints/epoch_1000.pt") # 恢复 agent = Agent.load_checkpoint("checkpoints/epoch_1000.pt")如果不能恢复训练,那你前面所有工作时间都白费了,这个功能一定在开工前就验证好。
8. 接口 API 与批量实验设计
如果项目没有自带 WebUI 或 API 服务,也不需要失望。训练型项目更常见的做法是提供 Python 接口和命令行参数,方便你做批量实验。
8.1 训练接口的通用结构
一个典型的训练接口长这样:
python train.py \ --algorithm rlm \ --env-address 127.0.0.1 \ --env-port 34197 \ --learning-rate 0.0003 \ --batch-size 64 \ --epochs 500 \ --save-dir checkpoints/run1这类接口的关键参数通常包括:
| 参数 | 作用 |
|---|---|
--algorithm | 指定使用 RLM 还是 GEPA |
--env-address | Factorio 通信地址 |
--env-port | Factorio 通信端口 |
--learning-rate | 强化学习策略网络的学习率 |
--batch-size | 每次更新的样本量 |
--epochs | 训练轮数 |
--save-dir | checkpoint 保存目录 |
8.2 批量跑配置矩阵
研究项目经常需要对比不同超参数的效果。你可以用 Python 脚本串联多个实验:
import subprocess import itertools learning_rates = [0.0001, 0.0003, 0.001] batch_sizes = [32, 64] algorithms = ["rlm", "gepa"] for idx, (lr, bs, alg) in enumerate(itertools.product(learning_rates, batch_sizes, algorithms)): save_dir = f"runs/{alg}_lr{lr}_bs{bs}" subprocess.run([ "python", "train.py", "--algorithm", alg, "--learning-rate", str(lr), "--batch-size", str(bs), "--save-dir", save_dir ], check=True) print(f"finished run {idx}: {alg}, lr={lr}, bs={bs}")批量实验时要注意以下几点:
- 每个实验使用不同的随机种子,避免结果都跑在同一张地图上。
- 日志和 checkpoint 按实验名分目录存储。
- 给每个子进程设置超时时间,防止某个实验卡住后阻塞整个队列。
8.3 观察接口与实时监控
如果你希望在训练过程中实时查看智能体的行为,可以让环境定期输出关键状态:
# 伪代码模板 import time for epoch in range(epochs): train_one_epoch() state = env.get_game_state() print(f"epoch {epoch}: " f"iron_plates={state['iron_plates']}, " f"buildings={state['building_count']}, " f"science_packs={state['science_packs']}")这个输出可以作为轻量的监控指标,确认训练方向是否合理。
9. 资源占用与训练性能观察
训练这类游戏智能体时,瓶颈通常不是 GPU 显存,而是环境仿真的速度。Factorio 是游戏引擎模拟,每 tick 都要完整计算所有实体状态,这一步很难被并行化。
9.1 观察环境吞吐量
训练速度的核心指标是 tick/s,也就是每秒能模拟多少游戏 tick。你可以通过日志或者计时函数来统计:
import time start = time.time() obs = env.reset() done = False ticks = 0 while not done: action = policy(obs) obs, reward, done, info = env.step(action) ticks += 1 elapsed = time.time() - start print(f"{ticks} ticks in {elapsed:.2f}s, throughput={ticks / elapsed:.1f} ticks/s")如果吞吐量太低,比如只有 10 tick/s,一次上千 tick 的任务就需要上百秒,完全无法做大规模训练。此时优先检查是否开启了不必要的渲染。
9.2 GPU 显存占用
使用 GPU 时,可以通过nvidia-smi实时查看显存占用:
watch -n 1 nvidia-smi如果显存不足,优先降低 batch size,或者把游戏环境切换为 headless 模式,减少显存中的画面缓冲。模型是否能用混合精度训练,取决于项目使用的深度学习框架和代码是否做了相关配置。如果 README 里没有说明 bfloat16 支持,就不要强行开启,容易导致训练不稳定。
9.3 CPU 训练与 GPU 训练的差异
小规模策略网络在 CPU 上训练不是不能跑,但速度差距非常明显。以常见的两层 MLP 策略网络为例,CPU 训练虽然能推进,但每一步的梯度计算耗时可能是 GPU 的 5 到 10 倍。如果 Factorio 环境本身是仿真瓶颈,GPU 的提速会被环境速度掩盖,这时你需要先优化环境吞吐量,再考虑升级 GPU。
9.4 降低资源占用的方法
- 使用 headless 模式跑训练,不要开画面。
- 关闭游戏的自动保存,或者调大自动保存间隔。
- 限制日志输出频率,避免长时间满盘写日志。
- 定期清理旧的 checkpoint,只保留最近几个版本。
- 训练进程和实时可视化分开,训练时不跑监控面板。
10. 常见问题与排查方法
训练类项目的坑非常多,下面整理了一张排查表。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| Python 端连不上 Factorio | mod 未加载、端口不一致 | 查看游戏日志和网络配置 | 检查 mod 目录,对齐端口配置 |
| 游戏启动后立刻闪退 | 游戏版本与 mod 版本不匹配 | 查看崩溃日志 | 切换 Factorio 版本或 mod 版本 |
| 训练速度极慢 | 渲染模式未关闭、tick 率受限 | 查看 tick/s 指标 | 切换 headless,关闭自动保存 |
| 训练时显存不足 | batch size 过大或模型过大 | nvidia-smi 观察占用 | 降低 batch size,关闭画面缓存 |
| 奖励一直不变化 | 奖励函数过稀疏 | 打印每一步 reward 分布 | 增加逐步奖励,缩小任务范围 |
| 奖励不断上升但实际产能无变化 | 奖励函数被钻空子 | 检查智能体是否在无效循环刷分 | 增加惩罚项,设置最短动作间隔 |
| 训练到一半崩溃 | 内存不足或 checkpoint 保存失败 | 查看系统日志和错误堆栈 | 减少环境并行数,修复保存路径 |
| 恢复 checkpoint 后结果不一致 | 随机种子未固定、环境状态未恢复 | 固定 seed,重新加载存档 | 统一 seed,使用同一份游戏存档 |
| 服务器上无法启动游戏 | 缺少图形库或 license 问题 | 查看启动日志 | 使用 headless 模式,检查授权文件 |
| 多进程批量实验互相影响 | 端口冲突或共享目录写入冲突 | 查看进程端口占用 | 每个实验独立端口和输出目录 |
在这些问题中,最容易被忽视的是“奖励函数被钻空子”。Factorio 环境非常开放,智能体可能找到一个循环动作,既不断触发奖励,又没有真正建设生产线。排查时不能只看 reward 曲线,要定期人工观察游戏截图或状态统计,确认行为是否合理。
11. 最佳实践与工程化建议
11.1 先跑最小闭环
拿到项目的第一天,不要急着启动完整训练。先跑一个最小闭环:Python 连上 Factorio,执行 100 个随机动作,确认观测和奖励数据完整返回。这个过程应该控制在半小时以内。如果连最小闭环都跑不通,后面所有实验都无从谈起。
11.2 用小型地图做调试
Factorio 默认地图太大,训练初期智能体连资源点都找不到。建议先把地图缩到很小,资源密度调高,让智能体用最少的时间学会“挖矿搬运冶炼”这一条基本链路。地图生成参数用随机种子固定,调试时始终使用同一份地图。
11.3 保存完整训练日志
训练日志不只是监控用的,也是事后分析的必要依据。建议记录:
- 每个 epoch 的 reward。
- 每 100 epoch 的累计产量。
- 游戏 tick 数和墙钟时间。
- checkpoint 路径。
- 每次启动的命令行参数。
日志格式用 JSON Lines 或者 CSV 都可以,关键是方便后续画图对比。
{"epoch": 100, "reward": 123.4, "ticks": 51230, "iron_plates": 520, "elapsed_sec": 431.2}11.4 分层次检查模型效果
不要只盯着总奖励。把任务拆成小目标逐项检查:
- 智能体能否找到最近的铁矿?
- 能否持续采集到背包满?
- 能否把铁矿石送到熔炉旁?
- 能否把铁板送到组装机?
- 能否完成第一个科研包?
每一层都通过之后,再叠加下一层。这样出问题时你能很快定位是哪个环节失败。
11.5 注意合规和授权
无论项目最终是发论文还是做演示,都要在文档里写清楚:使用了正版 Factorio、mod 来源、训练数据不涉及敏感信息。如果复用了其他人的模型权重、数据集或者地图存档,要保留原作者署名和协议要求。
11.6 实验队列要可重启
批量训练跑十几个小时很常见,进程意外退出是大概率事件。建议每个子实验都能从最近的 checkpoint 恢复,并且用独立的输出目录。外层循环捕获异常后应该继续跑下一个实验,而不是整个队列崩溃。
import subprocess experiments = [...] for exp in experiments: try: subprocess.run(exp.cmd, check=True) except subprocess.CalledProcessError as e: print(f"experiment {exp.name} failed: {e}") # 记录失败原因,继续下一个实验12. 总结与下一步
这个项目最值得尝试的点,在于它把强化学习和进化算法放在了一个真正需要长周期规划的游戏环境里。和 Atari、MuJoCo 相比,Factorio 的任务结构更接近现实问题:资源有限、空间布局重要、奖励延迟严重。如果你已经在 RL 上有一点点基础,直接在这个项目里做小的算法对比实验,会比你刷十个经典 benchmark 更容易形成完整的工程认知。
最先应该验证的功能,不是模型最终能建多复杂的工厂,而是两件事:环境和 Python 能不能稳定通信,以及随机策略和训练策略是否真的存在明显的奖励差。这两关过了,项目的核心价值你基本就能体验到。
最容易踩的坑是奖励函数设计。Factorio 环境太开放,一个设计不当的奖励函数很容易被智能体钻空子。你会在修复奖励函数上花掉比训练更多的时间,这是正常的。想办法让奖励和可视化状态绑定,出现异常分数时直接看游戏截图,会节省大量排查时间。
后续可以继续扩展的方向包括:给 RLM 加更长的记忆长度来观察它能否稳定维持长期规划,把 GEPA 的搜索目标从奖励权重扩展到行为树结构,或者对比分层强化学习和端到端策略在这个任务上的效果差距。如果你对进化算法与强化学习的组合感兴趣,这个项目也是一个很合适的起点。