ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

用 HelloAgents 与 Godot 构建赛博小镇:从零打造具有记忆与好感度的 AI NPC 游戏

用 HelloAgents 与 Godot 构建赛博小镇:从零打造具有记忆与好感度的 AI NPC 游戏 用 HelloAgents 与 Godot 构建赛博小镇从零打造具有记忆与好感度的 AI NPC 游戏【免费下载链接】hello-agents 《从零开始构建智能体》——从零开始的智能体原理与实践教程项目地址: https://gitcode.com/GitHub_Trending/he/hello-agents本篇技术指南以《从零开始构建智能体》第十五章为骨架完整讲解如何将 HelloAgents 智能体框架与 Godot 游戏引擎结合构建一个包含智能 NPC 对话、短期/长期记忆、五级好感度、批量对话生成与实时日志的 2D 像素风 AI 小镇。读者将掌握游戏引擎 后端服务分层架构的搭建方法理解 SimpleAgent 如何承载 NPC 智能并能独立复现或扩展一个真正活着的 AI NPC 系统。1 项目概述与架构设计1.1 为什么要构建 AI 小镇传统游戏中的 NPC 通常只能说出固定台词或通过预设对话树进行有限互动。即使是最复杂的 RPGNPC 对话也由编剧事先写死——这种方式虽然可控但缺乏真正的智能和生命力。如果游戏中的 NPC 能够理解玩家说的任何话、记住上次聊了什么、记得你们的关系甚至记住玩家的喜好会怎样每个 NPC 都有自己的职业、性格和说话风格对玩家的态度会随互动变化从陌生人到朋友再到挚友。这正是大语言模型与游戏引擎结合带来的新可能它并非单纯的技术演示而是对未来游戏形态的探索教育游戏NPC 扮演历史人物、科学家与学生进行互动式教学虚拟办公室NPC 扮演同事、导师提供帮助和建议陪伴场景NPC 作为陪伴者进行情感交流可应用于心理健康领域传统游戏增强为既有游戏加入 AI NPC提升玩家体验。1.2 技术架构概览游戏引擎 后端服务赛博小镇采用游戏引擎 后端服务的分离架构分为四个层次层次技术选型职责前端层Godot 4.5 游戏引擎游戏渲染、玩家控制、NPC 显示、对话 UI后端层FastAPI 框架API 路由、NPC 状态管理、对话处理、日志记录智能体层HelloAgents 框架NPC 智能、记忆管理、好感度计算每个 NPC 是一个 SimpleAgent 实例外部服务层LLM API、Qdrant、SQLite大模型能力、向量存储、数据持久化数据流转闭环如下玩家在 Godot 中按 E 键与 NPC 互动 → Godot 通过 HTTP API 发送对话请求到 FastAPI 后端 → 后端调用 HelloAgents 的 SimpleAgent 处理对话 → Agent 从记忆系统检索相关历史 → 调用 LLM 生成回复 → 后端更新 NPC 状态和好感度、记录日志 → 返回回复给 Godot 前端 → Godot 显示回复并更新 UI完成一次完整交互循环。项目源码位于 code/chapter15/Helloagents-AI-Town其结构如下Helloagents-AI-Town/ ├── helloagents-ai-town/ # Godot游戏项目 │ ├── project.godot # Godot项目配置 │ ├── scenes/ # 游戏场景 (main/player/npc/dialogue_ui .tscn) │ ├── scripts/ # GDScript脚本 (main/player/npc/dialogue_ui/api_client/config .gd) │ └── assets/ # 游戏资源 (characters/interiors/ui/audio) └── backend/ # Python后端 ├── main.py # FastAPI主程序 ├── agents.py # NPC Agent系统 ├── relationship_manager.py # 好感度管理 ├── state_manager.py # 状态管理 ├── batch_generator.py # 批量对话生成器 ├── logger.py # 日志系统 ├── config.py # 配置管理 ├── models.py # 数据模型 ├── requirements.txt # Python依赖 └── view_logs.py # 日志查看工具1.3 快速体验5 分钟运行项目环境要求Godot 4.2 或更高版本、Python 3.10 或更高版本、LLM API 密钥。启动后端# 1. 进入backend目录 cd Helloagents-AI-Town/backend # 2. 安装依赖 pip install -r requirements.txt # 3. 配置环境变量 cp .env.example .env # 编辑.env文件填写你的API密钥 # 4. 启动后端服务 python main.py实际仓库的依赖清单见 backend/requirements.txt包括fastapi0.104.0、uvicorn[standard]0.24.0、pydantic2.0.0、python-dotenv以及 HelloAgents 框架依赖hello-agents0.2.4,0.2.9。关于 LLM 配置需要说明的是实际仓库的 config.py 并不直接读取OPENAI_API_KEY而是通过三个环境变量驱动且默认接入 ModelScope魔搭推理服务环境变量默认值说明LLM_MODEL_IDQwen/Qwen2.5-72B-Instruct使用的模型LLM_API_KEY无未设置时启动会告警服务密钥LLM_BASE_URLhttps://api-inference.modelscope.cn/v1/API 服务地址启动时会先执行settings.validate()检查密钥若未配置LLM_API_KEY会打印告警但服务仍可启动——此时 NPC Agent 进入模拟模式返回请配置 API_KEY 以启用 AI 对话的提示方便无密钥时先联调前后端流程。成功启动后输出如下 赛博小镇后端服务启动中... ✅ 所有服务已启动! API地址: http://0.0.0.0:8000 API文档: http://0.0.0.0:8000/docs 启动 Godot从官网下载对应平台的安装包Windows 为.exemacOS 为.dmg。打开 Godot 引擎点击导入浏览到Helloagents-AI-Town/helloagents-ai-town/scenes/main.tscn点击导入并编辑。等待资源导入后按F5或点击运行启动游戏。体验核心功能使用 WASD 移动玩家角色走近 NPC 时屏幕显示按 E 键交互提示按 E 键弹出对话框可输入任意内容。NPC 会根据角色设定Python 工程师、产品经理、UI 设计师和互动历史做出回应。随着对话推进好感度会从陌生逐步提升到挚友。好感度系统在后端实现虽然前端不直接显示数值但所有变化都被记录到backend/logs/dialogue_YYYY-MM-DD.log中包括当前好感度值、检索到的相关记忆、NPC 的回复、好感度变化量2.0、3.0 等、变化原因友好问候、正常交流等与情感分析结果positive、neutral 等。可在 backend 目录下运行以下命令实时查看日志python view_logs.py2 NPC 智能体系统2.1 基于 HelloAgents 的 SimpleAgent在赛博小镇中每个 NPC 都是独立的智能体。我们使用 HelloAgents 框架中的SimpleAgent——一个轻量级智能体实现封装了 LLM 调用、消息管理和工具调用等核心功能。其核心是一个简单的对话循环接收用户消息 → 调用 LLM 生成回复 → 返回结果。为每个 NPC 创建独立 Agent 的流程是定义 NPC 基本信息ID、名称、职业、性格→ 据此构建系统提示词让 LLM 扮演角色 → 创建 SimpleAgent 实例并配置记忆系统。文档中的教学版示例代码如下from hello_agents import SimpleAgent, HelloAgentsLLM from hello_agents.memory import MemoryManager, WorkingMemory, EpisodicMemory def create_npc_agent(npc_id: str, name: str, role: str, personality: str): 创建NPC Agent system_prompt f你是{name},一位{role}。 你的性格特点:{personality} 你在Datawhale办公室工作,与同事们一起推动开源社区的发展。 请根据你的角色和性格,自然地与玩家对话。 记住你们之前的对话内容,保持对话的连贯性。 llm HelloAgentsLLM() memory_manager MemoryManager( working_memoryWorkingMemory(capacity10, ttl_minutes120), episodic_memoryEpisodicMemory( db_pathfmemory_data/{npc_id}_episodic.db, collection_namef{npc_id}_memories ) ) agent SimpleAgent( namename, llmllm, system_promptsystem_prompt, memory_managermemory_manager ) return agent这里 WorkingMemory 是短期记忆容量 10 条消息、保留 120 分钟EpisodicMemory 是长期记忆基于 SQLite 与 Qdrant 向量库存储并支持语义检索。仓库实际实现backend/agents.py在此基础上做了进一步工程化NPCAgentManager在初始化时为每个 NPC 创建MemoryManager并为其配置更精细的 MemoryConfigmemory_config MemoryConfig( storage_pathmemory_dir, # 每个NPC独立的存储目录 working_memory_capacity10, # 工作记忆最近10条对话 working_memory_tokens2000, # 工作记忆最多2000个token max_capacity100, # 长期记忆最多100条 importance_threshold0.3, # 检索时只关注重要性0.3的记忆 decay_factor0.95 # 时间衰减系数 ) memory_manager MemoryManager( configmemory_config, user_idnpc_name, # 用NPC名字作为user_id enable_workingTrue, # 启用工作记忆(短期) enable_episodicTrue, # 启用情景记忆(长期) enable_semanticFalse, # 不需要语义记忆 enable_perceptualFalse # 不需要感知记忆 )同时仓库实现为每个 NPC 一个记忆目录的持久化方案运行后会在backend/memory_data/张三/、李四/、王五/下分别生成memory.db实现 NPC 之间记忆隔离。2.2 NPC 角色设定与 Prompt 设计赛博小镇设计了三个性格鲜明的 NPC。仓库实际定义backend/agents.py#L21-L49比文档示例更完整每个 NPC 包含职位、位置、活动、性格、专长、说话风格、爱好七个维度NPC职位位置当前活动性格专长张三Python工程师工位区写代码技术宅喜欢讨论算法和框架多智能体系统、HelloAgents框架、Python开发、代码优化李四产品经理会议室整理需求外向健谈善于沟通协调需求分析、产品规划、用户体验、项目管理王五UI设计师休息区喝咖啡细腻敏感注重美感界面设计、交互设计、视觉呈现、用户体验对应文档中的简化版配置如下npc_zhang { npc_id: zhang_san, name: 张三, role: Python工程师, personality: 严谨、专业、喜欢分享技术知识。说话直接,注重代码质量。 } npc_li { npc_id: li_si, name: 李四, role: 产品经理, personality: 外向、善于沟通、注重用户体验。喜欢从用户角度思考问题。 } npc_wang { npc_id: wang_wu, name: 王五, role: UI设计师, personality: 温和、富有创意、审美独特。注重视觉呈现和用户体验。 }仓库中的create_system_prompt()会基于这些配置生成结构化提示词包含角色设定、行为准则如保持角色一致性用第一人称我回答回复控制在 30-50 字以内不要说自己是AI/语言模型、以及对话示例few-shot让 LLM 扮演的角色更稳定、更像真实的办公室同事。2.3 记忆系统集成记忆系统是 NPC 智能的关键。两层记忆分工明确短期记忆WorkingMemory存储最近对话容量有限、随时间自动清理作用是保持对话连贯性——当玩家说它是什么颜色的时NPC 需要从短期记忆中找出它指什么长期记忆EpisodicMemory存储全部对话历史使用向量库做语义检索——当玩家说还记得我们上次讨论的那个项目吗时NPC 能检索到相关历史。实际对话处理时Agent 先取短期记忆最近对话再从长期记忆检索相关历史拼装上下文后交给 LLM。文档中的核心流程如下def process_dialogue(agent, player_message): # 1. 从短期记忆获取最近对话 recent_messages agent.memory_manager.working_memory.get_recent_messages(5) # 2. 从长期记忆检索相关历史 relevant_memories agent.memory_manager.episodic_memory.search( queryplayer_message, top_k3 ) # 3. 构建上下文 context {recent: recent_messages, relevant: relevant_memories} # 4. 调用Agent生成回复 reply agent.run(player_message, contextcontext) # 5. 保存到记忆系统 agent.memory_manager.add_interaction(player_message, reply) return reply仓库实现NPCAgentManager.chat()在 agents.py 中把检索-增强-生成-记忆-好感度串成了完整流水线获取当前好感度并生成关系上下文等级 对话风格修饰词调用memory_manager.retrieve_memories(querymessage, memory_types[working, episodic], limit5, min_importance0.3)检索相关记忆构建增强提示词【当前关系】【之前的对话记忆】【当前对话】三段拼接后交给agent.run()调用好感度管理器分析并更新好感度将玩家说…与我说…两条消息连同好感度、情感倾向等元数据写入记忆见_save_conversation_to_memory()。值得注意的是仓库还会把当时的affinity、affinity_change、sentiment写入记忆的metadata即好感度信息本身也参与记忆存储为后续按情感/关系维度召回对话提供了数据基础。2.4 批量对话生成轻负载模式当多个玩家同时与不同 NPC 对话时后端需并发处理多个 LLM 请求成本与延迟都会上升。为此设计了批量对话生成系统将多个 NPC 的对话请求合并成一次 LLM 调用让 LLM 一次性生成所有 NPC 的回复——如同餐厅预制菜一次 API 调用成本可降至原来的约 1/3延迟大幅下降。仓库实现位于 backend/batch_generator.pyclass NPCBatchGenerator: def __init__(self): self.llm HelloAgentsLLM() self.npc_configs NPC_ROLES # 所有NPC的配置 def generate_batch_dialogues(self, contextNone) - Dict[str, str]: prompt self._build_batch_prompt(context) response self.llm.invoke([ {role: system, content: 你是一个游戏NPC对话生成器,擅长创作自然真实的办公室对话。}, {role: user, content: prompt} ]) dialogues json.loads(response) # {张三: ..., 李四: ..., 王五: ...} return dialogues批量生成提示词的关键是严格约束输出格式要求每个 NPC 生成 1 句话20-40 字、内容符合角色与场景氛围且必须严格按照 JSON 格式返回并给出示例输出{张三: 这个bug真是见鬼了,已经调试两小时了..., 李四: 嗯,这个功能的优先级需要重新评估一下。, 王五: 这杯咖啡的拉花真不错,灵感来了!}由于所有 NPC 的对话在同一个上下文中生成彼此天然存在关联性张三调试 bug 时李四可能提到帮忙看看王五设计界面时张三可能说等会儿去看设计稿办公室氛围更真实连贯。工程细节仓库为批量生成器设计了优雅降级路径。_get_current_context()根据当前小时自动推断场景清晨/上午工作/午餐/下午工作/傍晚/夜晚当 LLM 不可用时回退到按时间段morning/noon/afternoon/evening选取的预设对话库保证 NPC 状态接口始终可用。_parse_response()则依次尝试直接 JSON 解析、截取首尾花括号提取、失败后回退预设对话鲁棒性较好。批量生成更适合 NPC 的背景对话或自言自语主要应用于NPC 背景对话玩家进入场景时 NPC 正在做什么、定时更新、按时间生成场景氛围、以及高并发下降成本。混合模式批量生成 即时响应系统后台定期批量生成所有 NPC 的背景对话并缓存玩家靠近 NPC 但未交互时NPC 显示正在调试代码…在看产品文档…等背景对话看起来是活着的玩家按下 E 键发起交互时立即切换到即时响应调用该 NPC 的专属 Agent基于具体消息、历史记忆与好感度生成个性化回复。仓库中由 state_manager.py 的NPCStateManager承载默认每 30 秒NPC_UPDATE_INTERVAL触发一次_update_npc_states()批量生成并缓存同时提供force_update()支持前端手动触发刷新对应/npcs/status/refresh接口。这种混合模式的优势背景对话批量生成成本低玩家交互即时响应质量高NPC 始终有背景对话显得生动批量生成频率可根据服务器负载动态调整。3 好感度系统设计3.1 好感度等级划分好感度系统通过量化 NPC 与玩家的关系让回复更真实、有层次感。系统划分为五个等级每个等级对应分数范围和行为表现等级分数范围NPC 行为表现陌生0-20 分礼貌但保持距离回复简短不主动分享个人信息熟悉21-40 分开始记住玩家愿意简单交流偶尔分享工作信息友好41-60 分把玩家当朋友回复更详细主动询问玩家情况亲密61-80 分非常信任玩家愿意分享私人话题提供帮助和建议挚友81-100 分把玩家当最好的朋友无话不谈分享内心想法这种设计让玩家能清晰感知关系变化也为玩法扩展提供基础——比如只有达到一定好感度NPC 才分享特殊信息或提供特殊任务。3.2 好感度计算逻辑好感度不能简单固定加分否则会显得机械。赛博小镇使用LLM 分析对话内容自动判断玩家态度是友好、中立还是不友好再动态调整分数全程无需玩家刻意选择选项。文档中的教学版RelationshipManager通过一个简单 prompt 让 LLM 返回数字分数class RelationshipManager: def analyze_sentiment(self, player_message: str, npc_reply: str) - int: prompt f分析以下对话中玩家的态度: 玩家: {player_message} NPC: {npc_reply} 请判断玩家的态度是: 1. 友好(5分): 礼貌、热情、表示感谢或赞同 2. 中立(2分): 普通的询问或陈述 3. 不友好(-3分): 粗鲁、冷漠、批评或否定 只返回数字,不要其他内容。 response self.llm.think([{role: user, content: prompt}]) try: score_change int(response.strip()) return max(-3, min(5, score_change)) # 限制在-3到5之间 except: return 2 # 默认中立仓库实际实现backend/relationship_manager.py将情感分析升级为独立的SimpleAgent名为AffinityAnalyzer从四个维度分析并输出结构化 JSON{ should_change: true, change_amount: -15到10之间的整数, reason: 简短说明原因(10字以内), sentiment: positive/neutral/negative }好感度变化规则在分析 Agent 的系统提示词中明确定义赞美/感谢/请教 3 到 8友好问候/正常交流 1 到 3普通闲聊 0批评/质疑/不耐烦 -3 到 -8侮辱/攻击/恶意 -8 到 -15。更新时分数被钳制在 0-100 之间等级由get_affinity_level()判定。为提升鲁棒性_parse_analysis()对 LLM 输出做了三重解析兜底直接json.loads→ 截取首尾花括号再解析 → 正则提取字段均失败则返回默认值should_changeFalse避免一次解析异常影响整个对话流程。3.3 好感度影响对话好感度不是孤立数字它会真正改变 NPC 的行为——通过动态调整系统提示词实现。文档中给出了按等级映射对话风格的方案affinity_prompts { 陌生: 你刚认识这位玩家,保持礼貌但不要过于热情。回复简短专业。, 熟悉: 你已经认识这位玩家,可以进行正常的交流。回复自然友好。, 友好: 你把这位玩家当作朋友,愿意分享更多信息。回复详细热情。, 亲密: 你非常信任这位玩家,可以分享私人话题。回复充满关心。, 挚友: 你把这位玩家当作最好的朋友,无话不谈。回复亲切真诚。 }系统提示词中会注入当前与玩家的关系:{affinity_level}及对应风格描述。仓库中这一机制由get_affinity_modifier()实现并在NPCAgentManager.chat()中把关系上下文拼接到增强提示词的【当前关系】段落——好感度低时 NPC冷淡疏离回答简短高时非常热情友好像老朋友一样亲切。玩家可以明显感受到态度随互动逐渐变化沉浸感与趣味性大增。4 后端服务实现4.1 FastAPI 应用结构后端使用 FastAPI 构建采用模块化设计将不同功能分离到独立文件中。入口文件 backend/main.py定义应用与生命周期管理asynccontextmanager async def lifespan(app: FastAPI): # 启动时验证配置 - 初始化NPC管理器 - 启动状态管理器后台任务 settings.validate() npc_manager get_npc_manager() state_manager get_state_manager(settings.NPC_UPDATE_INTERVAL) await state_manager.start() yield # 关闭时停止后台任务 await state_manager.stop() app FastAPI( titlesettings.API_TITLE, versionsettings.API_VERSION, description赛博小镇 - 基于HelloAgents的AI NPC对话系统, lifespanlifespan ) app.add_middleware( CORSMiddleware, allow_originssettings.CORS_ORIGINS, # 默认[*]生产环境应限制具体域名 allow_credentialsTrue, allow_methods[*], allow_headers[*], )注意实际仓库使用了 FastAPI 推荐的lifespan异步上下文管理器而非文档示例中的app.on_event(startup)这是 FastAPI 新版本的推荐写法。4.2 API 路由设计实际仓库的 API 端点与文档教学示例略有差异文档示例为/dialogue仓库实现为/chat以仓库为准方法路径功能GET/服务信息与端点索引GET/health健康检查POST/chat与 NPC 实时对话即时响应走独立 AgentGET/npcs获取所有 NPC 列表GET/npcs/status获取批量生成的 NPC 背景对话POST/npcs/status/refresh强制刷新 NPC 背景对话GET/npcs/{npc_name}获取单个 NPC 详情含当前背景对话GET/DELETE/npcs/{npc_name}/memories查看/清空 NPC 记忆后者用于测试GET/PUT/npcs/{npc_name}/affinity查看/设置好感度后者用于测试GET/affinities获取所有 NPC 好感度核心的对话接口逻辑main.py#L103-L134app.post(/chat, response_modelChatResponse) async def chat_with_npc(request: ChatRequest): npc_mgr, _ get_managers() npc_info npc_mgr.get_npc_info(request.npc_name) if not npc_info: raise HTTPException(status_code404, detailfNPC {request.npc_name} 不存在) try: response_text npc_mgr.chat(request.npc_name, request.message) return ChatResponse( npc_namerequest.npc_name, npc_titlenpc_info[title], messageresponse_text, successTrue ) except Exception as e: raise HTTPException(status_code500, detailf对话处理失败: {str(e)})请求/响应模型使用 Pydantic 定义backend/models.py例如ChatRequest要求npc_name与message两个必填字段ChatResponse返回 NPC 名称、职位、回复内容与成功标记。文档示例还展示了完整的对话流程——验证 NPC 存在 → 检查是否忙碌409 冲突→ 标记忙碌 → 获取好感度 → 调用 Agent 生成回复 → 更新好感度 → 记录日志 → 返回响应 → finally 释放状态——这套忙碌互斥 事务式处理的流程设计在并发场景下仍有参考价值。4.3 状态管理与日志系统状态管理器负责跟踪每个 NPC 的位置、忙碌状态、当前动作等防止并发问题如一个 NPC 同时与多个玩家对话。文档示例用内存字典记录is_busy、current_action、last_interaction等字段实际仓库的 state_manager.py 则聚焦定时批量生成背景对话 状态缓存用asyncio后台任务每 30 秒执行一次批量更新对外提供get_current_state()含对话内容、上次更新时间、下次更新倒计时与force_update()。日志系统实现控制台 文件双输出。仓库版 logger.py 将每次对话拆分为多个语义化步骤对话开始、当前好感度、记忆检索条数、生成回复、NPC 回复、分析好感度、好感度变化及原因/情感、记忆保存、对话结束日志文件按日期命名dialogue_YYYY-MM-DD.log方便开发者完整追踪玩家消息 → 记忆召回 → 回复 → 关系变化的链路 对话开始: 张三 - 玩家 玩家消息: 你好! 当前好感度: 50.0/100 (熟悉) 检索到2条相关记忆 正在生成回复... 张三回复: 你好!我是张三,一名Python工程师... 正在分析好感度变化... 好感度变化: 50.0 - 52.0 (2.0) 原因: 友好问候 情感: positive 对话已保存到张三的记忆中 ✅ 对话完成4.4 理解 Godot 的场景系统节点Node是 Godot 最基本的构建块可理解为乐高积木每种节点专注做好一件事Sprite2D显示图片、AudioStreamPlayer播放音频、CharacterBody2D处理角色物理移动。节点可构成父子树状结构移动/隐藏父节点会连带影响所有子节点便于组织复杂游戏对象。场景Scene是节点的集合保存为.tscn文件相当于预制件。场景强大之处在于可复用与模块化可在场景内实例化另一场景形成嵌套修改 NPC 场景会自动影响所有 NPC 实例。例如一个玩家场景的树状结构Player (CharacterBody2D) ← 根节点,负责物理移动 ├─ AnimatedSprite2D ← 子节点,显示角色动画 ├─ CollisionShape2D ← 子节点,定义碰撞形状 └─ Camera2D ← 子节点,摄像机跟随玩家赛博小镇中三个 NPC张三、李四、王五都是同一个NPC.tscn的实例仅通过脚本参数设置不同名称和角色信息。若想给所有 NPC 增加新功能如头顶对话气泡只需修改 NPC 场景一处。5 Godot 游戏场景构建5.1 为什么选择 Godot选择 Godot 4.5 作为前端引擎主要基于四点考虑2D 开发天然优势赛博小镇是俯视角 2D 像素风格游戏Godot 提供TileMap、AnimatedSprite2D、CharacterBody2D等专为 2D 设计的节点开发效率高场景系统可将玩家、NPC、UI 封装为独立场景再实例化契合组件化需求完全开源免费MIT 许可证无版权费用或收入分成可自由修改引擎源码对教学与开源项目非常友好学习成本极低GDScript 是类似 Python 的动态类型语言变量声明、函数定义、控制流程与 Python 高度相似熟悉 Python 的读者几小时内即可上手节点树结构在编辑器中直观可见与 Python 后端集成简单内置HTTPRequest节点可轻松与 FastAPI 进行 HTTP 通信前后端分离的架构可独立开发和测试游戏逻辑与 AI 逻辑。局限性Godot 的 3D 能力相比 Unreal/Unity 尚有差距大型 3D 游戏需考虑其他引擎但对于 2D 游戏、独立游戏与教学项目Godot 是优秀选择。5.2 场景设计与资源组织游戏由四个核心场景组成Main主场景、Player玩家、NPC非玩家角色、DialogueUI对话界面。三个 NPC 是同一个 NPC 场景的实例只是通过脚本参数设置不同的角色信息。四个场景在 Godot 中的创建步骤Player 场景新建场景选CharacterBody2D为根节点添加AnimatedSprite2D、CollisionShape2D、Camera2D、InteractSound、RunningSound子节点保存为Player.tscnNPC 场景根节点CharacterBody2D添加CollisionShape2D、AnimatedSprite2D、InteractionAreaArea2D下含 CollisionShape2D、NameLabel、DialogueLabel保存为NPC.tscnDialogueUI 场景根节点CanvasLayer添加Panel其下放NPCName、NPCTitle、DialogueTextRichTextLabel、PlayerInputLineEdit、SendButton、CloseButton保存为DialogueUI.tscnMain 场景根节点Node2D添加BackgroundSprite2D 背景图与小鲸鱼装饰、实例化 Player 场景、创建NPCs节点并在其下三次实例化 NPC 场景、实例化 DialogueUI 场景、创建Walls节点组织墙体碰撞、添加AudioStreamPlayer播放背景音乐。5.3 玩家控制实现玩家场景的核心是CharacterBody2D根节点物理移动与碰撞AnimatedSprite2D动画CollisionShape2D碰撞形状Camera2D跟随 两个AudioStreamPlayer交互/走路音效。player.gd的关键机制_ready()中调用add_to_group(player)NPC 通过这个组识别玩家_physics_process()用Input.get_vector()读取方向move_and_slide()移动交互状态下velocity置零禁用移动update_animation()按移动方向播放 4 方向动画walk_up/down/left/right并处理flip_h镜像静止时播放idle_input()监听 E 键或回车触发interact_with_npc()播放交互音效后通过get_tree().call_group(dialogue_system, start_dialogue, nearby_npc.npc_name)通知对话系统set_nearby_npc()由 NPC 调用以注册当前可交互对象走路音效随移动状态自动播放/停止。5.4 NPC 行为与交互NPC 需要实现三个核心功能随机巡逻、响应玩家交互、显示对话气泡。npc.gd提供了丰富的可导出配置项导出属性默认值说明npc_name/npc_title张三 / Python工程师NPC 身份信息sprite_framesnull自定义精灵帧资源move_speed50.0巡逻移动速度wander_enabledtrue是否启用巡逻wander_range200.0巡逻范围围绕出生点wander_interval_min/wander_interval_max3.0 / 8.0 秒巡逻间隔区间关键机制_ready()中add_to_group(npcs)连接InteractionArea的body_entered/body_exited信号_on_body_entered()检测到玩家通过is_in_group(player)后调用player.set_nearby_npc(self)完成交互注册_physics_process()中巡逻计时器递减到期后在出生点wander_range范围内随机选点移动到达后播放 idle交互状态is_interacting下停止移动update_dialogue()更新对话气泡文本并显示10 秒后自动隐藏——主场景会定时调用它展示 NPC 之间的自主对话。由于三个 NPC 共用同一场景只需在 Main 场景的NPCs节点下分别设置npc_name/npc_title/sprite_frames即可获得三个性格各异但行为一致的角色。6 前后端通信实现6.1 API 客户端封装Godot 前端通过api_client.gd封装所有 API 调用并设为 AutoLoad 单例供全局使用。核心设计是使用 HTTPRequest 节点 信号回调而非 await保证游戏流畅且允许多个脚本同时监听同一响应。客户端定义了四个信号signal chat_response_received(npc_name: String, message: String) signal chat_error(error_message: String) signal npc_status_received(dialogues: Dictionary) signal npc_list_received(npcs: Array)三个独立 HTTPRequest 节点http_chat/http_status/http_npcs对应三类请求互不干扰。API 地址统一从全局配置单例 config.gd 读取const API_BASE_URL http://localhost:8000 const API_CHAT API_BASE_URL /chat const API_NPCS API_BASE_URL /npcs const API_NPC_STATUS API_BASE_URL /npcs/status const NPC_STATUS_UPDATE_INTERVAL 30.0 # NPC状态更新间隔(秒)send_chat()用JSON.stringify构造请求体并通过http_chat.request()POST 到/chat响应在_on_chat_request_completed()中校验 HTTP 状态码、解析 JSON 后发出chat_response_received信号。get_npc_status()在请求未完成时会跳过重复请求检查STATUS_DISCONNECTED避免轮询堆积。6.2 对话 UI 实现对话 UI 是CanvasLayer根节点始终显示在最上层不被遮挡Panel锚定屏幕底部作为背景。内部 6 个元素分工明确NPCName显示名字、NPCTitle显示职位、DialogueTextRichTextLabel显示对话内容支持富文本、PlayerInputLineEdit接收输入、SendButton/CloseButton发送与关闭。dialogue_ui.gd的关键逻辑start_dialogue(npc_name)设置 NPC 信息、清空对话区、聚焦输入框并显示对话框显示/隐藏对话框时通过get_tree().get_first_node_in_group(player)通知玩家set_interacting(true/false)实现对话中禁用移动send_message()用append_text以富文本追加玩家消息青色随后禁用输入框和发送按钮防止重复提交异步等待响应on_chat_response_received()收到匹配 NPC 的回复后以黄色追加显示重新启用输入并聚焦发送支持按钮点击与输入框回车text_submitted两种触发方式。6.3 主场景整合main.gd负责协调所有组件并定时拉取 NPC 状态、更新对话气泡_ready()中获取 APIClient 单例、连接npc_status_received信号并立即请求一次_process()中每Config.NPC_STATUS_UPDATE_INTERVAL默认 30 秒轮询一次/npcs/status收到更新后遍历所有 NPC 调用其update_dialogue()让 NPC 之间的自主对话在气泡中呈现。即使玩家不与 NPC 交互办公室也始终有人在说话。至此前后端通信全部打通玩家自由移动、与 NPC 自然语言对话、NPC 定时展示自主背景对话整个系统以信号机制松耦合通信易于维护扩展。7 总结与展望7.1 本章回顾赛博小镇将 HelloAgents 框架与 Godot 引擎结合创造出一个充满生命力的虚拟世界核心成果可归纳为五点技术架构采用游戏引擎 后端服务分离架构Godot 负责画面与交互、FastAPI 负责 API 与状态管理、HelloAgents 负责 NPC 智能与记忆各层可独立开发测试NPC 智能体用 SimpleAgent 为每个 NPC 创建独立智能体通过精心设计的系统提示词塑造出严谨的 Python 工程师张三、善于沟通的产品经理李四、富有创意的 UI 设计师王五记忆与好感度短期记忆保证对话连贯长期记忆通过向量检索召回历史五级好感度让 NPC 态度随互动从陌生演进到挚友游戏场景Godot 场景系统实现像素办公室、玩家控制、NPC 巡逻与对话 UI场景实例化让新增 NPC 只需复制一份配置前后端通信HTTP REST 异步信号保证流畅性API 客户端单例封装统一入口对话 UI 提供自然交流体验。7.2 扩展方向赛博小镇只是起点文档与仓库提供了清晰的扩展蓝图多人在线支持引入 WebSocket 实时通信与数据库持久化NPC 对每个玩家保持独立好感度任务系统好感度达到阈值后 NPC 提供特殊任务张三请玩家调试代码、李四请玩家收集反馈、王五请玩家评价设计完成任务获奖励并提升好感度NPC 之间互动让张三与李四讨论产品需求、李四与王五讨论界面设计后台自动进行玩家可观察世界更生动情感系统在好感度之上增加开心、难过、生气等情绪状态影响回复风格与行为动态事件系统定期团队会议、生日派对、突发任务等事件增加变化性与趣味性更大的世界扩展咖啡厅、图书馆、公园等场景每个场景有不同的 NPC 与互动方式个性化学习NPC 学习玩家偏好与习惯如常聊 Python 则主动分享相关内容、晚间活跃则晚上更热情。7.3 思考与展望AI NPC 为游戏带来了前所未有的可能性但同时也面临现实挑战成本——每次对话都调用 LLM API大型多人在线场景成本可观延迟——LLM 推理需要时间网络不佳时玩家可能等待数秒内容控制——LLM 生成内容不完全可控需要精心设计提示词与内容过滤机制。尽管如此AI NPC 的未来依然充满希望LLM 推理速度持续加快、成本不断下降本地化小型模型快速发展未来甚至可能在玩家设备上直接运行、完全无需网络请求。本项目的批量生成 即时响应混合模式、记忆与好感度一体化设计也为其他需要大量 AI 调用的场景提供了可复用的工程思路。【免费下载链接】hello-agents 《从零开始构建智能体》——从零开始的智能体原理与实践教程项目地址: https://gitcode.com/GitHub_Trending/he/hello-agents创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表