ARTICLE DETAIL

资讯详情

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

赛博小镇后端实战:基于 HelloAgents 与 FastAPI 构建 AI NPC 对话系统

赛博小镇后端实战:基于 HelloAgents 与 FastAPI 构建 AI NPC 对话系统 赛博小镇后端实战基于 HelloAgents 与 FastAPI 构建 AI NPC 对话系统【免费下载链接】hello-agents 《从零开始构建智能体》——从零开始的智能体原理与实践教程项目地址: https://gitcode.com/GitHub_Trending/he/hello-agents导读本文以《Hello-agents》教材第 15 章配套项目赛博小镇的 后端服务 为核心系统讲解如何基于HelloAgents 框架 FastAPI构建一个可被 Godot 游戏前端调用的 AI NPC 对话后端涵盖单 NPC 实时对话、批量自主对话生成成本降低 66% 的方案、NPC 状态缓存管理、记忆系统与好感度系统等核心机制。读完本文你将掌握一套可直接运行的AI 小镇后端架构设计并理解其源码级的调用链路与配置调优方法。说明本项目为 code/chapter15/Helloagents-AI-Town 的组成部分对应教材第十五章《构建赛博小镇》游戏客户端为 Godot 4.x完整安装流程见 SETUP_GUIDE.md。一、项目定位与功能概览赛博小镇后端是一个基于 HelloAgents 框架的AI NPC 对话系统为 Godot HTML5 导出的小镇游戏提供对话与状态服务。它模拟了 Datawhale 办公室里的三位同事角色NPC职位所在位置默认活动张三Python 工程师工位区写代码李四产品经理会议室整理需求王五UI 设计师休息区喝咖啡角色设定性格、专长、说话风格、爱好全部集中定义在 agents.py 的NPC_ROLES字典中便于统一管理与扩展。后端核心功能可归纳为四类单个 NPC 对话玩家与指定 NPC 实时对话由独立的SimpleAgent处理批量对话生成定时批量生成所有 NPC 的自主对话相比逐个调用可将 API 成本降低约 66%状态管理自动更新并缓存 NPC 状态供 Godot 客户端轮询CORS 支持允许 Godot HTML5 导出后的跨域访问。此外从 agents.py 与 relationship_manager.py 的源码可以看出该后端在 README 描述的基础上还内置了记忆系统短期工作记忆 长期情景记忆与好感度系统5 个等级这两块内容在项目根目录也有独立文档 MEMORY_SYSTEM_GUIDE.md 与 AFFINITY_SYSTEM_GUIDE.md 详述。二、环境准备与安装1. 安装 Python 依赖进入后端目录并安装依赖cd backend pip install -r requirements.txtrequirements.txt 中的核心依赖如下fastapi0.104.0、uvicorn[standard]0.24.0Web 服务框架与 ASGI 服务器pydantic2.0.0数据模型校验models.py 中的请求/响应模型均基于它定义python-dotenv1.0.0从.env文件加载环境变量python-multipart0.0.6CORS 等表单相关支持hello-agents0.2.4,0.2.9HelloAgents 框架本体NPC Agent、记忆系统均来源于此。注意源码通过sys.path.insert(0, os.path.join(os.path.dirname(__file__), .., HelloAgents))将 HelloAgents 加入 Python 路径见 agents.py因此运行前需确保..即项目根目录下存在 HelloAgents 框架代码。2. 配置环境变量创建.env文件或直接设置环境变量。从 config.py 的源码可以看到本项目不使用OPENAI_API_KEY而是通过 HelloAgents 框架自定义 LLM 配置# LLM 模型 ID默认 Qwen/Qwen2.5-72B-Instruct LLM_MODEL_IDQwen/Qwen2.5-72B-Instruct # LLM 服务地址默认 ModelScope 推理服务 LLM_BASE_URLhttps://api-inference.modelscope.cn/v1/ # API 密钥 LLM_API_KEYyour-api-key对应源码中的读取逻辑LLM_MODEL_ID: str os.getenv(LLM_MODEL_ID, Qwen/Qwen2.5-72B-Instruct) LLM_API_KEY: Optional[str] os.getenv(LLM_API_KEY) LLM_BASE_URL: str os.getenv(LLM_BASE_URL, https://api-inference.modelscope.cn/v1/)config.py 中的validate()方法会在启动时检查LLM_API_KEY若未设置打印警告并提示在.env中配置重要容错即使不配置 API 密钥系统也会以预设对话模式运行保证演示不中断详见下文故障排查章节。其余默认配置还包括API_TITLE 赛博小镇 API API_VERSION 1.0.0 API_HOST 0.0.0.0 API_PORT 8000 NPC_UPDATE_INTERVAL 30 # NPC 状态更新间隔秒 CORS_ORIGINS [*] # 生产环境应限制为具体域名三、启动服务方法 1直接运行python main.pymain.py 的入口会调用uvicorn.run(main:app, hostsettings.API_HOST, portsettings.API_PORT, reloadTrue, ...)开发模式下自动热重载。方法 2使用 uvicornuvicorn main:app --reload --host 0.0.0.0 --port 8000启动成功后访问API 文档http://localhost:8000/docs FastAPI 自动生成的 Swagger UI可在浏览器中直接调试所有接口根路径http://localhost:8000/启动流程源码视角从 main.py 的lifespan生命周期管理可以看到完整的启动链路调用settings.validate()校验配置通过get_npc_manager()初始化 NPC Agent 管理器内部完成 LLM 初始化、为每个 NPC 创建SimpleAgent、记忆管理器与好感度管理器通过get_state_manager(settings.NPC_UPDATE_INTERVAL)初始化状态管理器并await state_manager.start()启动后台定时更新任务服务关闭时调用await state_manager.stop()取消后台任务。get_npc_manager()与get_state_manager()均为单例模式见 agents.py 与 state_manager.py避免多次初始化重复创建 Agent 与后台任务。四、API 接口详解所有接口定义在 main.py请求/响应模型在 models.py 中由 Pydantic 声明。根路径接口还会返回一份服务自描述信息列出全部端点方便客户端动态发现。1. 获取 NPC 列表GET /npcs响应示例{ npcs: [ { name: 张三, title: Python工程师, location: 工位区, activity: 写代码, available: true } ], total: 3 }对应实现为 list_npcs内部调用npc_mgr.get_all_npcs()其中available字段表示该 NPC 的 Agent 是否可用模拟模式下可能为false。2. 与 NPC 对话POST /chat Content-Type: application/json { npc_name: 张三, message: 你好,你在做什么? }响应示例{ npc_name: 张三, npc_title: Python工程师, message: 你好!我正在优化一个多智能体系统的性能,挺有意思的。, success: true, timestamp: 2024-01-15T10:30:00 }对应实现 chat_with_npc先校验 NPC 是否存在不存在返回 404再调用npc_mgr.chat(request.npc_name, request.message)。而NPCAgentManager.chat()agents.py是整条链路的核心内部依次完成读取当前好感度与好感度等级、对话风格修饰词从记忆管理器检索相关记忆工作记忆 情景记忆默认取 5 条、min_importance0.3将好感度上下文、记忆上下文与玩家消息拼接为增强提示词调用agent.run(enhanced_message)生成 NPC 回复调用relationship_manager.analyze_and_update_affinity()分析对话情感并更新好感度将本轮对话含好感度、情感倾向元数据写入记忆系统。3. 获取 NPC 状态自主对话GET /npcs/status响应示例{ dialogues: { 张三: 终于把这个bug修复了,测试通过!, 李四: 下周的产品评审会需要准备一下资料。, 王五: 这个配色方案看起来不错,再调整一下细节。 }, last_update: 2024-01-15T10:30:00, next_update_in: 25 }该接口供 Godot 客户端定时轮询用于展示 NPC 的自主行为气泡。实现见 get_npcs_status数据来自状态管理器的缓存其中next_update_in为下次更新的倒计时秒数。4. 强制刷新状态POST /npcs/status/refresh实现见 refresh_npcs_status会立即触发一次state_mgr.force_update()方便调试时跳过等待间隔。5. 其他扩展接口除 README 列出的基础接口外源码中还提供了记忆与好感度相关接口接口方法说明/npcs/{npc_name}GET获取单个 NPC 详情含当前对话/npcs/{npc_name}/memoriesGET获取 NPC 记忆列表limit参数默认 10 条/npcs/{npc_name}/memoriesDELETE清空 NPC 记忆memory_type可指定 working/episodic不传则清空全部用于测试/npcs/{npc_name}/affinityGET获取 NPC 对玩家的好感度player_id默认player/npcs/{npc_name}/affinityPUT设置好感度0-100越界返回 400用于测试/affinitiesGET获取所有 NPC 的好感度信息五、核心设计批量对话生成与成本优化为什么需要批量生成小镇中有 3 个 NPC如果每个 NPC 每 30 秒都单独调用一次 LLM3 个 NPC × 每 30 秒 6 次 API 调用/分钟每小时约360 次调用而采用一次调用生成全部 NPC 对话的批量策略1 次批量调用/30 秒 2 次 API 调用/分钟每小时约120 次调用成本降低约 66%批量生成的实现NPCBatchGenerator 实现了这一策略其生成流程为定时器触发默认 30 秒见 state_manager.py 的_auto_update_loop批量生成器构建提示词_build_batch_prompt()一次 LLM 调用生成所有 NPC 对话使用llm.invoke()而非chat()解析 JSON 响应_parse_response支持直接解析与截取花括号内容两种容错策略更新状态管理器缓存Godot 客户端定时获取状态。提示词构建逻辑batch_generator.py会动态拼接当前场景与 NPC 描述并要求严格按 JSON 格式返回例如请为Datawhale办公室的3个NPC生成当前的对话或行为描述。 【场景】上午工作时间,大家都在专注工作,办公室氛围专注而忙碌 【NPC信息】 - 张三(Python工程师): 在工位区写代码,性格技术宅,喜欢讨论算法和框架 ... 【输出格式】(严格遵守) {张三: ..., 李四: ..., 王五: ...}此外_get_current_context()会根据当前小时自动推断场景清晨/上午/午餐/下午/傍晚/夜晚让 NPC 对话更贴合真实时间氛围。预设对话降级当 LLM 不可用时未配置密钥或调用失败批量生成器自动降级为预设对话模式batch_generator.py内置 morning/noon/afternoon/evening 四套对话库按当前时间选取保证小镇永不冷场。六、NPC 状态管理器与定时调度NPCStateManager 负责状态缓存与定时更新关键设计如下启动即更新start()会立即执行一次_update_npc_states()随后创建asyncio.create_task(self._auto_update_loop())后台任务循环调度后台任务while self._running: await asyncio.sleep(self.update_interval)单次更新异常会被捕获并打印不中断后续循环缓存查询get_current_state()返回dialogues、last_update与next_update_in根据上次更新时间计算倒计时Godot 客户端只需轮询/npcs/status即可获得全部 NPC 的当前行为优雅关闭stop()取消后台任务并等待其结束。从实现细节看state_manager.start()在 main.py 的lifespan中被调用且传入的是settings.NPC_UPDATE_INTERVAL因此调整更新频率只需修改 config.py 中的配置项。七、配置说明与调优config.py 核心配置# NPC更新间隔(秒) NPC_UPDATE_INTERVAL 30 # LLM配置 LLM_MODEL_ID Qwen/Qwen2.5-72B-Instruct # 默认模型 LLM_BASE_URL https://api-inference.modelscope.cn/v1/ # 默认服务地址 CORS_ORIGINS [*] # 生产环境应限制具体域名注意README 中提到的OPENAI_MODEL gpt-4o-mini为早期版本示例当前源码已改为通过LLM_MODEL_ID/LLM_BASE_URL配置可对接任意兼容 OpenAI 协议的模型服务默认 ModelScope推荐使用 mini 级别模型以进一步降低成本。调整更新频率修改 config.py 中的NPC_UPDATE_INTERVAL开发测试10 秒刷新更快便于观察正式运行3060 秒默认 30 秒低成本模式120 秒减少 API 调用次数频率越低单位时间 API 调用越少但 NPC 状态更新的实时感也会下降需要根据游戏体验与成本预算权衡。八、故障排查问题 1启动失败 / LLM 初始化失败❌ LLM初始化失败解决检查LLM_API_KEY环境变量是否设置或在.env文件中配置。对应源码 agents.pyLLM 初始化失败时会将self.llm置为None并进入模拟模式此时chat()会返回带提示的固定回复。问题 2对话无响应⚠️ 将使用预设对话模式解决这是系统自动降级的表现不影响基本功能。/npcs/status会返回预设对话/chat会返回模拟回复仅 AI 个性化能力暂时不可用。配置好LLM_API_KEY后重启即可恢复。问题 3CORS 错误Godot HTML5 跨域解决检查 config.py 中的CORS_ORIGINS。默认[*]允许所有来源适合开发生产环境应改为具体域名列表。CORS 中间件配置见 main.py。九、开发建议扩展 NPC 与自定义风格添加新 NPC在 agents.py 的NPC_ROLES字典中添加角色配置职位、位置、活动、性格、专长、风格、爱好在 batch_generator.py 的preset_dialogues中为新 NPC 添加各时段预设对话重启服务。自定义对话风格修改 agents.py 中的create_system_prompt函数。该函数生成的系统提示词包含角色设定、行为准则如回复 30-50 字以内不要说我是 AI与对话示例是 NPC 人格一致性的关键。调整批量生成提示词修改 batch_generator.py 中的_build_batch_prompt函数例如调整每句对话的字数限制默认 20-40 字、输出 JSON 的字段结构或场景描述。相关独立文档项目根目录还提供了三份专题指南可与本文配合阅读记忆系统指南工作记忆/情景记忆的配置与原理好感度系统指南5 级好感度陌生/熟悉/友好/亲密/挚友的判定与对话风格变化对话日志系统指南通过 logger.py 记录对话、记忆、好感度变化全过程可用 view_logs.py 查看。十、项目结构速览backend/ ├── main.py # FastAPI 主程序路由 生命周期管理 ├── config.py # 配置LLM、端口、更新间隔、CORS ├── models.py # Pydantic 数据模型 ├── agents.py # NPC Agent 系统角色、提示词、对话、记忆 ├── batch_generator.py # 批量对话生成器成本优化核心 ├── state_manager.py # NPC 状态管理器定时调度 缓存 ├── relationship_manager.py # 好感度管理系统 ├── logger.py # 对话/记忆/好感度日志 ├── view_logs.py # 日志查看工具 ├── memory_data/ # 各 NPC 的记忆存储目录SQLite ├── requirements.txt # Python 依赖 └── README.md # 后端说明文档结语赛博小镇后端是一个麻雀虽小、五脏俱全的多智能体落地案例它把 HelloAgents 的 Agent、记忆、LLM 能力封装为干净的 REST API用批量生成策略解决多 NPC 场景下的成本问题再通过状态缓存与定时调度衔接 Godot 游戏前端。无论是学习 FastAPI Agent 框架的工程集成还是想快速搭建自己的 AI 小镇/虚拟办公室这份代码都提供了可直接复制运行的参考实现。结合 SETUP_GUIDE.md 将前后端串联起来即可获得一个完整的可玩 Demo。【免费下载链接】hello-agents 《从零开始构建智能体》——从零开始的智能体原理与实践教程项目地址: https://gitcode.com/GitHub_Trending/he/hello-agents创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表