乐于分享
好东西不私藏

智能体软件工程 #8 | 从游戏引擎到 Agent 认知:ECS 架构的三次跨界

智能体软件工程 #8 | 从游戏引擎到 Agent 认知:ECS 架构的三次跨界

2026 年 3 月,估值 10 亿美元的硬件测试公司 Nominal 发布了一篇技术博文[1],回顾了他们用 Rust、Bevy 游戏引擎和 egui 构建实时桌面软件的一年历程。Connect 已部署在发射台、机场停机坪和核试验场,每秒处理 340 万数据点。


其实 Bevy ECS 我都关注好几年了,之前也写过 Bevy ecs 的相关系列文章。 上个月也用 bevy 实现了一个自己的小游戏「荒野智居」(关注我的朋友应该看见我发的截图和视频)。可以说,我对 ECS 算不上陌生。我一度以为 AI 都可以直接生成实时游戏级的世界模型了,怀疑 Bevy 这种游戏引擎还有没有未来。 但我上周看见这条 Nominal 的新闻,还是大感意外,没想到 Bevy ECS 还能用到这么硬核的场景。

于是我带着疑问写下这篇文章。从这条新闻出发,逐层拆解 Bevy ECS 的架构本质,然后追踪 ECS 可能正在发生的三次跨界,从游戏引擎到硬件测试、从硬件测试到 AI Agent 记忆系统、从记忆系统到多智能体社会模拟。最终论证一个架构观点:ECS 不只是游戏引擎的实现细节,而是复杂系统的通用组织范式

借助这篇文章的写作过程,我也构建了一本  《Bevy 之书》[2] ,适合有 Rust 语言基础的读者阅读,深入了解 Bevy ECS 架构

文章有点长,前半部分是分析 Nominal 采用 ECS 的原因; 后半部分是对于 ECS 在 AI 领域可能应用的疆域的推理。 大家可以选择性阅读

一、背景:一家独角兽公司用游戏引擎发货

Nominal[3] 的产品分两块:Core[4] 是云端数据分析平台,Connect[5] 是跑在测试现场的边缘桌面应用。

(Core 截图)

 (Connect 截图)

Connect 的官网定位很明确:"边缘计算平台,用于硬件测试"。它在边缘端实时读写仪器,从 Python 出发实现数据采集、硬件控制和可重复测试编排。

2026 年 3 月 17 日,Connect 工程师 Jasmine Schweitzer 发布了上线一年后的技术回顾,就是开头提到那篇文章。最吸引我的不是产品本身,而是技术栈:Rust + Bevy + egui一个游戏引擎驱动的硬件测试平台。

Nominal 先后完成了 Sequoia 领投的 7500 万美元 B 轮和后续 8000 万美元融资,估值 10 亿美元,客户包括美国海军(可能,没确认到)、空军、Anduril、Shield AI 和 Hermeus。Connect 在 Windows、Linux 和 macOS 三平台交付,压力测试显示每秒处理 340 万个数据点。

一个游戏引擎的架构,正在驱动真实的、有安全要求的硬件测试流程。


二、技术栈选择:每一步都有工程理由

Connet 为什么必须是桌面应用

Connect 是一个用于开发、控制和自动化测试台的边缘平台,与 Nominal Core(云端数据平台)互补。它有三个核心目标:

  1. 采集(Ingest):从硬件采集数据,本地可视化,同时上传到 Core 做进一步分析
  2. 指挥(Command):通过人类操作员或自动化测试脚本控制测试台
  3. 随行(Travel):跟随用户到任何测试环境,无需依赖中心服务器连接

团队从一开始就确定 Connect 必须是桌面应用而非 Web 应用。它必须靠近硬件、低延迟、在任何环境下可靠运行

为什么是 Rust

与 Web 端 React 一统天下不同,桌面开发没有公认的默认框架。团队考虑过的选项包括:

  • React + Electron / Tauri(JavaScript)
  • Avalonia(C#)
  • GTK(C,有 Rust 绑定)
  • Flutter(Dart)
  • egui / Dioxus / Iced(Rust)

与硬件交互和低延迟的需求,首先排除了解释型语言,它们的 C FFI 复杂、依赖垃圾回收,不适合 Connect。

在剩余选项中,Rust 最有说服力,相比 C/C++ 提供:

  • 线程安全:Connect 大量使用多线程
  • 健壮的错误处理:不能让 Connect 在昂贵的测试过程中崩溃
  • WASM 编译:为与 Core 的互操作性打开大门
  • 现代工具链和依赖管理

Connect 的三个硬约束决定了语言选择:必须在边缘硬件上实时运行(不能有 GC 停顿),必须直接与仪器交互(需要底层硬件访问能力),必须不能崩溃(测试台上的软件故障可能损坏昂贵的硬件甚至危及安全)。

Rust 的所有权系统在编译期消除数据竞争。零成本抽象意味着高级抽象不引入运行时开销。没有 GC 意味着没有不可预测的停顿。这三个特性的交集把选项缩窄到 Rust 和 C++,而 Rust 的 cargo 生态和 crate 复用能力让一个 5 人团队能维护 50 个 crate 的项目。

为什么是 Bevy

Connect 用 Bevy 不是因为需要做游戏,而是因为 Bevy 提供了五个非游戏领域罕见的架构能力:

  1. 3D 渲染,Connect 需要在 3D 空间中可视化测试台的数字孪生(URDF 模型)
  2. ECS 自动并行,数据采集、Python 脚本监控、云端同步、渲染可以由调度器自动并行
  3. 资产管线,URDF 模型的热重载、传感器配置的动态加载
  4. 插件系统,模块化架构,每个功能是一个 Bevy Plugin
  5. WASM 编译,同一套代码可以编译为桌面应用或浏览器版本

Foresight Spatial Labs 封装的统一 SDK[6] 进一步简化了基于 Bevy 的开发,提供了 Inspector 工具(widget 级耗时分析)和快速 3D 管线。让 Nominal 团队可以专注于为测试工程师打造最佳用户体验。

Foresight Spatial Labs 是 Nominal 的合作伙伴,它是一家使用 Rust 编程语言和 Bevy 游戏引擎开发 SDK 的公司,该公司专注于空间数据、感知计算和建筑应用工具。

为什么是 egui 而不是 Makepad

Dioxus + Tauri 方案虽然也是 Rust,但需要 Rust ↔ Webview 通信开销和昂贵的 DOM 更新。

egui 的即时模式渲染天然适合 Connect 的实时、持续更新的遥测和可视化仪表盘。当时它也是最成熟、经过实战检验的 Rust 原生 UI 方案,已在 Rerun[7] 中验证过。

团队没有用 egui 自带的 eframe 驱动应用,而是选择了 Bevy 游戏引擎。Bevy 负责 Connect 中所有 3D 可视化,同时带来了资产处理(Asset Handling)和通过插件系统实现的模块化等能力。

**egui 在 Connect 架构里的角色不是"UI 框架",而是"UI 渲染层"**。bevy_egui 桥梁 crate 把 egui 上下文作为 Bevy 组件挂到相机实体上,让 UI 系统作为标准的 Bevy System 运行在 ECS 调度器中。

egui 的即时模式有一个被低估的架构优势:它不拥有任何状态egui 不管理自己的事件循环、不维护 widget 树、不做自己的渲染,它只输出一堆三角形数据,让宿主决定怎么画。这意味着 Bevy 的 World 可以做唯一的状态源,Bevy 的调度器可以决定什么时候更新 UI。

因为我在用 Makepad 构建类 Flutter 但纯 Rust 的App 开发框架 Robius[8],以及 Matrix IM 的 Rust 客户端 Robrix[9]。平时也用 Makepad 构建自己日常自用的一些工具。Makepad 和 egui 一样都支持即时模式并且也支持保留模式,所以我深入考察了一下 Nominal 没有选择 Makepad 的原因。

Makepad 是 Rik Arends 创建的 Rust 原生跨平台 UI 框架,用一套代码覆盖 macOS、Windows、Linux、iOS、Android 和 WebAssembly。它不依赖 DOM、不依赖系统 UI 控件,所有 UI 元素(按钮、文字、圆角、阴影、动画)全部由 GPU shader 直接绘制。 2026 年初 Makepad 发布了 2.0 版本,引入了核心创新 Splash 脚本语言,一门运行时 UI 脚本,支持热重载和 AI 流式生成,和 Rust 无缝交互。 感兴趣可以查阅 Makepad 2.0 之书[10]  和 makepad 2.0 skills[11] 。

Makepad 与 egui 截然不同的点在于,它是一个自带完整应用框架的独立生态系统,有自己的跨平台运行时、事件循环、保留模式渲染架构。它的每一个优势,shader 样式、live design、保留模式渲染,都来自它对整个栈的垂直整合控制。这恰恰是它难以嵌入 Bevy 的原因。

Makepad 是更好的独立 UI 框架,但 egui 是更好的嵌入式 UI 层。 Connect 的架构选择是"Bevy 做骨架、egui 做皮肤"。在这个前提下,egui 的"无状态、无事件循环、只输出几何"的特性反而成了它最大的竞争优势。Nominal Connect 用 egui 做遥测面板和控制界面这个场景中,egui 则完全消失在 Bevy 的架构里

下面是 Makepad 和 egui 简单的对比:

在不需要 3D 渲染但需要精美 2D 交互画布的场景中(如多智能体可视化),Makepad 做骨架、bevy_ecs 做内脏同样可行。bevy_ecs 可以独立于 Bevy 游戏引擎使用,只引入 ECS 核心不带渲染。Makepad 拥有事件循环和 GPU 渲染,bevy_ecs 作为纯数据+逻辑库被 Makepad 每帧调用。两者各自做自己擅长的事,不争抢事件循环。

关于 Makepad 和 egui 的详细介绍和对比,我会另起一篇文章,本文暂且不表。总之,对于 Nominal 的场景更适合 egui 。

使用 Rust 的代价

Nominal 官方博文中也坦诚了使用 Rust 的代价:

编译时间长。 50 个 crate 的拆分和快速链接器有所帮助,但不够。团队正在升级到 Bevy 0.17 以获得 Subsecond 代码热重载。亚秒级的补丁周期将把"改代码→看效果"的循环从分钟级降到即时反馈。

空闲 CPU 占用。 即时模式每帧重绘 UI,空闲时也不停。解决方案是自研线程安全的 waker API,默认使用 UpdateMode::Reactive,有新数据或动画时切回连续更新。

跨平台分发的苦。 Linux 的 libc 兼容性、Windows 的显卡驱动 Bug、macOS 不用 Xcode 嵌入图标需要"未文档化的魔法"、WebGPU 尚未全面普及。

题外话: Subsecond 代码热重载

Dioxus 实现的 Subsecond 是目前 Rust 生态中最具突破性的热重载方案。它通过跳转表函数指针重定向机制实现了亚秒级的代码热补丁周期(官方文档声明在 dev 优化 profile 下增量构建可缩至 500 毫秒以内),而非传统的动态库重载或二进制内存修改。

由 Jonathan Kelley(jkelleyrtp)领导的 Dioxus Labs 团队开发,subsecond 于 2025 年 3 月首次发布,10 月随 Dioxus 0.7 正式稳定,并已被 Bevy 0.17 和 Iced 等主流框架集成。它的核心创新在于:不修改进程内存、不需要 #[no_mangle] 标注、不需要将代码拆分为独立动态库,仅需在调用点包裹 subsecond::call() 即可实现函数级热替换。

据我所知,2021 年华为就开始探索如何给 Rust 应用增加热补丁,但是当时基础条件都不成熟。

比如, Rust 增量编译不可靠,偶有正确性 bug;name mangling 的 v0 scheme 未稳定;ld 慢,lld 有 bug;Android memfd 不可用;libloading 0.5(有 bug)等等。

当时做 Rust 热补丁的选择只有三条路:#[no_mangle] + dlopen/dlclose(泛型不兼容、TypeId 断裂)、指令级替换(在函数入口写 jmp 指令,极度不安全)、或进程重启(cargo watch)。但单独看这三条路都不靠谱。

到 2025 年条件成熟了,Subsecond 把这三条路合并为一条:跳转表提供了 dlopen 的安全性 + 指令替换的透明度 + 不需要重启的状态保持。

关于 Subsecond 的细节,我们还是需要另外一篇文章再讲,当然你感兴趣的话,也可以问 AI 。


三、深入拆解 Bevy ECS:六层架构

想深入了解 Bevy ,可以看看我这本 Bevy 之书[12] 。

理解 ECS 为什么能跨界,需要理解它不只是一个"设计模式",而是一套完整的运行时架构

什么是 ECS ?

ECS 的心智模型可以用一句话打底:不要问"这个东西是什么类型",要问"这个东西有哪些属性"。下面用四张图拆解。

三要素的角色分工。 Entity 是一个空盒子,只有一个 ID,没有数据、没有行为、没有类型。Component 是贴在盒子上的标签,纯数据,没有逻辑。Position(x, y) 是一个 Component,Health(100) 是一个 Component,CanFly 也可以是一个 Component。System 是一条流水线,它声明"我要处理所有同时贴了 Position 和 Velocity 标签的盒子",调度器自动把匹配的 Entity 送过来。Entity "是什么"完全由它身上贴了哪些标签决定,而且标签可以随时增减。

组合 vs 继承的根本差异。 OOP 中 FlyingFish 要同时继承 Bird 的飞行能力和 Fish 的游泳能力,这就是著名的菱形继承问题。ECS 中,FlyingFish 只是一个同时贴了 CanFly 和 CanSwim 两个标签的 Entity,不需要任何继承关系。想给 Penguin 加上"会飞"?运行时附加 CanFly 组件,不改任何代码。OOP 中你是什么类型 → 继承决定能力 → 类型爆炸;ECS 中你有什么组件 → 组合决定能力 → 自由搭配。这不是理论优雅,Dungeon Siege 有 7,300 种对象类型,用继承树管理是不可能的。

查询匹配:声明式而非命令式。 System 不遍历全部对象、不做类型判断——它声明需要哪些 Component,调度器自动把匹配的 Entity 送过来。move_system 声明需要 Position + Velocity,调度器扫描所有 Archetype,Entity 0/1/3 匹配(同时拥有两者)→ 被选中,Entity 2/4 缺少 Velocity → 跳过。整个过程没有任何 if x instanceof Player 的类型判断。

自动并行:数据需求即并行依据。 调度器是工头——它查看每个 System 的读写声明,自动决定哪些可以同时开工。move_system(读 Pos,写 Vel)、health_system(读写 Health)、render_system(读 Pos,读 Sprite)三者读写不冲突,直接在三个 CPU 核心上并行执行。这种自动并行在 OOP 中几乎不可能——player.update() 可能修改对象上的任何字段,编译器无法判断两个 update() 是否冲突。

一句话总结:数据(Component)和逻辑(System)完全分离,通过声明式查询连接,由调度器自动编排。这就是 ECS 和 OOP 的根本区别。


下面按 Bevy ECS 的六个架构层次逐层拆解。每一层都是前一层的运行时支撑,前三层是"数据如何存储",后三层是"行为如何执行"。

"组合优于继承"这个教科书答案并不是 Bevy 选择 ECS 的全部理由。更深层的动机在于数据布局对性能的决定性影响。OOP 中对象的字段在内存中是"行式"排列的。一个 GameObject 的 Transform、Renderer、Collider、Health 紧挨着存储。当你的系统只需要遍历所有 Position 时,CPU 缓存被 Renderer 和Collider 等无关字段"污染"了,每次 cache line 加载都浪费了大量带宽。ECS 的列式存储(SoA)将同类型组件紧密排列,遍历时的缓存命中率可以达到接近 100%。这不是理论上的微优化。在有数万实体的场景中,SoA 布局相比 AoS(行式)可以带来 5-10 倍的遍历性能差异。此外,OOP 的继承层级使得"这个对象到底拥有哪些能力"在编译期难以穷举,这让自动并行变得几乎不可能。ECS 将每个 System 的数据需求显式编码为 Query 类型签名,调度器可以在初始化时就构建完整的数据访问依赖图,从而安全地并行执行互不冲突的 System。              --- 来自 《Bevy 之书》。 

更多内容阅读:https://zhanghandong.github.io/bevy-book/

第一层:四个核心类型(bevy_ecs::world

World 是一切的容器,持有所有 Entity、Component、Archetype、Storage、Observer 和延迟命令队列。整个应用的状态住在一个 World 里。

Entity 是一个 8 字节的值类型,内部分为 index(定位存储位置)和 generation(版本计数器)两个 32 位字段。当一个 Entity 被销毁、其 index 被新 Entity 复用时,generation 递增,如果你持有一个旧 Entity 句柄但它已被销毁并回收,generation 不匹配会让访问立即失败而非返回错误数据,从而检测 use-after-free。

Component 是纯数据,必须满足 Send + Sync + 'static。每个 Component 声明自己的 StorageType(Table 或 SparseSet),这个选择直接影响性能特征。

System 是一个普通 Rust 函数,签名如 fn(Query, Res, Commands, Local),它可以查询 Component(Query)、读取全局资源(Res)、发出延迟指令(Commands)、持有本地状态(Local)。Bevy 通过 trait 系统自动将函数签名转换为数据依赖声明,系统之间不直接调用,由调度器自动并行执行。这是 Bevy 最独特的 Rust 魔法,详见《Bevy 之书》第 8 章

第二层:双层存储系统(bevy_ecs::storage

Bevy 提供两种截然不同的存储后端,让开发者按场景选择:

Table Storage(默认) 是列式 SoA 布局。拥有相同 Component 组合的 Entity 被分组到同一张表中,每种 Component 的数据在内存中连续存放。当一个 System 遍历所有 Velocity 组件时,CPU 缓存行只加载速度数据,不会被其他 Component 污染,缓存友好,迭代极快。代价是插入/移除较慢。

SparseSet Storage 是 sparse→dense 双数组结构,提供 O(1) 的插入和移除,不需要移动任何其他数据。代价是缓存友好性较差。

这不是抽象的,它直接映射到 Connect 的使用场景。对于每帧都要遍历的传感器数据(温度读数、采样率),Table Storage 的列式布局确保了高效批量迭代。而对于频繁动态变化的标记性组件("当前正在运行的测试脚本"、"告警状态"),SparseSet 的 O(1) 增删避免了频繁的 Archetype 迁移。双存储的选择指南详见《Bevy 之书》第 5 章。

SoA 内存布局展开

理解 ECS 的性能基础,需要理解 AoS 和 SoA 的区别。

现代 CPU 读内存以缓存行为单位(64 字节)。AoS(Array of Structures)是传统的面向对象布局——每个对象的所有字段放在一起。当一个 System 只需要读 position 字段时,CPU 加载一个缓存行(64 bytes),里面包含 position、health、name、padding,但你只用其中的 position。1000 个对象的 position 遍历,缓存利用率可能只有 18%,81% 的缓存带宽被浪费。

SoA(Structure of Arrays)翻转了存储方式,所有对象的同一字段放在一起。1000 个 position 在内存中紧挨着,CPU 加载一个缓存行全是 position,零浪费。同样的硬件、同样的数据量,SoA 比 AoS 快 3-10 倍。

Bevy 用 Archetype 存储 = SoA + 按 Component 组合分组。这是 Connect 能"无需大量优化"就达到 340 万数据点/秒的物理基础。

第三层:Archetype 图(bevy_ecs::archetype

拥有完全相同 Component 组合的所有 Entity 构成一个 Archetype。Archetype 之间通过添加/移除 Component 的关系形成有向图:

Empty → [Transform] → [Transform, Velocity] → [Transform, Velocity, Health]

当你给一个只有 Transform 的 Entity 添加 Velocity 时,它从 [Transform] Archetype 迁移到 [Transform, Velocity] Archetype——涉及数据从一个 Table 拷贝到另一个 Table。Bevy 缓存这些迁移路径(Edges),使得重复发生的 Archetype 转换接近免费(O(1) 查表)。详见《Bevy 之书》第 6 章。

第四层:System 数据流(bevy_ecs::query

以 fn move_sys(q: Query<(&Pos, &mut Vel)>) 为例,一次 Query 执行触发四步数据流:

  1. QueryState 匹配:扫描所有 Archetype,找到同时包含 Pos 和 Vel 的那些,缓存匹配结果。&Pos 是只读、&mut Vel 是可写——这决定调度器是否允许它与其他 System 并行
  2. Table Columns 访问:按 ComponentId 索引到 Table 对应的列,批量读取数据
  3. 类型化引用:从原始字节数组中产出类型安全的 Rust 引用
  4. 变更追踪:每次通过 &mut 访问时,Bevy 自动标记该 Component 为"已变更"

这套机制让 Changed<T> 和 Added<T> 过滤器以 O(1) 成本检测变化,详见《Bevy 之书》第 7、10 章。

第五层:调度执行(bevy_ecs::schedule

调度器是让应用能自动并行化的核心机制,包含三个子系统:

Schedule(DAG 调度)。 根据所有 System 的数据访问声明构建依赖图,检查访问冲突,在无冲突的 System 之间并行执行,在帧末应用延迟命令。Bevy 本质上把 Rust 编译期的借用规则(&T 可共享、&mut T 必独占)映射到了运行时的调度器。

Change Detection(变更检测)。 全局 tick 计数器配合每个 Component 实例的 tick 时间戳,实现零成本的变更追踪。对 Connect 的 UI 非常重要——遥测图表只在数据实际变化时重绘。

Events & Observers。 三种通信模型各司其职:Events 是推送式的立即事件,Messages 是拉取式的缓冲队列,Observers 是实体作用域的响应器,通过 Hooks(on_insert/on_remove)在 Component 增删时自动触发。

第六层:模块全景

Bevy ECS 的核心由这些模块构成:worldentitycomponentarchetypestoragequerysystemscheduleeventobserverresourcebundlerelationshipchange_detection。其中 bundle 是 Component 的组合模板,让你一次性给 Entity 附加一组相关的 Component;relationship 在 2024 年引入,支持定义任意双向实体关系(父子只是其中一种)。

完整的模块架构与设计哲学,详见《Bevy 之书》全书


四、Subsecond 热补丁:ECS 天然适配运行时代码替换

Connect 博文提到的"升级到 Bevy 0.17 以获得 Subsecond 代码热重载",背后是一个值得展开的技术突破。

问题:Rust 编译慢是游戏开发的致命伤

游戏开发有独特的工作模式——"改一行→看一眼→再改一行"的紧密视觉反馈循环。Unity/Unreal 的开发者习惯了秒级反馈。Bevy 的增量编译要 5-15 秒,这是与 Unity/Unreal/Godot 竞争时的根本性体验劣势。

Subsecond 的核心机制:跳转表函数指针重定向

Subsecond(由 Dioxus Labs 的 Jonathan Kelley 团队开发)的核心设计是:所有函数调用通过一张可原子更新的跳转表间接派发。与 C++ 的 Live++ 直接修改进程内存中的机器码不同,Subsecond 明确声明"不修改进程内存"。

跳转表本质是 HashMap<u64, u64>——键为旧函数地址,值为新函数地址。使用方式极简:

subsecond::call(|| {// 这里的代码可以在运行时被替换});

配套的 ThinLink 自定义链接器在首次构建时将所有依赖打包为"胖依赖"动态库,后续增量构建仅处理顶层 crate 中变化的代码生成单元。Subsecond 官方文档声明,在 dev 优化 profile 下 ThinLink 可将增量构建缩短到 500 毫秒以内;Dioxus 团队在 Apple M4 上对 Bevy 应用的演示更达到了亚秒级的编译-链接-补丁全链路体验。

跳转表机制极其通用

跳转表间接派发是计算机科学中最古老的模式之一。C++ 的 vtable、操作系统动态链接器的 PLT/GOT、WebAssembly 的间接函数表、JVM 的 JIT 编译入口替换、Erlang BEAM 的模块版本切换、Linux 的 syscall table,本质上都是"查表再跳转"的变体。

Subsecond 的创新不在于发明跳转表,而在于解决了 Rust 特有的工程难题:不稳定 ABI 下的符号追踪、ASLR 地址随机化的绕过(通过 dlsym 查找 main 符号作为锚点计算偏移)、以及闭包带捕获状态的特殊派发路径,ZST 闭包(无捕获)直接作为函数指针走跳转表,带捕获的闭包则通过 trait 对象的 call_it 方法间接派发。当前的一个重要限制是不支持跨 crate 追踪:Subsecond 只补丁"tip" crate(即 main.rs 所在的 crate),因为 rustc 的构建图在跨 crate 泛型转发时是非确定性的。

ECS 让热补丁从"危险的 hack"变成"架构支持的特性"

这是 Bevy 引入 Subsecond 的深层原因,不是所有程序都能轻松引入热补丁,但 ECS 架构的程序天然适合:

System 是纯函数。 签名声明了所有数据依赖,函数本身不持有状态。替换 System 的函数体不会破坏任何状态,新函数读取同样的 Component 数据,产出同样类型的结果。

数据和逻辑分离。 数据全在 World 中(Component + Resource),逻辑全在 System 中。热补丁替换的是 System 函数指针,纯逻辑。World 中的数据完全不受影响。

调度器提供自然的同步点。 热补丁生效的时机是"下一帧调度器选择跑这个 System 时",不需要额外的同步机制。调度器本身就是安全的替换时机。

当前限制:仅限顶层二进制 crate、System 参数签名不能变、struct 定义不能变、WASM 需要 Bevy 侧适配。这些限制在实际开发中不那么痛苦,ECS 开发者改的最多的就是 System 函数体内的逻辑,而这恰好是 Subsecond 完美支持的范围。

历史对比:2020 年的 Rust 热补丁只能走指令级替换

2020 年做 Rust 热补丁,选择只有三条路:#[no_mangle] + dlopen/dlclose(泛型不兼容、TypeId 断裂)、指令级替换(直接在函数入口写 jmp 指令,极度不安全)、或进程重启(cargo watch)。

Subsecond 能在 2025 年实现,不依赖 Rust 的任何特定 edition——它依赖的是 2022-2025 年间多项基础设施的成熟:rustc 增量编译的正确性修复、v0 name mangling 方案的稳定化、mold 链接器的发布、proc-macro 生态的成熟、Android memfd 和 WASM Table.grow 的平台可用性。


五、ECS vs SoA/列存:本质区别

一个常见的评价是:"ECS 本质就是列存/SoA,换汤不换药"。这有一个正确的内核,但犯了以偏概全的错误

它们解决的问题在不同层次

列式存储(ClickHouse、DuckDB、Parquet)解决的是:怎么高效地存取同类数据。关注点是 I/O 效率、压缩比、分析型查询性能。

ECS 解决的是:怎么组织一个由大量异构实体组成的复杂系统,让实体可以动态获得和失去能力、让行为可以按数据依赖自动并行、让变更可以被高效追踪。

SoA 内存布局只是 ECS 架构六层中最底层的存储策略。上面还有 Archetype 分组(按组件组合自动分表)、System 签名驱动的并行调度、O(1) 变更检测、Entity 关系模型、Schedule DAG 执行。

更准确的类比

ECS 更像是 响应式运行时 + 内存列存 + 自动并行调度器 的三合一体。说"ECS 本质是列存",就像说"Kubernetes 本质是个 cgroup 管理器",技术上不错,但你用裸 cgroup 编排不了微服务。

Nominal 选 Bevy 不是因为它把数据排成列,而是因为 ECS 的 World / Entity / Component / System / Schedule 五元组给了一个复杂实时桌面应用一个天然并行、类型安全、可模块化组合的架构骨架。


六、Nominal 的性能来自哪里

Connect 博文强调"无需大量优化"就达到每秒 340 万数据点。但这个性能不是 Bevy ECS 单独提供的,需要分层理解:

Rust 语言本身(~60%)。 零成本抽象、无 GC、编译期内存管理、多线程无 GIL。如果用传统 OOP 架构但仍用 Rust,性能可能只慢 20-30%。

Bevy ECS 的 SoA 存储(~15%)。 批量遍历传感器数据时的缓存命中率接近 100%,这在"每秒 340 万数据点"的场景下是显著的。

调度器的自动并行(~10%)。 数据采集和渲染管线并发执行,工程师不需要手写线程池。

Connect 团队自研优化(~10%)。 Reactive 渲染模式、线程安全的 waker API、按需更新。

Foresight SDK 封装(~5%)。 Widget 级性能分析、优化的 egui 抽象。

核心观点是:**Bevy ECS 提供了性能的"地板"**,你不需要做任何优化就能达到一个相当高的基准线。在 Python 中你的性能"地板"可能是每秒几万个数据点,需要用 numpy、cython、多进程一步步优化。在 Rust + Bevy ECS 中,"地板"直接在百万级,SoA 存储和并行调度是架构送的礼物,不是工程师一行一行调出来的。


七、ECS 可能的下一个疆域:AI Agent 记忆系统

Nominal Connect 证明了 ECS 在游戏之外的工程价值。但这个架构的适用范围可能远比硬件测试更广,它的下一个疆域,很可能是 AI Agent 的记忆系统

一个正在发生但无人命名的收敛

调研发现一个惊人的现象:主流 AI Agent 记忆系统正在独立地重新发明 ECS 模式,但没有人叫它 ECS。

Stanford 的 Generative Agents(Smallville)将记忆存储为带有时间戳、重要性、嵌入和内容的条目,通过多因素查询(近因性 × 重要性 × 相关性)检索——这就是带 Component 的 Entity 被 System 查询。Mem0 通过 CRUD 操作管理带有元数据的记忆实体。A-MEM 创建带有动态演化属性和链接关系的笔记实体。MemGPT/Letta 从命名的记忆块组合 Agent——本质上就是 Component。

这些系统都在做 ECS 做的事,但因为没有识别出这个模式,它们错失了数据导向设计带来的性能优势和架构清晰度。

经典认知架构早已是"隐性 ECS"

更深层的结构平行来自认知科学。对 ACT-R、SOAR、OpenCog 三大经典认知架构的分析揭示了它们与 ECS 的精确映射:

ECS 概念
认知架构等价物
Entity(唯一 ID)
记忆元素标识符(ACT-R chunk、OpenCog Atom)
Component(类型化数据)
类型化元数据:激活值、时间戳、重要性分数、嵌入
System(行为)
处理模块:检索机制、学习算法、决策循环
Archetype(组件分组)
记忆类型:声明性 chunk、情景痕迹、程序性规则
Query(组件过滤)
基于线索的检索、激活扩散、嵌入相似度搜索

OpenCog 的 AtomSpace 是最接近的匹配,Atom 充当实体,Value 充当组件,MindAgent 充当系统。ACT-R 的 chunk 清晰地映射到 ECS 组件,类型化数据容器携带隐藏的激活元数据。SOAR 将数据(多种记忆模块)与处理(决策周期)分离的方式直接平行于 ECS 的组件/系统分离。

游戏 AI 模式正在跨界

行为树已经通过 Dendron(2024)和 PORTAL(2025)正式跨入 LLM Agent 领域。黑板架构——游戏 AI 中用于多 Agent 协调的经典共享记忆模式,通过 LbMAS(2025)复活用于 LLM 多 Agent 系统。

黑板架构值得展开说明。它和 ECS 有深层的结构相似性。黑板架构的核心是:一群独立的"知识源"(专家模块)围绕一块共享的"黑板"(数据结构)协作。每个知识源只看黑板、判断自己能否贡献、写下分析、退后。没有中央控制器编排流程,问题的解决通过共享状态上的渐进注解涌现。

映射到 ECS:黑板就是 World,知识源就是 System,控制器就是 Schedule。区别在于 ECS 走得更远——黑板是一整块共享状态,ECS 将数据拆散为 Component,让调度器根据读写声明自动并行。在 Bevy 生态中,bevy_dogoap(目标导向行动规划)展示了一个关键洞察:在 ECS 中,World 本身就是黑板,不需要单独维护。

ECS 用于 Agent 记忆的六个理论优势

动态记忆组合。 当前系统强制在固定记忆类型之间选择。ECS 中,Agent 实体可以运行时动态获得或失去记忆组件,导航时添加 SpatialMemory,社交时附加 EmotionalContext,被反驳时移除陈旧的 BeliefComponent。新增记忆类型不需要修改任何现有代码,只需定义新的 Marker Component。

查询驱动检索。 现代 Agent 记忆通过不同 API 查询向量存储、知识图谱和对话历史。ECS 提供单一查询接口:选择所有同时拥有 (EpisodicComponent AND EmotionalValence > 0.5 AND Timestamp > last_hour) 的记忆实体。

并行处理。 记忆整合、相关性评分、过期检测和检索都可以作为独立 System 自动并行化。Madrona(SIGGRAPH 2023,斯坦福/NVIDIA)证明 ECS 可以在 GPU 上处理数百万 Agent 实体。

Archetype 存储。 检索情景记忆时,ECS 遍历连续的组件数组,没有指针追逐,没有缓存未命中。对百万级记忆的 Agent 系统,这是质的差异。

变更检测。 Bevy ECS 原生追踪组件的最后修改时间。应用到记忆上,系统可以高效识别哪些记忆过期、哪些知识需要重新验证,无需维护单独的时间戳或版本计数器。这直接映射到认知科学中的"记忆衰减"和"巩固"机制。

实体关系。 特别是 Flecs 的关系模型,允许 (Knows, fact_entity)(Contradicts, other_memory_entity) 等关系直接嵌入 ECS——将向量存储 + 知识图谱的常见双系统模式折叠为单一数据模型。

研究空白确实存在

2025 年的综述"Rethinking Memory in AI"没有提及 ECS。arxiv 上没有论文分析 ECS Archetype 存储用于知识表示。Reddit 社区几乎没有相关讨论。目前唯一完全采用 ECS 的 AI Agent 框架是 ArgOS(基于 BitECS 的 TypeScript 实验框架,33 GitHub stars)。这是一个被学术界和工业界同时忽视的交叉领域。


八、Concordia v2:DeepMind 对"游戏引擎架构 + Agent"的学术验证

核心论点:把多 Agent AI 当桌游引擎来做

2025 年 7 月,Google DeepMind 发表论文"Multi-Actor Generative Artificial Intelligence as a Game Engine"(arXiv:2507.08892),这是 Concordia v2.0 的官方技术报告。核心论点:构建多角色生成式 AI 系统的正确方式是把它们当作桌面角色扮演游戏(TTRPG),Game Master 负责叙述世界和裁决行动,玩家控制角色,底层用 Entity-Component 架构组织一切。

Entity-Component 在 Concordia 中的实现

Concordia 采用 EC(Entity-Component)而非完整的 ECS,组件既持有数据也包含行为(Python 代码 + LLM 调用),"System"角色由 Engine(模拟循环)承担。

实体可以代表个体 Agent、集体行动者(公司、政府),甚至 Game Master 本身,所有实体类型共享相同结构基础,仅通过组件组合区分。这意味着所有模块化和可组合性同时适用于 Agent 和环境模拟。

组件在行动阶段扮演两种角色:上下文组件(多个,并行处理,SelfReflection、Beliefs、SocialNorms、Memory 等)聚合形成全面的上下文画面;行动组件(恰好一个)综合一切产出唯一行动。

论文还引入了一个来自桌游设计理论的三类用户动机分类法:评估主义者(受控基准测试)、戏剧主义者(涌现叙事)、模拟主义者(因果一致的社会动态建模)。一个场景应该针对其中一种优化,而非试图同时服务三者——这条原则直接借自数十年的游戏设计智慧。

最重要的架构决策:GM 统一为实体

v2 最具意义的变化是将 Game Master 与实体系统统一。GM 的行为完全通过组件选择定制:戏剧主义场景装叙事导演组件,评估主义场景装协议执行组件。GM 可以被给予完全的创造自由,也可以约束为硬编码护栏,在同一个组件系统内结合程序化逻辑和生成式 LLM 能力。

与其他框架的本质差异

CAMEL、AutoGen、CrewAI 都是任务完成框架,不建模持久环境、不支持空间或社会落地。Concordia 是世界模拟框架——唯一将环境模拟作为与 Agent 认知同等重要的一等关注点的主要框架。

验证了概念,但留下了性能空白

Concordia 用 Python 实现 EC,没有 Archetype 存储、没有自动并行调度(Python GIL)、没有 Change Detection。GitHub 1200+ stars,支持 GPT-4o/5、Gemini、Mistral 等后端。

这给下一步留下了明确方向:如果 Concordia 的 EC 模式已验证了组合式 Agent 架构,那么用真正的高性能 ECS(如 bevy_ecs)重新实现记忆和认知系统,能释放多少性能红利?


九、用 Bevy ECS 构建多智能体模拟引擎

MiroFish 类项目:ECS 的天然应用场景

以 MiroFish 这类多智能体预测引擎为例,数千个有独立人格、记忆和行为逻辑的 Agent 在虚拟社交平台上互动,通过群体涌现产生预测结果。这在结构上就是一个典型的 ECS 应用场景:大量异构实体、每个实体有不同的组件组合、多个系统并行处理、需要高效的批量迭代。

Agent 通过 Component 组合定义,不用类继承

金融分析师 Agent = AgentMarker + Identity + Personality(Big Five)                   + Stance(-0.6) + EmotionalState + Memory                   + SocialGraph + FinancialExpertise + InfluencerStatus散户投资者 Agent = AgentMarker + Identity + Personality(Big Five)                   + Stance(0.2) + EmotionalState + Memory                   + SocialGraph"既懂金融又有政治倾向"的复合 Agent:  直接附加 FinancialExpertise + PoliticalOrientation 两个 Component  不需要多重继承

这就是 ECS 的核心价值,Agent 类型的差异不是"不同的类",而是"不同的 Component 组合"。

12 个 System 的模拟循环

每 tick 执行:event_injection → clock_advance → perception + social_influence + emotion_decay(自动并行)→ decision → action_execution → memory_update + viral_propagation + metrics(自动并行)→ snapshot → termination_check

调度器根据 System 的读写声明自动构建 DAG:perception 写 Memory 和 EmotionalState,social_influence 写 Stance 和 Beliefs,emotion_decay 只写 EmotionalState,三者读写不冲突,自动并行。工程师不需要手写线程池。

双模式决策:规则默认,LLM 可选

规则模式(默认,零 LLM 成本): Agent 的决策基于 Personality、Stance、EmotionalState 的数值计算。高外向性 + 情绪激动 + 强立场 → 高概率发言。这足以验证"群体涌现"。

LLM 模式(按需启用): 给特定 Agent 附加 LlmBacked Component。决策 System 检测到 LlmBacked 时,将 Agent 状态打包为 prompt 发给 LLM。异步处理,发送时附加 AwaitingLlmResponse Component,当前 tick 跳过,下一 tick 收到响应后行动。

这让 1000 Agent 的模拟从"几十元+几分钟"变成"零成本+几秒钟"。少数 KOL Agent 用 LLM 生成高质量发言,其余靠规则跑。

World 即记忆:不需要外部数据库

传统方案(如原版 MiroFish)用 Zep GraphRAG 存知识图谱,Agent 状态在 Python 内存中。查询"所有持看空立场且在最近 5 轮中发过言的金融类 Agent"需要跨两个存储系统。

ECS 中一切都在 World 里,Agent 状态是 Component,关系是 Entity Relations,知识图谱是 Entity + 关系查询。统一的 Query 接口覆盖所有查询需求。这也回应了前面提到的黑板架构,在 ECS 中,World 本身就是黑板,不需要单独维护

Makepad Canvas + bevy_ecs:可视化的交互式模拟

如果要给这个模拟引擎加上可视化,角色头像分布在画布上(位置反映社交亲疏),关系用连线表示,消息气泡弹出,情绪用颜色光晕表达,Makepad Canvas 是自然的选择。

架构关系反转:Makepad 做骨架(拥有事件循环和 GPU 渲染),bevy_ecs 做内脏(纯数据+逻辑库被调用)。与 Nominal Connect 的"Bevy 做骨架、egui 做皮肤"是镜像关系。

维度
Nominal Connect
多智能体模拟
骨架(拥有事件循环)
Bevy 游戏引擎
Makepad UI 框架
皮肤/内脏(被嵌入)
egui(UI 渲染层)
bevy_ecs(数据+逻辑层)
为什么能被嵌入
egui 不拥有状态/渲染
bevy_ecs 不拥有窗口/渲染
适合场景
3D + 实时数据流
精美 2D UI + 交互画布

这套架构远不止多智能体预测,任何"一群有不同动机的角色在共享世界中互动,产出涌现行为"的问题都是目标场景:互动小说引擎、剧本杀辅助、世界观构建、舆情推演、政策沙盘、谈判训练、博弈论可视化、AI 驱动的经营模拟。


十、结语:从游戏引擎到 Agent 认知的架构统一

这篇文章从 Nominal Connect 的一条技术新闻出发,走了一条出人意料的长路。

第一段路是工程实践,Nominal 证明了 Rust + Bevy ECS + egui 可以交付生产级桌面应用。Rust 解决了"不能崩溃"的硬约束,egui 的"薄"让它消失在 Bevy 架构里,Bevy 的 ECS 提供了自动并行 + 资产管理 + 插件模块化的基座,Subsecond 热补丁让迭代速度追平解释型语言。

第二段路是架构深潜,Bevy ECS 的六层架构远不止"把数据排成列"。Entity 的 generation 防 use-after-free,双层存储同时优化批量遍历和高频增删,DAG 调度器从函数签名自动推断并行策略,Change Detection 让"什么变了"成为 O(1) 操作。这些机制叠加产生了 Connect 的性能"地板"——不需要优化就达到高基准线。

第三段路是跨界发现,ECS 的特性精确映射到 AI Agent 记忆系统的核心需求。DeepMind 的 Concordia v2 从学术方向验证了 Entity-Component 模式对 Agent 认知有效,但停在了 Python EC 层面。多智能体模拟引擎的架构设计则展示了完整 ECS(含自动并行、Archetype 存储、Change Detection)对社会模拟的实际价值——规则模式零 LLM 成本、调度器自动并行、World 即记忆无需外部数据库。

三段路汇聚到一个结论:ECS 不只是游戏引擎的实现细节,而是一种通用的复杂系统组织范式,用组合替代继承、用声明式查询替代手动遍历、用自动调度替代手动线程管理。它在硬件测试(Nominal)、社会模拟(Concordia/MiroFish 类项目)和 Agent 记忆三个截然不同的领域展示了相同的架构价值。

Nominal 的 10 亿美元估值证明了这个范式在工程上可行。Concordia 的 NeurIPS 论文证明了它在学术上有效。缺失的是将两者结合的正式工作,用 bevy_ecs 的完整数据导向设计重新实现 Concordia 验证过的 Agent 认知模式。

谁先完成这个组装,谁就占据了下一代 AI Agent 架构的制高点。

参考资料
[1] 

Nominal 发布了一篇技术博文: https://nominal.io/blog/nominal-connect-shipping-realtime-desktop-software-with-rust-bevy-and-egui

[2] 

《Bevy 之书》: https://zhanghandong.github.io/bevy-book/

[3] 

Nominal: https://nominal.io/

[4] 

Core: https://nominal.io/products/core

[5] 

Connect: https://nominal.io/products/connect

[6] 

Foresight Spatial Labs 封装的统一 SDK: https://github.com/fslabs

[7] 

Rerun: https://rerun.io/

[8] 

Robius: https://robrix.app/

[9] 

Robrix: https://robrix.app/

[10] 

Makepad 2.0 之书: https://zhanghandong.github.io/makepad-2.0-book/

[11] 

makepad 2.0 skills: https://github.com/ZhangHanDong/makepad-skills

[12] 

Bevy 之书: https://zhanghandong.github.io/bevy-book/

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-04-10 09:20:34 HTTP/1.1 GET : https://www.yeyulingfeng.com/a/508711.html
  2. 运行时间 : 0.240690s [ 吞吐率:4.15req/s ] 内存消耗:4,886.25kb 文件加载:145
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=9a6b4f0313d0818dea7611d5d6290cfa
  1. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_static.php ( 6.05 KB )
  7. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/ralouphie/getallheaders/src/getallheaders.php ( 1.60 KB )
  10. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  11. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  12. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  13. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  14. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  15. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  16. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  17. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  18. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  19. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions_include.php ( 0.16 KB )
  21. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions.php ( 5.54 KB )
  22. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  23. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  24. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  25. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/provider.php ( 0.19 KB )
  26. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  27. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  28. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  29. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/common.php ( 0.03 KB )
  30. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  32. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/alipay.php ( 3.59 KB )
  33. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  34. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/app.php ( 0.95 KB )
  35. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cache.php ( 0.78 KB )
  36. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/console.php ( 0.23 KB )
  37. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cookie.php ( 0.56 KB )
  38. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/database.php ( 2.48 KB )
  39. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/filesystem.php ( 0.61 KB )
  40. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/lang.php ( 0.91 KB )
  41. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/log.php ( 1.35 KB )
  42. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/middleware.php ( 0.19 KB )
  43. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/route.php ( 1.89 KB )
  44. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/session.php ( 0.57 KB )
  45. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/trace.php ( 0.34 KB )
  46. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/view.php ( 0.82 KB )
  47. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/event.php ( 0.25 KB )
  48. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  49. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/service.php ( 0.13 KB )
  50. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/AppService.php ( 0.26 KB )
  51. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  52. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  53. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  54. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  55. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  56. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/services.php ( 0.14 KB )
  57. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  58. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  59. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  60. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  61. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  62. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  63. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  64. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  65. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  66. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  67. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  68. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  69. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  70. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  71. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  72. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  73. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  74. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  75. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  76. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  77. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  78. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  79. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  80. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  81. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  82. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  83. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  84. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  85. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  86. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  87. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/Request.php ( 0.09 KB )
  88. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  89. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/middleware.php ( 0.25 KB )
  90. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  91. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  92. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  93. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  94. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  95. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  96. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  97. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  98. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  99. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  100. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  101. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  102. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  103. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/route/app.php ( 3.94 KB )
  104. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  105. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  106. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Index.php ( 9.87 KB )
  108. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/BaseController.php ( 2.05 KB )
  109. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  110. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  111. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  112. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  113. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  114. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  115. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  116. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  117. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  118. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  119. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  120. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  121. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  122. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  123. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  124. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  125. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  126. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  127. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  128. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  129. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  130. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  131. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  132. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  133. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  134. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  135. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Es.php ( 3.30 KB )
  136. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  137. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  138. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  139. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  140. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  141. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  142. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  143. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  144. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/runtime/temp/c935550e3e8a3a4c27dd94e439343fdf.php ( 31.80 KB )
  145. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000972s ] mysql:host=127.0.0.1;port=3306;dbname=wenku;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001701s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000879s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000605s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001533s ]
  6. SELECT * FROM `set` [ RunTime:0.000566s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001523s ]
  8. SELECT * FROM `article` WHERE `id` = 508711 LIMIT 1 [ RunTime:0.001102s ]
  9. UPDATE `article` SET `lasttime` = 1775784034 WHERE `id` = 508711 [ RunTime:0.020904s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.000742s ]
  11. SELECT * FROM `article` WHERE `id` < 508711 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.001208s ]
  12. SELECT * FROM `article` WHERE `id` > 508711 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.001053s ]
  13. SELECT * FROM `article` WHERE `id` < 508711 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.003765s ]
  14. SELECT * FROM `article` WHERE `id` < 508711 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.003622s ]
  15. SELECT * FROM `article` WHERE `id` < 508711 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.001856s ]
0.244694s