☰
AIRI × Factorio 纯视觉实践:Docker 容器化游戏环境与 YOLO11n 浏览器实时目标检测全链路
2026/10/16 5:49:28 网站建设 项目流程
  • 人工智能
  • AI Agent
  • MCP 服务
  • 工具调用
  • GUI 自动化
  • 语音
  • 数字人
  • 交互助手

【免费下载链接】airi

💖🧸 自托管、归你拥有的 Grok 风格 AI 伴侣与 waifu / 赛博生命灵魂容器,目标是接近 Neuro-sama 的高度;支持实时语音聊天、Minecraft 和 Factorio 游玩,支持 Web / macOS / Windows。

项目地址:https://gitcode.com/moeru-ai/airi
点击查看免费下载

本文基于 AIRI 项目 2025 年 8 月 26 日的开发日志(原文档)整理,完整还原airi-factorio在“纯视觉”方向的第一阶段成果:如何把 Factorio 客户端装进 Docker 并提供 VNC 可视化、如何通过 Lua 脚本与 RCON 自动采集截图和标注数据、如何训练并导出 YOLO11n ONNX 模型、如何在浏览器里借助 WebGPU 完成接近实时的目标检测推理,以及如何对 8400 组检测结果做置信度过滤与 NMS 后处理。读完本文,你将获得一套可复现的“游戏画面 → 实时目标检测”工程链路,以及纯前端推理性能调优的一手经验。

为什么先做“纯视觉”方向

在进入正题之前,先交代一下上下文。AIRI 生态中有一个让 AI 游玩异星工厂(Factorio)的独立仓库airi-factorio,早期方案是“TypeScript 编写 Mod + RCON 交互 + LLM 生成 Lua 代码操作游戏”,具体做法与踩坑记录见前一篇 DevLog @ 2025.07.18:包括用typescript-to-lua(tstl)把 TypeScript 编译成 Lua、通过 factorio-rcon-api 调用/c命令执行 Mod 注册的函数、用 LLM 生成操作代码等等。但这条路线调试困难(Mod 改动常需重进地图甚至重启游戏)、健壮性差,维护者随后参考 Factorio Learning Environment(FLE)论文开始重新设计。

本篇 DevLog 则切换到另一个更直接的思路:纯视觉。受 2025 年 6 月发布的近乎实时的 VLM Playground 启发,维护者想先验证“让 AI 看见游戏画面”这条通路——用实时目标检测识别游戏中的机器、传送带等对象,把检测结果交给 AI 做决策,最终输出动作让游戏执行。整个链路分为三个可独立复用的阶段:可控的游戏运行环境(Docker + VNC)→ 目标检测模型(数据采集 + 训练)→ 浏览器端实时推理。

第一步:把 Factorio 客户端装进 Docker

AI 要“看见”游戏画面,前提是游戏运行在可控环境中——不受窗口大小、位置、桌面环境影响,最好还能开箱即用。因此第一步就是把 Factorio 客户端容器化。

Factorio 官方虽然提供 Docker 镜像,但那是纯服务端,没有画面可供 AI 观察,也无法让 AI 操控游戏。而社区中没有现成的客户端镜像(Factorio 许可协议不允许分发客户端),所以只能自己打包,且最终也只能分享 Dockerfile,不能分发打包好的客户端镜像。

把 Factorio 客户端装进 Docker,一共分三步:

  1. 下载 Factorio 客户端——它是主角;
  2. 准备虚拟显示器——图形界面程序需要一块“屏幕”;
  3. 准备 VNC 服务——读取虚拟显示器内容传给外部客户端,同时把用户输入传给游戏。

音频则被刻意忽略:当时的 AI 还不会听声音。

下载 Factorio 客户端

官网下载需要登录手动操作,不适合构建自动化流程,于是维护者使用了factorio-dl这个下载脚本:只需提供用户名、密码和目标版本,脚本就会根据系统架构自动下载对应客户端,从而可以在 Dockerfile 的构建阶段无人工介入地获取客户端。

准备虚拟显示器

图形界面程序其实不需要完整的桌面环境——不需要窗口管理器,只要一个最简单的 X 环境加一个显示服务器就够了。在 Ubuntu/Debian 系镜像中安装三个包即可:

sudo apt install -y xvfb x11-apps mesa-utils
  • xvfb:虚拟帧缓冲器和 X 服务器,为无显示器环境提供“隐形屏幕”;
  • x11-apps:X 相关工具集,安装时顺带把 X 环境装齐;
  • mesa-utils:Mesa(OpenGL 的软件实现)相关工具,用于测试和调试 OpenGL 程序。

准备 VNC 服务

VNC(Virtual Network Computing)是远程桌面协议,能让人像坐在那台计算机前一样远程操作。安装:

sudo apt install -y x11vnc

至此,Docker 内已经可以运行 Factorio 客户端并通过 VNC 控制它。但这还不足以在浏览器里游玩并实时做目标检测:浏览器只能使用 HTTP 协议,因此还需要websockify把 VNC 协议桥接成 HTTP 协议,同时用noVNC提供一个网页界面来显示 VNC 画面并方便调试:

sudo apt install -y websockify novnc

从源码结构看,这套“浏览器 + VNC 玩 Factorio”的 Playground 被组织在airi-factorio仓库的apps/factorio-yolo-v0-playground中,配套的容器构建文件是仓库根目录下的docker/Dockerfile。AIRI 主仓库中与此衔接的功能是 Factorio 集成模块,配置入口在 设置 → 机体模块 → 异星工厂,其默认端口为34197(见 gaming-factorio.ts 与 GamingFactorio.vue)。

第二步:训练目标检测模型

环境就绪后,下一步是让模型认识游戏里的对象。为了快速验证,维护者直接以 YOLO11n 预训练权重为基础微调目标检测模型。

准备数据集:用 Lua 脚本自动采集并自动标注

数据采集的思路是“让游戏自己生成带标注的截图”,全部通过 Factorio 的 Lua API 完成:

  1. 使用surface.create_entity在场景随机位置放置机器,并记录机器选择框(selection_box)的大小与位置;
  2. 使用game.take_screenshot以各种缩放比例和光照条件(daytime)截屏;
  3. 根据选择框生成标注数据,并用helpers.write_file保存到文件。

采集脚本本体是 TypeScript 写的(位于airi-factorio仓库的packages/factorio-rcon-snippets-for-node/src/factorio_yolo_dataset_collector_v0.ts):它使用typescript-to-lua把 TypeScript 编译成 Lua,再通过 RCON 传递给 Factorio 执行。数据集规模为:三个型号的组装机和传送带,每个机器采集 20 张 1280×1280 分辨率的截图,画面中不包含 UI。

为了更方便地调试采集脚本,还配套开发了一个 VSCode 插件(位于airi-factorio仓库的packages/vscode-factorio-rcon-evaluator),提供 CodeLens 操作,一键编译并执行脚本。

按 YOLO 格式组织数据

图片和标注收集完成后,需要按 YOLO 官方数据集格式组织目录结构(每个目标一行class x_center y_center width height,坐标归一化),然后可以上传到 Ultralytics Hub 预览效果:

训练与导出 ONNX

训练代码非常直接,以 YOLO11n 预训练模型为基础开始训练:

from ultralytics import YOLO model = YOLO("yolo11n.pt") model.train(data="./dataset/detect.yaml", epochs=100, imgsz=640, device="mps") model.export(format="onnx")

几个关键训练参数的含义与取值:

  • imgsz=640:训练输入分辨率 640×640。注意模型在 640 尺度下训练,与推理端输入尺寸必须保持一致(后文“非正方形图片失效”的问题正与输入尺寸处理有关);
  • device="mps":在 macOS 上使用 Apple Metal(MPS)设备,可获得比 CPU 更好的训练性能;
  • epochs=100:共训练 100 个 epoch,每个 epoch 有 5 个 batch,大约在 70 个 epoch 时达到最佳效果;
  • model.export(format="onnx"):导出 ONNX 格式,供浏览器端onnxruntime-web加载推理。

实际结果:训练耗时约8 分钟,导出模型大小约10MB。数据集、训练代码和导出的 ONNX 模型都放在airi-factorio仓库的apps/factorio-yolo-v0-playground中。

第三步:浏览器端实时推理

把前两步的“零件”组装起来:用@novnc/novnc在浏览器中显示 VNC 画面,同时把画布像素数据取出来喂给模型;用onnxruntime-web在浏览器中做推理,它提供 WebGPU 后端,可以充分利用 GPU 性能。

一个必须显式开启的选项:executionProviders

初版推理速度非常慢(约 400ms),还会卡死 UI,连 VNC 画面都显示不正常。维护者临时补课 WebWorker,把推理和显示拆到不同线程才解决了 UI 卡死问题——随后发现更关键的问题:WebGPU 根本没有真正启用,所以速度依然慢。正确写法是:

ort.InferenceSession.create(model, { executionProviders: ['webgpu', 'wasm'] })

需要显式列出webgpu和wasm两种执行提供方:这样在 WebGPU 不可用的环境下,推理会自动回退到 WASM 执行。

性能优化:400ms → 80ms → 20ms

启用 WebGPU 后,推理速度从约 400ms 提升到约 80ms。继续优化时,一个来自 AI 编程助手的建议点醒了维护者:像素颜色值归一化时一直在做除法(除以 255),应该先把1/255算出来,然后直接乘以这个常数,避免逐像素除法。这看似微小的改动让推理速度提升到了约20ms,体验已经相当不错——这也印证了在前端热路径里“乘优于除”的基本功。

演示视频存放在 airi-factorio-yolo-v0-playground-vnc.mp4:视频中左侧是通过网页 VNC 游玩的 Factorio 画面,右侧是几乎实时的目标检测结果叠加。

处理模型输出:8400 组检测结果

模型输出是一个 84000 个元素的一维数组,dims为[1, 10, 8400]。也就是说,84000 个元素按10 个为一组排列,每组包含:

  • 边界框中心 x、y 坐标;
  • 边界框宽、高;
  • 6 个类别各自的置信度;

合计8400 组检测结果。

后处理分两步:

  1. 置信度过滤:以 0.6 为阈值,过滤掉置信度过低的边界框;
  2. NMS(非极大值抑制):用 IOU 过滤掉重叠的边界框。

用 NMS 去掉重叠框

IOU(Intersection over Union,交并比)的计算思路:把两个框的面积加起来,减去重叠面积得到“实际占用面积”(并集),再用重叠面积除以并集面积,得到 0~1 之间的重合度。实现非常简单:把所有边界框按置信度排序,从高到低遍历,若当前最高置信度框与某个候选框的 IOU 大于 0.7,就认为它们指向同一个物体,将其过滤掉:

function nms(boxes: Box[], iouThreshold: number): Box[] { // 1. Filter by confidence and sort in descending order const candidates = boxes .filter(box => box.confidence > 0.6) .sort((a, b) => b.confidence - a.confidence) const result: Box[] = [] while (candidates.length > 0) { // 2. Pick the box with the highest confidence const bestCandidate = candidates.shift()! result.push(bestCandidate) // 3. Compare with remaining boxes and remove ones with high IOU for (let i = candidates.length - 1; i >= 0; i--) { // The iou() function needs to be implemented separately, as described in the article. if (iou(bestCandidate, candidates[i]) > iouThreshold) { candidates.splice(i, 1) } } } return result }

Playground 的完整源码位于airi-factorio仓库的apps/factorio-yolo-v0-playground。本仓库中还保留了配套的可视化教学组件 nms-iou.vue,它以两个可拖拽的检测框演示完整的 IOU 计算:实时计算重叠判断(isOverlapping)、交叠区域(intersect,通过Math.max/Math.min求左右上下边界)、并集面积(union = box1 面积 + box2 面积 − 交叠面积)以及iou = intersect / union,并把每一步的中间算式直接显示在界面下方。拖动标签改变框的位置,即可直观感受两个框从分离到重叠再到高度重合时 IOU 值的变化,是理解 NMS 阈值(0.7)含义的绝佳互动教具。

实战中踩到的三个坑

这套方案跑通之后,维护者总结出三个在实践中发现的问题,对后续迭代非常有参考价值:

  1. 无法识别非正方形图片:一旦输入图片不是正方形,模型输出的所有结果置信度都会非常低,甚至为 0。这与训练时固定 640×640 的输入处理(letterbox 填充)直接相关;
  2. 类别混淆:模型能区分一级组装机和二级组装机,但会把箱子等方形物体也误识别为组装机——方形物体与组装机在视觉特征上过于接近;
  3. 状态标志干扰:实际游戏中,机器贴图上往往叠加状态标志(电力状态、当前配方、使用的插件等),这些标志会干扰模型的识别结果。

有意思的是,这些坑在后续项目中被系统性地解决并沉淀成了方法论:在 DevLog @ 2026.02.16(Dome Keeper 方向)中,维护者总结了更成熟的数据采集规则——只在出现目标时才采“有目标帧”、用“先采够 5 张有目标帧才允许采 1 张无目标帧”的规则稀释负样本、输出统一到 640×640 时用灰色114/255居中 padding 并对 bbox 做同样的缩放与偏移、按 30 秒时间段以 4/1/1 循环切分 train/val/test 等等。这些经验正是从本篇 Factorio 纯视觉实践中的问题延伸而来。

后续方向与 AIRI 生态衔接

这篇 DevLog 记录的是“纯视觉”的第一步:AI 能够实时看见游戏画面。维护者明确表示,接下来要做的是提升模型性能,然后“以某种方式让 AI 来控制游戏”。

在 AIRI 主仓库中,Factorio 属于已规划的游戏集成之一(见 README.md 中的功能清单与生态列表,相关组件为 gaming-factorio.vue)。桌面端提供连接配置(服务器地址、端口、玩家名),实际连接仍取决于可访问的 Factorio 服务器与服务端集成(Factorio 集成文档)。本篇的纯视觉 Playground 正是为这条“视觉感知 → AI 决策 → 游戏操作”链路补上最前端的感知环节。

参考与延伸阅读

  • 本篇原始开发日志:DevLog @ 2025.08.26
  • 前篇(Factorio 方案重设计与 FLE 论文解读):DevLog @ 2025.07.18
  • 后篇(Dome Keeper 方向,数据采集方法论延续):DevLog @ 2026.02.16
  • IOU/NMS 交互教学组件:nms-iou.vue
  • AIRI 的 Factorio 集成配置说明:integrations/factorio.md
  • Factorio 集成前端实现:GamingFactorio.vue 与 gaming-factorio.ts
  • 人工智能
  • AI Agent
  • MCP 服务
  • 工具调用
  • GUI 自动化
  • 语音
  • 数字人
  • 交互助手

【免费下载链接】airi

💖🧸 自托管、归你拥有的 Grok 风格 AI 伴侣与 waifu / 赛博生命灵魂容器,目标是接近 Neuro-sama 的高度;支持实时语音聊天、Minecraft 和 Factorio 游玩,支持 Web / macOS / Windows。

项目地址:https://gitcode.com/moeru-ai/airi
点击查看免费下载

相关推荐

上一篇:Hermes Agent终极指南:如何打造你的个人AI智能助手
下一篇:如何用DanmakuFlameMaster打造沉浸式博物馆弹幕导览体验

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询