> 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.md).

***

### 模式比较

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

***

### `TurnTakingOptions` — 根字段

`TurnTakingOptions` 是顶层配置对象。将其设置在 `ConvaiRoomManager` 中（内联）或通过一个 `ConvaiRoomManagerProfile` 资源，或者将其传递给 `RoomSessionConnectOptions` 以进行每个连接的覆盖。

| 字段                    | 类型                      | 默认           | 说明                                         |
| --------------------- | ----------------------- | ------------ | ------------------------------------------ |
| `模式`                  | `ConversationInputMode` | `HandsFree`  | 为此会话设置当前活动的对话模式。                           |
| `TurnDetection`       | `TurnDetectionMode`     | `UseDefault` | 控制自动结束轮次检测。仅在免提模式下适用。                      |
| `CustomTurnDetection` | `SmartTurnSettings`     | 见下文          | 精细调优的智能轮次参数。仅在 `TurnDetection` 是 `Custom`. |
| `InitialServerStt`    | `ServerSttInitialState` | `UseDefault` | 控制会话开始时是否启用 Convai 的语音转文本。                 |
| `LocalAudioPolicy`    | `LocalAudioPolicy`      | 见下文          | 此设备上的麦克风行为。适用于两种模式。                        |
| `PushToTalkPolicy`    | `PushToTalkPolicy`      | 见下文          | 按键通话交互规则。仅在按键通话模式下适用。                      |
| `BargeIn`             | `BargeInOptions`        | 见下文          | 角色打断行为——平滑音频淡出和可选的客户端语音检测。适用于两种模式。         |

***

### 免提模式

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

#### `TurnDetectionMode`

控制如何检测轮次结束。

| 值            | 行为                                           |
| ------------ | -------------------------------------------- |
| `UseDefault` | Convai 默认的服务器端语音活动检测。适用于大多数情况。               |
| `Disabled`   | 不进行自动轮次检测。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`                      | `bool` | `true`  | 在按下和松开按键通话控件时，对 Convai 的语音转文本进行静音和取消静音。可降低成本并防止意外处理背景音频。                                     |
| `InterruptBotOnPress`                        | `bool` | `true`  | 如果用户按下按键通话时角色正在说话，则立即打断角色，以便用户开始发言。                                                          |
| `RequireTurnCompletionBeforeNextPress`       | `bool` | `true`  | 用户必须等角色完整回应结束后才能再次按下按键通话。防止轮次重叠。                                                             |
| `TurnCompletionTimeoutMs`                    | `int`  | `5000`  | 备用超时，单位毫秒。如果角色的轮次完成事件从未到达（例如网络小故障），则会在超时后释放按键通话锁。                                            |
| `AllowSpeechStoppedFallbackAfterSpeechStart` | `bool` | `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`         | `bool`                     | `true`         | 在按键通话模式激活时，麦克风以静音状态开始。只有在按住按键通话控件时才会捕获音频。        |
| `EnableAcousticEchoCancellation` | `bool`                     | `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
    }
};
```

***

### 插话与打断

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

| 字段                   | 类型                  | 默认         | 说明                                              |
| -------------------- | ------------------- | ---------- | ----------------------------------------------- |
| `SmoothInterruption` | `bool`              | `true`     | 在请求或确认打断时，将角色音频在本地淡出为静音，而不是在一个音频帧上直接切断播放。       |
| `FadeOutSeconds`     | `float`             | `0.12`     | 淡出所需时长。限制为 `0.04`–`0.25` 秒。                     |
| `ClientDetection`    | `ClientBargeInMode` | `Disabled` | 可选的原生客户端语音检测，可在服务器确认用户正在说话之前，先对角色音频进行压低或打断。见下文。 |

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

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

#### `ClientBargeInMode`

| 值          | 行为                                                      |
| ---------- | ------------------------------------------------------- |
| `Disabled` | 不进行客户端语音检测。由服务器作为检测和确认打断的唯一权威来源。                        |
| `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 都以启用状态开始。                                                                                                                                         |
| `Disabled`   | 无论模式如何，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                                                 |

***

### 下一步

你现在已经获得了轮次切换配置的完整字段参考。接下来阅读事件系统，了解如何在运行时对语音、转录和情感事件做出响应。

{% 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
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=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
