资源剖析:OpenHuman Rust 核心的内存与 CPU 画像(2026-07-21 profiling session 全解析)

资源剖析:OpenHuman Rust 核心的内存与 CPU 画像(2026-07-21 profiling session 全解析)

【免费下载链接】openhumanOpenHuman is an open source personal AI for Mac, Windows and Linux — local-first memory, agent orchestration, and deep research.项目地址: https://gitcode.com/GitHub_Trending/op/openhuman

导读

本文深度解析 OpenHuman 团队在 2026-07-21 完成的一轮**资源画像(resource profiling)**专项:在 Apple Silicon macOS 26.5.1 上,系统回答"OpenHuman 桌面应用到底吃掉多少 CPU 与 RAM、这些内存分别由哪些组件贡献、以及把 Rust 核心打磨成高效可嵌入库还需要做什么"。文章完整继承该 session 的三层测量边界、全部实测数据表、冷/热路径差异、内存归属结论与七条推荐优化顺序,并结合当前仓库中的基准二进制、特征开关与进程采样源码(src/bin/rss_bench.rs、src/bin/library_profile/main.rs、src/openhuman/platform/proc_metrics/mod.rs 等)逐一印证测量机制。读完你将掌握:如何分层隔离 Tauri/CEF 与纯 Rust 核心的占用来定位开销来源、如何复现这批rss-bench/library-profile测量、以及把一个应用导向型启动流程改造成可嵌入 Rust 库的设计要点。


1. 会话背景与核心结论

测量环境与议题

  • 日期:2026-07-21
  • 平台:Apple Silicon macOS 26.5.1
  • 工作树:worktrees/tauri-resource-profiler
  • 核心问题:OpenHuman 消耗多少 CPU/RAM?各组件分别贡献多少?要把 Rust 核心作为高效嵌入式库使用还需要做什么?

执行摘要(Executive summary):桌面应用庞大的内存占用绝大部分不在 Rust 核心内部。完整的 Tauri/CEF 进程族根据 CEF 预热与 spaCy 是否启用,测得约1.2–1.4 GiB;禁用 CEF 预热节省约86 MiB,之后再禁用 spaCy 再省约146 MiB。

Rust 核心则小得多:

测量项结果
预热后的单 Agent roster(默认特性)38.7 MiB RSS
预热后的单 Agent roster(slim 构建)35.5 MiB RSS
从 1 个增长到 8 个预热 Agent每个额外 Agent 仅约 0.40 MiB
摄取 100 条代表性聊天消息保留约 9.3 MiB,耗时约 2.25 秒
冷聊天回合(真实孵化 2 个子 Agent)RSS 增长约 26–31 MiB(随特性选择与运行条件变化)
预热后同等回合(持久化关闭 / 正常记忆捕获)分别只增加 0.52 MiB / 1.84 MiB

不存在任何一个持有 45 MiB 活跃数据的单一 Rust 模块。在约 42 MiB 总 RSS 的干净 slim 构建快照中:

  • 私有物理占用仅15.2 MiB;
  • 活跃堆分配仅3.18 MiB;
  • OpenHuman 可执行文件常驻代码占18.7 MiB;
  • malloc 区域虽常驻9.4 MiB,但其中活跃的仅约 3.2 MiB——说明存在显著的分配器高水位保留/碎片。

模块级最重要的五项发现:

  1. 父、子 Agent 各自初始化完整的记忆/SQLite 基础设施。
  2. TinyCortex 多语言 PIIRegexSet及其正则缓存,主导了正常记忆捕获期间被识别的 Rust 活跃堆增长。
  3. 首个回合触达约 15 MiB 先前非常驻的 OpenHuman 可执行代码。
  4. 内置 Agent 的 TOML 解析、Agent 构造、统一记忆(unified-memory)构造与 SQLite 初始化主导冷路径 CPU。
  5. 编译期特性选择能大幅缩小二进制体积,但对活跃 RSS 的削减幅度有限。

2. 三层测量边界与测量方法学

本轮剖析使用三个逐步收窄的边界:

  1. 完整的 Tauri 桌面进程族,包括 CEF 及 helper 进程;
  2. 无 Tauri 宿主、独立运行的 Rust 核心;
  3. 直接走 Rust 库路径:Agent 构造、记忆摄取、聊天编排与子 Agent 委派。

所有 Rust 测量均使用release 构建。网络推理被rss-bench(默认关闭)特性下的确定性 provider替换;子 Agent 场景仍走真实的LongLivedSession、内置 Agent 注册表、Agent builder、spawn_parallel_agents工具、两个 researcher Agent、记忆基础设施、prompt 强制约束与回合后 hooks。

采样方式:测量工作负载期间每 5 ms 采样一次 RSS。在 macOS 上,profiler 获取:

  • 当前 RSS:proc_pid_rusage;
  • 峰值 RSS:getrusage;
  • 线程数:proc_pidinfo;
  • 二进制体积:从运行中的可执行文件读取。

macOS 无法通过同一接口暴露 Linux/proc风格的 PSS 与私有 clean/dirty 页字段,因此这些 JSON 字段保持为零。更深层的归属分析使用vmmap、heap、malloc_history、Instruments Allocations 与 Samply。

除非另有说明,汇总的 Rust 结果取5 个全新进程的中位数;来自/usr/bin/time的 CPU 采样为代表运行而非 5 次中位数。

源码印证:这套采样逻辑沉淀为跨平台模块 src/openhuman/platform/proc_metrics/mod.rs。Linux 侧解析/proc/self/status的VmRSS/VmHWM/Threads与/proc/self/smaps_rollup的Pss/Private_Clean/Private_Dirty(见parse_status/parse_smaps_rollup),macOS 侧则通过proc_pid_rusage、getrusage、proc_pidinfo补齐。ProcSample结构还携带 CPU 用户态/系统态毫秒数与打开 fd 数。值得一提的是代码顶部还定义了产品级预算常量:roster RSS 目标20 MiB(RSS_BUDGET_KIB)与硬上限30 MiB(RSS_HARD_CAP_KIB),为将来的 CI 门槛预留了判定依据。


3. 桌面端(Tauri/CEF)测量

这些测量统计的是整个桌面进程族(而不只是 Rust 进程)。

配置平均 RAM变化
默认 CEF 预热 + spaCy1,439.8 MiB基线
禁用 CEF 预热1,353.5 MiB-86.3 MiB
CEF 预热与 spaCy 均禁用1,207.6 MiB总计 -232.2 MiB

由此得出的最明确的桌面端优化:

  • 仅当 memory-tree 操作确实需要时才惰性初始化 spaCy;
  • 避免常驻式 CEF 预热,或将预热进程做成短生命周期;
  • 让辅助功能快照与osascript类探测保持事件驱动 + 限流,而不是持续轮询。

这些桌面结果正是把 Rust 核心剥离出来单独测量的动因:整个发布应用的大部分内存并不由核心 Agent 对象解释。


4. 裸 Rust Agent roster(rss-bench)

现有rss-bench二进制在不带 Tauri 的情况下构造真实的 OpenHuman Agent,并在全新子进程中测量稳定 RSS。其源码注释把测量契约描述为镜像 OpenCompany 嵌入契约——直接经Agent::builder构建裸Agent(无CoreBuilder、无 RPC、无后台服务),注入 mock 模型与进程内"none"记忆后端,每个 Agent 一个临时工作区,先做确定性预热回合以触达惰性分配,再结算并采样(见 src/bin/rss_bench.rs)。一个值得注意的实现细节是NoopMemory:fixture 注释明确指出create_memory(MemoryConfig{ backend: "none" })并不会选择 no-op 后端,而总是构造会撑大 RSS 的UnifiedMemory(SQLite + 默认云端 embedder),因此注入真正的 no-opMemory才能让读数落在 Agent harness 本身之上。

4.1 默认特性构建

Roster中位 RSS线程二进制体积
1 agent39,616 KiB / 38.7 MiB22115.9 MiB
8 agents42,480 KiB / 41.5 MiB24115.9 MiB

7 个额外 Agent 总共只增加 2,864 KiB,即每个 Agent 约 409 KiB。固定运行时与链接代码的代价远大于边际 Agent 对象代价。

4.2 Slim 特性构建

slim 二进制按如下命令构建:

GGML_NATIVE=OFF cargo build --release \ --no-default-features --features rss-bench \ --bin rss-bench --bin library-profile
Roster中位 RSS二进制体积
1 agent36,368 KiB / 35.5 MiB68.4 MiB
8 agents39,584 KiB / 38.7 MiB68.4 MiB

特性选择把剖析二进制砍掉了约40%,但单 Agent RSS 仅下降 3.2 MiB。编译期裁剪对下载与嵌入体积极具价值,但单凭它无法最小化活跃工作集。

源码印证:rss-bench与library-profile两个 bin 在 Cargo.toml 中都以required-features = ["rss-bench"]声明,而rss-bench特性默认关闭(rss-bench = ["dep:tinycortex", "dep:tinymemory-core"]),配套注释明确写着"默认关闭,因此永远不会进入发布的桌面/库构建"。这样即便引入clap、env_logger与整个子模块特性集,也不会污染生产构建。


5. Rust 纯内存摄取(memory-ingest场景)

memory-ingest场景创建隔离工作区,禁用本地推理、Python、spaCy 与 embeddings,然后把100 条代表性聊天消息走完真实的规范化(canonicalization)、摄取、准入(admission)、持久化与 memory-queue 排空路径。

5.1 默认特性

指标中位数
耗时2,251 ms
基线 RSS16,624 KiB / 16.2 MiB
结算 RSS26,144 KiB / 25.5 MiB
保留/峰值增量9,536 KiB / 9.31 MiB
吞吐约 44 条消息/秒

5.2 Slim 特性

指标中位数
耗时2,313 ms
基线 RSS15,536 KiB / 15.2 MiB
结算 RSS24,320 KiB / 23.8 MiB
保留/峰值增量8,784 KiB / 8.58 MiB

特性切换让结算 RSS 下降约 1.8 MiB,且没有带来有意义的吞吐收益。

有代表性的默认特性/usr/bin/time -l运行报告用户态 CPU 0.18 秒、系统态 0.69 秒。应把它视作上界:每 5 ms 的 RSS 采样会引入 macOS 进程检视系统调用,且该工作负载本身也在做真实临时工作区 I/O。


6. Rust 纯子 Agent 聊天(subagents场景)

subagents场景使用确定性本地 provider,但其余完全遵循真实编排路径:

  1. 构建长生命周期潜意识(subconscious)会话;
  2. 提交一条提升(promoted)的聊天消息;
  3. 调用真实的spawn_parallel_agents工具;
  4. 孵化两个拥有独立所有权作用域的真实researcherAgent;
  5. 验证两个子 prompt 都已执行;
  6. 测量基线、峰值与结算 RSS。

6.1 冷启动默认特性结果

指标中位数
耗时163 ms
基线 RSS18,192 KiB / 17.8 MiB
结算 RSS49,712 KiB / 48.5 MiB
保留/峰值增量31,520 KiB / 30.8 MiB

代表性进程使用 0.04 秒用户态、0.06 秒系统态 CPU;模型与网络延迟被刻意排除在外。

6.2 冷启动 Slim 特性结果

指标中位数
耗时158 ms
基线 RSS17,072 KiB / 16.7 MiB
结算 RSS43,392 KiB / 42.4 MiB
保留/峰值增量26,304 KiB / 25.7 MiB

slim 构建在这个更丰富的工作负载里节省了约6.2 MiB结算 RSS。


7. 深层内存归属(Deep memory attribution)

7.1 干净正常快照

一个非插桩的 slim 构建运行(带正常记忆捕获)结算在 43,104 KiB RSS,即42.1 MiB。

VM/堆测量结果
总 RSS42.1 MiB
私有物理占用15.2 MiB
近似 clean/file-backed 部分26.9 MiB
活跃堆分配3.18 MiB
常驻 malloc 区域约 9.4 MiB
常驻栈0.97 MiB
常驻 OpenHuman 可执行文本18.7 MiB

这些类别互相重叠,绝不能相加。例如活跃堆与栈属于私有占用的一部分,而可执行文本属于 clean/file-backed RSS。

关键解读是:RSS 不等于私有堆。进程报告约 42 MiB RSS,但活跃堆分配只有约 3.2 MiB。

7.2 首次使用造成的可执行分页(first-use executable paging)

聊天回合前,profiling 可执行文件的__TEXT段只有约 3.3 MiB 常驻;回合后变为 18.7 MiB。因此首个回合触达(fault in)了约 15.4 MiB OpenHuman 自身的可执行代码。

CoreFoundation、Foundation、ICU、Security、CoreAudio 等 macOS 框架的__TEXT常驻量在受控基线与回合后快照中几乎一致——增长来自 OpenHuman 可执行文件,而非某个新加载的 macOS 框架。可执行页是 clean、file-backed 的,内存压力下可回收,且可在相同进程间共享;它们计入 RSS,却不等于永久保留的私有数据。

7.3 分配器保留(allocator retention)

正常快照在约 9.4 MiB 常驻 malloc 页中只有约 3.2 MiB 活跃分配,意味着约有6 MiB 是分配器空闲、碎片、size-class 页或首回合分配突发之后的高水位保留。

这不能证明存在泄漏。反复回合的平台(plateau)测试比指望 macOS RSS 立即回落到回合前水平更有意义。

7.4 记忆捕获与 PII 成本

一个受控 profiler 开关同时禁用了:

  • memory.auto_save;
  • learning.episodic_capture_enabled及其 archivist hook。

关闭这些写入后,冷回合增量中位数从约 25.9 MiB 降到 22.0 MiB,节省约 3.8 MiB。

栈日志式(stack-logged)分配分析确认:TinyCortex 的多语言 PII 脱敏器是正常记忆捕获期间占主导的活跃 Rust 分配族。重要分配源自:

  • tinycortex::memory::store::safety::pii::SCREEN;
  • 组合式RegexSetNFA;
  • 每线程 hybrid-DFA 正则缓存;
  • 经sanitize_text、文档 upsert、FTS5 情景(episodic)插入、autosave 与 archivist hook 的调用链。

SCREEN实现被描述为廉价预过滤器,但其大型多语言、Unicode 感知的组合自动机在保留内存上并不廉价。一种有前景的替代是字节向候选扫描 + 对命中的候选做定向正则求值。

7.5 Prompt 注入检测器

关闭记忆写入后,下一个可见的正则分配族来自prompt_injection::detector::DETECTION_RULE_SET。它远小于 TinyCortex PII 机制——该工作负载下约为数百 KiB 量级。

当前它不是内存优化的第一优先级,但当 Agent 回合高度并行时,应考虑其 scratch/cache 策略。

7.6 时区控制

current_datetime_line通常调用iana_time_zone(macOS 上走 CoreFoundation)。把 profiling 构建强制为 UTC 在隔离子 Agent 场景里只省约0.5–0.6 MiB。可测量,但不是 42–49 MiB 工作集的主要解释。

源码印证:时区控制的钩子在 src/openhuman/agent/prompts/render_helpers_part_01.rs 中作为 profiling-only UTC 控制暴露,且受rss-bench门控;确定性 provider 覆盖则在 src/openhuman/inference/provider/factory.rs 及factory_part_02.rs/factory_part_03.rs的 routed-provider 分支中实现。二者都是默认关闭的 profiling 特性的一部分。


8. 冷路径 CPU 归属(Cold-path CPU attribution)

一次符号化的 Samply profile 在"无网络、无记忆写入、强制 UTC"的重复运行上记录。由于一个采样点会向其调用栈上的每个父帧贡献一次,inclusive 百分比互相重叠。

冷路径组件约计 inclusive CPU
内置 Agent 注册表初始化17%
LongLivedSession::build_agent16%
Agent::from_config_for_agent15%
内置 Agent TOML 解析/加载13%
统一记忆(unified-memory)构造10%
SQLite / unified-memory 初始化7%
真正的 TinyAgents 回合运行器5%

profile 还显示了Config::load_or_init、配置序列化/迁移、文件系统同步、tool-policy 克隆、prompt 注入初始化和运行时任务调度等开销。

重要时序细节:内置注册表在 profiler 的 RSS 基线之前就初始化完成,所以它的 CPU 出现在整进程 profile 中,但已常驻的页被算入基线,而非测得的回合增量。这就是为什么 CPU 归属与 RSS 归属不能直接对齐。


9. 预热进程对照(Warmed-process control)

本轮最重要的实验:先预热一轮完整的双子 Agent 回合,丢弃该预热会话,再在同一进程中让新会话执行相同负载并测量。

后续等价回合中位耗时中位 RSS 增量
关闭持久化并强制 UTC46 ms528 KiB / 0.52 MiB
正常记忆捕获60 ms1,888 KiB / 1.84 MiB

正常记忆捕获的重复之一出现了8.3 MiB 离群值,与异步持久化或分配器行为一致;其余四次落在约 1.4–1.9 MiB。

这一结果改变了冷启动 26–31 MiB 增量的解读:它压倒性地来自初始化、代码分页、全局正则/缓存构造与分配器高水位行为——而不是每个聊天回合的线性 26 MiB 成本。

源码印证:预热控制通过OPENHUMAN_PROFILE_PREWARM_SUBAGENTS=1环境变量开启(见 src/bin/library_profile/main.rs 的 env 读取逻辑);它专门用来"隔离首次使用成本与稳态",是 docs/library-benchmarking.md 所固化基准环境里的标准旋钮之一。


10. 作为嵌入式库的设计启示

OpenHuman 作为 Rust 库是可行的,但当前构造路径表现得像一个应用引导(bootstrap),而非轻量级的逐实例库 API。

10.1 在 Agent 之间共享服务

Agent::build_session_agent_inner为 Agent 构造会话记忆并获取 SQLite 连接。父 Agent 与子 Agent 应当改为接收共享的实例级服务,例如:

OpenHumanLibrary Arc Arc Arc Arc Arc Arc

子 Agent 应借用或克隆这些Arc句柄,而不是重建配置、记忆存储、schema 状态、provider 与工具目录。

10.2 提供显式预热(warm-up)

库 API 应暴露可选预热方法,把可预见的首次使用成本提前初始化:

  • 内置 Agent 定义;
  • prompt 与 PII 检测器;
  • 记忆 schema 与连接池;
  • 工具目录与策略快照;
  • provider 路由;
  • 常用 prompt 片段。

这让对延迟敏感的宿主可以在"低启动工作量"与"可预期的首条消息延迟"之间做选择。

10.3 区分运行时裁剪与编译期裁剪

DomainSet适合做运行时 surface 选择,但运行时禁用的代码仍会被链接。库的消费者需要文档化的编译期特性配方或专门的 library/harness 特性集,才能保证无关域永不进入二进制。

10.4 避免强制性全局状态

当前 profiling harness 不得不初始化一个全局事件总线、一个全局内置注册表、环境派生的工作区选择与一个全局 provider 覆盖。改为实例自有的状态会让单进程内嵌入多个 OpenHuman 实例更安全,也有利于确定性测试。


11. 推荐的优化顺序

  1. 在父/子 Agent 之间共享 unified-memory 与 SQLite 服务——这是冷路径中最清晰的结构性重复。
  2. 用轻量候选扫描替换 TinyCortex PIIRegexSetscreen——命中候选后仍保留严格的 regex/校验和验证。
  3. 在 CI 或本地 profiling 套件中加入预热重复回合基准——同时跟踪冷启动与稳态,避免一个掩盖另一个。
  4. 提供受支持的 library-minimal 特性配方——针对该确切配方测量二进制体积、冷代码分页与稳态 RSS。
  5. 复用临时 prompt、tool-schema 与脱敏缓冲——降低突发分配与 malloc-zone 碎片。
  6. 只在 profiling 二进制中基准替代分配器——可以揭示 6 MiB malloc 空闲中有多少是分配器特异的;但库不应强加全局分配器给消费者。
  7. 加入按阶段检查点——分别测量 config 加载、Agent 构建、记忆构造、prompt 渲染、委派、子执行、合并、hooks 与 teardown。

这项"加按阶段检查点"的建议后来落地为cold-phases场景,其实现见 src/bin/library_profile/scenarios/cold_phases.rs。


12. 附带的功能性观察(Functional observation)

在确定性的LongLivedSession工作负载中,两个并行子 Agent 都执行了,但会话返回的是最后一个子 Agent 的结果,而不是执行准备好的父合成响应。直接的Agent::turn测试在别处覆盖了合成行为,因此长生命周期会话边界值得一次针对性的正确性审计。这与资源发现相互独立,但由同一套 harness 暴露出来。


13. 复现这批测量

构建默认特性的 profiling 二进制:

GGML_NATIVE=OFF cargo build --release --features rss-bench \ --bin rss-bench --bin library-profile

构建 slim 版本:

GGML_NATIVE=OFF cargo build --release \ --no-default-features --features rss-bench \ --bin rss-bench --bin library-profile

运行裸 roster 基准:

target/release/rss-bench --repeat 5 \ --out target/profile/rust-library/bare-agents.json

--repeat 5对应"每个 roster 尺寸采样 5 个全新进程"的方法学;rss-bench 默认对 roster 尺寸[1, 8]各重复 5 次,并对单子进程设置 120 秒墙钟超时以防卡死阻塞整个 CI 任务(见 src/bin/rss_bench.rs)。RSS 采样端由同一二进制内的 process driver 与proc_metrics采样逻辑协作完成。

运行有状态的库工作负载:

target/release/library-profile memory-ingest target/release/library-profile subagents

测量预热后的子 Agent 回合:

OPENHUMAN_PROFILE_PREWARM_SUBAGENTS=1 \ target/release/library-profile subagents

把编排与持久化、本地时区初始化隔离:

OPENHUMAN_PROFILE_DISABLE_MEMORY_WRITES=1 \ OPENHUMAN_PROFILE_FORCE_UTC=1 \ target/release/library-profile subagents

让进程停在基线或结算态,供vmmap/heap/malloc_history外部检视:

OPENHUMAN_PROFILE_HOLD_BEFORE_SECS=120 \ target/release/library-profile subagents OPENHUMAN_PROFILE_HOLD_SECS=120 \ target/release/library-profile subagents

实时检视示例:

vmmap -summary  heap -sH  MallocStackLogging=1 OPENHUMAN_PROFILE_HOLD_SECS=120 \ target/release/library-profile subagents malloc_history  -allBySize

录制符号化 CPU profile:

OPENHUMAN_PROFILE_DISABLE_MEMORY_WRITES=1 \ OPENHUMAN_PROFILE_FORCE_UTC=1 \ samply record --save-only --unstable-presymbolicate \ --rate 1000 --iteration-count 5 \ --output target/profile/rust-library/subagents-cpu.json.gz \ -- target/release/library-profile subagents

本次 session 新增的代码工件:

  • src/bin/library_profile/main.rs:hermetic 记忆摄取与子 Agent 工作负载、峰值 RSS 采样器、隔离控制、预热控制与调试器驻留点;
  • src/openhuman/platform/proc_metrics/mod.rs:macOS RSS、峰值 RSS、线程数与二进制体积采样(后扩展出 CPU 时间、fd 计数与进程树采样器);
  • src/openhuman/inference/provider/factory.rs:在默认关闭的 profiling 特性下启用的确定性 provider 覆盖;
  • src/openhuman/inference/provider/ops/provider_factory.rs:为同一 profiling 覆盖提供 routed-provider 支持;
  • src/openhuman/agent/prompts/render_helpers_part_01.rs:rss-bench下的 profiling-only UTC 控制;
  • target/profile/rust-library/:本地运行的 JSON、Instruments 与 Samply 工件(被 gitignore)。

所有 profiling 二进制或 provider 覆盖都需要默认关闭的rss-bench特性,因此不会进入正常发布构建。

已完成的有效性验证:rss-bench与library-profile的默认特性 release 构建;--no-default-features --features rss-bench的 slim release 构建;主要场景的 5 次全新进程重复;macOS 进程指标单元测试;开启rss-bench的既有 datetime prompt 测试;cargo fmt --check;git diff --check。构建中出现过的仓库告警均为先前已有的 unused-import/dead-code 与 future-incompatibility 告警,profiling harness 未引入任何新构建失败。


14. 最终结论(Bottom line)

OpenHuman 的 Rust 核心并没有持有 45 MiB 的 Agent 对象。稳态进程的主体是可执行工作集加上运行时/分配器页,活跃堆很小。冷首回合之所以昂贵,是因为它初始化并触达了一条宽广的应用导向路径;一旦预热,子 Agent 回合非常廉价,并且呈现平台期而非线性增长。

因此,通往高效库的最佳路线不是逐字段微调每个 Agent 结构体,而是收窄并共享初始化图:复用记忆与 SQLite 服务、避免为子 Agent 重建 Agent 基础设施、简化 PII 预过滤器、暴露显式预热生命周期,并提供编译期 library-minimal profile。


15. 附:2026-07-22 库基准化后续 session

(原文附录,作为对主 session 的增量记录,全文收录如下)

后续 session 把上述手工调研变成了永久基准环境,执行了其中两条推荐优化,并回答了部署密度问题。完整细节见 docs/library-benchmarking.md;此附录记录相对本文的增量。

15.1 构建了什么

  • library-profile中的十个 hermetic 场景(原为两个):agent-turn、long-agent、workflow、subconscious、cold-phases、fleet、skill-run、subagent-storm加入原有memory-ingest/subagents。全部离线、mock-provider、JSON schema v2 并带每阶段/每回合检查点。

    当前仓库 src/bin/library_profile/scenarios/ 下保留着agent_turn.rs、cold_phases.rs、fleet.rs、long_agent.rs、memory_ingest.rs、skill_run.rs、subagent_storm.rs、workflow.rs等场景实现,main.rs的dispatch即按场景名路由。

  • scripts/profile/ 下的五个驱动脚本:library-bench.sh(中位数 + 摘要)、library-fleet.sh(Agent 数扫描,含 2 GB/2 vCPU 通过/失败门槛)、library-instances.sh(多进程模型)、library-cpu.sh(samply)、library-heap.sh(dhat)。
  • 专业 profiler 接入:dhat 挂在默认关闭的rss-bench-dhat特性后;samply 脚本化;proc_metrics扩展出 CPU 时间、fd 计数与后代的进程树采样器(tree.rs)。

15.2 头条结果(Apple Silicon,默认构建,除非另有注明)

问题答案
冷回合成本(任意形态:chat/subconscious/委派/workflow)~29–30 MiB 保留——是共享 bootstrap,而非工作负载
预热 long-agent 增长30–150 KiB/回合平台期;偶发 6–8 MiB 异步持久化突发
活跃堆 vs RSS(dhat,agent-turn)总计分配 33.4 MB,峰值活跃 5.0 MB,退出时 3.1 MB
fleet 单进程内每 Agent 边际成本~1.7–2.0 MiB(N=50/100/500 扫描)
停驻 fleet 的空闲 CPU每个 N 在每 10 s 中约 3 ms
2 GiB 单进程内 1000 个 AgentPASS——1000 个时投影 ~1747 MiB;真实 500-Agent 运行结算 1393 MiB
同一负载以 N 进程运行~48 MiB/实例持平 → 2 GiB 只能约 42 实例;单进程模型密度约高25 倍
JS skill 运行的真实成本node 子进程 ~72–75 MB RSS(进程树 ~121 MB vs 自身 ~51 MB)
并行子 Agent 边际成本(storm K=8→32)~0.78 MiB
library-minimal 构建(--no-default-features --features skills,flows)二进制 81 MiB(stripped 60)对比 116;RSS -3.5 至 -4.7 MiB

15.3 已落地的变更

  • PII 预过滤器已在上游替换(上文建议 2):tinycortex#119 把常驻的 17 模式RegexSet+ 每线程 DFA 缓存,换成单遍字节候选扫描 + 惰性编译的按类别 regex;相对旧集合做了超集校验,常见路径无堆回归,收益随线程/Agent 并发数放大。与 #120(无关的 rustdoc 修复)一同合并,子模块已 bump。
  • library-minimal 配方已文档化并测量(docs/library-minimal-recipe.md);已排序列出后续 shed 项(首先是 whisper/GGML 的inference门)。
  • harness 对比(docs/harness-comparison-2026-07-22.md):范围匹配的同行(Hermes,Python)自称 RSS 约为我们 10 倍;ZeroClaw 的"负载下 7.8–12 MiB"数字找不到可定位的一手来源,现凡引用处均已标记为未证实。我们的进程内 ~2 MiB 边际扩展在被调研的 harness 中无对等物。

15.4 fleet 扫描暴露的新观察项

  1. 线程随 Agent 数增长 ~0.35/Agent(N=50 时 71 → N=500 时 211,→1000 时投影约 420)。需要在 1000-Agent 运行前定位来源(SQLite?阻塞池?)并封顶。
  2. 2 个 worker 上负载约束是 CPU 而非内存:200 ms mock 延迟下 N=500 时 p95 回合延迟 25.5 s。fleet 密集后,调度/背压设计比 RAM 更重要。
  3. 解释器子进程会击穿预算:node 与 python 运行时的池化/共享已作为 issue #5106 提出——否则约 25 个并发 JS skill 运行就会耗尽整个 2 GiB 机器。

15.5 更新后的优化顺序

  1. 父/子 Agent 间共享服务(不变,仍居首;fleet 基准是它的回归检测仪)。
  2. PII 预过滤器——已完成,上游合并。
  3. node/python 运行时池化(#5106)——新增,被 skill-run 测量推至近顶端。
  4. 线程增长归因与封顶(新增)。
  5. 预热 API、分配器实验、CI 中的按阶段检查点——检查点已存在(cold-phases);CI 接线待办。
  6. library-minimal profile 的inference编译门(whisper/GGML)。

15.6 下一步:真实桌面应用

同样的严谨度现在需要覆盖已发布的 Tauri/CEF 应用(即本文开头的 ~1.2–1.4 GiB 进程族)。为那次 session 准备的简报——场景、可复用资产、门槛——见 docs/tauri-live-profiling-brief.md。


16. 延伸阅读(仓库内关联材料)

  • docs/library-benchmarking.md——把 2026-07-21 手工调研固化为可重复基准环境:八个库场景、四/五个驱动脚本、2 GB/2 vCPU 服务预算模型、fleet(单进程)与 instances(多进程)两种部署形态的成本差异,以及最新基线数字表。
  • docs/library-minimal-recipe.md——library-minimal 特性配方与测量。
  • docs/harness-comparison-2026-07-22.md——与其他 agent harness 的对比与出处核验。
  • docs/tauri-live-profiling-brief.md——针对 Tauri/CEF 桌面应用后续剖析的简报。
  • scripts/profile/README.md——profiling 驱动脚本的快速参考。
  • src/bin/library_profile/main.rs 与 src/bin/rss_bench.rs——各场景与 roster 基准的当前实现;src/openhuman/platform/proc_metrics/mod.rs 为跨平台采样与预算常量所在。

复现与适用前提:本文全部 Rust 数字来自 2026-07-21 在 Apple Silicon macOS 26.5.1 上的 release 构建测量(中位数基于 5 个全新进程),其中桌面进程族数字包含 CEF/helper 进程且为平均值。测量依赖默认关闭的rss-bench(及可选的rss-bench-dhat)特性,发布构建不受影响。若在 Linux 上运行,proc_metrics会额外报告 PSS 与私有页字段,但 macOS 侧这些字段恒为零;跨平台复现请先核对 docs/resource-profiling-session-2026-07-21.md 中的方法学限制。

【免费下载链接】openhumanOpenHuman is an open source personal AI for Mac, Windows and Linux — local-first memory, agent orchestration, and deep research.项目地址: https://gitcode.com/GitHub_Trending/op/openhuman

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考