“你如何解释进化中的代理,而不要求人们阅读日志或相信一张汇总图表?”——这是Agent Genome项目在起步时就抛出的尖锐问题。答案不是又一套晦涩的数据看板,而是一个由40个发光生物体构成的微型可视化种群,每一个个体都背负着一份显式的1到10整数基因组,在资源与危险交织的网格上自主行动、繁殖、变异。参观者不需要听讲解,更不需要读论文,只用盯着那块深色画布,就能看懂演化到底在怎样发生。

这个交互式浏览展项刻意把自己定位成“既不是聊天应用,也不是游戏”。它的全部设计都指向一个目标:让人几乎在扫一眼之后就能回答三个核心问题——这些生物体在做什么?为什么一个的行为与另一个截然不同?上一代到底把什么东西传到了下一代?为了达成这一点,项目没有藏起任何复杂度,反而把它摊在了台面上。能量源、危险区、运动轨迹、右侧的标本面板,以及全屏切换的世代更替动画,都不是为了装饰,而是一部因果链条的活字典。

打开网易新闻 查看精彩图片

把可解释性推到极致的关键,是一套反直觉的简化:所有特征都用1到10的整数表达。planning(规划力)、memory(记忆力)、risk(风险偏好)、curiosity(好奇心)、cooperation(合作性)、explorationRadius(探索半径)、toolUsage(工具使用)、reflectionFrequency(反思频率)——总共8个维度,没有小数点,没有归一化,任何一个参观者看到柱状图就能立刻读懂。而代码层面用一行clampTrait把数值死死锁在这个区间里,不是靠渲染层美化,而是在数据域里就直接确保所有下游消费者拿到的都是“合法”基因组。这个选择的妙处在于,它给突变和交叉留下了极其清爽的语义:一次突变就是某个特征值加1或减1,一眼就能看出“它变得更爱冒险了”。

遗传算子同样没有黑箱。交叉函数crossover接收双亲的基因组,逐一特征随机继承父亲或母亲的值,然后每个特征有8%的概率触发一步突变——正负方向随机。最终用clampTrait剪裁回1 – 10。这个函数不到二十行,却完整描绘了遗传、变异与约束三条最基本的进化逻辑。而在父选择阶段,决定谁能把基因传下去的逻辑被剥离出来,安静地呆在simulation包里,与渲染、记忆、反射完全解耦。这种干净的分层意味着,将来无论是换用React Three Fiber做3D场景、运行户外的无头模拟器,还是回放历史谱系,都可以直接复用同一套遗传接口。

工程上的刻意分离远不止于此。整个Agent Genome运行在一个Turborepo工作空间上,七个包各司其职:apps/web掌管Next.js界面、Canvas渲染和本地交互状态;packages/genome聚焦特征类型定义、裁剪、交叉与突变;packages/simulation负责亲代选择与子代构建;packages/core维护上限20条的基于结构的记忆记录;packages/agents存放目标词汇表;packages/langgraph接入真实的LangGraph反思工作流和提供商适配器;packages/ui只输出基因组颜色令牌;packages/shared收敛公共常量。每条边界都是为了让遗传、物理、记忆、渲染这四个维度可以独立演进,任何一个方向的重构都不会在另一个方向引发连锁灾难。

更值得留意的是,记忆和反思在这里不是概念上的点缀。每个生物体最多记录20条结构化记忆,并且有一条基于LangGraph的反思工作流在背后运行,周期性地让个体消化近期经历。参观者点开标本面板,能直接看到该个体的“近期反思”,文本长度只有一两行,却清楚交代了这个体对上一轮行动的判断——“这个区域能量密度太低,我打算向西南方探索半径扩至六格”。这瞬间把“反思”从纸上术语拉成了实时可见的行为倾向,也是整个展览告别聚合图表的底气所在。

当一代结束时,全屏转场会一口气拉出选择、继承和突变三条链的合成结果:被淘汰的个体暗下去,存活的后代带着从亲本拼贴来的基因诞生,偶尔某个特征因突变跳了一档。那一刻没有任何文字说明,但观察者差不多都会默认推导出“哦,高规划力的个体在能量密集的区域存活率更高”——而这恰恰就是项目想交付的洞察。Agent Genome不是在展示进化算法跑分,而是用一个极小的、可逐帧解剖的种群,把“演化AI”这四个字从报告里的图表拆成了可以被人类直觉直接消化的事实。