实时与多模态智能体
构建能够实时交谈、倾听、观察和行动的智能体——通过与 OpenAI 的 Realtime API 或 Google 的 Gemini Live API 建立实时、低延迟的连接。
实时智能体并不是请求/响应式聊天机器人。它会保持一个开放会话:用户的麦克风持续传输音频,模型将音频和实时转录文本传输回来;它能够检测用户何时开始和停止说话,可以在句子中途被打断(插话),可以观察摄像头传来的画面,还可以调用你的工具并朗读结果——整个过程中“通话”始终不会结束。
你可以构建什么
| 能力 | 含义 | 页面 |
|---|---|---|
| 语音对话 | 支持 VAD 和插话的双向 PCM16 音频 | 架构 |
| 两个提供商,一个 API | OpenAI Realtime(GA)或 Gemini Live,可按会话切换 | 提供商 |
| 服务器端工具 | 模型调用 process_refund(...);您的 Rust 运行它,模型表达结果 | 工具 |
| 多模态视觉 | 流式传输摄像头画面——agent 能看到用户向其展示的内容 | 多模态 |
| 情感对话 | agent 读取用户的情绪语调并进行调整(Gemini 原生音频) | 情感对话 |
| 长期记忆 | agent 在会话开始时读取并在学习过程中整理的知识图谱 | 记忆 |
| Web 应用 | 通过您的服务器桥接的浏览器前端(麦克风 + 摄像头) | 构建 Web 应用 |
然后参见这四个可运行的示例应用。
心智模型
这里有两层,大多数应用使用上层:
IntegratedRealtimeRunner ← sessions, memory, tools, plugins (use this)
│ wraps
RealtimeRunner ← event loop + tool dispatch
│ drives
RealtimeSession (a transport) ← the live WebSocket to the provider
│ created by
RealtimeModel (OpenAI | Gemini)
RealtimeModel(例如OpenAIRealtimeModel、GeminiRealtimeModel)知道如何connect()并生成一个**RealtimeSession**——活动的传输层。- **
RealtimeRunner**拥有该会话:它持续处理事件;当模型请求工具时,它会执行处理程序并将结果发送回去。 - **
IntegratedRealtimeRunner**包装运行器,并将其连接到 ADK 的其余部分——SessionService(转录持久化)、MemoryService(召回 + 存储)、EnhancedPluginManager(钩子),以及一个桥接器,使任何adk-coreTool都能在实时会话中运行。示例使用的就是这一层。
(此外,还有面向简单纯语音代理的更高层RealtimeAgent,以及直接传输方式——WebRTC、LiveKit、Vertex AI
Live——相关文档请参见其中的说明。)
安装
# Voice + tools + the integration layer (recommended)
adk-realtime = { version = "2.1.0", features = ["openai", "gemini", "integration"] }
| 功能 | 添加内容 |
|---|---|
openai | OpenAI 实时功能(WebSocket) |
gemini | Gemini Live(WebSocket) |
integration | IntegratedRealtimeRunner — 会话、内存、插件、工具桥接 |
openai-webrtc | OpenAI 基于 WebRTC(需要 cmake) |
vertex-live | 通过 Vertex AI Live 使用 Gemini(OAuth2 / ADC) |
livekit | LiveKit WebRTC 桥接 |
60 秒快速入门
无头语音轮次:连接、通过文本提问,并持续处理流式回复。
use adk_realtime::config::{RealtimeConfig, VadConfig};
use adk_realtime::events::ServerEvent;
use adk_realtime::integration::{IntegratedRealtimeRunner, IntegrationConfig};
use adk_realtime::model::BoxedModel;
use adk_realtime::openai::OpenAIRealtimeModel;
use adk_session::{CreateRequest, InMemorySessionService, SessionService};
use std::sync::Arc;
# async fn run() -> anyhow::Result<()> {
let model: BoxedModel = Arc::new(OpenAIRealtimeModel::new(
std::env::var("OPENAI_API_KEY")?,
"gpt-realtime-2.1",
));
let config = RealtimeConfig::default()
.with_instruction("You are a friendly assistant. Keep replies short.")
.with_voice("marin")
.with_audio_only()
.with_vad(VadConfig::server_vad()) // model decides turn boundaries
.with_transcription(); // emit a text transcript too
let sessions = Arc::new(InMemorySessionService::new());
sessions.create(CreateRequest {
app_name: "demo".into(), user_id: "u1".into(),
session_id: Some("s1".into()), state: Default::default(),
}).await?;
let runner = IntegratedRealtimeRunner::builder()
.model(model)
.config(config)
.identity("demo", "u1", "s1")
.session_service(sessions)
.integration_config(IntegrationConfig::default())
.build()?;
runner.connect().await?;
runner.send_text("Say hello in one short sentence.").await?;
runner.create_response().await?; // text input needs an explicit trigger
while let Some(event) = runner.next_event().await {
match event? {
ServerEvent::TranscriptDelta { delta, .. } => print!("{delta}"),
ServerEvent::AudioDelta { .. } => { /* PCM16 to play */ }
ServerEvent::ResponseDone { .. } => break,
_ => {}
}
}
runner.close().await?;
# Ok(()) }
在实际应用中,你可以使用 runner.send_audio(base64_pcm16) 流式传输麦克风音频,
而不是使用 send_text,并由服务器端 VAD 自动驱动响应——无需
create_response()。请参阅构建 Web 应用。