☰
AI驱动自涌现游戏原型:从NPC复读机到社会分工的架构实践
2026/10/14 6:26:17 网站建设 项目流程

最近我搞了个大的——一个由 AI 驱动的自涌现游戏原型。标题里“大”不是指画面多好、地图多大,而是指游戏里的行为复杂度:没有预设剧情、没有脚本任务,NPC 自己会说话、会模仿、会干活、会传播消息,甚至能自己“长”出社会分工来。这篇文章就聊聊我踩过的坑、最终的架构,以及对“涌现”这件事的理解。

先说结论:如果你以为“给每个 NPC 接一个大模型,扔进沙盒世界,就能自动涌现出文明”,那大概率会失望。我第一次就是这么干的,结果跑出来一群站桩复读机。真正的自涌现,不是模型有多聪明,而是交互结构有没有闭环。

1. 先泼盆冷水:给每个NPC塞个大模型,只会得到一群站桩复读机

1.1 我第一次的翻车现场

第一版做得特别简单:我给镇子上的每个 NPC 配了一段身份提示词,比如“你是铁匠,性格沉稳”“你是面包师,性格热情”,然后写了一个循环——每隔几十秒,让每个 NPC 向大模型提问“你现在想做什么?”,把返回的文本直接当行为输出。

刚启动那会儿还挺惊喜的,确实有 NPC 会主动搭话,见面会问“今天天气不错”。但最多跑二十分钟,画风就开始诡异了:所有 NPC 开始互相重复同一句话,见面永远是“你好,我叫XX”“很高兴认识你”;有的 NPC 干脆站在广场中央发呆,每轮都输出“我望着远方,思考人生”;更离谱的是,我写的“性格”在对话里第三句就会碎掉,沉稳的铁匠突然变成话痨,热情的面包师开始复读机式地拒绝所有人。

我一度以为是模型参数调得不对,换了好几个模型重试,结果都差不多。后来把日志拉出来看才发现,问题根本不在单一模型上——每个 NPC 都活在“真空”里。它不知道周围有谁、不知道几小时前自己说过什么、不知道镇上正在发生什么事。它每次被唤醒,都是从零开始重新“扮演”一个角色,那当然只会产出碎片化的表演,而不是连续的行为。

1.2 问题出在哪:大模型是无状态决策器

想明白这个本质之后,我才理解自涌现游戏的第一个前提:大模型本身是无状态的决策器,它每一次被调用,都相当于一个失忆的人从梦里醒来,只靠当前这段文字做判断。想让它产生有连续性的行为,你必须把“状态”放在外部,而不是指望它自己记住。

我当时想起蚁群算法——蚁群里没有任何一只蚂蚁知道全局计划,每只蚂蚁只对身边的信息素浓度做局部反应,但整体上却能形成高效的觅食路径。所谓涌现,就是大量简单局部决策叠加出来的高级秩序。AI 游戏也是同理:你不需要给 NPC 一个“拯救世界”的宏大目标,你要做的是给它足够的局部信息、一套反馈机制,让它的一个个小决策在交互中汇聚成集体行为。

想通这一点后,我立刻把第一版推倒重来。

2. 把世界和脑子分开:这套系统最终长这样

2.1 世界服务器 + NPC大脑

我的最终架构一句话总结:世界归世界,脑子归脑子。游戏世界里所有客观事实——谁在哪儿、仓库里有多少粮食、天气如何——统一由一个“世界状态服务”管理;每个 NPC 的“脑子”则是一个决策模块,通过感知接口拿到局部信息,做出行动,再由行动接口把结果写回世界。二者完全解耦。

这个设计思路其实很像传统游戏服务器:数据库维护世界,客户端渲染画面,逻辑层处理规则。只不过我这里把“逻辑层”里的硬编码规则,换成了大模型的开放决策。数据流大概是这样的:

世界状态 → 感知模块(按位置/关系筛选) → 记忆检索 → Prompt组装 → 大模型决策 → 结构化行动输出 → 行动执行器 → 更新世界状态 → 广播事件 → 其他NPC感知到 → 下一轮循环

每一步之间通过消息队列连接,而不是函数直接调用。这样好处是:任何一环卡住,不会拖垮整个镇子;每个 NPC 的感知、决策、行动可以异步进行。

2.2 为什么不能直接把世界状态全塞进Prompt

早先我还犯过一个错误:为了省事,把整个镇子的状态表格(几百行的 JSON)直接拼进每个 NPC 的 Prompt,心想“给它足够的信息,它总该做出聪明的选择了吧”?结果更糟——上下文一长,模型反而失去了焦点,NPC 开始纠结一些无关紧要的细节,比如反复念叨某间房子的门是开的,而完全忽略了自己已经饿了一天。

后来我把感知模块加了“视野范围”概念,跟真实世界的感官逻辑保持一致。每个 NPC 只能感知到:自己所在位置附近的物体、当前在场的人、和它直接相关的事件。超出视野的一律不提供。这一步做完,决策质量立刻上了一个台阶。我随手写了个很小的数据结构示例:

{ "agent_id": "sarah_001", "location": [12, 38], "energy": 80, "hunger": 55, "inventory": ["wood"], "visible_entities": [ {"type": "person", "id": "tom_002", "distance": 4}, {"type": "tree", "id": "tree_033", "distance": 2} ], "recent_events": [ {"time": 12, "text": "你看到隔壁的tom在砍树"}, {"time": 15, "text": "仓库里的食物不多了"} ] }

这个结构看起来朴实,但它解决了自涌现游戏最关键的问题:每个 NPC 的世界是“主观”的,不是“客观”的。不同 NPC 会因为位置和亲疏关系,看到完全不同的信息,行为自然就会产生差异,而不是所有人同时对全局作出反应。

3. 单个NPC是怎么“活”起来的:从感知到行动的完整循环

3.1 行为循环伪代码

每个 NPC 的核心逻辑,我最后收敛成了一个循环:感知、回忆、做决定、行动、沉淀记忆。伪代码差不多是这样:

while running: # 1. 获取该NPC当前能看到的世界状态 perception = sense_world(agent_id) # 2. 从记忆中检索相关的历史信息 memories = retrieve_memories(agent_id, perception) # 3. 组装成Prompt,交给大模型决策 prompt = build_prompt(agent_profile, perception, memories) decision = llm_call(prompt) # 4. 把决策解析成结构化行动,写回世界 execute_action(agent_id, decision) # 5. 把这次决策和结果存回记忆库 store_memory(agent_id, perception, decision) sleep(tick_interval)

很多人会忽略第 5 步——记忆沉淀,但这个恰恰是整个循环的灵魂。没有记忆,NPC 永远在“失忆重生”,永远无法积累经验,也就不可能产生涌现。我那版跑出一模一样的复读机,根子就出在记忆缺失上。

3.2 记忆怎么分层

记忆不是把历史记录全部堆进 Prompt,那样上下文会迅速被撑爆。我实际用下来,分成三层最省心:

  • 短期记忆:保留最近 10~20 条事件记录,按时间顺序放进 Prompt。它负责“此刻我正在做什么”。
  • 长期记忆:把更早的信息向量化存入数据库,每次按相关性检索 Top 5 出来。它负责“我过去经历过什么类似的事”。
  • 印象归档:每隔一段时间(比如模拟世界的一天),让模型把短期记忆压缩成几行摘要,再存入长期记忆。它负责“我是一个什么样的人”。

印象归档这个点子帮我解决了一个大问题:NPC 的“人格连续性”。我发现如果只靠短期记忆,NPC 过半天就会忘光自己早期的经历,变得前后矛盾;但有了“每天存档总结”之后,角色的行为会呈现一种缓慢演化。比如某个 NPC 连续几天被人骗,它的归档摘要就会逐渐变成“这里的人不值得信任”,然后它的行为模式真的会越来越警惕。

3.3 决策输出要用结构化JSON

一开始我把模型的输出直接当文本处理,发现非常难接回世界状态:它会说一大段“我想走向东边的树林,然后砍一棵树”,你要用正则去解析,稍微复杂一点的句子就解析失败。我后来强制要求模型输出严格的 JSON,只允许抛出三类行动指令:

{"action": "move_to", "target": [12, 39], "reason": "去河边看看"} {"action": "interact", "target": "tom_002", "kind": "chat", "content": "晚上要一起烤火吗?"} {"action": "pickup", "target": "wood_003", "reason": "柴火不够了"}

这个改动看似微小,但直接决定了系统能不能稳定跑起来。结构化输出让行动执行器可以像处理普通游戏指令一样去验证、执行、广播——比如移动要检查路径是否合法、拾取要检查物品是否还在。模型只负责“决定”,规则交给系统,两边各司其职。

4. 涌现是怎么逼出来的:事件传播、性格漂移、资源约束

4.1 事件传播让NPC开始“八卦”

这是我最得意的一个机制:每个行动都会在世界上产生一条事件,而事件是可以被其他 NPC 听到的。一开始我只把事件当作简单的广播——每个人的行为都会同步给全镇人,结果跑出来一个灾难场面:几十条互相矛盾的信息叠加,NPC 集体精神分裂,上一秒还在讨论打雷,下一秒就开始转发仓库着火的谣传。

后来我限制了事件的传播条件:只有处于一定空间距离内、或者与该事件直接相关的人,才会收到播报。这样一来,信息不再均匀扩散,而是像真实小镇一样沿着社交关系流动。举一个具体例子:某天镇子东边的“玛拉”打碎了一个花瓶,她的邻居“凯”看见了,于是凯的记忆里有了这件事;之后凯去广场找别人聊天,才在对话中把这件事当作谈资说出来。

最有意思的是,这件事我没写过任何一条“NPC应该传播谣言”的规则,它完全是从“看见事件 → 存入记忆 → 聊天时检索相关记忆”的链路里自然长出来的。这就是最典型的涌现——信息沿着局部交互网络传播,形成所谓的“八卦链”,而八卦又反过来影响 NPC 之间的亲密度:说人坏话的次数多了,被说的人会渐渐疏远对方。我后来专门把 NPC 之间的关系值单独存了一张表,用来记录这种动态变化。

4.2 性格漂移让角色会“变”

另一个关键机制是性格漂移。最初我给每个 NPC 写死了一个性格标签,比如“开朗”“阴郁”,但跑久了发现角色很扁平——开朗的人永远开朗,遇到悲剧也开朗,这显然不符合真实感。

我把性格从固定标签改成了动态评分:每次行为都会影响几个维度的数值,比如社交倾向、攻击倾向、好奇度、勤勉度。社交多一点,社交分就涨;成功做成一件事,自信分就涨;连续遭遇失败,消极倾向就会上升。然后我在 Prompt 里的角色描述不再写死“你是一个开朗的人”,而是写“你最近的行为显示:你经常主动找人聊天,成功率中等,你对自己的判断是……”。模型会根据这个流动的描述,逐渐调整自己的行为风格。

效果非常明显。有个 NPC 起初是标准的温和派,但因为连续几天自己的农田被踩,每次去交涉都以失败告终,它的冲突倾向评分慢慢走高。终于有一天,它不再去理论,而是直接做出了一个行动——“趁夜把对方田里的木栅栏拆了”。这一刀不是我写进代码里的,而是它在一次次失败反馈中自己“学”出来的应对方式。这比任何写死的性格系统都更有生命力。

4.3 资源约束逼出分工与合作

如果没有资源压力,NPC 的行为会倾向于“闲逛”——没有生存压力,就没有动力去做复杂的事。我给世界加了最朴素的资源系统:每人需要吃饭,食物来自农田和采集;工具会磨损,需要铁匠修补;冬天来临之前,必须储存足够的柴火。这些约束写得很简单,但组合起来,社会行为就开始分化了。

我看到的第一个真正称得上“涌现”的场景是这样的:镇子的粮仓存量见底,负责种地的那几个 NPC 开始疯狂加班,但收成依然不够。其中一个 NPC 在路过河边时发现另一个 NPC 在钓鱼,于是它的记忆里多了一条“原来可以钓鱼吃”;没过多久,它自己也开始尝试钓鱼;再后来,粮仓里出现了鱼制品,关于“钓鱼好用还是种地靠谱”的讨论出现在好几个 NPC 的聊天里。另有一个 NPC 因为总钓不到鱼,转而开始研究能不能用树枝做捕鱼陷阱,结果它真的在河边制造了一个简易陷阱——这个新物品直接诞生于它的行动。

注意,这个捕鱼陷阱不是我事先做好的物品,而是 NPC 根据自己的需求、工具材料和地点,组合出了一个世界上本来不存在的新实体。系统只是提供了“材料可以组合”的底层规则,NPC 自己完成了设计。看到日志里蹦出这条记录的时候,我确实愣了好一会儿——这种“新事物从行为里长出来”的感觉,正是我做这个项目最想追求的东西。

5. 别把随机当涌现:我自己用的三套测评方法

5.1 事件新颖度曲线

做自涌现系统最危险的事情是自我感动:看到一个新鲜行为,就觉得“哇,涌现了”,但其实那可能只是随机噪声。我用来给自己泼冷水的第一套工具是“事件新颖度曲线”。

做法很简单:把所有行动按“动作类型 + 对象类型”组合成事件类型,比如“move_to+river”“chat+friend”“pickup+wood”。然后按时间窗口统计每个窗口里新出现的事件类型占比。如果系统真的有涌现能力,那么运行后期应该不断出现早期没有见过的新组合——某两个行为模式拼接出了之前从未发生的交互。如果这个曲线很快就平了,说明所谓涌现不过是刚开始各种可能性的随机爆炸,之后系统一直在走老路。

我跑过一个对照组:关闭记忆检索环节,让 NPC 只依靠当前感知做决策。结果新颖度曲线在前二十分钟到顶,之后就躺平成一条直线——所有 NPC 的行为都收敛到几种固定模式,再也长不出新东西。这说明记忆不是锦上添花,而是涌现的发动机。

5.2 反事实测试

第二个方法是从科学实验里借来的反事实推理:找一个你觉得“涌现”出来的现象,定位到疑似触发机制,然后把它在系统里关掉,看现象是否消失。如果消失了,说明现象确实来自机制,不是偶然。

当时我发现 NPC 之间出现了“社会模仿”——一个 NPC 开始砍柴,附近的 NPC 跟着也开始砍柴。我怀疑这是“观察者机制”导致的,于是我做了一次反事实测试:把“看到他人行动”这个感知输入临时屏蔽,只保留资源短缺信号。结果呢,砍柴行为依然存在(因为资源短缺本身就能触发),但“一群人集中砍柴”的聚集效应消失了,大家各自分散在不同的时间点砍,不再形成同步浪潮。

由此我得出结论:资源压力是第一动力,“看见别人在做什么”带动的是同步与放大。一个自涌现系统里,不同现象往往由不同机制驱动,只有用反事实测试区分开,你才真正理解这个系统的因果结构,而不是笼统地说“它自己动起来了”。

5.3 噪声与涌现的判断标准

最后,我给自己定了一套主观判断标准,用来区分随机噪声和涌现行为:

  • 可解释:涌现出来的行为,必须能向前追踪出一条因果链。比如“粮仓不足 → 某NPC尝试钓鱼 → 钓鱼经验写入记忆 → 下次看到河优先选择钓鱼”,这就是涌现;而“NPC突然开始跳舞,原因未知”,那不是涌现,是故障。
  • 可重复:相同初始条件下,跑多次实验,行为可以不完全相同,但必须保持“同一类模式”。比如每次都会出现分工,但分工的具体人选可能不同——这叫涌现的稳定性;如果每次都出现完全不同的荒唐行为,那叫混沌。
  • 可干预:你能通过调整某个参数,稳定地压制或放大这个行为。比如把资源压力调低,分工就消失;把观察距离调大,模仿就扩散更快。能干预,说明现象在系统控制范围之内,而不是不可控的意外。

满足这三点,我才愿意称之为“涌现”,而不是“随机”。

6. 跑起来的真实代价:并发、上下文和token账单

6.1 并发:50个NPC同时思考是伪并发

把规模从 5 个 NPC 扩到 50 个时,我踩了一坑:模型调用是串行的,一个 NPC 决策需要两三秒,50 个下来一轮就要两分钟,游戏节奏完全跑不动。我第一反应是“上多线程并行调用”,结果更糟——50 个 NPC 同时决策,同一件东西可能被 5 个人同时捡走,状态写入互相覆盖,日志里全是矛盾和回滚。

后来我换成了 actor 模式:每个 NPC 是一个独立执行单元,内部串行处理自己的决策;全局的任务分发器只负责为不同 NPC 分配并行的 worker,保证“跨 NPC 并行、同 NPC 串行”。同时我在行动执行器里加了最基础的乐观锁:任何东西被取走之后,状态版本号 +1,其他 NPC 的动作如果基于旧版本,就被拒绝并提示“目标已不在那里”。这一步做了之后,资源类逻辑瞬间稳定了。

6.2 上下文塞爆了怎么办

并发解决了,下一个杀手是 token 消耗。每个 NPC 每轮决策都要携带角色设定、视野状态、短期记忆和检索到的长期记忆,很快就把上下文窗口顶满了。我算了一笔账:一个 NPC 每小时决策 30 次,每次输入 4000 token,一个 NPC 一小时就是 12 万 token,50 个 NPC 就是 600 万 token,跑一天的数字非常恐怖。

我的解法就是前面提到的三层记忆,再配合一个规则:短期记忆超过 20 条时,最早的 5 条会被压缩成 1 条摘要,移动到长期记忆区;检索长期记忆时,最多只取 Top 5,每条不超过 200 字。这套策略能把单次决策的上下文稳定压在 3500 token 左右,而不是随运行时间无限膨胀。

6.3 成本估算与模型取舍

说到钱,我给想复刻的朋友一个实际参考。如果全用商用大模型 API,50 个 NPC 跑一个模拟日(约 2 小时真实时间),大概要消耗 2000 万 token,成本非常可观。我的做法是“混合模型策略”:日常感知、移动、简单交互,全部用本地开源小模型跑,输出质量虽然糙一点,但胜在便宜且快;只有每天晚上的“归档反思”和重大事件决策,才调商用大模型,让它在信息充足的情况下做长程规划。

两种模型跑出来的角色有个明显差异:本地小模型做即时行动没问题,但让它写角色回顾时内容比较干巴,经常只有“今天做了 X、Y、Z”这种流水账;商用大模型则能在摘要里加入“我因此觉得……”,这种自我认知再回流到 Prompt 里,角色深度就有了显著提升。所以我的建议是:别把昂贵的模型用在每一轮行动上,把它放在“对记忆做沉淀”的环节,性价比最高。

模型策略适合场景单次输入token量成本
本地开源小模型移动、采集、简单对话、即时反应1000~3000极低
商用大模型每日回顾、重大事件复盘、长程规划3000~5000高,仅关键节点使用

7. 下一步计划与给想动手的人的三条建议

这个项目离“成品游戏”还很远,我现在主要在补三块:一是世界的地形生成,让河流、森林、矿点的分布影响社会分工;二是文化传播,比如 NPC 开始给某些地点起名字,并把故事一代一代传下去;三是更复杂的团体行为,让 NPC 不只是两两交互,而是能形成小团体并产生团体间的竞争与合作。每一条都不能贪多,一次只加一个机制,然后跑大量实验去观察它是否真的带来行为深度的变化。

如果你也想做类似的 AI 自涌现游戏,我的三条建议是:第一,先跑一个只有 5 个 NPC 的小镇,把决策日志完整打印出来,像看监控录像一样反复看十个小时,直到你能一眼看出哪条行为链断了;第二,先把单 NPC 调通,确保它能连续完成“出门、找资源、带回来”这种闭环任务,再扩大到多 NPC,否则你会被交互 Bug 淹没;第三,别一上来就写复杂的“社会规则”,先保证世界状态一致性和事件传播不出错,最简单的基础设施稳定之后,涌现自己就会出现。

最后分享一点个人感受:自涌现游戏最迷人的时刻,不是你写了一堆规则跑出一个复杂世界,而是某个深夜,你盯着日志,突然看到一个从未写进代码里的行为模式冒出来——那个行为是系统的产物,也是你亲手搭建的机制结出的果实。你在里面看到了“开发者没设计过的东西”,那是一种很难被复制的成就感。这个坑很深,但非常值得跳。

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

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

立即咨询