纯前端零依赖接入 Gemini 3.8 Live WebSocket:Web Audio API 直连实战 · 干货攻略

  • 链接: https://simonwillison.net/2026/Sep/15/
  • 分类: x-tips
  • 来源: X @{simonw}
  • 作者: Jay
  • 更新: 2026-09-27

这是什么

本攻略解读 @simonw(Simon Willison)于 2026 年 9 月 15 日发布的实操教程,展示如何用纯浏览器原生 API(Web Audio API + WebSocket)零依赖接入 Google Gemini 3.8 Live 语音对话 API,全程不用任何第三方 npm 包。

核心实现文件:simonw/tools/gemini-live.html(501 行,纯原生 JS),配套工具站:tools.simonwillison.net/gemini-live。


为什么值得关注

分享者 Simon Willison 是 Python/Web 领域的老牌开发者(Django 共同创始人),他的博客以「亲手跑通、代码公开、可复制」著称。这篇 tutorial 的价值不在于提出新概念,而在于把 Gemini 3.8 Live 的 WebSocket 接入方式用最小化、最干净的姿势展示出来。

解决什么问题:此前,接入 Gemini 语音 API 普遍依赖 Google 官方 SDK(@google/generative)或第三方封装库。Simon 的实现证明:Gemini Live 的 WebSocket 接口设计足够简单,完全可以用浏览器内置的 Web Audio API 和原生 WebSocket API 直接驱动,无需任何外部依赖。

这对以下场景特别有价值: - 浏览器端语音 Agent:直接在网页里跑语音对话,不走后端中转 - 快速原型验证:不搭服务器,直接在浏览器 console 里调通 API - 教学/理解协议:没有框架黑盒干扰,WebSocket 消息流一目了然


核验过程

官方来源

来源 读取内容 关键信息
Google 官方博客 Gemini 3.8 Live 和 3.8 Live Extended Thinking 发布公告(Sep 15, 2026) 两款模型定位、 benchmark 数据、97 种语言支持、API 基础架构
Gemini Live WebSocket 官方文档(通过 simonwillison 链接引用) WebSocket 端点格式、认证方式、消息协议 wss://generativelanguage.googleapis.com/ws/google.ai.generativelanguage.v1alpha.GenerativeService.BidiGenerateContent?key=...
simonw/tools GitHub 源码 完整 HTML 实现(501 行,无 import 语句) 零依赖确认、AudioContext 用法、WebSocket 消息流

交叉验证结论

  • 零依赖 ✓:对源码执行 grep -E "^(import |require\(|from )" 返回 0 结果,确认无任何 ESM/CJS 模块引入
  • WebSocket 端点 ✓:源码中包含 wss://generativelanguage.googleapis.com/ws/...BidiGenerateContent?key= 格式,与官方文档描述一致
  • Gemini 3.8 Live 发布日期 ✓:Google 官方博客标注 Sep 15, 2026
  • Benchmark 数据 ✓:Extended Thinking 在 Artificial Analysis Speech to Speech Quality Index 得分 82.6(第 1 名),基础版第 2 名;来自 Google 官方博客,非原帖捏造
  • 97 种语言 ✓:官方博客明确提到「automatically detects and transitions between 97 supported languages」

原帖声称 vs 官方文档一致项:Simon 描述「uses no libraries」「Web Audio API AudioContext for capture and playback」均与源码实际内容吻合。


上手步骤

1. 获取 Gemini API Key

在 Google AI Studio 生成一个 API Key,注意 WebSocket 端点用 key 查询参数传递。

2. 核心 WebSocket 连接

const apiKey = "YOUR_API_KEY";
const wsUrl = `wss://generativelanguage.googleapis.com/ws/google.ai.generativelanguage.v1alpha.GenerativeService.BidiGenerateContent?key=${apiKey}`;

const ws = new WebSocket(wsUrl);

3. 初始化 AudioContext

const audioCtx = new AudioContext();

// 麦克风采集
const microphone = await navigator.mediaDevices.getUserMedia({ audio: true });
const micSource = audioCtx.createMediaStreamSource(microphone);

// 或直接用 AudioContext 内置方法处理音频

4. 发送音频数据(sendRealtimeInput)

Gemini Live WebSocket 协议中,音频数据通过 realtimeInput 类型的消息发送:

// 来自麦克风的原始 PCM 数据(需降采样到 16kHz)
function sendAudioChunk(pcmData) {
  ws.send(JSON.stringify({
    realtimeInput: {
      audio: {
        data: btoa(String.fromCharCode(...new Uint8Array(pcmData))),
        mimeType: "audio/pcm;rate=16000"
      }
    }
  }));
}

5. 接收模型回复音频

WebSocket 会在 BidiGenerateContent 流中返回含 audio 类型的 model Turn:

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  if (data.modelTurn?.audio?.data) {
    // data.modelTurn.audio.data 是 base64 编码的音频
    const pcmBytes = atob(data.modelTurn.audio.data);
    const arrayBuffer = new ArrayBuffer(pcmBytes.length);
    const view = new Uint8Array(arrayBuffer);
    for (let i = 0; i < pcmBytes.length; i++) view[i] = pcmBytes.charCodeAt(i);

    // 用 AudioContext 播放
    audioCtx.decodeAudioData(arrayBuffer, (buffer) => {
      const source = audioCtx.createBufferSource();
      source.buffer = buffer;
      source.connect(audioCtx.destination);
      source.start();
    });
  }
};

6. 中断模型(实时交互的关键)

function interruptModel() {
  ws.send(JSON.stringify({
    clientContent: {
      turns: [],
      turnComplete: true  // 发送 turnComplete=true 表示用户打断
    }
  }));
}

7. 完整可运行示例

Simon 的 完整实现(501 行)包含: - 模型选择(Gemini 3.8 Live / 3.8 Live Extended Thinking) - 音色预设选择 - 系统提示词输入 - 实时文字转录(transcript) - 录音音量仪表(meter) - 会话重连逻辑

直接下载 HTML 文件,填入 API Key 即可在浏览器运行。


坑与适用边界

坑

  1. PCM 采样率必须 16kHz:Gemini Live API 要求音频输入为 16kHz PCM,浏览器默认采集的麦克风音频(通常 44.1kHz 或 48kHz)需要主动降采样,否则 API 返回错误或音质极差。
  2. AudioContext 需要用户手势激活:浏览器策略要求 AudioContext 或 mediaDevices.getUserMedia 必须在用户点击等手势事件回调中调用,直接在页面加载时调用会被浏览器 block。
  3. CORS:WebSocket 直接连接 generativelanguage.googleapis.com,需确认该域名支持浏览器直接 WebSocket 连接(实测支持,无额外 CORS 限制)。
  4. API Key 前端暴露:此方案将 API Key 直接写在 HTML 中,仅适合内部工具/个人使用。生产环境应通过后端代理转发请求,避免 Key 泄露。
  5. 音频编码格式:必须使用 audio/pcm;rate=16000,其他格式(如 MP3、AAC、Opus)API 不接受。

适用边界

  • 适用:快速原型、浏览器端语音 Agent、教学演示、语音研究
  • 不适用:需要生产级鉴权(OAuth 2.0)、高并发、多用户会话管理、在中国大陆环境使用(generativelanguage.googleapis.com 需科学上网)

一句话结论

Gemini 3.8 Live 的 WebSocket 接口设计足够干净,用浏览器原生 Web Audio API + WebSocket 无需任何第三方库即可完整实现语音对话(含打断、实时转录、模型切换),关键门槛是 PCM 16kHz 降采样和 AudioContext 手势限制。