实时提供商
ADK-Rust 在同一 RealtimeModel 接口后提供两个实时后端,因此应用可以同时提供两者,并按会话进行切换。本页面介绍模型、语音、端点、身份验证以及如何进行选择。
OpenAI 实时(GA)
use adk_realtime::openai::OpenAIRealtimeModel;
use adk_realtime::model::BoxedModel;
use std::sync::Arc;
let model: BoxedModel = Arc::new(OpenAIRealtimeModel::new(
std::env::var("OPENAI_API_KEY")?,
"gpt-realtime-2.1",
));
| 模型 | 用途 |
|---|---|
gpt-realtime-2.1 | 当前的生产级语音到语音模型,也是默认选择。 |
gpt-realtime-translate | 专用的 翻译解释器(不同的端点;请参阅 实时翻译示例)。 |
- 传输:WebSocket(
openai功能)或 WebRTC(openai-webrtc,需要cmake)。 - 音频:输入和输出均为 24 kHz PCM16。
- 语音:
marin(自然的 GA 语音)、alloy及其他语音;通过RealtimeConfig::with_voice("marin")进行设置。 - 身份验证:
OPENAI_API_KEY。密钥存储在服务器上(绝不存储在浏览器中)。
Gemini Live
use adk_realtime::gemini::{GeminiLiveBackend, GeminiRealtimeModel};
let model: BoxedModel = Arc::new(GeminiRealtimeModel::new(
GeminiLiveBackend::studio(std::env::var("GEMINI_API_KEY")?),
"models/gemini-3.1-flash-live-preview",
));
| 模型 | 用途 |
|---|---|
models/gemini-3.1-flash-live-preview | 半级联实时模型。可靠地调用工具并接受视频帧。默认选择。 |
models/gemini-live-2.5-flash-native-audio | 原生音频模型——语音最自然,并支持情感对话。工具调用能力较弱。 |
models/gemini-3.5-live-translate-preview | 专用的翻译模型(请参阅翻译示例。 |
- 传输:WebSocket(
gemini功能,AI Studio)或 Vertex AI Live (vertex-live、OAuth2 / ADC — 请参阅 实时代理)。 - 音频:16 kHz PCM16 输入,24 kHz PCM16 输出。
- 语音:
Kore及其他语音;with_voice("Kore")。 - 身份验证:
GEMINI_API_KEY(或GOOGLE_API_KEY)。
模型名称因端点而异。 AI Studio(API-密钥)使用类似
models/gemini-3.1-flash-live-preview的名称;Vertex/Agent Platform 使用不同的 名称。该 crate 的GeminiLiveBackend::studio(...)通过v1alpha端点面向 AI Studio(情感对话也使用此端点)。
选择模型
- 通用语音 + 工具 →
gpt-realtime-2.1或gemini-3.1-flash-live-preview。 两者都能可靠地调用工具。对于连续视频,Gemini 更为合适。 - 最自然的语音 / 情感感知 → Gemini 原生音频
(
gemini-live-2.5-flash-native-audio)搭配情感对话 — 但工具调用的可靠性会有所降低。 - 侧重推理 →
gpt-realtime-2.1。 - 翻译 → 专用翻译模型(使用其自身的协议)。
为每个会话选择提供商
应用通常从请求中读取提供商,并构建相匹配的模型。由于音频采样率不同, 也应将其公开:
#[derive(Clone, Copy)]
enum Provider { OpenAI, Gemini }
impl Provider {
fn audio_rates(self) -> (u32, u32) { // (input, output)
match self {
Provider::OpenAI => (24_000, 24_000),
Provider::Gemini => (16_000, 24_000),
}
}
}
fn build_model(p: Provider) -> anyhow::Result<(BoxedModel, &'static str)> {
Ok(match p {
Provider::OpenAI => (
Arc::new(OpenAIRealtimeModel::new(std::env::var("OPENAI_API_KEY")?, "gpt-realtime-2.1")),
"marin",
),
Provider::Gemini => (
Arc::new(GeminiRealtimeModel::new(
GeminiLiveBackend::studio(std::env::var("GEMINI_API_KEY")?),
"models/gemini-3.1-flash-live-preview",
)),
"Kore",
),
})
}
示例允许通过环境变量覆盖所有这些设置
(OPENAI_REALTIME_MODEL、GEMINI_REALTIME_MODEL),因此无需重新编译即可固定模型。
能力矩阵
OpenAI gpt-realtime-2.1 | Gemini 3.1-flash-live | Gemini 原生音频 | |
|---|---|---|---|
| 语音(音频输入/输出) | ✅ | ✅ | ✅ |
| 实时转录 | ✅ | ✅ | ✅ |
| 服务器端工具 | ✅(可靠) | ✅(可靠) | ⚠️(较弱) |
| 视频帧 | ✅(图片项目) | ✅(连续) | ✅(连续) |
| 情感对话 | ❌ | ❌ | ✅ |
下一步:工具 →
诊断与载荷隐私
实时帧包含转录文本、工具参数、工具结果和标识符。当识别到的事件反序列化失败时——即提供商架构发生漂移——警告会报告字段安全摘要,并不提供该帧:
| 字段 | 内容 |
|---|---|
event_type | 失败的提供商事件类型 |
error | 反序列化错误 |
payload.bytes | 帧大小(字节) |
payload.digest | 短摘要,用于关联同一漂移的重复出现 |
payload.raw | 除非编译时启用了有效载荷记录,否则为 <redacted> |
**注意:**摘要会将一次运行中的日志行分组。它不是加密摘要,也不会在不同进程之间保持稳定。
要在掌握帧的情况下诊断漂移,请使用 record-payloads 功能编译 adk-realtime,该功能会记录前 300 个字节:
[dependencies]
adk-realtime = { version = "2.1.0", features = ["openai", "record-payloads"] }
默认情况下该功能处于关闭状态,并且这是每次构建时的刻意选择,因为模式漂移正是操作人员扩大日志收集范围和保留期限的时候。