资讯动态

强化学习结合进化算法:教智能体玩转《异星工厂》的工程实践

发布时间:2026/8/29 14:28:47 来源:尧图企业网站定制
前几天 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.pypython 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, steps100): 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(fstep {i}: reward{reward:.3f}, done{done}) if done: print(episode finished at step, i) break如果每一步都能返回 reward 和 observation说明环境接口正常。如果卡住或者报错问题大概率出在 mod 版本和游戏版本不匹配。7.2 随机策略基线测试在训练之前先记录随机策略的得分。这个分数是后面判断算法是否有效的最重要基线。def evaluate_random(env, episodes5, max_steps2000): 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, episodes10) 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-addressFactorio 通信地址--env-portFactorio 通信端口--learning-rate强化学习策略网络的学习率--batch-size每次更新的样本量--epochs训练轮数--save-dircheckpoint 保存目录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 fruns/{alg}_lr{lr}_bs{bs} subprocess.run([ python, train.py, --algorithm, alg, --learning-rate, str(lr), --batch-size, str(bs), --save-dir, save_dir ], checkTrue) print(ffinished 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(fepoch {epoch}: firon_plates{state[iron_plates]}, fbuildings{state[building_count]}, fscience_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 端连不上 Factoriomod 未加载、端口不一致查看游戏日志和网络配置检查 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, checkTrue) except subprocess.CalledProcessError as e: print(fexperiment {exp.name} failed: {e}) # 记录失败原因继续下一个实验12. 总结与下一步这个项目最值得尝试的点在于它把强化学习和进化算法放在了一个真正需要长周期规划的游戏环境里。和 Atari、MuJoCo 相比Factorio 的任务结构更接近现实问题资源有限、空间布局重要、奖励延迟严重。如果你已经在 RL 上有一点点基础直接在这个项目里做小的算法对比实验会比你刷十个经典 benchmark 更容易形成完整的工程认知。最先应该验证的功能不是模型最终能建多复杂的工厂而是两件事环境和 Python 能不能稳定通信以及随机策略和训练策略是否真的存在明显的奖励差。这两关过了项目的核心价值你基本就能体验到。最容易踩的坑是奖励函数设计。Factorio 环境太开放一个设计不当的奖励函数很容易被智能体钻空子。你会在修复奖励函数上花掉比训练更多的时间这是正常的。想办法让奖励和可视化状态绑定出现异常分数时直接看游戏截图会节省大量排查时间。后续可以继续扩展的方向包括给 RLM 加更长的记忆长度来观察它能否稳定维持长期规划把 GEPA 的搜索目标从奖励权重扩展到行为树结构或者对比分层强化学习和端到端策略在这个任务上的效果差距。如果你对进化算法与强化学习的组合感兴趣这个项目也是一个很合适的起点。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价