> 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/turn-taking-modes.md).

# 轮替模式

轮流发言决定谁在什么时候说话、一个发言轮次何时结束，以及 SDK 如何处理用户发言与角色回应之间的过渡。SDK 支持两种模式：免提自动检测和明确的按住说话。选择合适的模式——并正确调优——会直接影响你的训练模拟、交互体验或游戏中对话的自然度和可靠性。

有关基于 Inspector 的设置步骤，请参见 [配置对话输入模式](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/getting-started/configure-conversation-input-mode.md)。此页面是完整的字段参考。

`TurnTakingOptions` 配置的是房间，而不是某个角色。在多角色会话中，每个成员身份共享相同的轮流发言配置，当前交互目标决定下一个发言轮次分配给哪个成员身份。参见 [切换交互目标](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/multi-character-sessions/switch-the-interaction-target.md).

***

### 模式对比

| Mode     | `ConversationInputMode` 值 | 最适合                      |
| -------- | ------------------------- | ------------------------ |
| **免提**   | `HandsFree` (0)           | 自然对话的训练模拟、环境交互、以无障碍优先的体验 |
| **按住说话** | `PushToTalk` (1)          | 嘈杂环境、工厂安全演练、必须防止误触发的场景   |

***

### `TurnTakingOptions` — 根字段

`TurnTakingOptions` 是顶层配置对象。将其设置在 `ConvaiRoomManager` 中（Inspector 内联）或通过 `ConvaiRoomManagerProfile` 资源，或者将其传递给 `RoomSessionConnectOptions` 以用于按连接覆盖。

| 字段                    | 类型                      | 默认值          | 描述                                               |
| --------------------- | ----------------------- | ------------ | ------------------------------------------------ |
| `Mode`                | `ConversationInputMode` | `HandsFree`  | 设置此会话的当前对话模式。                                    |
| `TurnDetection`       | `TurnDetectionMode`     | `UseDefault` | 控制自动结束发言轮次的检测。仅适用于免提模式。                          |
| `CustomTurnDetection` | `SmartTurnSettings`     | 见下文          | 微调后的智能轮次参数。仅在以下情况生效： `TurnDetection` 是 `Custom`. |
| `InitialServerStt`    | `ServerSttInitialState` | `UseDefault` | 控制在会话开始时是否启用 Convai 的语音转文本。                      |
| `LocalAudioPolicy`    | `LocalAudioPolicy`      | 见下文          | 此设备上的麦克风行为。适用于两种模式。                              |
| `PushToTalkPolicy`    | `PushToTalkPolicy`      | 见下文          | 按住说话交互规则。仅适用于 PushToTalk 模式。                     |
| `打断进入`                | `BargeInOptions`        | 见下文          | 角色中断行为——平滑音频淡出以及可选的客户端语音检测。适用于两种模式。              |

***

### 免提模式

在免提模式下，SDK 会持续采集麦克风音频，并检测用户何时说完。无需按按钮。

#### `TurnDetectionMode`

控制如何检测发言结束。

| 值            | 行为                                            |
| ------------ | --------------------------------------------- |
| `UseDefault` | Convai 默认的服务器端语音活动检测。适用于大多数情况。                |
| `已禁用`        | 无自动轮次检测。SDK 不会自动结束用户的发言轮次。仅在你完全在代码中管理轮次切换时使用。 |
| `Custom`     | 使用 `SmartTurnSettings` 以便自行配置检测参数。            |

#### `SmartTurnSettings`

在以下情况下生效： `TurnDetection` 设置为 `Custom`.

| 字段                | 类型      | 默认值   | 描述                                             |
| ----------------- | ------- | ----- | ---------------------------------------------- |
| `StopSecs`        | `float` | `3.0` | 在 SDK 结束用户发言轮次前所需的静音秒数。减小可更快响应；在嘈杂环境中增大。       |
| `PreSpeechMs`     | `int`   | `0`   | 在捕获到的轮次中，包含在检测到语音起始前的音频毫秒数。如果轮次的第一个词经常被截断，请增大。 |
| `MaxDurationSecs` | `float` | `8.0` | 单个用户轮次的硬性时长上限（秒）。无论用户是否停止说话，轮次都会结束。            |

```csharp
var options = new TurnTakingOptions
{
    Mode = ConversationInputMode.HandsFree,
    TurnDetection = TurnDetectionMode.Custom,
    CustomTurnDetection = new SmartTurnSettings
    {
        StopSecs = 2.0f,       // 医疗评估流程中更快响应
        PreSpeechMs = 100,
        MaxDurationSecs = 10.0f
    }
};
```

{% hint style="warning" %}
设置 `StopSecs` 过低会导致用户在句中停顿时过早结束轮次。在学习者回应前会先思考的训练模拟中，请将 `StopSecs` 保持在 2.5 或更高。
{% endhint %}

***

### 按住说话模式

在按住说话模式下，用户通过按下并松开一个控制项（按钮、按键或 UI 元素）来明确开始和结束自己的轮次。SDK 不使用语音活动检测来结束轮次。

#### `PushToTalkPolicy`

控制所有按住说话交互规则。将 `RequireTurnCompletionBeforeNextPress = true` 设置为大多数训练模拟所需——它会强制一种自然的对话节奏，即角色先说完，学习者再回应。

| 字段                                           | 类型    | 默认值     | 描述                                                                                          |
| -------------------------------------------- | ----- | ------- | ------------------------------------------------------------------------------------------- |
| `ReleaseTailMs`                              | `int` | `1000`  | 用户松开按住说话控制后，每个有界收尾窗口的持续时间（毫秒）。范围 `0`–`5000`. `0` 在松开时立即关闭麦克风。参见 [释放时序](#release-timing) 如下。 |
| `EnableServerSttToggle`                      | `布尔值` | `true`  | 在按住说话控制被按下和松开时，对 Convai 的语音转文本进行静音和取消静音。可降低成本并防止对背景音频的意外处理。                                 |
| `InterruptBotOnPress`                        | `布尔值` | `true`  | 如果角色在用户按下按住说话时正在讲话，则会立即打断角色，以便用户开始说话。                                                       |
| `RequireTurnCompletionBeforeNextPress`       | `布尔值` | `true`  | 用户必须等待角色完整回应结束后，才能再次按下按住说话。可防止轮次重叠。                                                         |
| `TurnCompletionTimeoutMs`                    | `int` | `5000`  | 回退超时（毫秒）。如果角色的轮次完成事件从未到达（例如网络卡顿），则会在超时后释放按住说话锁定。                                            |
| `AllowSpeechStoppedFallbackAfterSpeechStart` | `布尔值` | `false` | 如果启用，在语音已开始后，来自角色的 speech-stopped 事件也可以释放按住说话等待状态。适用于轮次完成事件丢失的边缘情况恢复。                       |

```csharp
var options = new TurnTakingOptions
{
    Mode = ConversationInputMode.PushToTalk,
    PushToTalkPolicy = new PushToTalkPolicy
    {
        InterruptBotOnPress = false,       // 让角色先说完，用户才能开口
        RequireTurnCompletionBeforeNextPress = true,
        TurnCompletionTimeoutMs = 8000
    }
};
```

#### 释放时序

当用户松开按住说话控制时，SDK 不会立即关闭麦克风——它会保持麦克风和 Convai 的语音转文本保持打开足够长的时间，以捕获用户所说内容的尾部。此行为已在 SDK `4.4.1`.

SDK 首先等待 `ReleaseTailMs` 最终语音识别结果。如果先收到最终结果，捕获会立即关闭。如果窗口在最终结果到达前到期，SDK 会发送权威停止信号，并将捕获继续保持打开一个额外的 `ReleaseTailMs` 窗口，以便 Convai 完成处理，然后无论此时是否已收到最终结果，都会关闭捕获。设置 `ReleaseTailMs` 到 `0` 会跳过两个窗口并在松开时立即关闭捕获。降低 `ReleaseTailMs` 可减少麦克风在松开后关闭前的最坏情况延迟，但数值过低可能会截断用户仍在说完的最后一个词—— `5000` 是最大值。

***

### 本地音频策略

`LocalAudioPolicy` 控制本地设备上的麦克风行为。它适用于免提和按住说话两种模式。

| 字段                               | 类型                         | 默认值            | 描述                                               |
| -------------------------------- | -------------------------- | -------------- | ------------------------------------------------ |
| `StartMutedInPushToTalk`         | `布尔值`                      | `true`         | 当按住说话模式处于活动状态时，麦克风默认静音。只有在按住按住说话控制时才会捕获音频。       |
| `EnableAcousticEchoCancellation` | `布尔值`                      | `false`        | 启用声学回声消除。适用于 Android 和 iOS 在使用设备扬声器（免提扬声器）而非耳机时。 |
| `PushToTalkStartupMode`          | `PushToTalkMicStartupMode` | `PrewarmMuted` | 控制按住说话模式开始时麦克风如何初始化。                             |

#### `PushToTalkMicStartupMode`

| 值                  | 行为                                | 权衡                                          |
| ------------------ | --------------------------------- | ------------------------------------------- |
| `PrewarmMuted`     | 麦克风会在会话开始时打开并预热，但会保持静音，直到用户按下控制项。 | 消除了首次按下的延迟；会使用少量后台资源。                       |
| `OpenOnFirstPress` | 直到用户第一次按下按住说话之前，麦克风才会打开。          | 节省资源；首次按下时会引入短暂延迟（约 100–300 毫秒），因为麦克风正在初始化。 |

```csharp
var options = new TurnTakingOptions
{
    Mode = ConversationInputMode.PushToTalk,
    LocalAudioPolicy = new LocalAudioPolicy
    {
        EnableAcousticEchoCancellation = true,   // 工厂车间场景，设备扬声器
        PushToTalkStartupMode = PushToTalkMicStartupMode.PrewarmMuted
    }
};
```

***

### 打断与中断

`打断进入` 控制角色音频在被打断时如何响应，适用于免提和按住说话两种模式。它包含两个独立部分：中断发生时播放如何淡出，以及 SDK 多快能检测到用户已经开始说话。

| 字段               | 类型                  | 默认值    | 描述                                                   |
| ---------------- | ------------------- | ------ | ---------------------------------------------------- |
| `平滑中断`           | `布尔值`               | `true` | 在请求或确认中断时，将角色音频在本地淡出到静音，而不是在单个音频帧上直接切断播放。            |
| `FadeOutSeconds` | `float`             | `0.12` | 淡出持续时间。限制为 `0.04`–`0.25` 秒。                          |
| `客户端检测`          | `ClientBargeInMode` | `已禁用`  | 可选的原生客户端语音检测，可在服务器自身检测确认用户正在说话之前，对角色音频进行压低音量或中断。见下文。 |

`平滑中断` 同样适用于原生 LiveKit 播放和 WebGL 浏览器播放。当触发中断时，当前活动的角色流会通过一个短暂的增益包络淡出到静音，并且来自被中断响应的传入音频会被抑制，直到下一次响应开始——因此诸如口型同步之类的展示系统会随着音频一起稳定下来，而不会在中断后继续播放。

```csharp
var options = TurnTakingOptions.CreateHandsFreeDefault();
options.BargeIn.SmoothInterruption = true;
options.BargeIn.FadeOutSeconds = 0.12f;
options.BargeIn.ClientDetection = ClientBargeInMode.Disabled;
```

#### `ClientBargeInMode`

| 值        | 行为                                                     |
| -------- | ------------------------------------------------------ |
| `已禁用`    | 无客户端语音检测。服务器仍是检测和确认中断的唯一权威。                            |
| `Silero` | 原生客户端会针对现有麦克风流运行本地 Silero 语音活动模型，以提前检测语音，而无需开启第二个采集会话。 |

`Silero` 需要 Unity Inference Engine 包 `com.unity.ai.inference` 版本 `2.2.1` 或更高版本。如果该包不可用，或当前传输层未暴露麦克风 PCM，SDK 会记录警告并回退到仅服务器端中断。

自动的客户端触发中断还需要 `LocalAudioPolicy.EnableAcousticEchoCancellation` 以及一个已成功初始化且带有活动渲染音频引用的回声消除路径。仅启用 AEC 并不能在该处理路径未能启动时授权客户端中断。没有 AEC 时，本地语音候选仍可在本地压低角色播放音量，但服务器仍是提交中断的权威——这可防止角色音频泄漏回麦克风并反复打断自身。

`Silero` 客户端检测仅限原生平台。WebGL 只接收平滑中断，但始终使用服务器检测。

***

### `ServerSttInitialState`

控制会话开始时是否启用 Convai 的语音转文本。

| 值            | 行为                                                                                                                                                                 |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `UseDefault` | 服务器端默认值：免提启用 STT，按住说话禁用 STT。                                                                                                                                       |
| `已启用`        | 无论模式如何，STT 都会在启动时启用。                                                                                                                                               |
| `已禁用`        | 无论模式如何，STT 都会在启动时禁用。若要在运行时手动对 Convai 的语音转文本进行静音或取消静音，请调用 `SetSttMuted(bool)` 时自行注册 `IConvaiRoomConnectionService`，可通过 `ConvaiManager.TryGetRoomConnectionService`. |

***

### 运行时模式切换

在不断开会话的情况下，在免提和按住说话之间切换：

```csharp
// 在会话中切换到按住说话
await _manager.SetConversationInputModeAsync(ConversationInputMode.PushToTalk);
```

`SetConversationInputModeAsync` 返回一个 `IConvaiOperation<Unit>`。切换后的活动模式可通过以下方式获取： `_manager.ActiveConversationInputMode`.

{% hint style="warning" %}
运行时模式切换会应用新模式的 `LocalAudioPolicy` 默认值。如果你切换到按住说话，麦克风将根据 `StartMutedInPushToTalk`进行静音。会话不会重新连接。
{% endhint %}

***

### 使用示例

#### 示例 1：医疗培训模拟器——带严格轮次检测的免提模式

学习者执行患者评估。AI 角色扮演患者。更短的静音阈值让对话持续推进。

```csharp
var options = new TurnTakingOptions
{
    Mode = ConversationInputMode.HandsFree,
    TurnDetection = TurnDetectionMode.Custom,
    CustomTurnDetection = new SmartTurnSettings
    {
        StopSecs = 2.0f,
        PreSpeechMs = 80,
        MaxDurationSecs = 12.0f   // 学习者可以给出更长回答
    }
};
```

**预期结果：** 在学习者停止说话后约 2 秒，角色会进行回应。学习者的更长回答（描述症状、提问）最多可捕获 12 秒。

***

#### 示例 2：工厂安全演练——带回声消除的按住说话

安全培训师在嘈杂的工厂模拟环境中与 AI 安全员互动。按住说话可防止环境噪声触发意外轮次。使用扬声器，因此启用了 AEC。

```csharp
var options = new TurnTakingOptions
{
    Mode = ConversationInputMode.PushToTalk,
    PushToTalkPolicy = new PushToTalkPolicy
    {
        InterruptBotOnPress = true,
        RequireTurnCompletionBeforeNextPress = false,   // 安全场景的紧急优先级覆盖
        TurnCompletionTimeoutMs = 6000
    },
    LocalAudioPolicy = new LocalAudioPolicy
    {
        EnableAcousticEchoCancellation = true,
        PushToTalkStartupMode = PushToTalkMicStartupMode.PrewarmMuted
    }
};
```

**预期结果：** 培训师可通过按下按钮随时打断 AI。设备扬声器不会产生回声反馈。

***

#### 示例 3：通过 UI 按钮在模式之间运行时切换

一个从免提开始、但允许主持人在实时会话中切换到按住说话的场景。

```csharp
public class InputModeToggle : MonoBehaviour
{
    [SerializeField] private ConvaiManager _manager;
    private bool _isPushToTalk;

    public async void ToggleMode()
    {
        _isPushToTalk = !_isPushToTalk;
        var mode = _isPushToTalk
            ? ConversationInputMode.PushToTalk
            : ConversationInputMode.HandsFree;

        await _manager.SetConversationInputModeAsync(mode);
    }
}
```

**预期结果：** 模式在会话中切换而不会中断连接。检查 `_manager.ActiveConversationInputMode` 以确认切换后的活动模式。

***

### 故障排查

| 症状                              | 可能原因                                                            | 修复方法                                                                                            |
| ------------------------------- | --------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| 角色在用户说完之前就中途回应                  | `StopSecs` 对于此场景的节奏来说过低                                         | 增加 `StopSecs` 提高到 2.5–3.0 `SmartTurnSettings`                                                   |
| 用户轮次的第一个词被截断                    | 语音起始检测得太晚                                                       | 增加 `PreSpeechMs` 将其调整为 80–150 毫秒 `SmartTurnSettings`                                            |
| 角色说完后，按住说话按钮仍保持锁定               | 未收到轮次完成事件（网络卡顿）                                                 | `TurnCompletionTimeoutMs` 在超时后释放锁定；降低该值，或设置 `AllowSpeechStoppedFallbackAfterSpeechStart = true` |
| 背景噪声在免提模式下触发回应                  | 环境对自动语音检测来说过于嘈杂                                                 | 切换到按住说话模式，或者提高 `StopSecs`                                                                       |
| 首次按下按住说话时有短暂延迟                  | `PushToTalkMicStartupMode` 是 `OpenOnFirstPress` — 麦克风在首次按下时初始化  | 切换到 `PrewarmMuted`                                                                              |
| 按住说话在松开后关闭麦克风的速度感觉很慢            | `ReleaseTailMs` 窗口正在运行以捕获用户语音的尾部                                | 降低 `ReleaseTailMs`，或将其设置为 `0` 以便立即关闭，但代价是可能截断最后一个词                                              |
| 角色音频在中断时不是淡出而是突然切断              | `BargeIn.SmoothInterruption` 是 `false`，或者平台不支持平滑路径              | 设置 `BargeIn.SmoothInterruption = true`；确认会话使用原生 LiveKit 或 WebGL 播放                              |
| `ClientDetection = Silero` 没有效果 | `com.unity.ai.inference` 缺失或低于 `2.2.1`，传输层未暴露麦克风 PCM，或者平台不是原生平台 | 安装/升级 Inference Engine 包；确认目标平台为原生平台，而非 WebGL                                                   |

***

### 下一步

你现在已经拥有轮流发言配置的完整字段参考。接下来阅读 Event System，了解如何在运行时响应语音、转录和情绪事件。

{% content-ref url="/pages/0bd691fc4d8a06b0dbafd0f28b11f39be6f57f9a" %}
[事件系统](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/core-concepts/event-system.md)
{% endcontent-ref %}

{% content-ref url="/pages/8c561f7c198c46628ed5818040fdaa9af3397caf" %}
[功能](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features.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, and the optional `goal` query parameter:

```
GET https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/core-concepts/turn-taking-modes.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
