实时提供方
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", // or "gpt-realtime-2" (reasoning)
));
| 模型 | 用途 |
|---|---|
gpt-realtime | GA 语音转语音模型。速度快,工具使用能力强。默认选择。 |
gpt-realtime-2 | 推理变体——更擅长复杂的多步请求。 |
gpt-realtime-translate | 专用翻译解释器(不同的端点;请参见 Live Translation example)。 |
- 传输: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-2.5-flash-native-audio-preview-12-2025 | 原生音频模型——最自然的语音,也是支持情感对话的模型。工具调用较弱。 |
models/gemini-3.5-live-translate-preview | 专用的 translation 模型(参见translation example)。 |
- 传输: WebSocket(
gemini功能,AI Studio)或 Vertex AI Live (vertex-live,OAuth2 / ADC — 参见 Realtime Agents)。 - 音频: 16 kHz PCM16 输入,24 kHz PCM16 输出。
- 语音:
Kore及其他;with_voice("Kore")。 - 认证:
GEMINI_API_KEY(或GOOGLE_API_KEY)。
模型名称因端点而异。 AI Studio(API-key)使用类似
models/gemini-3.1-flash-live-preview的名称;Vertex/Agent Platform 使用不同的 名称。该 crate 的GeminiLiveBackend::studio(...)目标是通过v1alpha端点连接 AI Studio(这也是情感对话所需的方式)。
选择模型
- 通用语音 + 工具 →
gpt-realtime或gemini-3.1-flash-live-preview。 两者都能可靠地调用工具。Gemini 更适合 连续视频。 - 最自然的语音 / 感知情绪 → Gemini 原生音频
(
gemini-2.5-flash-native-audio-*)配合 affective dialogue — 但工具调用可靠性会有所下降。 - 偏重推理 →
gpt-realtime-2。 - 翻译 → 专用的 translate 模型(它们自己的协议)。
为每个会话选择提供方
应用通常会从请求中读取提供方并构建匹配的 模型。音频采样率也不同,因此也要将其暴露出来:
#[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")),
"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 | Gemini 3.1-flash-live | Gemini native-audio | |
|---|---|---|---|
| 语音(音频输入/输出) | ✅ | ✅ | ✅ |
| 实时转录 | ✅ | ✅ | ✅ |
| 服务端工具 | ✅(可靠) | ✅(可靠) | ⚠️(较弱) |
| 视频帧 | ✅(图像项) | ✅(连续) | ✅(连续) |
| 情感对话 | ❌ | ❌ | ✅ |
下一步:工具 →
诊断和负载隐私
实时帧包含转录、工具参数、工具结果和标识符。当一个 已识别的事件反序列化失败时——提供方模式漂移——警告会报告一个 字段安全的摘要并扣留该帧:
| 字段 | 内容 |
|---|---|
event_type | 失败的提供方事件类型 |
error | 反序列化错误 |
payload.bytes | 以字节为单位的帧大小 |
payload.digest | 简短摘要,用于关联同一漂移的重复项 |
payload.raw | 除非编译时包含有效载荷记录,否则为 <redacted> |
注意: digest 会将一次运行中的日志行分组。它不是加密摘要, 并且在不同进程之间不稳定。
要在手头有 frame 的情况下诊断 drift,请使用
adk-realtime 并启用 record-payloads feature,它会记录前 300 字节:
[dependencies]
adk-realtime = { version = "2.0.0", features = ["openai", "record-payloads"] }
该 feature 默认关闭,并且这是按构建做出的刻意选择,因为 schema drift 正是运维人员会扩大日志收集与保留范围的时候。