实时提供方

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-realtimeGA 语音转语音模型。速度快,工具使用能力强。默认选择。
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-realtimegemini-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_MODELGEMINI_REALTIME_MODEL),这样你就可以在不重新编译的情况下 锁定某个模型。

能力矩阵

OpenAI gpt-realtimeGemini 3.1-flash-liveGemini 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 正是运维人员会扩大日志收集与保留范围的时候。