V0.11 开发日志 — 论文复现

概述

V0.11 是连接 V0.1 概念探索与 V0.2 原创认知增强之间的桥梁。这个版本的目标很直接:忠实复现 Generative Agents 论文(Park et al., UIST 2023),使用现代技术和本地 LLM 推理。

V0.1 揭示了朴素的基于 prompt 的对话配合扁平记忆会导致僵硬、重复的行为。解决方案不是调参——而是架构层面的变革。V0.11 实现了论文中描述的完整认知架构,将基于云端的 GPT-3.5 调用(原作者每次 2 天仿真花费约 $1000)替换为通过 Ollama 的免费本地推理。

开发周期:2026年3月30日 – 4月1日

代码仓库github.com/jeffliulab/ALICE_PROJECT


复现内容

完整认知循环

论文的架构以六阶段认知循环为核心,每个智能体在每个仿真步都执行完整循环。V0.11 实现了全部六个阶段:

  1. 感知(Perceive) — 每个智能体检测其空间区域内的附近事件。每个被感知的事件通过 LLM 评分为"触动度"(情感重要性),决定该事件对记忆的影响强度。这将 V0.1 简单的观察记录替换为具有上下文感知的事件过滤。

  2. 检索(Retrieve) — 三因子记忆检索系统,解决了 V0.1 "总是检索相同记忆"的问题:

    • 时效性(Recency):指数衰减——越近的记忆得分越高
    • 相关性(Relevance):当前上下文嵌入与存储记忆嵌入之间的余弦相似度
    • 重要性(Importance):感知时赋予的触动度分数

    每个因子独立归一化(在检索集内做最小-最大归一化),然后以可调权重组合(默认:时效性 0.5,相关性 3.0,重要性 2.0)。这确保检索能适应智能体当前的情境,而不是总是浮现相同的高重要性记忆。

  3. 规划(Plan) — 三级时间分解:

    • 日计划:当天的宏观目标
    • 时段安排:将每个日目标分解为小时级别的行动
    • 微任务:将每个时段行动进一步拆分为 5-15 分钟的子任务

    大多数复现跳过了微任务层。V0.11 实现了它,因为它对有机社交互动至关重要——当一个智能体正在执行 5 分钟的子任务时遇到另一个智能体,规划模块需要决定是参与、等待还是忽略。

  4. 反思(Reflect) — 当累积的重要性分数超过阈值时(默认:累积值降至零),智能体进入反思模式:

    • 从近期高重要性记忆中生成焦点问题
    • 检索与每个焦点问题相关的证据
    • 综合产生更高层次的洞见,存储为"思想"节点

    这创建了一个记忆层次结构:原始观察 → 反思想法 → 元反思。一个观察了许多小事件的智能体最终会将它们综合为更广泛的理解。

  5. 执行(Execute) — 将当前计划的目标位置解析为瓦片坐标,在碰撞网格上运行 A* 寻路,生成下一步移动和行动描述。智能体的精灵沿计算路径每步移动一个瓦片。

  6. 对话(Converse) — 逐轮对话,带有结构化知识提取。当两个智能体相遇并决定交谈时:

    • 每轮为当前对话上下文检索相关记忆
    • LLM 以角色身份生成回应
    • 对话结束后,双方智能体提取关键信息并存储为新的记忆节点
    • 关系上下文在多次对话间保持

记忆架构

V0.11 实现了三种不同的记忆结构,取代了 V0.1 的扁平时间戳列表:

  • 关联记忆(Associative Memory):使用概念节点的长期存储。每个节点存储:

    • 主语-谓语-宾语三元组(如"薇薇安——听到——来自森林的奇怪声音")
    • 关键词索引,用于快速查找
    • 语义嵌入向量(由本地运行的 sentence-transformers MiniLM 计算)
    • 创建时间戳、最后访问时间和重要性分数

    这本质上是一个知识图谱,每个记忆都是一个丰富索引的节点,而不仅仅是一个文本字符串。

  • 空间记忆(Spatial Memory):层级树结构——世界 → 区块 → 区域 → 物品。智能体知道有哪些建筑、建筑内有哪些房间、每个房间里有什么物品。这使得导航决策更加真实("我需要去教堂——它在神圣区域——我应该往北走")。

  • 工作记忆(Scratch):动态状态容器,捕捉智能体当前的认知上下文:身份、日计划、时段安排、当前行动、对话伙伴和各种阈值。这相当于一个不断演化的"系统提示词",每个仿真步都会更新。

世界:Smallville

V0.11 复现了原始论文的世界环境:

  • 25个智能体,各有独特的人设、日常作息和关系网络
  • 140 × 100 瓦片网格,多层地图:
    • 碰撞层(墙壁、障碍物)
    • 区块层(命名区域)
    • 区域层(区块内的具体房间/区域)
    • 物品层(可交互物品)
    • 出生点层(智能体初始位置)
  • 285个命名地址
  • 带碰撞感知的 A* 寻路

技术栈

与原始论文最大的不同在于技术栈。原始版本使用云端 API 和 Django 单体架构;V0.11 使用现代的本地优先工具:

组件原始论文V0.11
LLMGPT-3.5-turbo(云端,约 $1000/2天)Ollama + Qwen 14B(本地,免费)
嵌入OpenAI ada-002(云端)sentence-transformers MiniLM(本地)
后端Django + 基于文件的 IPCFastAPI + REST API
前端Phaser.js + Django 模板React + Phaser 3 + Vite
仿真仅实时(慢,耦合 UI)仿真/回放分离
数据自定义文件格式全程 JSON

为什么选择本地 LLM?

三个原因:

  1. 成本:原始论文在单次 2 天仿真中花费约 $1000 的 GPT-3.5 API 调用费。Ollama 本地推理在下载模型后完全免费。
  2. 可复现性:云端 API 的行为随时间变化。固定权重的本地模型产生确定性的结果。
  3. 隐私:所有智能体数据——记忆、对话、反思——都保留在本地机器上。

代价是推理质量。Qwen 14B 在某些方面不如 GPT-3.5,但对于认知循环中使用的结构化 prompt,它的表现足够好,能够复现论文的关键发现。


架构:仿真/回放分离

V0.11 最重要的设计决策之一是将仿真与可视化分离。

仿真模式python -m backend.simulate):

  • 在终端无界面运行
  • 每步:全部 25 个智能体执行认知循环
  • 输出 master_movement.json——完整记录每个智能体在每个时间步的位置、行动和状态
  • 100 步仿真需要 30-60 分钟(主要被 LLM 推理时间占据)

回放模式(基于浏览器):

  • FastAPI 通过 REST API 提供仿真数据
  • React + Phaser 3 前端渲染瓦片地图和精灵动画
  • 播放控制:播放/暂停、进度条、可变速度(1×–20×)
  • 逐智能体状态检查(点击智能体查看其当前想法、计划和记忆)

这种分离意味着:

  • 可以在过夜时运行实验而无需 UI
  • 通过加载不同的回放文件来比较多次仿真
  • 回放查看器即时加载——无需等待 LLM 推理

代码结构

ALICE_PROJECT/
├── backend/
│   ├── simulate.py              # CLI 仿真运行器
│   ├── main.py                  # FastAPI 回放服务器
│   ├── world_engine.py          # 核心仿真引擎 + 全局时钟
│   ├── maze.py                  # 140×100 瓦片世界地图
│   ├── recorder.py              # 保存回放数据为 JSON
│   ├── path_finder.py           # A* 寻路算法
│   ├── config.py                # LLM 和仿真配置
│   ├── llm/
│   │   ├── llm_client.py        # OpenAI 兼容 LLM 接口
│   │   └── embedding.py         # 本地 sentence-transformers 嵌入
│   ├── persona/
│   │   ├── persona.py           # 智能体认知循环编排器
│   │   ├── cognitive_modules/
│   │   │   ├── perceive.py      # 事件感知 + 触动度评分
│   │   │   ├── retrieve.py      # 三因子记忆检索
│   │   │   ├── plan.py          # 三级计划分解
│   │   │   ├── reflect.py       # 重要性触发的反思
│   │   │   ├── execute.py       # 移动 + 行动执行
│   │   │   └── converse.py      # 逐轮对话引擎
│   │   └── memory_structures/
│   │       ├── associative_memory.py  # 概念节点知识图谱
│   │       ├── spatial_memory.py      # 层级世界模型
│   │       └── scratch.py             # 工作记忆 / 状态
│   └── data/
│       └── the_ville/           # Smallville 世界数据(25个智能体)
├── frontend/
│   ├── src/
│   │   ├── App.tsx              # 回放查看器界面
│   │   ├── GameScene.ts         # Phaser 3 地图渲染
│   │   └── api.ts               # 后端 REST 客户端
│   └── public/assets/           # 瓦片集和角色精灵
└── paper-generative-agent/
    ├── ANALYSIS.md              # 15 节深入分析原始代码
    └── reverie/                 # 原始论文源代码(参考)

关键技术细节

记忆检索公式

对于查询上下文 q 和候选记忆集 M,每个记忆 m ∈ M 获得评分:

score(m) = w_recency × norm(recency(m)) + w_relevance × norm(relevance(m, q)) + w_importance × norm(importance(m))

其中:

  • recency(m) = e^(-λ × (t_now - t_created)),衰减率 λ = 0.995
  • relevance(m, q) = cosine_similarity(embedding(m), embedding(q))
  • importance(m) = LLM 评定的触动度分数(1-10)
  • norm() = 在当前检索集内的最小-最大归一化
  • 默认权重:w_recency = 0.5w_relevance = 3.0w_importance = 2.0

反思触发机制

当新记忆的重要性分数累积和降至零时触发反思(概念上:智能体已积累了足够多的重要经历,值得进行综合)。系统:

  1. 从近期高重要性记忆中生成 3 个焦点问题
  2. 对每个问题,检索最相关的 top-k 记忆
  3. 将每组综合为一个带有证据指针的"思想"节点
  4. 将思想节点存回关联记忆(使未来循环中的元反思成为可能)

计划分解

三个时间层级处理不同的时间尺度:

  • 宏观(日级):"起床、吃早餐、在铁匠铺工作、吃午饭、逛市场、回家、睡觉"
  • 中观(时级):"9:00-10:00: 加热锻炉并准备材料;10:00-12:00: 制作委托的剑"
  • 微观(5-15分钟):"9:00-9:05: 拨旺煤炭;9:05-9:15: 整理金属原料;9:15-9:30: 开始加热锻炉"

当意外事件发生时(另一个智能体到来、巨大响声),规划模块评估是否:

  • 继续当前任务
  • 暂停并参与事件
  • 放弃当前任务并重新规划

经验教训

论文做对了什么

  1. 三因子检索效果出奇的好。 时效性、相关性和重要性的组合产生了自然的记忆访问模式。智能体记住近期事件、回忆相关的过去经历、保留情感上重要的时刻——就像人类一样。

  2. 反思创造了真正的深度。 当足够多的观察累积后,智能体综合出有意义的洞见。一个多次对话失败的铁匠可能反思:"我觉得人们躲避我,因为我说了太多关于我工作的事情。"

  3. 计划层次防止了漫无目的的游荡。 没有计划,智能体只会对刺激做出反应。三级分解给了他们目标、常规,以及在有趣的事情发生时打破常规的能力。

出乎意料的发现

  1. 本地 LLM 表现超出预期。 Qwen 14B 很好地处理了结构化 prompt。关键洞见:认知架构将 LLM 的输出限制在可管理的、聚焦的任务中。每个模块问一个具体的问题,有明确的格式要求。LLM 不需要聪明绝顶——它需要在狭窄范围内可靠。

  2. 仿真/回放分离是必要的。 早期带 UI 的实时仿真尝试极其缓慢(25 个智能体每步需要数分钟)。将两者分离使实验变得实际可行。

  3. 智能体对话是最薄弱的环节。 即使有记忆检索和关系上下文,对话在几轮后倾向于礼貌和重复。这就是 LLM 权重静态性最明显的地方——智能体无法真正从对话中学习,只能记录它们。


与 V0.1 和 V0.2 的关系

V0.1 提出了问题:"两个 LLM 驱动的智能体能进行有意义的对话吗?"
答案是:"用朴素 prompt 和扁平记忆,不能。"

V0.11 回答了:"如果我们实现论文中的完整认知架构呢?"
答案是:"可以——有了感知、结构化检索、规划和反思,智能体的行为可信度大大提高。"

V0.2 追问:"我们能超越论文吗?智能体能成长、遗忘、做梦和反叛吗?"
V0.2 在 V0.11 坚实的基础上添加了受生物学启发的增强:短期/长期记忆分裂、基于梦境的记忆巩固、Ego 演化、能力检定,以及异见机制。它还从 Smallville 转移到原创世界塔纳波西亚——乌瓦村,一个充满中世纪奇幻设定、宗教张力和隐藏血脉的舞台。