资讯动态

用LLM驱动马里奥:实时游戏Agent的架构与调试实录

发布时间:2026/10/5 14:28:15 来源:尧图企业网站定制
拿起LLMario这个名字的时候我脑子里先冒出来的是Nintendo标志性的红帽子水管工紧接着才意识到后面跟的是Large Language Model。一个纯粹用大语言模型驱动游戏角色、让它在一个实时模拟器环境里自己观察、自己决策、自己按手柄的项目这正是我最近两个月一直在折腾的东西。把LLM塞进超级马里奥的世界里看似是个玩票性质的实验实际上它在逼你解决一连串很严肃的问题模型怎么看游戏画面、怎么把观察结果压缩进上下文、怎么保证动作输出赶得上游戏的实时节奏。这篇文章想把我从零搭起LLMario的过程、架构上的取舍、以及踩进去就爬出来的坑一次性讲清楚给同样想做LLM Agent 或者用游戏环境评测模型能力的朋友一条能直接走的路。1. 为什么要把LLM塞进马里奥——这个项目解决的其实不是通关1.1 从Gym Retro说起游戏环境本来就是为了测Agent要理解LLMario的定位得先说清楚超级马里奥这类游戏在AI圈子里是怎么被使用的。OpenAI 早年发布过一套叫Gym Retro的强化学习环境库把一批经典红白机游戏的模拟器封装成标准的RL接口提供obs游戏画面给智能体接收action手柄输入返回reward和是否结束。当年的玩法是训练一个策略网络去吃像素、学跳跃、过水管。现在把主角换成LLM本质上还是同一套交互范式只是策略网络变成了一个读文本/读图、输出自然语言指令的通用模型。我看过不少人在讨论LLM能否玩好动作游戏时把重点放在了能不能通关上。实际搭过一遍你就会发现这一类项目的价值根本不在通关率。LLM的决策周期从看到画面到生成动作天然是几百毫秒甚至几秒级别的跟人类玩家比不了手速更没法跟端到端RL策略比帧级反应。LLMario真正值得关注的地方是它把智能体拆成了三个可以被单独评测的能力视觉理解看懂场景里的敌人、台阶、道具、规则推理把视觉信息翻译成该往哪走、该不该跳、行动计划连续多次决策保持目标一致而不是东一下西一下。1.2 为什么选马里奥而不是别的游戏挑游戏这事也有讲究。3D开放世界画面漂亮但信息量爆炸LLM的上下文根本装不下而且动作空间太连续输出映射复杂。俄罗斯方块、打砖块这类又太简单决策链长度太短测不出多少东西。超级马里奥属于信息密度适中的典型样本单屏内要素足够多——砖块、水管、蘑菇怪、金币、悬崖、台阶但每帧的状态变化又没复杂到非用实时视频理解不可动作空间是离散的——八个方向、跳跃、加速正好可以用自然语言或者Tool Call来表达关卡设计里既有短期的陷阱前方三格有坑要跳又有中期的规划先踩怪再上水管很适合观察LLM的综合推理。我当时选它的另一个原因是环境可复现性好模拟器状态可以随时重置到固定帧方便做对比实验。这一点在后面调prompt、调采样参数时非常关键如果你每次测试的初始条件都对不齐你根本分不清模型能力提升了还是运气变好了。2. 整体架构LLM是怎么看见马里奥、又是怎么伸手去按手柄的2.1 视觉输入多模态模型的画面接入LLMario的第一步是解决看的问题。我使用的方案是把模拟器渲染出的每一帧以固定频率比如每秒2帧截取转成JPEG压缩后交给多模态大模型。注意这个频率不能太贪心我最初试过每秒4帧视觉API的延迟和token开销会直接导致决策跟不上游戏节奏降到每秒2帧之后画面信息的丢失也在可接受范围内。截帧程序用传统cv2就能搞定从模拟器窗口抓屏或者直接走环境内部的帧缓冲都行。为了压缩成本我还会把相邻帧去重——两帧画面完全相同就不重新发送因为模型不需要对一个静止画面反复思考。多模态模型输出的并不是按键而是自然语言指令比如向右移动并跳跃过面前的缺口。我不让模型直接输出离散动作码比如action: 3原因有两个第一自然语言对模型来说更自然它本来就是被训练来理解和生成语言的第二后续如果想换模型或者调整动作映射语言层可以保持不变只改解析模块。2.2 动作执行从语言指令到红白机手柄模型说向右跑并跳程序怎么知道该按下哪些键我在中间加了一个指令解析层维护一张从自然语言动作到按键握持状态的映射表。举个例子指令里含向右就按住右键加速就按住B键跳跃就短促按下A键下蹲就按下方向下。解析层的工作方式不是简单的关键词匹配——向右移动和往右边走都得能映射到同一组按键所以我把模型输出约束成一小段格式化的JSON字段包括direction左/右/无、jump是否跳跃、speed普通/加速、action_desc自然语言的自述。解析器读direction和jump字段映射按键action_desc留作日志记录方便我反看模型当时的决策意图。这里有一个很关键的时序问题LLM输出动作到程序执行动作之间存在不可忽略的延迟。模型API的响应时间通常长达一两秒这段时间游戏画面早变了。所以我做了一个决策缓冲队列模型返回一个动作之后程序并不立即执行而是放进一个待执行队列里结合当前帧的时间戳按顺序消费。同时我限制队列的最大长度防止模型输出跟不上导致动作堆积延迟越积越大。这是整个项目里最影响手感的一个设计。2.3 中间层环境状态的结构化转述多模态模型直接看截图的时候有个麻烦它会把画面里的细节看错。马里奥的像素本身不大截图压缩后更容易出现误判比如把水管当成砖块、把敌人看成背景。所以我另外加了一个状态转述层在把截图交给模型之外还会从模拟器内存里读出一组结构化状态信息包括马里奥当前的横纵坐标、水平速度、朝向、金币数、剩余时间、当前关卡的名称和大致位置。这些数据整理成一段很短的文本拼在图片后面一起发给模型例如状态马里奥位于 1-1 关卡坐标 x1273, y214朝右水平速度 1.2金币 5时间 312。结构状态的存在价值不是为了代替视觉而是为了校正视觉。模型读图说前方是悬崖坐标数据却说前方是平地我可以在系统提示里让模型优先采信坐标信息。实际测试中加了这段文本之后模型在关键位置上的判断准确率明显稳定多了误把背景方块当障碍物的次数大幅下降。3. 上下文窗口是最大的敌人——状态管理与提示词设计3.1 你不能把整个游戏进程都塞给模型LLM有一个绕不开的约束上下文窗口有限而且token一多响应变慢、成本变高。游戏是一个连续过程如果每一次决策都把从开局到现在的所有截图指令全部重新发送用不了几步窗口就被撑爆了而且模型会被冗长的历史干扰注意力都分散到老旧的画面信息上反而忽略了当前帧。我的做法是滚动式状态摘要维护一个内存中的历史记录对象记录最近N个关键节点发生的事——比如跳过了一个坑踩死了一只蘑菇怪吃到了金币掉了一次血。每次决策时把这些摘要以列表形式附在系统提示里而不是回放完整历史帧。这个设计参考的是对话系统里常见的memory bank思路只不过这里的记忆单元是游戏事件不是聊天记录。3.2 我的状态摘要模板长什么样系统提示我固定成四段式顺序很重要【角色设定】你是一个超级马里奥游戏的AI玩家目标是尽可能安全地向前推进收集金币而不是冒险尽量避免死亡。 【环境背景】这是超级马里奥1的第一关。角色会向你提供当前坐标和速度信息图片是当前看到的画面。 【实时状态】{结构化坐标/速度/时间} 【近期事件】{最近5个关键事件的摘要} 【输出要求】只输出如下JSON格式的动作指令不要输出任何其他内容{direction: left|right|none, jump: true|false, speed: run|walk, reason: 不超过10个字说明理由}我踩过的坑是把近期事件放在实时状态前面。模型接收信息时靠后的内容注意力权重更高实时状态必须放在更靠近输出的位置才能让它在生成动作时优先参考当前坐标。这个顺序问题我调了好几版是一个很容易被忽略的细节。3.3 提示词里一定要写清楚的约束条件除了格式要求我还必须在提示词里明令禁止几类行为否则模型会表现出灾难性的自由发挥。第一类是禁止原地连续跳跃——没有障碍物的时候不要跳否则很容易跳进坑里第二类是禁止长时间停留不动——一旦画面连续几帧没有明显变化就要主动向右推进第三类是禁止回头——马里奥关卡是单向设计的回头是无效动作第四类是注意时间限制——当剩余时间不足60秒时优先前进而不是收集金币。这些约束不是从AI安全之类的角度出发的纯粹是游戏常识。但模型并不会天生知道这些常识它可能见过马里奥游戏的语料知道水管工要跳要跑却不知道当前时间只剩20秒还跑去吃金币是必死行为。把游戏规则显式写进提示词是让LLM从会玩变成玩得像样的最便宜的改进方式。3.4 上下文轮替旧画面怎么退场除了事件摘要我还设计了一套局部观察窗口的帧选择策略不把当前帧的截图直接发出去而是带上当前帧之前四帧累计的画面拼图横向拼接成一张图让模型能看出一点运动趋势。这个设计也是踩坑踩出来的——单帧截图给模型它判断前方是一个水管没问题但判断我正以多快的速度靠近水管就很吃力。拼图给了它一个粗略的运动感代价是图片token增加不过我实测下来收益远大于成本。旧帧的处理上我采取只保留最近四帧的极简策略。哪怕模型上下文窗口能容纳更多也不贪多。原因很简单马里奥的关卡是连续但分段推进的决策所需的信息窗口其实很小过了那个点再看旧帧反而干扰判断。事件摘要已经承担了长程记忆的职责图片信息就专注服务当下的局面判断。4. 踩过的坑——从原地跳二十次到能跑能停的调试实录4.1 初始版本的行为有多离谱第一次跑通LLMario的时候我满怀期待地看它操作结果是马里奥站在关卡起点原地跳了近二十次然后向左走回了屏幕边缘撞墙继续原地跳。整个行为模式可以用惊慌失措来形容。回头翻日志发现模型每一轮输出reason字段写的都是尝试探索前方清除潜在障碍调整位置以观察环境。它根本不知道自己该往哪去只是机械地生成看起来合理的动作。这个现象背后是个很本质的问题LLM不是强化学习策略它没有目标函数它对合理行为的理解来自训练语料里的统计规律马里奥是一个会跳跃的角色跳跃是它的标志性动作。你让一个语言模型控制马里奥它会扮演马里奥而不是玩马里奥。解决这个问题的第一步是把系统提示里的目标描述从你是超级马里奥游戏中的AI玩家改成你的目标是在关卡内向右推进到终点过程中尽量安全不要无故使用跳跃。加上了明确的奖励倾向描述之后原地跳的情况明显减少但它又开始犯第二个错遇到砖块就跳。明明可以绕过去或者直走它偏要在砖块前起跳撞到头再落回来。这个错误背后的逻辑是模型把障碍物和跳跃必要错误地画了等号。4.2 温度参数和采样策略怎么影响操作稳定性我先说结论LLMario这类项目的采样温度我最终调到了接近0并且把top_p也限制到0.9以内。原因是动作游戏对行为一致性要求太高。把温度调到0.4之后模型给出的动作明显花样繁多会突然跳起来转方向理由写的是尝试不同策略。这种探索性对于聊天是优点对手柄操作是灾难。你需要的是确定性同一画面下模型每次应该给出同样的动作这样才能稳定调试prompt。但温度也不是越低越好。我把温度调到0之后出现过一个新问题——模型在遇到可选择路径时会卡住比如面前有两个平台一个高一个低它倾向于反复输出完全相同的保守动作比如站着不动因为没有随机性帮它打破僵局。这时候我会临时把温度提到0.3让它动一下或者用工具调用里的参数强制调整方向。最终的方案是分段采样大方向推理用低温度保证一致性具体的跳跃时机判断用稍高温度留一点灵活性。4.3 延迟比想象中更致命从API调用到按键按压的完整链路项目跑通之后我做了个简单的计时发现一次完整决策链路的时间分布大致是截帧和图像压缩约50毫秒调用多模态API约800到2000毫秒解析输出和映射按键约10毫秒。整体下来从马里奥看到悬崖到马里奥起跳中间隔了一秒多。这个延迟放在动作游戏里是致命的。你让模型看到悬崖再跳它按下的那一帧崖边早过去了。针对这个问题我做了三层补救。第一层是提前预判辅助在状态转述层里额外输出一个ahead_obstacle字段程序根据坐标数据估算前方最近障碍物的距离把这句前方2.5米处有坑直接写进给模型的实时状态里。模型不需要自己从截图里数像素算距离只要回答看到前方有坑就跳就行。第二层是动作保持如果模型连续两轮都输出向右跳程序会让马里奥保持跳跃状态更长一点相当于把按键粘滞时间做了个软扩展。第三层是危险兜底当障碍距离小于某个阈值、而模型还没来得及返回动作时程序自动执行一个保守动作一般是跳跃避免马里奥直接走进坑里。这三层下来模型的生存率提升了一个台阶虽然代价是马里奥的动作看起来有点傻——它会在模型的指令到来之前就自动跳起来但至少活着走到了关底。4.4 模型分不清左右坐标语义与画面视角冲突这是我当时完全没有预料到的一个坑。明明截图里水管在右边马里奥在左边模型输出的direction字段居然是left。翻日志发现它的reason写的是向左侧移动以规避陷阱。后来我才搞明白问题出在多模态模型对左右的定义上。有些模型的训练数据里图片中的左是按观察者视角定义的但游戏内马里奥的朝向和画面方位混合在一起之后模型的判断出现了歧义。而当我在状态文本里写上坐标马里奥x1500水管x1620时模型基于数字就能正确判断出水管在右边我应该向右移动。这说明语言模型对数字坐标的对比较文字空间描述更敏感。这之后我再也不依赖模型的纯视觉空间判断了位置估算一律走状态文本。这个调整也让我开始认真对待视觉文本双通道的设计——不是所有信息都适合让模型通过图像来读取。4.5 奖励信号和自杀倾向为什么模型会主动跳崖调试过程中最让我迷惑的一个行为是马里奥明明站在平地上前方没有任何障碍它突然就往坑里跳。日志里reason写的是主动探索前方区域。这个情况在模型判别这个坑可能跳得过去也有风险的时候尤其常见。后来我意识到模型是在用一个概率性的思路决策跳过去有概率成功不跳会被卡住横竖都要赌一把。这是文本模型和游戏玩家之间巨大的心智差异——真人玩家知道掉坑损失一条命很心疼但LLM没有对死亡的恐惧感死亡对它来说只是文本中的一个词。要修正这个问题我在奖励/反馈机制上做了文章。虽然LLM训练不能实时调参但我在系统提示里加入了强烈的损失厌恶描述并且用近期事件记录里的死亡次数来提醒它当前已经死亡2次请以生存为最优先目标。这个羞辱式反馈意外地有效。模型开始收敛到一个更保守的策略宁可站在原地等我兜底跳跃也不再贸然冲进看起来像陷阱的区域。这一点给我的启发是LLM Agent的价值对齐是靠提示词里的反复塑造构建的不是靠强化学习奖励函数你需要像教孩子一样通过上下文对话一点点把什么才是对的行为灌输进去。5. 评测方法除了通关率还应该看哪几个指标5.1 单一通关率指标会骗人项目跑了一个月左右我对LLMario最不满意的一点是没有一个客观的方式回答它到底有没有变强。如果只看通关率会陷入一个尴尬的境地调一版prompt让它更保守通关率上升了但它因为停下来时间太长超时失败的概率也上来了调一版让它更激进见坑就跳偶尔能跳过几个难关但大多数时候死于冒进。通关率升升降降根本不反映真实能力的变化你需要一套更细粒度的指标。我把评估体系拆成了四个维度存活进度以关卡内坐标为基准衡量单次运行最远走到哪里、资源效率单位时间内收集的金币数衡量它是否兼顾了变强的目标而不只是苟活、无效动作比一段时间内没有产生位置变化的动作占全部动作的比例衡量决策的有效性、决策一致率相邻两次决策之间运动方向是否保持一致的比率衡量它有没有朝令夕改的毛病。这四个指标组合起来比通关率更能说明模型的能力短板在哪里。比如无效动作比很高就说明决策频率需要降低或者提示词里要多强调没情况就往前走决策一致率低说明模型对场景的判断不够稳定可能要补一点坐标上下文。5.2 批量评测需要的基建回放与随机种子评测必须能自动跑、能复现。我给LLMario做了三样基建第一是固定存档点每次评测从同一关卡同一位置开始避免开局位置差异引入噪音第二是自动录像与事件日志把每一帧画面、每次决策的JSON输入输出、每次按键动作都记录为结构化日志方便事后定位到某一秒发生了什么第三是可复现的参数归档每次评测前把提示词版本号、模型版本号、温度参数、截图频率、队列长度全部记录下来。没有这套基建你做的每次prompt调整都可能是瞎调——你根本说不清是这次改动生效了还是上一局运气好。5.3 实测效果与能力边界经过多轮调整LLMario的最终实绩大概是这样在超级马里奥1-1关卡它有机会在不动用危险兜底的情况下走过大约三分之一到一半的流程然后在某个看起来不算复杂的坑前犹豫超过十秒最终被时间压力推着跳到坑里。如果开启兜底跳跃它能走得更远但此时你会明显感觉到决策者不是模型而是规则。模型真正的强项在于理解全局目标——你让它不要吃问号砖块它能一路做到让它优先吃金币它真的会在行进路线上刻意绕一下。它的短板则在于毫秒级的时机判断和物理直觉什么速度、什么距离、什么角度可以跳过一个坑这对LLM来说依旧是近乎黑盒的高难度课题。这个边界本身就是有意义的结论当下LLM作为游戏Agent更适合当指挥官而不是操作者。让它每隔几秒做一个方向性的战略决策比让它严格盯着画面做每一个跳跃判断结果要稳定得多。这其实也映射了LLM Agent在更广泛的真实世界应用中的现状——规划上限很高执行链路太脆弱需要靠谱的底层策略去兜底。6. LLMario的下一步从自娱自乐到更通用的Agent实验台6.1 把它改造成带语音指令的双人协作玩了一圈之后我脑子里冒出来一个更有意思的方向让LLMario不只是自己玩而是变成一个人机协作的马里奥。人类的自然语言指令可以直接传进系统提示里比如跳过这个坑然后蹲下LLM接收后结合实时画面解析成动作序列。这样人类变成了指挥官LLM变成了副驾驶我负责战略意图的表达它负责把模糊的意图拆解成具体的按键时序。这比纯粹的自动化游戏更有现实意义——它其实就是具身智能里人类给指令、AI规划执行的一个缩小版demo。同样的范式未来用在真实世界的机器人上逻辑上是完全一致的人类发出把桌上的杯子拿过来机器人大模型需要看懂场景、规划轨迹、控制机械臂再通过传感器反馈修正动作。马里奥只是这个链条里成本最低的验证环境。6.2 模型选型的经验不是越大的模型越好用在LLMario上换了几个模型之后我对模型选型有了些跟日常Chat体验完全不同的感触。大参数模型的理解能力和指令遵循能力强推理也更细腻但响应速度慢成本高放在游戏环境里会导致决策延迟变大。中小参数的模型虽然指令遵循没那么稳但API响应快配合上状态文本辅助很多场景下反而表现得更好——它至少能在对的时间做对的事哪怕做得糙一点。这个取舍经验很有迁移价值在实时决策类Agent里响应延迟通常比单次决策质量更致命。你可以让模型犯点小错然后靠兜底规则修正但你不能让它连错误都来不及犯就输给了时间。根据我的实测体会优先选本地部署的量化模型或响应快的小模型把大模型的聪明用在离线规划这种不赶时间的环节上效果最好。6.3 对做LLM Agent的人这个项目的迁移价值在哪里如果抛开马里奥这个外壳LLMario本质上是一个实时的、有视觉输入的、有因果反馈的、延迟敏感的LLM Agent系统。这类系统里有几个通吃的工程要点一是多模态输入里结构化文本和图像必须各司其职图像抓语义文本抓精确数值别让模型纯靠视觉去理解坐标和速度这类量化的东西二是上下文必须分层——用摘要管长期记忆用滚动窗口管短期观察不要幻想一次把所有历史都塞进去三是别让LLM承担毫米级精度的控制让规则系统兜底低速高频的常规操作LLM负责中速低频的决策判断四是评测必须数据化没有细粒度的日志和可复现的环境你做的优化就是玄学。以上任何一条放到真实的RPA、智能客服、具身智能项目里同样成立。折腾LLMario这一个月给我最大的体感是LLM在动作游戏里的表现远没有大家期待的那样无所不能但它提供了一个绝佳的检验场让你用最低的成本去理解语言模型如何跟物理世界交互这个核心悖论——它读得懂规则写得出计划却未必踩得准脚下的坑。我自己在做后续项目时已经开始把模拟器游戏当作Agent系统的标准测试集来用换一个环境保留同一套架构看看哪些模块能迁移、哪些模块需要重写这比任何benchmark都来得直观。如果你也正在尝试类似的LLM Agent项目我的建议很直接别追求花哨的端到端智能先把观察-摘要-决策-执行-反馈这条链路的延迟和稳定性打磨顺你会看到比操控一个会跳的马里奥更有价值的成果。

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

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

免费获取报价 →
↑