用 TiMem 给游戏 NPC 加上长期记忆:让 NPC 记住玩家的每个选择

5 阅读3分钟

用 TiMem 给游戏 NPC 加上长期记忆:让 NPC 记住玩家的每个选择

玩过《上古卷轴》或《巫师》的玩家都有这种体验:NPC 有固定台词,你做了什么它全不记得。你上次帮了村民,第二天他还是那句「又见面了,旅行者」。

AI NPC 改变了这件事的可能性——但大多数实现还是有同一个缺陷:会话内有记忆,跨会话清零。玩家今天救了 NPC 的儿子,明天 NPC 全忘了。

本文用 TiMem 搭一个真正有长期记忆的 AI NPC,让它记住玩家每一个关键选择,并在未来的互动中体现出来。


设计目标

  1. 记住关键事件:玩家帮了/伤害了 NPC、完成了某个任务
    1. 关系随时间演变:正面互动积累信任,负面事件导致关系恶化
    1. 对话自然融入记忆:NPC 提及历史时自然,不要像在背日志
    1. 跨会话持久化:游戏重启后记忆不丢失

TiMem 五层时序记忆树(L1 原始片段 → L2 互动摘要 → L3 阶段总结 → L4 关系模式 → L5 玩家画像)天然支持这些需求。


动手实现

1. 安装依赖

pip install timem-client openai

API Key:console.timem.cloud

2. NPC 类(含对话 + 记忆)

import os, uuid
from timem_client import TiMemClient
from openai import OpenAI

timem = TiMemClient(api_key=os.environ["TIMEM_API_KEY"])
llm = OpenAI()

class NPC:
  def __init__(self, npc_id, name, role, personality):
      self.npc_id = npc_id
          self.name = name
              self.role = role
                  self.personality = personality
                  
                    def memory_key(self, player_id):
                        return f"{self.npc_id}_{player_id}"
                        
                          def talk(self, player_id, player_input, session_id):
                              memories = timem.search(
                                    query=player_input,
                                          user_id=self.memory_key(player_id),
                                                session_id=session_id,
                                                      top_k=5
                                                          )
                                                              memory_ctx = ""
                                                                  if memories:
                                                                        lines = [f"- {m['content']}" for m in memories]
                                                                              memory_ctx = "你对这位玩家的记忆:\n" + "\n".join(lines)
                                                                                  system_prompt = (
                                                                                        f"你是NPC {self.name}{self.role},性格:{self.personality}\n"
                                                                                              "根据历史关系调整语气,自然提及过去事件。\n\n" + memory_ctx
                                                                                                  )
                                                                                                      messages = [
                                                                                                            {"role": "system", "content": system_prompt},
                                                                                                                  {"role": "user", "content": player_input}
                                                                                                                      ]
                                                                                                                          reply = llm.chat.completions.create(model="gpt-4o", messages=messages)
                                                                                                                              reply = reply.choices[0].message.content
                                                                                                                                  timem.add(
                                                                                                                                        messages=[
                                                                                                                                                {"role": "user", "content": f"[玩家] {player_input}"},
                                                                                                                                                        {"role": "assistant", "content": f"[{self.name}] {reply}"}
                                                                                                                                                              ],
                                                                                                                                                                    user_id=self.memory_key(player_id),
                                                                                                                                                                          session_id=session_id
                                                                                                                                                                              )
                                                                                                                                                                                  return reply
                                                                                                                                                                                  ```
                                                                                                                                                                                  
                                                                                                                                                                                  ### 3. 关键事件写入
                                                                                                                                                                                  
                                                                                                                                                                                  ```python
                                                                                                                                                                                  def record_event(npc, player_id, event, event_type):
                                                                                                                                                                                    tags = {"positive": "[正面]", "negative": "[负面]", "neutral": "[中性]"}
                                                                                                                                                                                      tag = tags.get(event_type, "[事件]")
                                                                                                                                                                                        timem.add(
                                                                                                                                                                                            messages=[{"role": "system", "content": f"{tag} {event}"}],
                                                                                                                                                                                                user_id=npc.memory_key(player_id)
                                                                                                                                                                                                  )
                                                                                                                                                                                                  
                                                                                                                                                                                                  innkeeper = NPC("npc_inn_01", "老托马斯", "酒馆老板", "沧桑、话不多,对帮过他的人讲义气")
                                                                                                                                                                                                  record_event(innkeeper, "player_001", "玩家击退歹徒,救了老托马斯的女儿", "positive")
                                                                                                                                                                                                  record_event(innkeeper, "player_002", "玩家趁夜偷走了酒馆备用钱箱", "negative")
                                                                                                                                                                                                  ```
                                                                                                                                                                                                  
                                                                                                                                                                                                  ### 4. 运行效果
                                                                                                                                                                                                  
                                                                                                                                                                                                  ```python
                                                                                                                                                                                                  session = str(uuid.uuid4())
                                                                                                                                                                                                  r = innkeeper.talk("player_001", "老板,给我来杯酒。", session)
                                                                                                                                                                                                  print(f"老托马斯(对恩人):{r}")
                                                                                                                                                                                                  # 预期:温热语气,提到救女儿的事
                                                                                                                                                                                                  
                                                                                                                                                                                                  r = innkeeper.talk("player_002", "老板,给我来杯酒。", session)
                                                                                                                                                                                                  print(f"老托马斯(对小偷):{r}")
                                                                                                                                                                                                  # 预期:戒备冷淡,暗示钱箱的事
                                                                                                                                                                                                  ```
                                                                                                                                                                                                  
                                                                                                                                                                                                  ---
                                                                                                                                                                                                  
                                                                                                                                                                                                  ## 效果对比
                                                                                                                                                                                                  
                                                                                                                                                                                                  | 场景 | 传统 NPC | TiMem NPC |
                                                                                                                                                                                                  |------|---------|------------|
                                                                                                                                                                                                  | 玩家第二次对话 | 重复初始台词 | 自然延续上次互动 |
                                                                                                                                                                                                  | 玩家完成过任务 | 不知道 | 表达感激,增加信任 |
                                                                                                                                                                                                  | 玩家曾经攻击 | 不记得 | 保持警惕,态度冷淡 |
                                                                                                                                                                                                  | 关系演变 | 静态 | 随互动动态变化 |
                                                                                                                                                                                                  | 跨会话记忆 | 清零 | 永久保留关键事件 |
                                                                                                                                                                                                  
                                                                                                                                                                                                  ---
                                                                                                                                                                                                  
                                                                                                                                                                                                  ## 小结
                                                                                                                                                                                                  
                                                                                                                                                                                                  真正有记忆的 NPC = 记住关键事件 + 关系随时间演变 + 自然融入历史。
                                                                                                                                                                                                  
                                                                                                                                                                                                  TiMem 让这件事核心代码不超过 80 行,且随玩家历史积累 token 消耗不增长(-52%)。
                                                                                                                                                                                                  
                                                                                                                                                                                                  GitHub:https://github.com/TiMEM-AI/timem
                                                                                                                                                                                                  
                                                                                                                                                                                                  ---
                                                                                                                                                                                                  如果你对 AI 记忆技术感兴趣,欢迎访问 TiMem 的 GitHub 仓库:
                                                                                                                                                                                                  https://github.com/TiMEM-AI/timem
                                                                                                                                                                                                  给我们一个 Star,你的支持是我们持续开源的最大动力!
                                                                                                                                                                                                  
                                                                                                                                                                                                  在线体验:https://playground.timem.cloud
                                                                                                                                                                                                  技术文档:https://docs.timem.cloud