一个铁匠的锤子被偷了,只有铁匠亲眼看见。到了中午,他把这事告诉了酒馆老板娘;傍晚,老板娘又转述给卫队长。卫队长从头到尾没看见任何东西,却在第二天清晨堵住你,说这事能一路追到铁匠本人。
![]()
这不是剧本写死的对话,而是一个叫 Living Town 的演示项目。小镇 Thornbury 里住着 10 个 NPC:铁匠、酒馆老板、卫队长、副手、神父等。每个 NPC 的记忆,都是 FalkorDB 图数据库里的一个邻域。
项目作者在动手前先抛出一个问题:现在多数所谓的“智能体记忆”,本质是一个私人笔记本——一个智能体、一个存储、一堆向量片段。单个智能体够用,一旦智能体之间开始交流,真正有意思的问题就变了:你是怎么知道这件事的?谁告诉你的?又是谁告诉他的?有人亲眼见过,还是这已经是谣言的第 N 手转述?两个智能体说法冲突时,听谁的?
这些问题全都关于“关系”,而向量存储恰恰把关系丢掉了。于是作者用图数据库把关系本身做成了记忆。
三种记忆,三种边
赛题要求覆盖情景记忆、语义记忆和程序记忆。放进图里,它们不再是三套系统,而是三种边类型。再补上两块,社交记忆就成型了:
- 来源链:故事每流转一次,两个 NPC 之间就写一条 TOLD 边。每个相信者针对同一事实只有一条主入边,于是回溯到目击者的链条是一棵可以走通的树。
- 社交结构:NPC 之间带信任度和好感度的 KNOWS 边。铁匠讨厌卫队长(好感度 0.1),从不跟他说话,所以消息只能绕道酒馆老板娘。这条路由路径除了图里,别处都不存在。
传谣规则故意做得很无聊
目击者以 1.0 的置信度相信。听者的置信度等于:说话者置信度 × 听者对说话者的信任 × 0.9。低于 0.3 就只是存疑,不算采信。同一件事从别人嘴里再听一遍,是“佐证”而不是另起一条链。每天黎明,传闻衰减 7%;目击记忆保持置信度,但失去鲜活度。谎言不过是与其他事实相矛盾的事实——如果你告诉老板娘是 Pip 偷了锤子,而她已以更高置信度相信了别的版本,她会当场识破,而这本身又变成一条关于你的新故事。
108 条查询,智能体一条都不写
智能体从不自己写 Cypher。所有查询都是手写并参数化的,共 108 条:50 条读、50 条写、8 次图算法调用。智能体、大模型或 MCP 客户端只负责选择跑哪条、传什么参数。读操作走只读通道。
传谣交接是一条原子语句:匹配来源 NPC 的信念和目标 NPC,合并信念边,新建时写入置信度、立场(达到阈值算“采信”,否则“存疑”)、跳数和来源;已存在时把佐证计数加一;同时写一条 TOLD 边。
“你怎么知道的”则是对主 TOLD 边做变长路径查询。作者踩过一个坑:第一版先展开路径再过滤边,等于把全镇所有传谣路径都枚举一遍再扔掉大半,模拟到第五天左右查询就超时了。把过滤条件写进关系模式本身,数据库边展开边剪枝,稳定在 4 到 9 毫秒,镇子传得再凶也不涨。
任务板上的争抢也在数据库里解决,不在 Python 里。一个任务只能被一个智能体认领,而且它必须真的掌握对应流程——认领语句同时匹配任务状态为开放、且该 NPC 通过 KNOWS_HOW 边连到所需流程,才设置认领人和归属边。
图算法当小镇洞察
FalkorDB 把图算法作为过程提供,每一个都回答一个关于小镇的问题:标签传播在亲密友谊上找小团体,也就是八卦跑得最快的地方;介数中心性在 KNOWS 上找八卦中间人,结果永远是酒馆老板娘;PageRank 在 TOLD 上找谁听到的故事最多;最短路径按社交距离预测下一个可能听到故事的人,在地图上画成虚线圆环;连通分量和调和中心性则用来找“谣言孤岛”和谁传消息最快。
每个玩家一张图
多租户是作者最满意也最省事的部分。FalkorDB 一个实例能装很多张互相独立的图,于是每个玩家分到一张:town:ada、town:bo 依此类推。代码里没有任何一处按租户 ID 过滤。演示中两个玩家并排,各自活在不同的图里,一边的犯罪永远不会漏到另一边。换个新会话用同一个名字回来,小镇会凭记忆跟你打招呼。
最有价值的一个 bug:往返次数
本地跑一个模拟 tick(十个智能体全部感知、传谣、认领任务)大约 100 毫秒。部署后,应用在新加坡、FalkorDB Cloud 在孟买,同样的 tick 变成 2.8 秒。单看每条查询都不慢,慢的是一个 tick 里大约 25 次串行的跨区域往返。
修法是从“按查询思考”改成“按往返思考”:独立的按智能体读写用 asyncio.gather 并发;小查询合并,写操作用 UNWIND 批处理;整座小镇用一条语句建完;启动时预热连接池,因为每次新开一条到云实例的连接要花约 350 毫秒。现在一个 tick 约六次串行往返,线上 260 到 400 毫秒,新建世界从约 15 秒降到约 1.4 秒,一个完整模拟日在线上大约十秒跑完。
智能体、大模型与 MCP
默认情况下智能体是规则驱动的,这是刻意的:记忆、传谣和协作才是产品本体,有没有模型行为都一样。配上 Anthropic API key 后,NPC 对话由 Claude 通过工具调用生成,工具背后是同一套固定的记忆目录;模型提到的每个人、每件物品、每个地点都要与该轮工具返回结果核对,一旦说出图里从未返回过的东西,这条回复直接作废,改显示基于记忆的模板。
同一套工具也通过 MCP 暴露,任何 MCP 客户端都能打开一座小镇,问一句“在玩家 ada 的小镇里,卫队长 Oswin 是怎么知道锤子这事的?”
作者列出的下一步包括:让智能体主动遗忘,把旧的情景记忆压缩成语义摘要但保留来源边;让名声也能传播,目前每个 NPC 对你的看法只来自他自己的信念;以及把这套引擎搬出游戏,用于共享客户信息的客服智能体,并留下“谁从谁那里学到了什么”的可审计链路。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.