J'Blog

16 课 · 实战

语义检索

基于 Chroma 向量库,与 Workspace 知识库分离。用自然语言描述你想查的内容。 非管理员每人每天可检索 5 次(消耗站点 AI 配额)。

构建赛博小镇

原文:Hello-Agents · 第十五章 构建赛博小镇 · 在线阅读

一句话

将智能体技术与游戏引擎结合,构建一个充满生命力的AI小镇,实现智能NPC对话、记忆系统和好感度系统。

什么时候翻这页

当你需要将AI技术与游戏开发结合,创建具有真实交互体验的虚拟世界时。

核心概念

  • 智能NPC对话系统:玩家可以与NPC进行自然语言对话,NPC会根据角色设定和记忆做出回应。
  • 记忆系统:NPC拥有短期记忆和长期记忆,能够记住与玩家的互动历史。
  • 好感度系统:NPC对玩家的态度会随着互动而变化,从陌生到熟悉,从友好到亲密。
  • 游戏化交互:玩家可以在2D像素风格的办公室场景中自由移动,与不同的NPC互动。
  • 实时日志系统:所有对话和互动都会被记录,方便调试和分析。
  • 批量对话生成:将多个NPC的对话请求合并成一次LLM调用,降低成本和延迟。
  • 混合模式:结合批量生成和即时响应,既保证效率又保证交互质量。

怎么做

项目架构

赛博小镇采用游戏引擎+后端服务的分离架构,分为四个层次:

  1. 前端层:使用Godot 4.5游戏引擎,负责游戏渲染、玩家控制、NPC显示和对话UI。
  2. 后端层:使用FastAPI框架,负责API路由、NPC状态管理、对话处理和日志记录。
  3. 智能体层:使用HelloAgents框架,负责NPC智能、记忆管理和好感度计算。
  4. 外部服务层:提供LLM能力、向量存储和数据持久化,包括LLM API、Qdrant向量数据库和SQLite关系数据库。

NPC智能体系统

每个NPC都是一个独立的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实例
    llm = HelloAgentsLLM()

    # 创建记忆管理器
    memory_manager = MemoryManager(
        working_memory=WorkingMemory(capacity=10, ttl_minutes=120),
        episodic_memory=EpisodicMemory(
            db_path=f"memory_data/{npc_id}_episodic.db",
            collection_name=f"{npc_id}_memories"
        )
    )

    # 创建Agent
    agent = SimpleAgent(
        name=name,
        llm=llm,
        system_prompt=system_prompt,
        memory_manager=memory_manager
    )

    return agent

NPC角色设定

设计了三个NPC,分别代表不同的职业和性格:

  • 张三 - Python工程师:严谨、专业、喜欢分享技术知识。说话直接,注重代码质量。
  • 李四 - 产品经理:外向、善于沟通、注重用户体验。喜欢从用户角度思考问题。
  • 王五 - UI设计师:温和、富有创意、审美独特。注重视觉呈现和用户体验。

好感度系统

好感度分为五个等级:

  1. 陌生(0-20分):NPC刚认识玩家,态度礼貌但保持距离。
  2. 熟悉(21-40分):NPC开始记住玩家,愿意进行简单的交流。
  3. 友好(41-60分):NPC把玩家当作朋友,愿意分享更多信息。
  4. 亲密(61-80分):NPC非常信任玩家,愿意分享私人话题。
  5. 挚友(81-100分):NPC把玩家当作最好的朋友,无话不谈。

好感度计算使用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  # 默认中立

批量对话生成

批量生成器将多个NPC的对话请求合并成一次LLM调用:

class NPCBatchGenerator:
    """批量生成NPC对话的生成器"""

    def generate_batch_dialogues(self, context: Optional[str] = None) -> Dict[str, str]:
        """批量生成所有NPC的对话"""
        # 构建批量生成提示词
        prompt = self._build_batch_prompt(context)

        # 一次LLM调用生成所有对话
        response = self.llm.invoke([
            {"role": "system", "content": "你是一个游戏NPC对话生成器,擅长创作自然真实的办公室对话。"},
            {"role": "user", "content": prompt}
        ])

        # 解析JSON响应
        dialogues = json.loads(response)
        return dialogues

前后端通信

使用HTTP REST API实现Godot前端与FastAPI后端的通信:

# api_client.gd
extends Node

# 信号定义
signal chat_response_received(npc_name: String, message: String)
signal chat_error(error_message: String)

# HTTP请求节点
var http_chat: HTTPRequest

func send_chat(npc_name: String, message: String) -> void:
    """发送对话请求"""
    var data = {
        "npc_name": npc_name,
        "message": message
    }

    var json_string = JSON.stringify(data)
    var headers = ["Content-Type: application/json"]

    var error = http_chat.request(
        Config.API_CHAT,
        headers,
        HTTPClient.METHOD_POST,
        json_string
    )

    if error != OK:
        print("[ERROR] 发送对话请求失败: ", error)
        chat_error.emit("网络请求失败")

命令 / 代码速查

启动后端

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

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

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

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

启动Godot

  1. 下载Godot引擎(Windows / Mac)
  2. 打开Godot引擎,点击"导入"按钮
  3. 浏览到Helloagents-AI-Town/helloagents-ai-town/scenes/main.tscn,点击"导入并编辑"
  4. 按F5或点击"运行"按钮启动游戏

查看日志

# 在backend目录下
python view_logs.py

与 Python / Claude Code 手册的联系

  • 使用Python的FastAPI框架构建后端服务
  • 使用Godot引擎的GDScript语言开发游戏前端
  • 利用HelloAgents框架实现NPC智能体系统
  • 使用向量数据库(Qdrant)存储长期记忆
  • 使用SQLite关系数据库存储状态数据

初学者易错点

  1. CORS配置:确保FastAPI后端正确配置CORS,允许Godot前端访问
  2. 异步处理:Godot中的HTTP请求是异步的,需要正确处理回调函数
  3. 内存管理:NPC的短期记忆容量和TTL需要合理设置,避免内存泄漏
  4. 好感度计算:LLM的情感分析可能不稳定,需要设置合理的分数变化范围
  5. 批量生成限制:批量生成不适合与玩家的直接互动,仅适用于背景对话

相关词条

官方原文:https://github.com/datawhalechina/hello-agents/blob/main/docs/chapter15/%E7%AC%AC%E5%8D%81%E4%BA%94%E7%AB%A0%20%E6%9E%84%E5%BB%BA%E8%B5%9B%E5%8D%9A%E5%B0%8F%E9%95%87