> For the complete documentation index, see [llms.txt](https://tinyhumans.gitbook.io/openhuman/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://tinyhumans.gitbook.io/openhuman/zh/kai-fa/loadable-modules.md).

# 可加载模块

OpenHuman 如何在运行时加载可选的原生模块：注册表、准入检查，以及模块发生故障时会怎样。

功能门控决定哪些内容会编译进二进制文件。模块决定正在运行的二进制文件能访问什么。模块是加载到核心进程中的第一方原生库，通过 TinyBus 提供小型的类型化接口。

这种权衡是明确的。模块与核心共享地址空间和崩溃域，因此它是受信任代码，准入检查很重要。作为回报，从不生成文档的用户无需在下载大小、内存或依赖项方面为文档写入器付费。

## 主机访问和契约

主机通过以下组件访问模块客户端： `openhuman-rpc` 门面链。共享的 `openhuman_rpc::embed::modules::client(config)` 返回一个 `tinybus::module::ModuleClient` ，它基于进程范围的惰性加载器之上的显式配置构建，可在核心启动前或启动后使用。构造客户端不会启动任何内容，也不需要已登录会话。请在首次调用前设置捆绑制品发现。未启用 `modules` 功能的构建没有客户端；如果配置中禁用了模块，调用将返回明确的不可用错误。

一个 `*-bus` crate 包含序列化的词汇表、错误、标识符、版本、模式和静态工具声明。解析、提供程序分派、加密、进程和设备访问都在已编译的模块内执行。主机保留配置、凭据、批准和执行策略。当模块不可用时，它们绝不会链接实现后备方案。有状态适配器通过显式的关闭、取消和停机调用来释放模块拥有的资源。

其余迁移工作和临时依赖例外情况记录在 [模块边界清单](https://github.com/tinyhumansai/openhuman/tree/main/docs/module-boundary-inventory.md).

## 注册表

`crates/openhuman-core/src/modules/registry/` 编译了十一条记录。只有此注册表可以选择制品。不会有任何内容从配置读取模块名称后再去查找它。

| 模块               | 提供                                                      |
| ---------------- | ------------------------------------------------------- |
| `tinycomputer`   | 桌面和浏览器观察与控制                                             |
| `tinysearch`     | 网络搜索提供程序分派                                              |
| `tinydocs`       | 文档提取和 `.docx` / `.pptx` 生成                              |
| `tinywallet`     | 密钥派生和交易签名                                               |
| `tinyjuice`      | 工具输出压缩和恢复                                               |
| `tinyvoice`      | 音频分帧、VAD 和转录幻觉检测                                        |
| `tinymcp`        | MCP 客户端和注册表                                             |
| `tinyconnectors` | OAuth 连接器操作和触发器                                         |
| `tinybox`        | 沙箱/资源生命周期、受限且受监督的执行、jail 和 Docker 操作、shell 执行、文件传输和端口转发 |
| `tinychannels`   | 消息通道传输                                                  |
| `tinyflows`      | 计划任务：调度器运行时、cron 任务存储和计划计算（`tinyflows-bus` 计划契约）        |
| `tinyhosts`      | 托管提供程序操作                                                |

每条记录都带有一个版本、其来源发布版本，以及每个受支持构建对应的一个 `PlatformAsset` 。七条记录发布了十一种构建： `ubuntu-24.04` 和 `ubuntu-22.04` 开启 `x86_64` 和 `arm64`, `macos-26` 和 `macos-15` 开启 `arm64` 和 `x86_64`, `windows-2025-x86_64`, `windows-2022-x86_64` 和 `windows-11-arm64`。TinyComputer 发布十六个资产；TinyBox、TinyMCP 和 TinyWallet 各发布十七个，并增加了 Arch Linux 和 Fedora 构建。资产可用性因模块而异，因此不应根据另一个模块的矩阵推断某个发布版本的数量。

每个资产都带有从已发布版本自身的校验和文件中逐字复制的 SHA-256。请勿根据本地构建计算替代的固定值。摘要必须描述发布工作流签名的制品，而不是你机器上的制品。

## 解析顺序

每一步都避免了下一步的成本：

1. 已在主机的代理上提供服务。
2. 运维人员覆盖：位于 `[modules].overrides`中的路径，或源模式（`[modules] source` / `OPENHUMAN_MODULE_SOURCE`，仅用于本地开发；CI 使用 `release`). `linked` 提供一个被编译进正在运行的 `openhuman-core` 的模块（使用以下选项构建它： `--features linked-modules`，它会链接 `crates/openhuman-modules-linked`；没有任何产品构建或其他主机可以访问该 crate）。 `source` 通过以下方式从模块的供应商 gitlink 构建库并提供服务： `node scripts/modules/build.mjs <id|all>` （它会写入 `target/module-sources/<id>/` ，其中含有由运维人员信任的 `modules.toml`；将 `OPENHUMAN_MODULE_SOURCE_DIR` 设为该目录）。本地摘要绝不是注册表固定值。 `node scripts/modules/pin-status.mjs` 报告每个 gitlink 是否与其注册表固定值同步、领先或落后（领先意味着你正在运行 CI 会拒绝的本地编译模块），而 `node scripts/modules/release-and-repin.mjs <id>` 发布一个版本并根据其 `checksum.toml`重新固定。严格的 `check-module-pins.mjs` 保持不变。
3. 模块搜索路径： `OPENHUMAN_MODULE_PATH`，然后是平台数据目录。
4. 在构建时暂存到应用中的捆绑发布版本。
5. 发布缓存，仅当以下配置为真时才下载： `[modules].allow_download` 。

覆盖会绕过摘要检查，因为制品就是该路径上的任何文件。这仅在它是运维人员自己的文件、且在运维人员自己的配置中指定时才可接受。这也意味着覆盖无法添加注册表中尚不存在的模块。

平台候选项按从新到旧排序，并支持回退。在 Linux 上，glibc 2.39 或更高版本优先使用 24.04 构建，失败时回退到 22.04。glibc 2.35 或更高版本使用 22.04。任何更旧版本，以及 musl 或未知 libc，都会获得空候选列表，因此按设计不会在这些环境中加载任何已发布制品。

## 准入

这些检查按顺序运行，且均在任何模块代码运行之前：

1. 目录所有权和权限模式，以及位于大小上限内的常规平台库文件。
2. 制品旁的摘要允许列表（如存在），它对其目录具有权威性。
3. 解析 ABI 描述符符号，并在读取其余内容之前验证其冻结的 16 字节前缀。
4. 验证完整描述符：匹配的指针宽度、字节序和目标三元组，兼容的 TinyBus 系列，以及作为主机特性子集的模块特性位。使用以下设置构建的模块： `panic = "abort"` 会被拒绝，因为中止型 panic 会连同主机一起终止。
5. 解析清单并解析依赖项，拒绝缺失的提供程序、循环和名称冲突。
6. 初始化，获取 vtable，连接传输层。

每个模块都在自己的小型 `*-bus` 契约 crate 中声明其接口：接口名称、对象路径、每个成员一个常量，以及一个契约版本。绑定规则是主版本必须相等，且模块的次版本至少为主机的次版本。较新的模块可服务较旧的主机，反向情况会被拒绝，而不是半途工作。绝不要在 OpenHuman 中重新声明契约类型，并应通过契约的常量而不是字符串字面量调用成员。

## 故障是终止性的

在十一种生命周期状态中，五种是终止状态：rejected、faulted、failed、stopped 和 disabled。处于其中任一状态的模块会立即回答“不可用”，且在同一进程中绝不会重试。

这源于第二条规则：加载器绝不会卸载库。已停止的模块会释放其传输和名称，但其代码、线程局部变量、panic 元数据和回调地址会一直保持映射，直到进程退出。替换制品需要重启。在原地重试发生故障的模块，会运行你已经知道其不变量已被破坏的代码。

不受信任的代码不属于这里。它应放在单独的进程中，而这正是沙箱后端的用途。

## 配置

```toml
[modules]
enabled = true          # 关闭时，功能会报告此状态，而非在使用时失败
allow_download = true   # false 适合隔离网络或可复现的部署
# install_dir = "..."   # 默认为用户缓存目录，然后是工作区
```

无论哪种方式，都不会静默下载任何内容。摘要来自编译内置的注册表，而不是正在获取的发布版本。

该 `modules` RPC 命名空间公开 `list`, `status` 和 `load` （按 ID，绝不按路径），以及 `computer_status` 和 `browser_check_readiness` ，用于检查计算机模块的就绪状态。 `browser_forget_sites` 会忘记浏览器任务针对一个站点或所有站点学到的内容（参见 [Jev](/openhuman/zh/kai-fa/jev.md)).

## 添加或移动一个

模块的行为应属于拥有它的子模块。主机端是适配器：代理、它在初始化时推送的配置，以及调用周围的策略。更改模块时：

1. 在上游提交变更，并在那里发布版本。
2. 移动 gitlink 至 `vendor/`.
3. 从该发布版本的校验和文件更新记录的版本、发布 URL 和摘要。
4. 同时测试门控开启和关闭的构建，因为缺少叶级门控应意味着模块不存在，而不是存在但失败。

## 另见

* [架构](/openhuman/zh/kai-fa/architecture.md)：模块相对于核心的位置。
* [构建 Rust 核心](/openhuman/zh/kai-fa/building-rust-core.md)：决定编译内容的功能门控。
* [性能与占用空间](/openhuman/zh/kai-fa/performance.md)：惰性加载权衡的价值。
