GPT-Live 把语音交互推向实时对话

2026-07-08 33 预计阅读时间: 1 分钟
来源: openai.com AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:8 分钟

GPT-Live 被定位为新一代语音模型,目标是让人与 AI 的语音互动更自然,并且已经用于 ChatGPT Voice。这件事的重点不只是“能听能说”,而是语音模型开始更接近一场真实对话:更低的等待感、更自然的轮次切换,以及更适合移动端、客服、陪练和车载等场景的交互形态。

从“语音转文字”到“实时语音模型”

过去很多语音 AI 系统是拼装出来的:先 ASR 把声音转成文字,再把文字交给大模型,最后用 TTS 合成声音。这个链路可控、易调试,但天然会引入几类问题:

  • 延迟被多个组件叠加,用户说完后常常要等一拍。
  • 语气、停顿、打断等信息在转写阶段容易丢失。
  • 多轮对话像“语音版聊天框”,而不是自然交谈。

GPT-Live 这类模型值得关注,是因为它把语音交互视为一等输入输出,而不是文字模型外面套一圈麦克风和喇叭。来源摘要没有披露具体 API 细节,因此工程实践里要把下面的示例看作“可以这样组织实时语音应用”,而不是官方接口说明。

产品体验会先感受到变化

实时语音模型对用户体验的影响非常直接。文字聊天里,用户愿意等待几秒;语音对话里,半秒到一秒的空白都会让人觉得系统“没听懂”或者“卡住了”。

这会改变应用设计:

  • 按钮不再只是“发送”,而是“按住说话”“打断”“静音”“切换输入设备”。
  • 状态不再只有 loading,还需要区分 listening、thinking、speaking、interrupted。
  • 日志不能只存最终文本,还要记录音频片段、模型响应时间、打断次数和错误码。

对开发者来说,关键不是把一个聊天 API 换成语音 API,而是把整个交互循环改成流式、可中断、可观测。

可以这样实践:做一个可替换后端的语音代理

下面是一个最小可改造的 Python WebSocket 代理。它不假设 GPT-Live 的官方接口形态,而是演示实时语音应用常见的工程骨架:浏览器把音频分片发到后端,后端转发给语音模型服务,再把模型返回的音频或事件推回浏览器。

运行前需要改两处:

  • LIVE_MODEL_WS_URL 换成你的实时语音模型 WebSocket 地址。
  • 把鉴权 header 改成你使用的服务要求。
python -m venv .venv
source .venv/bin/activate
pip install websockets
export LIVE_MODEL_WS_URL="wss://example.com/v1/realtime"
export LIVE_MODEL_API_KEY="replace-me"
python voice_proxy.py

voice_proxy.py

import asyncio
import json
import os
import websockets

MODEL_WS_URL = os.environ["LIVE_MODEL_WS_URL"]
API_KEY = os.environ["LIVE_MODEL_API_KEY"]

async def pipe_client_to_model(client_ws, model_ws):
    async for message in client_ws:
        # 浏览器可以发送二进制音频帧,也可以发送 JSON 控制事件。
        await model_ws.send(message)

async def pipe_model_to_client(model_ws, client_ws):
    async for message in model_ws:
        await client_ws.send(message)

async def handler(client_ws):
    headers = {"Authorization": f"Bearer {API_KEY}"}

    async with websockets.connect(MODEL_WS_URL, additional_headers=headers) as model_ws:
        # 假设模型服务接受一个会话配置事件。实际字段按你的供应商文档调整。
        await model_ws.send(json.dumps({
            "type": "session.update",
            "session": {
                "input_audio_format": "pcm16",
                "output_audio_format": "pcm16",
                "turn_detection": "server_vad"
            }
        }))

        await asyncio.gather(
            pipe_client_to_model(client_ws, model_ws),
            pipe_model_to_client(model_ws, client_ws),
        )

async def main():
    async with websockets.serve(handler, "localhost", 8765, max_size=8 * 1024 * 1024):
        print("voice proxy listening on ws://localhost:8765")
        await asyncio.Future()

if __name__ == "__main__":
    asyncio.run(main())

这个代理的价值在于隔离变化。前端只连自己的 ws://localhost:8765 或生产域名;后端负责模型鉴权、会话参数、供应商切换和审计日志。等 GPT-Live 或其他实时语音模型提供明确接口时,可以替换 MODEL_WS_URL 和会话事件格式,而不用重写整套前端。

浏览器侧最小录音发送示例

下面的 HTML 可以直接打开。它会采集麦克风音频,通过 WebSocket 发给本地代理。为了保持示例短小,它使用 MediaRecorder 输出浏览器支持的音频块;如果你的模型要求 pcm16,生产环境通常需要在浏览器或后端做转码。

<!doctype html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8" />
  <title>Live Voice Test</title>
</head>
<body>
  <button id="start">Start</button>
  <button id="stop" disabled>Stop</button>
  <pre id="log"></pre>

  <script>
    const log = (line) => {
      document.querySelector("#log").textContent += line + "\n";
    };

    let recorder;
    let ws;

    document.querySelector("#start").onclick = async () => {
      ws = new WebSocket("ws://localhost:8765");
      ws.binaryType = "arraybuffer";

      ws.onopen = () => log("ws connected");
      ws.onmessage = (event) => log(typeof event.data === "string" ? event.data : "binary response received");
      ws.onerror = () => log("ws error");
      ws.onclose = () => log("ws closed");

      const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
      recorder = new MediaRecorder(stream, { mimeType: "audio/webm" });

      recorder.ondataavailable = async (event) => {
        if (event.data.size > 0 && ws.readyState === WebSocket.OPEN) {
          ws.send(await event.data.arrayBuffer());
        }
      };

      recorder.start(250);
      document.querySelector("#start").disabled = true;
      document.querySelector("#stop").disabled = false;
      log("recording started");
    };

    document.querySelector("#stop").onclick = () => {
      recorder?.stop();
      ws?.close();
      document.querySelector("#start").disabled = false;
      document.querySelector("#stop").disabled = true;
      log("recording stopped");
    };
  </script>
</body>
</html>

上线前别只测“能说话”

实时语音模型的风险边界比文本聊天更宽。上线前建议至少检查这些点:

  • 延迟:记录端到端首包时间,而不是只看后端模型耗时。
  • 打断:用户说话时模型是否停止输出,状态机是否会卡住。
  • 隐私:麦克风权限、音频留存、日志脱敏必须讲清楚。
  • 降级:实时通道失败时,是否能退回文字输入或传统语音转写。
  • 成本:持续音频流比单次文本请求更容易产生不可见消耗。

GPT-Live 的意义在于把语音交互从“功能入口”推向“主要界面”。真正落地时,工程团队要关注的不只是模型能力,还包括网络抖动、音频格式、权限体验、会话中断和监控指标。把这些基础设施做稳,实时语音才会从演示效果变成可长期运行的产品能力。


相关推荐