> For the complete documentation index, see [llms.txt](https://docs.convai.com/api-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/core-concepts/runtime-architecture.md).

# 运行时架构

Convai Unity SDK 采用分层架构。每一层都有明确的职责，并且通信方向向内——外层依赖内层，绝不相反。理解这一结构可以让你知道 SDK 的哪些部分面向开发者、哪些是可替换的，以及哪些是无需触碰的内部实现细节。

***

### 系统层

下图展示了四个主要层及其关系。 `ConvaiRuntime` 在第二层直接包含四个子系统—— `IRoomRuntime`, `IEventHub`, `IAgentRegistry`，以及模块列表。角色和玩家显示在 `IRoomRuntime` 是位于 `IAgentRegistry`，且所有模块共享一个公共上下文层。

```mermaid
graph TD
    A[ConvaiRuntime<br/>IConvaiRuntime] --> B[IRoomRuntime<br/>连接 · 音频 · 归属 · 诊断]
    A --> C[IEventHub<br/>解耦的发布/订阅]
    A --> D[IAgentRegistry<br/>角色 · 玩家]
    A --> E[IReadOnlyList&lt;IConvaiModule&gt;<br/>功能模块]
    B --> F[ConvaiCharacter<br/>每个角色的会话 + 状态]
    B --> G[ConvaiPlayer<br/>本地参与者身份]
    F --> H[模块上下文<br/>唇形同步 · 情绪 · 动作 · …]
    G --> H
```

**`ConvaiRuntime` （顶层）** ——拥有所有子系统并协调完整生命周期。通过 `ConvaiRuntimeBuilder`在整个应用生命周期内仅创建一次。暴露 start、pause、resume 和 stop 操作，并将其传播到所有已注册模块。它持有四个直接子系统：

* **`IRoomRuntime`** ——管理实时会话：连接、断开、音频路由、角色归属和诊断。角色和本地玩家显示在此层之下。
* **`IEventHub`** ——SDK 中用于跨系统通信的解耦发布/订阅总线。
* **`IAgentRegistry`** ——所有活动 `ConvaiCharacter` 是位于 `ConvaiPlayer` 实例的注册表。
* **`IReadOnlyList<IConvaiModule>`** ——已注册功能模块的集合。

**角色 / 玩家层** — `ConvaiCharacter` 是位于 `ConvaiPlayer` 向 `IAgentRegistry` 注册，并通过 `IRoomRuntime`接收各自的会话上下文。每个角色维护自己的会话状态。

**模块上下文层** ——功能模块（`IConvaiModule`）共享一个 `IModuleContext` ，它提供对运行时服务的访问。模块彼此隔离：它们不会直接相互调用。

***

### 运行时接口清单

`IConvaiRuntime` 通过属性暴露以下子系统。每个属性都是特定功能领域的入口点。

| 属性                   | 类型                              | 它拥有的内容        |
| -------------------- | ------------------------------- | ------------- |
| `State`              | `RuntimeState`                  | 运行时当前生命周期状态   |
| `Room`               | `IRoomRuntime`                  | 连接、音频、归属和诊断   |
| `事件`                 | `IEventHub`                     | 解耦的发布/订阅通信    |
| `Agents`             | `IAgentRegistry`                | 所有活动角色和玩家的注册表 |
| `Modules`            | `IReadOnlyList<IConvaiModule>`  | 所有已注册的功能模块    |
| `Transport`          | `ITransportProvider`            | 平台特定的实时传输     |
| `Conversation`       | `IConversationProvider`         | AI 后端通信       |
| `Config`             | `ConvaiBootstrapConfigSnapshot` | 不可变的引导配置      |
| `RuntimePreferences` | `IRuntimePreferences`           | 可变的运行时偏好设置    |
| `FeatureVariants`    | `IFeatureVariantProvider`       | 功能变体 / A/B 选择 |
| `Persistence`        | `IPersistenceProvider`          | 运行时拥有的数据存储    |
| `Telemetry`          | `ITelemetryProvider`            | 可观测性和分析       |

开发者最常与 `Room`, `Agents`，以及 `事件` 交互。 `Transport`, `Conversation`, `Persistence`, `Telemetry`，以及 `FeatureVariants` 可通过 `ConvaiRuntimeBuilder`.

***

### 你可以替换的内容

`ConvaiRuntimeBuilder` 在运行时启动前用于组合运行时的流式 API。每个方法都会返回 `this`，因此调用可以链式连接。

```csharp
var runtime = new ConvaiRuntimeBuilder()
    .UsePersistence(myPersistenceProvider)
    .UseTelemetry(myTelemetryProvider)
    .WithEndUserIdentityProvider(myIdentityProvider)
    .AddModule<MyCustomModule>()
    .Build();
```

下表列出了哪些内容可替换，哪些仅限内部使用。

| 组件       | 可通过构建器替换                         | 默认值                       |
| -------- | -------------------------------- | ------------------------- |
| 传输提供程序   | `UseTransport()`                 | 平台默认（WebSocket / LiveKit） |
| 对话提供程序   | `UseConversation()`              | Convai RTVI 对话后端          |
| 持久化提供程序  | `UsePersistence()`               | `PlayerPrefs`-支持的键值存储     |
| 遥测提供程序   | `UseTelemetry()`                 | 无操作遥测                     |
| 功能变体提供程序 | `WithFeatureVariants()`          | 静态功能标志                    |
| 运行时偏好设置  | `WithRuntimePreferences()`       | 默认值来自 `ConvaiSettings`    |
| 事件总线     | `UseEventHub()`                  | 默认的内存事件总线                 |
| 代理注册表    | `UseAgentRegistry()`             | 默认注册表                     |
| 终端用户身份   | `WithEndUserIdentityProvider()`  | 设备 ID 提供程序                |
| 最终用户元数据  | `WithEndUserMetadataProvider()`  | 无                         |
| Modules  | `AddModule()` / `AddModule<T>()` | 仅限 SDK 功能模块               |
| 房间运行时    | `UseRoomRuntime()`               | 内部的、由 LiveKit 支持的房间       |

{% hint style="info" %}
`ConvaiRuntime` 由 `ConvaiManager` MonoBehaviour 自动创建。大多数项目从不直接调用 `ConvaiRuntimeBuilder` 。仅在需要替换默认提供程序或添加自定义模块时使用它。
{% endhint %}

***

### `IRoomRuntime` 子结构

房间层本身由四个协调器组成，均可通过 `IConvaiRuntime.Room`.

| 属性   | 类型                           | 职责           |
| ---- | ---------------------------- | ------------ |
| `连接` | `IRoomConnectionCoordinator` | 连接、断开、会话状态   |
| `音频` | `IRoomAudioCoordinator`      | 麦克风采集、远程音频播放 |
| `归属` | `IRoomOwnershipCoordinator`  | 此客户端拥有并聚焦的角色 |
| `诊断` | `IRoomDiagnostics`           | 会话指标、健康监控    |

连接和音频是最可能在脚本中调用的协调器。当场景中有多个角色时，归属会自动管理。诊断用于性能监控和调试。

***

### 模块层

模块是运行在运行时生命周期内的功能扩展。它们接收共享的 `IModuleContext` ，并可以注册供其他模块或表现层使用的服务。

在调用 `Build()` 之前通过构建器添加模块：

```csharp
new ConvaiRuntimeBuilder()
    .AddModule<LipSyncModule>()
    .AddModule(new MyCustomModule(someConfig))
    .Build();
```

模块会随着运行时一起启动、暂停、恢复和停止。 `IConvaiModule` 接口定义了这些生命周期钩子。完整的模块编写参考请参见 [扩展 SDK](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/advanced-topics/extending-the-sdk.md) 。

{% hint style="warning" %}
模块不能直接相互依赖。如果两个模块需要共享数据，请使用 `IEventHub` ，或者使用通过 `IModuleContext`.
{% endhint %}

***

### `RuntimeState` 生命周期

运行时从创建到释放会经历以下状态。

| State     | 含义                           |
| --------- | ---------------------------- |
| `已创建`     | 运行时已构建但尚未启动                  |
| `启动中`     | `StartAsync()` 正在进行          |
| `运行中`     | 完全运行                         |
| `暂停中`     | `PauseAsync()` 正在进行          |
| `已暂停；可恢复` | 已暂停；可恢复                      |
| `恢复中`     | `ResumeAsync()` 正在进行         |
| `停止中`     | `StopAsync()` 正在进行           |
| `已停止`     | 已关闭；无法重新启动                   |
| `已释放`     | `DisposeAsync()` 已调用；所有资源已释放 |

```mermaid
stateDiagram-v2
    [*] --> Created
    Created --> Starting : StartAsync()
    Starting --> Running
    Running --> Pausing : PauseAsync()
    Pausing --> Paused
    Paused --> Resuming : ResumeAsync()
    Resuming --> Running
    Running --> Stopping : StopAsync()
    Stopping --> Stopped
    Stopped --> [*] : DisposeAsync()
```

所有状态转换都是封装在 `IConvaiOperation<Unit>`中的异步操作。在返回的操作上检查， `Status` 以确认转换完成后再继续。

{% hint style="info" %}
`ConvaiManager` 在销毁时自动处理。若你使用 `DisposeAsync()` 直接构建自定义宿主，请调用 `ConvaiRuntimeBuilder` 以释放所有资源。 `DisposeAsync()` 在 `StopAsync()` 来
{% endhint %}

***

### 下一步

你现在已经了解 Convai 运行时的组成方式，以及各层中哪些部分可替换。接下来阅读《会话生命周期》，了解每个角色的会话如何创建、持久化和恢复，然后继续阅读《轮流发言模式》和《事件系统》。

{% content-ref url="/pages/1b034b7638b343540a3b205274bd08beaff9d15e" %}
[会话生命周期](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/core-concepts/session-lifecycle.md)
{% endcontent-ref %}

{% content-ref url="/pages/251e0bf7030a5f742a1182e15529c0604e3ee150" %}
[轮次切换模式](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/core-concepts/turn-taking-modes.md)
{% endcontent-ref %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/core-concepts/runtime-architecture.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
