跳转至

语音频道

Discord 语音频道中的实时语音对话,以及独立的语音消息附件格式。

语音

Discord 有两种不同的语音形态:实时语音频道(连续对话)和语音消息附件(波形预览格式)。网关两者都支持。

语音频道

设置检查清单:

  1. 在 Discord 开发者门户中启用 Message Content Intent。
  2. 当使用角色/用户允许列表时,启用 Server Members Intent。
  3. 使用 bot 和 applications.commands 作用域邀请机器人。
  4. 在目标语音频道中授予 Connect、Speak、Send Messages 和 Read Message History 权限。
  5. 启用原生命令(commands.native 或 channels.discord.commands.native)。
  6. 配置 channels.discord.voice。

使用 /vc join|leave|status 控制会话。该命令使用账户默认代理,并遵循与其他 Discord 命令相同的允许列表和组策略规则。请在 Discord 消息输入框中以斜杠命令形式输入,而不是在 shell 中:

/vc join channel:<语音频道ID>
/vc status
/vc leave

在加入前检查机器人的有效权限:

openclaw channels capabilities --channel discord --target channel:<语音频道ID>

自动加入示例:

{
  channels: {
    discord: {
      voice: {
        enabled: true,
        model: "openai/gpt-6-astra",
        autoJoin: [
          {
            guildId: "123456789012345678",
            channelId: "234567890123456789",
            whenOccupied: true,
          },
        ],
        allowedChannels: [
          {
            guildId: "123456789012345678",
            channelId: "234567890123456789",
          },
        ],
        daveEncryption: true,
        decryptionFailureTolerance: 24,
        connectTimeoutMs: 30000,
        reconnectGraceMs: 15000,
        realtime: {
          provider: "openai",
          model: "gpt-realtime-2.1",
          speakerVoice: "cedar",
        },
      },
    },
  },
}

Discord 中的 GPT-Live

Discord 可以使用与 Talk、 Google Meet 和 Voice Call 相同的 GPT-Live 模型和语音。 这些形态共享 provider 解析、原生委派和打断策略, 同时保留各自的音频传输方式。未显式固定的 Discord 配置会保留 provider 的现有默认值;如需使用 GPT-Live,请显式选择。 对于使用 cove 的 Codex GPT-Live 路由,请先使用 openclaw models auth login --provider openai 登录,然后配置:

{
  channels: {
    discord: {
      voice: {
        enabled: true,
        realtime: {
          provider: "openai",
          model: "gpt-live-1-codex",
          speakerVoice: "cove",
        },
      },
    },
  },
}

该路由复用 Talk 的 Gateway 持有的 WebRTC 桥接,优先使用 ChatGPT OAuth, 其次使用 Platform API 密钥回退。对于公共 API,请选择 gpt-live-1 和 受支持的公共语音(如 marin);Discord 使用 Gateway 的 直接 Platform 密钥 WebSocket 桥接。模型和语音必须属于同一个 路由:cove 是 Codex GPT-Live 语音,将其与 gpt-live-1 一起选择时会回退到 marin。参见 OpenAI 语音与语音合成。

GPT-Live 自行控制响应时序和打断。Discord 播放其连续 音频时不会等待 completed-response 事件,也不会添加本地 speaker-start 打断。播放期间麦克风音频仍被允许进入, 因此 GPT-Live 可以自己听到并处理打断。委派任务使用路由后的 OpenClaw 代理, 并保留发起说话人的 Discord 身份和工具权限。房间控制 在请求其语音结果之前会清除已缓冲的本地播放内容;这些控制操作 保持连续 provider 流开启,以便它能够传递该结果。 Gateway 持续向麦克风输入节流,包括各说话人 捕获之间的静音。播放会在活跃流中保留静音 PCM,包括在 之前语音已播放完毕之后到达的暂停。当播放器的两秒空闲宽限期内 没有尚未播放的语音时,已接受的音频会在房间播放器释放前先排空。 在退出期间到达的语音会在新的资源下排队,因此不会随旧流被丢弃。 连续播放会构建一个 120 毫秒的启动缓冲区,以吸收短暂的投递 间隙。120 毫秒的启动截止时间可避免短回复等待 completed-response 事件。

GPT-Live 不支持主机强制的唤醒词门控,也不支持每次回复前强制咨询。 其默认关闭这些策略。显式的 requireWakeName: true 或 consultPolicy: "always" 会在启动时因 配置错误而失败;请移除这些设置,或在需要主机控制轮流发言的共享会议中选择 gpt-realtime-2.1。每个说话人仍然拥有 独立的语音模型连接;OpenClaw 代理对话提供 共享房间上下文。

注意:

  • 下方 OpenAI agent-proxy 响应和唤醒词策略需要 GA realtime 模型,例如 gpt-realtime-2.1。GPT-Live 遵循上文所述的 provider 自有响应和委派流程。
  • Discord 语音对纯文本配置是可选启用的;设置 channels.discord.voice.enabled=true(或保留现有的 channels.discord.voice 块)以启用 /vc 命令、语音运行时和 GuildVoiceStates 网关 intent。channels.discord.intents.voiceStates 可以显式覆盖 intent 订阅;将其留空则跟随有效的语音启用状态。
  • voice.mode 控制对话路径。默认值是 agent-proxy:实时语音前端负责轮次时序、打断和播放,通过 openclaw_agent_consult 将实质性工作委派给路由后的 OpenClaw 代理,并将结果视为该说话人输入的 Discord 文本提示。stt-tts 保留旧的批量 STT 加 TTS 流程。bidi 让实时模型直接对话,同时通过 openclaw_agent_consult 暴露 OpenClaw 大脑。
  • 实时语音将每个说话人的音频放在独立的 provider 连接中,因此延迟的转录和工具调用会保留该说话人的 Discord 身份。所有人仍然使用同一个路由后的 OpenClaw 代理对话和一个房间播放队列。直接 bidi 对话历史属于每个说话人的实时连接;共享房间历史请使用 OpenClaw 代理咨询。多个说话人可能消耗更多 provider 连接,且 provider 账户限额仍然适用。房间最多保留八个说话人连接,并会在其捕获、请求和播放完成后回收空闲连接。
  • voice.agentSession 控制哪个 OpenClaw 对话接收语音轮次。留空则使用语音频道自身的会话,或设置为 { mode: "target", target: "channel:<文本频道ID>" },使语音频道充当现有 Discord 文本频道会话(如 #maintainers)的麦克风/扬声器扩展。
  • 从 Discord 语音引导正在运行的代理需要后端能够在派发时重新检查说话人的权限。Copilot 目前缺少此受保护输入能力;状态和取消仍然可用,并且可以启动新请求。
  • voice.model 覆盖 Discord 语音响应和实时咨询所用的 OpenClaw 代理大脑。留空则继承路由后的代理模型。它与 voice.realtime.model 是分开的。
  • voice.followUsers 允许机器人随选定用户加入、移动和离开 Discord 语音。参见语音中跟随用户。
  • agent-proxy 通过 discord-voice 路由语音,这会为说话人和目标会话保留正常的 owner/工具授权,但会隐藏代理的 tts 工具,因为 Discord 语音自己拥有播放权。默认情况下,agent-proxy 为 owner 说话人提供完全的 owner 等效工具访问权限(voice.realtime.toolPolicy: "owner")。支持主机控制轮次的模型强烈倾向于在实质性回答前咨询 OpenClaw 代理(voice.realtime.consultPolicy: "always");GPT-Live 使用 provider 自有委派,consultPolicy 为 "auto"。在 always 模式下,实时层不会在咨询答案到达前自动说出填充内容;它会捕获并转录语音,然后说出路由后的 OpenClaw 答案。如果多个强制咨询答案在 Discord 仍在播放第一个答案时完成,后续的精确语音答案会排队,直到播放空闲,而不会在句子中途替换语音。
  • 当 Discord 播放暂时落后时,实时语音会缓冲生成的音频,并容忍短暂的 provider 或网络间隙。每个 provider 响应都会保留自己的缓冲音频,包括原生工具延续。正常背压不会取消响应,并且排队的答案会等到 Discord 播放完上一个答案后再播放,即使其 provider 响应或音频编码器已经完成。
  • GA OpenAI Realtime 和 xAI 打断会将每个保留的原生音频项截断为 Discord 已消费的量。排队的项在零处丢弃,已经播放完毕的已完成回复保持完整。播放进度在同一响应中的临时间隙中仍然有效;GA OpenAI Realtime 的 echo guard 使用保留项的组合已消费时长。GPT-Live 原生处理打断,不使用音频项截断。
  • 如果某个说话人的实时连接失败,其他说话人会保持连接。请检查 realtime speaker failed 日志,并再次尝试说话以打开新连接。如果在 /vc join 期间初始 provider 连接失败,加入会失败,而已连接的录音器会继续录音;请检查 realtime session failed terminally 日志并重试 /vc join。临时 provider 重连不会结束 Discord 语音会话。
  • 在 stt-tts 模式下,STT 使用 tools.media.audio;voice.model 不影响转录。
  • stt-tts 回复会保持活跃,直到 Discord 播放完毕;长响应不会被固定的一分钟播放截止时间截断。
  • 在实时模式下,voice.realtime.provider、voice.realtime.model 和 voice.realtime.speakerVoice 配置实时音频会话。对于 OpenAI Realtime 2.1 加 Codex 大脑,请使用 voice.realtime.model: "gpt-realtime-2.1" 和 voice.model: "openai/gpt-6-astra"。
  • 实时语音模式在可用时使用主机共享的 agent-context 解析器。它会告诉模型:它代表一个拥有多个会话的 OpenClaw 代理发言,并默认包含小的 IDENTITY.md、USER.md 和 SOUL.md 配置文件,以便快速直接轮次保持与路由代理相同的身份、用户锚定和人设。设置 voice.realtime.bootstrapContextFiles 为子集以自定义配置文件,或设为 [] 以省略它们但保留 agent-context 段落。在 OpenClaw 2026.9.6 上,插件保留该主机的仅配置文件上下文行为;[] 省略该上下文,且没有更新的多会话段落。两条路径都使用主机的 bootstrap 钩子和工作区访问。此设置仅支持这些配置文件;AGENTS.md 保留在正常代理上下文中。注入的配置文件上下文不会取代 openclaw_agent_consult 进行工作区工作、获取当前事实、记忆查找或工具支持的动​​作。
  • 在 OpenAI agent-proxy 实时模式下,唤醒词门控默认会适应房间:一个人可以不加唤醒词自然说话,而两个或更多人类必须以唤醒词开始或结束一轮。其他机器人不计为人类。设置 voice.realtime.requireWakeName: true 以始终要求唤醒词,或设为 false 以从不要求。配置的唤醒词必须是一个或两个词。如果 voice.realtime.wakeNames 未设置,OpenClaw 使用路由代理的 name 加 OpenClaw,回退到代理 id 加 OpenClaw。活跃的唤醒词门控会禁用实时 provider 自动响应,将接受的轮次路由到 OpenClaw 代理咨询路径,并在最终转录到达前从部分转录中识别出精确的前导唤醒词时给出简短的语音确认。模糊名称匹配会等待最终转录,因此未完成的普通词不会触发确认。该策略会跟随实时的加入和离开,而不会重连语音。

  • OpenAI 实时提供程序接受当前的 Realtime 2 事件名称,以及用于输出音频和转录事件的旧版 Codex 兼容别名,因此兼容的提供程序快照可以漂移而不会丢弃助手音频。

  • 对于基于响应的模型,voice.realtime.bargeIn 控制有声音的麦克风输入是否会打断正在进行的实时播放。仅靠静默数据包和说话者开始通知不会打断播放。如果未设置,则遵循实时提供程序的输入音频打断设置。GPT-Live 忽略此设置,因为它自行管理打断。
  • voice.realtime.minBargeInAudioEndMs 控制 GA OpenAI Realtime 打断截断音频前的最短助手播放时长。默认值:250。在低回声房间中设为 0 可立即打断,或在高回声扬声器设置中调高。这不适用于 GPT-Live。
  • voice.tts 仅覆盖 stt-tts 语音播放的 tts;实时模式改用 voice.realtime.speakerVoice。若要在 Discord 播放中使用 OpenAI 语音,请设置 voice.tts.provider: "openai",并在 voice.tts.providers.openai.speakerVoice 下选择文本转语音(Text-to-speech)声音。在当前 OpenAI TTS 模型上,cedar 是一个听起来不错的男性化选择。
  • Discord 按频道的 systemPrompt 覆盖会应用于该语音频道的语音转录轮次。
  • 当 OpenClaw 加入语音频道时,路由的代理会话会收到一个包含当前参与者名单的静默系统事件。之后的参与者加入和离开会更新该会话,但不会触发未经请求的语音回复;Discord 显示名称被视为不可信的标签。经授权的语音轮次也会收到一份新鲜的名单快照。
  • 语音转录轮次和 /vc 命令使用 commands.ownerAllowFrom 中的 Discord 条目来确定所有者状态。当没有配置 Discord 命令所有者时,所选 Discord 账户的 allowFrom(或旧版 dm.allowFrom)仍可授权语音访问,但不会授予所有者状态。代理工具可见性遵循路由会话所配置的工具策略。
  • 经授权的说话者可以要求代理通过 talk_voice 列出或更改当前实时通话的语音,而无需配置命令所有者。更改适用于共享房间,并保持已保存的语音默认值不变。语音控制仍绑定到已接纳的轮次,并在通话结束、轮次完成或取消、或其访问策略改变时停止;其他仅限所有者的工具保留其通常的权限。
  • 已取消或已撤销的语音轮次不会作为新的代理请求重试。离开会阻止待处理的批处理轮次启动代理工作或语音合成。已经运行的工作可以完成;转录录制单独管理。
  • 如果 voice.autoJoin 对同一个服务器(guild)有多个条目,OpenClaw 会加入该服务器最后配置的频道。
  • voice.autoJoin[].whenOccupied 默认值为 false。对于自动管理的房间,如果希望仅在至少有一名人类在场时才包含机器人,请将其设为 true。OpenClaw 在第一名人类到达时加入,并在最后一名人类离开后离开;OpenClaw 机器人和其他机器人不计入。启动、全新的网关会话和恢复的网关会话都会根据 Discord 的语音状态名单进行同步。
  • 占用管理只拥有它加入的会话。手动 /vc join、独立的仅转录会话、跟随用户会话、另一个频道中的活动会话,或其他临时加入,在配置的房间清空时不会被移动或断开。将转录捕获附加到占用管理会话会保留该所有权。
  • voice.allowedChannels 是一个可选的驻留白名单。保持未设置以允许 /vc join 加入任何已授权的 Discord 语音频道。设置后,/vc join、启动时自动加入和机器人语音状态移动将限制为列出的 { guildId, channelId } 条目。将其设置为空数组可拒绝所有 Discord 语音加入。如果 Discord 将机器人移出白名单,OpenClaw 会离开该频道,并在有可用的配置自动加入目标时重新加入。
  • voice.daveEncryption 和 voice.decryptionFailureTolerance 会透传给 @discordjs/voice 的加入选项;上游默认值为 daveEncryption=true 和 decryptionFailureTolerance=24。
  • OpenClaw 使用捆绑的 libopus-wasm 编解码器进行 Discord 语音接收和实时原始 PCM 播放。它附带固定版本的 libopus WebAssembly 构建,不需要原生 opus 附加组件。Discord 语音套接字、编解码器、播放转换和数据包节奏控制在工作线程中运行。GPT-Live 连续输出直接从其媒体工作线程传输到 Discord 播放工作线程,而不是通过 Gateway 事件循环中继每个音频块。说话者准入、代理工作和转录仍保留在 Gateway 上;繁忙的 Gateway 仍可能延迟这些控制操作。
  • DAVE 的原生加密池在第一次成员关系重新生成密钥时会为每个 CPU 初始化一个 Rayon 线程,且不计入 JavaScript Worker 数量。操作员可以通过在 Gateway 服务环境中设置 RAYON_NUM_THREADS 来限制它;OpenClaw 不设置此变量。该限制也适用于继承该环境的子进程。
  • voice.connectTimeoutMs 控制 /vc join 和自动加入尝试时对初始 @discordjs/voice Ready 的等待时间。默认值:30000。
  • voice.reconnectGraceMs 控制 OpenClaw 在销毁断开连接的语音会话之前,等待其开始重新连接的时长。默认值:15000。
  • 在 stt-tts 模式下,语音播放不会仅仅因为另一位用户开始说话而停止。为避免反馈循环,OpenClaw 在 TTS 播放期间不会接纳新的对话轮次;明确启动的捕获仍会录制该语音。请在播放结束后再说话,以进入下一个对话轮次。当启用打断时,基于响应的实时模型会将有声音的已授权麦克风输入作为打断信号接收;GPT-Live 自行处理传入音频。
  • 在 GA OpenAI Realtime 中,扬声器回声进入开放麦克风可能看起来像打断,并中断播放。对于回声较重的 Discord 房间,设置 voice.realtime.providers.openai.interruptResponseOnInputAudio: false 可防止提供程序因输入音频而自动打断。如果你仍希望有声音的 Discord 麦克风输入打断正在进行的播放,请添加 voice.realtime.bargeIn: true。GA OpenAI realtime 桥接会忽略短于 voice.realtime.minBargeInAudioEndMs 的播放截断(可能是回声/噪音),并将它们记录为已跳过,而不是清除 Discord 播放。这些控制不会覆盖 GPT-Live 的原生打断。
  • voice.captureSilenceGraceMs 控制 Discord 报告说话者已停止后,OpenClaw 在将该音频段定稿用于 STT 之前等待的时长。默认值:2000;如果 Discord 将正常停顿分成零碎的部分转录,可调高此值。
  • 当 ElevenLabs 是被选中的 TTS 提供程序时,Discord 语音播放使用流式 TTS,并从提供程序响应流开始。不支持流式的提供程序会回退到合成的临时文件路径。
  • OpenClaw 会监视接收解密失败,并在短时间内反复失败后通过离开/重新加入语音频道来自动恢复。
  • 如果更新后接收日志反复显示 DecryptionFailed(UnencryptedWhenPassthroughDisabled),请收集依赖报告和日志。捆绑的 @discordjs/voice 包含来自 discord.js PR #11449 的上游填充修复,该 PR 关闭了 discord.js issue #11419。
  • 当 OpenClaw 完成一个捕获的说话者段时,The operation was aborted 接收事件是预期出现的;它们是详细的诊断信息,不是警告。
  • 详细的 Discord 语音日志会为每个被接受的说话者段包含一条有长度限制的 STT 转录预览,因此调试时既能显示用户侧,也能显示代理回复侧,而不会倾倒无限制的转录文本。
  • 在 agent-proxy 模式下,强制咨询回退会跳过可能不完整的转录片段,例如以 ... 结尾的文本或类似 "and" 的尾部连接词,以及完整的不可执行结束语,如 "I'll be right back" 或 "bye"。提到结束语的请求(例如 "write a goodbye email")仍会到达代理。结束语检测使用有界的英语启发式规则;无法识别的措辞会继续传给代理。当日志显示 forced agent consult skipped reason=... 时,说明这阻止了一个过时的排队答案。

语音消息

Discord 语音消息会显示波形预览,并且需要 OGG/Opus 音频。OpenClaw 会自动生成波形,但需要在网关主机上安装 ffmpeg 和 ffprobe 以检查和转换。

  • 提供本地文件路径(URL 会被拒绝)。
  • 省略文本内容(Discord 会拒绝在同一负载中同时包含文本和语音消息)。
  • 接受任意音频格式;OpenClaw 会按需转换为 OGG/Opus。

代理通过 message 工具发送语音消息,而不是从 shell 发送:

message(action="send", channel="discord", target="channel:123", path="/path/to/audio.mp3", asVoice=true)

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw