ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

基于AI Agent框架构建动态Minecraft小镇:从原理到实践

2026/8/9 8:08:43 拓冰建站 浏览量
基于AI Agent框架构建动态Minecraft小镇:从原理到实践

如果你是一个 Minecraft 开发者,或者是一个服务器服主,有没有想过:为什么别人的服务器里总有那么几个让人流连忘返、充满惊喜的“小镇”,而自己搭建的场景却总是差了点意思?

问题往往不在于方块堆得不够多,而在于缺少一个“灵魂”——一套能够驱动整个小镇活起来的、有逻辑、有交互、有故事的“大脑”。传统的红石电路和命令方块虽然强大,但开发门槛高、调试复杂、难以维护,更别提实现复杂的 NPC 对话、任务系统和动态事件了。

今天要介绍的这个开源项目,或许能成为你构建“奇妙小镇”的终极工具箱。它不是一个预设好的地图,而是一个基于 Minecraft 的 AI Agent 开发框架。简单来说,它让你能用写 Python 脚本的方式,为 Minecraft 世界里的村民(或其他实体)注入“智能”,让他们能够自主决策、与环境交互、甚至彼此协作,共同演绎出一个动态、鲜活的小镇故事。

这篇文章,我们就来彻底拆解这个名为“MC的奇妙小镇”的项目。我不会只告诉你它“很酷”,而是要讲清楚三件事:

  1. 它到底解决了什么核心痛点?(从“静态布景”到“动态生态”的转变)
  2. 一个零 AI 基础的开发者,如何快速上手并跑通第一个智能村民?(提供可复现的完整流程)
  3. 在实战中,有哪些关键的“坑”和最佳实践?(避免你从入门到放弃)

无论你是想为自己的服务器增加独一无二的特色玩法,还是对 AI Agent 在游戏中的应用感兴趣,这篇文章都将提供一条清晰的实践路径。

1. 这个项目真正要解决的问题:从“景观”到“生态”

在深入代码之前,我们必须先统一认知:这个项目的价值远不止于“让村民会走路”。它瞄准的是 Minecraft 模组开发与服务器内容创作中的一个深层瓶颈:动态内容生成与可持续交互的缺失

传统方式的局限:

  • 命令方块/红石:逻辑复杂,可视化差,难以实现条件分支、状态记忆和异步行为。维护一个大型任务链如同维护一团“面条代码”。
  • 预设脚本/插件:行为是固定的。村民每天在固定时间走到固定地点,说固定的话。玩家体验几次后就会感到重复和枯燥。
  • 手动运营:服主或管理员需要像“上帝”一样手动触发事件、生成怪物、发布任务,无法形成自运转的生态。

“MC的奇妙小镇”带来的范式转变:它引入了一套Agent(智能体)体系。在这个体系下,每个村民、动物甚至怪物,都可以被定义为一个 Agent。这个 Agent 拥有:

  • 感知(Perception):能“看到”周围的玩家、方块、其他实体。
  • 技能(Skill):能执行移动、对话、使用物品、建造等基础动作。
  • 目标(Goal):有一个想要达成的状态,比如“把小麦卖给玩家”、“躲开僵尸”、“修建一面墙”。
  • 决策(Decision):基于当前感知到的环境信息和自身目标,决定下一步执行哪个技能。

这样一来,小镇就不再是一堆按照固定脚本移动的 NPC,而是一个多智能体系统。铁匠可能会因为木材短缺而暂停工作,跑去和农夫交涉;夜晚来临,村民会自主回家并关门;玩家与某个村民的友好度提升,可能会解锁新的交易或触发专属剧情。

核心价值判断:这个项目降低的不是“堆方块”的成本,而是创造复杂、动态、可交互游戏内容的认知与工程门槛。它将游戏逻辑的开发,从面向过程的“触发器”思维,转向了面向对象的“智能体”思维。这对于想要打造高粘性、高自由度 RPG 或生存服务器的团队来说,是一个潜在的“生产力革命”。

2. 核心概念与架构拆解

要玩转这个框架,需要理解几个核心概念,它们构成了整个系统的骨架。

2.1 核心组件

  1. Agent(智能体):系统的基本单位。一个村民、一只猫、一个巡逻的卫兵,都可以是一个 Agent。它封装了状态、目标和行为能力。
  2. Skill(技能):Agent 可以执行的最小动作单元。例如:MoveToSkill(移动到某处)、SaySkill(说话)、MineBlockSkill(挖掘方块)、CraftItemSkill(合成物品)。技能是可复用、可组合的。
  3. Goal(目标):驱动 Agent 行为的动机。例如:SurviveGoal(生存目标,会驱使 Agent 寻找食物和避难所)、TradeGoal(交易目标)、SocializeGoal(社交目标)。一个 Agent 可以同时拥有多个目标,并根据优先级进行仲裁。
  4. Environment(环境):对 Minecraft 游戏世界的抽象封装。它提供了统一的 API 让 Agent 感知世界(获取方块、实体信息)和影响世界(放置方块、攻击实体)。
  5. Brain(大脑):Agent 的决策中心。它周期性地运行一个“感知-决策-执行”循环:
    • 感知:通过 Environment 获取当前世界状态。
    • 评估:检查各个 Goal 的激活条件和优先级。
    • 规划:为最高优先级的 Goal 选择并组合一系列 Skills 来达成它。
    • 执行:执行第一个 Skill,并根据执行结果(成功、失败、进行中)决定下一步。

2.2 技术架构与工作流程

项目的典型架构是“Python 大脑 + Minecraft 客户端”模式。

+-------------------+ WebSocket / gRPC +----------------------+ | | <-----------------------> | | | Python Agent | (状态同步、指令) | Minecraft 客户端 | | 框架层 | | (通过Mod或插件连接) | | | | | +-------------------+ +----------------------+ | | | 调用框架API | 执行游戏内动作 V V +-------------------+ +----------------------+ | AI 模型层 | | Minecraft 游戏世界 | | (可选: LLM, RL) | | | +-------------------+ +----------------------+

工作流程简述:

  1. 你在 Python 中定义了一个BlacksmithAgent(铁匠智能体),并为其设定了CraftToolGoal(打造工具目标)和RestGoal(休息目标)。
  2. 框架通过一个连接 Mod(如Fabric/ForgeMod 或REST插件)与你的 Minecraft 游戏实例建立通信。
  3. BlacksmithAgent的 Brain 开始工作。它通过 Environment API 发现工作台旁没有铁锭了(感知)。
  4. CraftToolGoal因此无法进行,优先级下降。RestGoal优先级上升(评估)。
  5. Brain 为RestGoal规划技能:MoveToSkill(移动到床边) ->SleepSkill(睡觉)(规划)。
  6. Brain 执行MoveToSkill,通过通信链路向 Minecraft 客户端发送移动指令(执行)。
  7. 你在游戏中看到铁匠离开了工作台,走向了他的床铺。

关键点:所有复杂的决策逻辑都在 Python 端完成,Minecraft 客户端只负责渲染和执行最基础的指令。这带来了极大的灵活性,你可以利用 Python 丰富的 AI 生态(如 LangChain、Transformers 库)来增强 Agent 的“智力”。

3. 环境准备与快速启动

假设你是一个有一定 Python 基础,但对 AI 和 Minecraft 模组开发了解不多的开发者。以下是零基础启动一个“奇妙小镇”的最小可行步骤。

3.1 基础环境清单

  • 操作系统:Windows 10/11, macOS, 或 Linux (推荐 Ubuntu 20.04+)
  • Python:版本 3.8 - 3.11。推荐使用 3.9 以获得最佳兼容性。
  • Java:版本 17。这是运行现代 Minecraft 服务端(如 Paper, Purpur)的必需版本。
  • Minecraft 客户端:版本 1.19.2 或 1.20.1(具体版本需查看项目 README 的兼容性说明,这是最容易出问题的地方)。
  • Git:用于克隆项目代码。

3.2 第一步:搭建 Minecraft 服务端与客户端连接

这是整个流程中最容易卡住的一步。我们选择一种对开发者最友好的方式:使用REST通信插件

  1. 准备 Minecraft 服务端

    • 下载一个支持插件的服务端核心,如 PaperMC 。
    • 新建一个文件夹,将paper-1.20.1-123.jar(示例)放入,并创建一个启动脚本。
    • 启动脚本 (start.batfor Windows /start.shfor Linux):
      # start.sh (Linux/macOS) java -Xmx2G -Xms1G -jar paper-1.20.1-123.jar nogui
      @echo off java -Xmx2G -Xms1G -jar paper-1.20.1-123.jar nogui pause
    • 首次运行会生成文件并退出。编辑eula.txt,将eula=false改为eula=true
  2. 安装通信插件

    • 前往插件发布页(例如 GitHub Releases),下载对应的.jar文件(比如mc-agent-bridge-1.0.0.jar)。
    • 将其放入服务端文件夹的plugins目录中。
    • 再次启动服务端。在控制台看到[MC-Agent-Bridge] Enabled类似的字样即表示成功。
  3. 配置插件(关键!)

    • plugins/MCAgentBridge/目录下找到config.yml
    • 主要配置项:
      # config.yml bridge: host: "0.0.0.0" # 监听所有网络接口 port: 8765 # 自定义一个端口,确保防火墙开放 auth-token: "your-secret-token-here" # 设置一个密码,Python端需要 allowed-origins: "*" # 为开发方便,可设为*,生产环境应指定IP
    • 重启服务端使配置生效。

3.3 第二步:配置 Python 开发环境

  1. 克隆项目代码

    git clone https://github.com/username/mc-wonder-town.git cd mc-wonder-town
  2. 创建并激活虚拟环境(强烈推荐)

    # Windows python -m venv venv venv\Scripts\activate # Linux/macOS python3 -m venv venv source venv/bin/activate
  3. 安装依赖

    pip install -r requirements.txt

    如果项目没有requirements.txt,通常核心依赖包括websockets,requests,numpy等,需要根据项目文档手动安装。

4. 核心流程:创建你的第一个智能村民

现在,我们抛开复杂的理论,直接创建一个会打招呼并跟随玩家的村民。

4.1 项目结构概览

一个典型的项目结构如下:

mc-wonder-town/ ├── agents/ # 存放自定义的Agent类 │ └── my_villager.py ├── skills/ # 存放自定义的Skill类 │ └── follow_player.py ├── goals/ # 存放自定义的Goal类 │ └── greet_and_follow.py ├── environments/ # 环境配置与连接 │ └── local_mc_env.py ├── main.py # 主程序入口 └── requirements.txt

4.2 定义环境连接

首先,我们需要建立 Python 与 Minecraft 世界的桥梁。

# environments/local_mc_env.py import asyncio from mc_agent_framework.environment import MinecraftEnvironment from mc_agent_framework.bridge import RESTBridgeClient class LocalMinecraftEnv(MinecraftEnvironment): def __init__(self): # 连接到我们之前配置的REST插件 bridge_config = { 'host': 'localhost', # 如果Python和MC服务端在同一机器 'port': 8765, 'auth_token': 'your-secret-token-here' } self.bridge = RESTBridgeClient(bridge_config) super().__init__(self.bridge) async def connect(self): """建立连接""" await self.bridge.connect() print("成功连接到 Minecraft 服务器。") async def disconnect(self): """断开连接""" await self.bridge.disconnect()

4.3 创建一个简单的“跟随”技能

技能是行为的基础。这里我们创建一个让实体跟随附近玩家的技能。

# skills/follow_player.py from mc_agent_framework.skill import Skill, SkillStatus from typing import Dict, Any class FollowPlayerSkill(Skill): """跟随最近玩家的技能""" def __init__(self, agent, max_distance: float = 10.0): super().__init__(agent) self.max_distance = max_distance self.target_player = None async def execute(self, context: Dict[str, Any]) -> SkillStatus: """执行跟随逻辑""" # 1. 感知:通过环境获取附近玩家 nearby_players = await self.agent.environment.get_nearby_players( self.agent.entity_id, self.max_distance ) if not nearby_players: # 没有玩家在附近,技能失败 return SkillStatus.FAILURE # 2. 选择最近的玩家作为目标 self.target_player = min(nearby_players, key=lambda p: p['distance']) # 3. 决策:向目标玩家移动一步 target_pos = self.target_player['position'] success = await self.agent.environment.move_entity_to( self.agent.entity_id, target_pos, speed=0.5 ) if success: # 如果移动成功,并且距离还很远,则继续执行(进行中) current_pos = await self.agent.environment.get_entity_position(self.agent.entity_id) distance = self._calculate_distance(current_pos, target_pos) if distance > 2.0: # 距离大于2格,继续跟随 return SkillStatus.RUNNING else: # 距离足够近,跟随成功 return SkillStatus.SUCCESS else: return SkillStatus.FAILURE def _calculate_distance(self, pos1, pos2): """计算三维空间距离""" return ((pos1['x']-pos2['x'])**2 + (pos1['y']-pos2['y'])**2 + (pos1['z']-pos2['z'])**2) ** 0.5

4.4 定义一个“打招呼并跟随”的目标

目标决定了 Agent 要做什么。

# goals/greet_and_follow.py from mc_agent_framework.goal import Goal, GoalStatus from skills.follow_player import FollowPlayerSkill from mc_agent_framework.skill import SaySkill class GreetAndFollowGoal(Goal): """目标:向玩家打招呼,然后跟随他""" def __init__(self, agent, greeting_text="你好,旅行者!"): super().__init__(agent) self.greeting_text = greeting_text self.has_greeted = False self.follow_skill = None def get_priority(self) -> float: """优先级:始终较高""" return 0.8 # 优先级数值,0-1之间,越高越优先 async def create_plan(self): """为目标创建执行计划(技能序列)""" plan = [] if not self.has_greeted: # 第一步:打招呼 plan.append(SaySkill(self.agent, self.greeting_text)) # 第二步:跟随玩家 self.follow_skill = FollowPlayerSkill(self.agent) plan.append(self.follow_skill) return plan async def update(self) -> GoalStatus: """更新目标状态""" if not self.has_greeted: # 检查是否已经打过招呼(这里简化处理,实际可能需要更复杂的判断) # 假设我们执行一次SaySkill后就标记为已打招呼 self.has_greeted = True return GoalStatus.ACTIVE # 检查跟随技能的状态 if self.follow_skill and self.follow_skill.status == SkillStatus.SUCCESS: return GoalStatus.COMPLETED elif self.follow_skill and self.follow_skill.status == SkillStatus.FAILURE: return GoalStatus.FAILED else: return GoalStatus.ACTIVE

4.5 组装智能村民 Agent

现在,我们将环境、技能和目标组合成一个完整的 Agent。

# agents/my_villager.py from mc_agent_framework.agent import Agent from goals.greet_and_follow import GreetAndFollowGoal class FriendlyVillagerAgent(Agent): """友好的村民智能体""" def __init__(self, entity_id, environment, name="Bob"): super().__init__(entity_id, environment, name) # 为Agent添加目标 self.add_goal(GreetAndFollowGoal(self, f"{name}:欢迎来到小镇!")) async def on_spawn(self): """当Agent在游戏中生成时调用""" print(f"[Agent] {self.name} (ID: {self.entity_id}) 已激活。") async def on_perceive(self): """感知周期(可在此处添加自定义感知逻辑)""" # 基础感知由框架自动处理,这里可以添加额外逻辑 pass

4.6 主程序:启动一切

最后,我们需要一个主程序来初始化环境、创建 Agent 并启动大脑循环。

# main.py import asyncio import logging from environments.local_mc_env import LocalMinecraftEnv from agents.my_villager import FriendlyVillagerAgent logging.basicConfig(level=logging.INFO) async def main(): # 1. 初始化并连接环境 env = LocalMinecraftEnv() await env.connect() # 2. 假设我们已经知道游戏中某个村民的实体ID # 在实际项目中,你可能需要通过事件监听或命令来获取ID villager_entity_id = 42 # 这需要从游戏内实际获取 # 3. 创建智能村民Agent villager_agent = FriendlyVillagerAgent( entity_id=villager_entity_id, environment=env, name="铁匠鲍勃" ) # 4. 注册Agent到环境 env.register_agent(villager_agent) # 5. 启动Agent的大脑(决策循环) print("启动村民Agent大脑...") try: # 让大脑运行一段时间,例如300秒 await asyncio.sleep(300) except KeyboardInterrupt: print("接收到中断信号,正在关闭...") finally: # 6. 清理与断开连接 env.unregister_agent(villager_agent) await env.disconnect() if __name__ == "__main__": asyncio.run(main())

5. 运行与效果验证

5.1 启动步骤

  1. 启动 Minecraft 服务端:运行你的start.shstart.bat,确保 REST 插件加载成功。
  2. 启动 Minecraft 客户端并连接:使用局域网或直接连接localhost进入服务器。
  3. 在游戏中生成或找到一个村民。你需要获取它的实体 ID。一个简单的方法是通过管理员命令,例如使用F3+B显示碰撞箱,或者安装一个能显示实体信息的辅助 Mod。更程序化的方式是,让插件在村民生成时打印其 ID 到控制台。
  4. 修改main.py:将villager_entity_id = 42替换为你实际获取的实体 ID。
  5. 运行 Python 程序
    python main.py
    如果一切正常,控制台会输出“成功连接到 Minecraft 服务器。”和“启动村民Agent大脑...”。

5.2 预期效果验证

  1. 连接验证:Python 控制台无报错,Minecraft 服务端控制台能看到来自[MC-Agent-Bridge]的连接日志。
  2. 打招呼验证:靠近你指定的村民(ID 对应),他应该在聊天栏说出预设的话:“铁匠鲍勃:欢迎来到小镇!”
  3. 跟随验证:说完话后,村民应该开始尝试向你移动,与你保持较近的距离。你可以走动,观察他是否跟随。
  4. 停止验证:在 Python 控制台按Ctrl+C,程序应优雅退出,村民停止所有 AI 行为,恢复为普通村民。

5.3 调试与日志查看

  • Python 端:日志级别设为INFODEBUG可以查看详细的决策、技能执行状态。
  • Minecraft 服务端:查看控制台是否有来自桥接插件的错误信息,如连接失败、指令格式错误等。
  • 游戏内:如果村民没有反应,首先检查:
    1. 实体 ID 是否正确?
    2. 村民是否被其他插件或游戏规则限制了移动?(如mobGriefing规则不影响移动,但某些领地插件会)
    3. 通信端口是否被防火墙阻挡?

6. 常见问题与排查思路

在实践过程中,你几乎一定会遇到下面这些问题。这里提供一份排查清单。

问题现象可能原因排查方式解决方案
Python 程序无法连接服务器1. 服务端未运行或插件未加载。
2. 防火墙/安全组阻止了端口。
3.config.yml中的host/port/auth_token配置错误。
1. 检查服务端控制台是否有插件加载成功的日志。
2. 在服务器本机使用telnet localhost 8765测试端口。
3. 核对 Python 代码中的连接配置与服务端config.yml是否一致。
1. 确保服务端和插件正常运行。
2. 关闭防火墙或添加规则放行指定端口。
3. 仔细检查并修正连接配置。
村民接收到指令但无动作1. 实体 ID 错误,指令发给了其他实体。
2. 游戏规则或插件限制了实体移动。
3. 移动路径被阻挡(如门关闭、方块堵塞)。
1. 在 Python 代码中打印或记录发送指令的目标 ID。
2. 在游戏内手动尝试推动村民,看是否有阻力。
3. 检查村民周围环境。
1. 使用可靠方法(如插件事件监听)获取实体 ID。
2. 暂时禁用可能干扰的领地、保护类插件进行测试。
3. 在技能逻辑中加入路径检测和绕行逻辑。
技能执行状态混乱1.Skillexecute方法返回值不正确。
2.Goalupdatecreate_plan逻辑有冲突。
3. 多个 Goal 优先级仲裁逻辑有问题。
1. 为每个SkillGoal添加详细的日志输出。
2. 使用调试器或打印语句,跟踪 Brain 的决策循环。
1. 严格遵守SkillStatus(SUCCESS, FAILURE, RUNNING) 的语义。
2. 确保Goal.update()能准确反映目标完成情况。
3. 简化初始目标,确保单个目标能正确工作后再添加复杂逻辑。
游戏客户端卡顿或延迟高1. Python 端决策循环频率过高,发送指令太快。
2. 网络通信数据量过大。
3. Agent 数量过多,服务器性能不足。
1. 监控 Python 程序的 CPU 使用率。
2. 查看服务端 TPS (Tick Per Second) 是否下降。
3. 使用性能分析工具。
1. 在 Brain 循环中添加await asyncio.sleep(0.1)等间隔,降低频率。
2. 优化感知数据,只获取必要的信息。
3. 对 Agent 进行分帧更新,不要所有 Agent 在同一 tick 决策。
Agent 行为不符合预期1. 对 Minecraft 游戏机制理解有误(如碰撞箱、移动速度)。
2. AI 逻辑存在 bug 或边界条件未处理。
1. 在 Minecraft Wiki 上确认相关游戏机制。
2. 编写单元测试来验证SkillGoal的核心逻辑。
1. 将游戏机制相关的常数(如移动速度、跳跃高度)提取为可配置参数,便于调整。
2. 采用测试驱动开发,先写测试用例,再实现逻辑。

7. 进阶最佳实践与工程建议

当你成功运行第一个智能村民后,想要构建一个真正的“奇妙小镇”,就需要考虑工程化和扩展性问题了。

7.1 架构设计建议

  1. 技能池(Skill Pool):不要为每个 Agent 都实例化技能。创建一个全局的技能池,Agent 按需从池中获取技能实例。这有利于技能的状态管理和复用。
  2. 目标仲裁器(Goal Arbiter):当 Agent 拥有多个目标时,一个稳健的仲裁器至关重要。不要只用简单的优先级数值,可以考虑引入效用理论(Utility Theory),根据当前环境动态计算每个目标的“效用值”,选择最高的执行。
  3. 事件驱动感知:与其让每个 Agent 在每个 tick 都去轮询感知全世界,不如采用事件驱动模型。让 Environment 在特定事件(如玩家进入范围、方块被破坏)发生时,主动通知订阅了该事件的 Agent。这能极大提升性能。
  4. 配置数据驱动:将村民的类型、默认目标、对话文本、移动速度等属性抽取到配置文件(如 JSON 或 YAML)中。这样,策划或服主可以在不修改代码的情况下调整小镇的生态。

7.2 性能优化

  • 空间分区:对于感知(寻找附近玩家、实体),使用空间网格或四叉树来快速过滤,避免 O(n) 的全图遍历。
  • 异步与并发:利用 Python 的asyncio,让多个 Agent 的“思考”过程并发进行,但注意对游戏世界状态的写入操作可能需要加锁或使用队列串行化。
  • LOD(细节层次):对于远离玩家的 Agent,可以降低其大脑的更新频率(例如每秒更新一次),对于玩家附近的 Agent,则保持较高频率(例如每秒 5 次)。

7.3 集成外部 AI 能力

这是项目最激动人心的部分。你可以将大型语言模型(LLM)或强化学习(RL)融入 Agent 的决策。

  • LLM 驱动对话:将玩家的聊天内容、村民的记忆和当前环境作为提示词,调用 OpenAI API 或本地部署的 Llama 模型,生成动态、有趣的对话。
    # 伪代码示例 async def generate_dialogue(self, player_input, villager_memory): prompt = f""" 你是一个名叫{self.name}的Minecraft村民。你的性格是{self.personality}。 你记得以下事情:{villager_memory}。 玩家对你说:{player_input} 请用一句简短的话回复: """ reply = await call_llm_api(prompt) return reply
  • RL 训练行为:对于复杂行为(如高效采矿、建筑规划),可以设计一个奖励函数(如:获得钻石奖励高,受到伤害惩罚低),使用强化学习库(如 Stable-Baselines3)来训练 Agent 的策略网络。

7.4 安全与稳定性

  • 指令速率限制:严格限制向游戏客户端发送指令的速率,避免被服务器误判为作弊或造成服务器过载。
  • 异常处理与重试:所有网络调用和游戏指令调用都必须有 try-catch 包裹,并设计合理的重试和降级逻辑。
  • 状态持久化:定期将 Agent 的记忆、物品栏、位置等信息保存到数据库或文件。这样服务器重启后,小镇的居民能“记得”之前发生的事情。
  • 操作边界检查:任何试图修改世界的操作(放置/破坏方块、伤害实体)前,都必须进行权限和合法性检查,防止 Agent 破坏游戏平衡或玩家建筑。

从让一个村民说“你好”到构建一个拥有数十个角色、充满动态故事的小镇,中间隔着大量的工程实践。这个框架提供了起点和骨架,而真正的“奇妙”,来自于开发者对游戏的理解、对 AI 的运用以及无限的创造力。它不是一个开箱即用的解决方案,而是一把强大的“瑞士军刀”,让你能够亲手雕刻出心目中那个独一无二、生机勃勃的方块世界。建议你将本文的示例代码作为起点,从修改一个对话、增加一个目标开始,逐步探索更复杂的多智能体交互与叙事生成,你的“奇妙小镇”就在下一行代码中。