15.1 项目概述与架构设计

配套代码:code/chapter15

15.1.1 为什么要构建 AI 小镇

传统游戏中的 NPC 通常只能说固定的台词,或者通过预设的对话树进行有限的互动。即使是最复杂的 RPG 游戏,NPC 的对话也是由编剧事先写好的。这种方式虽然可控,但缺乏真正的"智能"和"生命力"。

想象一下,如果游戏中的 NPC 能够理解你说的任何话,不再局限于预设的选项,你可以用自然语言与 NPC 交流。NPC 会记得你上次说了什么,你们的关系如何,甚至你的喜好。每个 NPC 都有自己的职业、性格和说话风格。NPC 对你的态度会随着互动而变化,从陌生人到朋友,甚至挚友。

这就是 AI 技术为游戏带来的新可能。通过将大语言模型与游戏引擎结合,我们可以创造出真正"活着"的 NPC。这不仅仅是一个技术演示,更是对未来游戏形态的探索。在教育游戏中,NPC 可以扮演历史人物、科学家,与学生进行互动式教学。在虚拟办公室中,NPC 可以扮演同事、导师,提供帮助和建议。NPC 还可以作为陪伴者,与用户进行情感交流,应用于心理健康领域。当然,最直接的应用就是为传统游戏增加 AI NPC,提升玩家体验。

15.1.2 技术架构概览

赛博小镇采用游戏引擎+后端服务的分离架构,分为四个层次,如图 15.1 所示。

图 15.1 赛博小镇技术架构

前端层使用 Godot 4.5 游戏引擎,负责游戏渲染、玩家控制、NPC 显示和对话 UI。Godot 是一个开源的 2D/3D 游戏引擎,非常适合快速开发像素风格的游戏。后端层使用 FastAPI 框架,负责 API 路由、NPC 状态管理、对话处理和日志记录。FastAPI 是一个现代化的 Python Web 框架,性能优秀且易于开发。智能体层使用我们自己构建的 HelloAgents 框架,负责 NPC 智能、记忆管理和好感度计算。每个 NPC 都是一个 SimpleAgent 实例,拥有独立的记忆和状态。外部服务层提供 LLM 能力、向量存储和数据持久化,包括 LLM API、Qdrant 向量数据库和 SQLite 关系数据库。

数据流转过程如图 15.2 所示:

图 15.2 数据流转过程

玩家在 Godot 中按 E 键与 NPC 互动,Godot 通过 HTTP API 发送对话请求到 FastAPI 后端。后端调用 HelloAgents 的 SimpleAgent 处理对话,Agent 从记忆系统中检索相关历史,然后调用 LLM 生成回复。后端更新 NPC 状态和好感度,记录日志到控制台和文件,最后返回回复给 Godot 前端。Godot 显示 NPC 回复并更新 UI,完成一次完整的交互循环。

项目的结构如下,方便你定位源码:

Helloagents-AI-Town/
├── helloagents-ai-town/           # Godot游戏项目
│   ├── project.godot              # Godot项目配置
│   ├── scenes/                    # 游戏场景
│   │   ├── main.tscn              # 主场景(办公室)
│   │   ├── player.tscn            # 玩家角色
│   │   ├── npc.tscn               # NPC角色
│   │   └── dialogue_ui.tscn       # 对话UI
│   ├── scripts/                   # GDScript脚本
│   │   ├── main.gd                # 主场景逻辑
│   │   ├── player.gd              # 玩家控制
│   │   ├── npc.gd                 # NPC行为
│   │   ├── dialogue_ui.gd         # 对话UI逻辑
│   │   ├── api_client.gd          # API客户端
│   │   └── config.gd              # 配置管理
│   └── assets/                    # 游戏资源
│       ├── characters/            # 角色精灵图
│       ├── interiors/             # 室内场景
│       ├── ui/                    # UI素材
│       └── audio/                 # 音效音乐
│
└── backend/                       # Python后端
    ├── main.py                    # FastAPI主程序
    ├── agents.py                  # NPC Agent系统
    ├── relationship_manager.py    # 好感度管理
    ├── state_manager.py           # 状态管理
    ├── logger.py                  # 日志系统
    ├── config.py                  # 配置管理
    ├── models.py                  # 数据模型
    ├── requirements.txt           # Python依赖
    └── .env.example               # 环境变量示例

详细的架构设计和数据流转将在后续章节中介绍。

15.1.3 快速体验:5 分钟运行项目

在深入学习实现细节之前,让我们先把项目跑起来,看看最终的效果。这样你会对整个系统有一个直观的认识。

环境要求:

  • Godot 4.2 或更高版本
  • Python 3.10 或更高版本
  • LLM API 密钥(OpenAI、DeepSeek、智谱等)

获取项目:

你可以到code/chapter15/Helloagents-AI-Town中查看,或者从 GitHub 克隆完整的 hello-agents 仓库。

启动后端:

# 1. 进入backend目录
cd Helloagents-AI-Town/backend

# 2. 安装依赖
pip install -r requirements.txt

# 3. 配置环境变量
cp .env.example .env
# 编辑.env文件,填写你的API密钥

# 4. 启动后端服务
python main.py

成功启动后,你会看到如下输出:

============================================================
🎮 赛博小镇后端服务启动中...
============================================================
✅ 所有服务已启动!
📡 API地址: http://0.0.0.0:8000
📚 API文档: http://0.0.0.0:8000/docs
============================================================

启动 Godot:

Godot 的安装非常简单,Windows 提供了直接打开的.exe文件,Mac 也提供了.dmg文件。可直接在官网下载(Windows / Mac)

打开 Godot 引擎,点击"导入"按钮,浏览到Helloagents-AI-Town/helloagents-ai-town/scenes/main.tscn,点击"导入并编辑"。等待 Godot 导入资源后,按F5或点击"运行"按钮启动游戏。

体验核心功能:

游戏启动后,你会看到一个像素风格的 Datawhale 办公室场景,如图 15.3 所示。

图 15.3 赛博小镇游戏场景

使用 WASD 键移动玩家角色,走到 NPC 附近时,屏幕上会显示"按 E 键交互"的提示。按下 E 键后,会弹出对话框,你可以输入任何想说的话,如图 15.4 所示。

图 15.4 与 NPC 对话界面

NPC 会根据自己的角色设定(Python 工程师、产品经理、UI 设计师)和你们的互动历史做出回应。随着对话的进行,NPC 对你的好感度会逐渐提升,从"陌生"到"熟悉",再到"友好"、"亲密"甚至"挚友"。

好感度系统在后端实现,每次对话都会根据玩家的消息内容和情感分析来调整好感度值。虽然前端游戏界面中没有直接显示好感度数值,但所有的好感度变化都会被详细记录在后端日志中。你可以在backend/logs/dialogue_YYYY-MM-DD.log文件中查看每次对话的好感度变化。日志文件会记录每次对话的详细信息,包括:当前好感度值、检索到的相关记忆、NPC 的回复、好感度变化量(+2.0、+3.0 等)、变化原因(友好问候、正常交流等)以及情感分析结果(positive、neutral 等)。这种设计让开发者可以清晰地追踪 NPC 与玩家的关系发展,也为后续在前端添加好感度 UI 提供了数据基础。

所有的对话都会被记录在后端的日志文件中,你可以通过以下命令实时查看:

# 在backend目录下
python view_logs.py

这个简单的体验展示了 AI 小镇的核心功能。接下来,我们将深入学习如何实现这些功能。