リアルタイムおよびマルチモーダルエージェント
ライブで低遅延な接続を介して、リアルタイムに話し、聞き、見て、行動するエージェントを構築できます。接続先は OpenAI の Realtime API または Google の Gemini Live API です。
リアルタイムエージェントは、リクエストとレスポンスをやり取りするチャットボットではありません。開いたセッションを維持します。ユーザーのマイクから音声が継続的にストリーミングされ、モデルは音声とライブ文字起こしを返し、ユーザーが話し始めたときと話し終えたときを検出します。また、文の途中で割り込まれる(割り込み発話)ことにも対応でき、カメラからのフレームを確認し、ツールを呼び出してその結果を話すこともできます。これらすべてを、「通話」を一度も終了することなく実行できます。
ADK-Rust は初めてですか?まず 概要 と クイックスタート をお読みください。このセクションでは、 エージェント、ツール、セッションとは何かを理解していることを前提とします。
構築できるもの
| 機能 | 意味 | ページ |
|---|---|---|
| 音声会話 | VAD と割り込みに対応した双方向 PCM16 オーディオ | アーキテクチャ |
| 2 つのプロバイダー、1 つの API | OpenAI Realtime(GA)または Gemini Live。セッションごとに切り替え可能 | プロバイダー |
| サーバーサイドツール | モデルがprocess_refund(...)を呼び出し、Rustがそれを実行して、モデルが結果を伝えます | ツール |
| マルチモーダルビジョン | カメラフレームをストリーミングし、エージェントがユーザーの見せるものを認識します | マルチモーダル |
| 感情対応対話 | エージェントがユーザーの感情的なトーンを読み取り、適応します(Geminiネイティブオーディオ) | 感情対応対話 |
| 長期的な記憶 | エージェントがセッション開始時に読み取り、学習しながら整理するナレッジグラフ | メモリ |
| Web アプリ | サーバーを介して接続されたブラウザフロントエンド(マイク + カメラ) | Web アプリの構築 |
その後、4つの実行可能なサンプルアプリをご覧ください。
メンタルモデル
2つのレイヤーがあり、ほとんどのアプリケーションでは上位のレイヤーを使用します。
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(()) }
実際のアプリでは、send_text の代わりに runner.send_audio(base64_pcm16) でマイク音声をストリーミングします。また、サーバー VAD によって応答が自動的に開始されるため、create_response() は必要ありません。Web アプリの構築を参照してください。