Voice Live APIでFoundryのエージェントを会話してみる話
Microsoft Foundry の Voice Live API は、Foundry上で構築したエージェントや生成AIモデルをリアルタイム音声会話やアバター経由で利用できるようにするためのFoundry Toolsの1つです。
音声会話に必要な音声認識(STT)、音声合成(TTS)、アバター処理といった機能をWebSocketで実現したリアルタイム音声対話 API(SDK) です。文字ベースでの使っていたエージェントを簡単に音声対話で活用できます。
最新のバージョンは 2026年4月にGAされたものになります。このバージョンで現在はSDKが提供されているのですが、先行機能としてPreview版も提供されています。SDKのバージョンもGA版とベータ版が提供されています。
実はこの記事を書いている数日前にSDKのバージョン1.2.0がリリースされていました。2026-06-01-preview版の機能も正式に提供されているようなので、後日差分更新する予定です。
現時点では、SDK V1.1.0、API 2026-06-01-previewで提供される機能をベースに解説しています。
| API バージョン | 時期 | 位置づけ |
|---|---|---|
2025-10-01 |
2025年11月 | GA。音声対話・ターン検出・function calling・Avatar といった土台 |
2026-01-01-preview |
2026年1月 | 新しい Agent 接続(agent-name)、画像入力、photo avatar、interim response などを追加 |
2026-04-10 |
2026年4月 | GA。上記のいくつかが GA 昇格。OpenTelemetry トレースが新規 GA |
2026-06-01-preview |
2026年6月 | 本記事の主対象。WebSocket アバター、smart end-of-turn ほか |
| Preview版を見るとGAに早くほしい機能が追加されていたりします。Preview版はAPIが先行していることが多くSDKだけでは検証できないです。Preview版はドキュメントが提供されているのでそれを読み解くのですが、リージョン制限があったり、フィールド名がドキュメントと違ったり、そもそも使い方が未整備で困るものもあります。 |
そこで本記事では、2026-06-01-preview の機能を実際に試してエージェントをテキスト以外の手段で活用する方法を紐解いていきたいと思います。
1記事では長くなりすぎるため、検証できた機能や動作についていくつか記事に分けていきたいと思います。今回はその最初の記事として全体をとらえられる内容でまとめてみました。
- 公式 SDK の状況
-
2026-06-01-previewの実機検証 : 9つの追加機能のうち、何が動いて何が動かないのか -
旧バージョンの非互換:
agent-idの廃止(2026年8月31日)
検証に使ったコードはこちらで公開しています。
SDKとAPIの関係
Voive Liveに関する機能を利用する場合は、大きく2つの手段があります。
- SDK : .NET,Pythonといった言語で書かれているライブラリ。Voice Live APIを各言語で扱いやすいようにラッピングしたもの
- Voice Live API: WebScoket通信を軸にしたリアルタイム通信
.NET の公式 SDKはVoice Live APIのラッパー的な位置づけなので、使用するAPIバージョンと指定することができます。 Azure.AI.VoiceLive (GA 1.1.0) が持つ ServiceVersion は、次の2つです。
V2025_10_01V2026_01_01_PREVIEW
つまり最近の更新である 2026-04-10 と 2026-06-01-preview は SDK 経由では指定できません。6月版の機能を触るには、wire プロトコル(WebSocket)を直接叩くクライアントが必要になります。
公式 SDK を使って 2026-06-01-preview の新機能を試そうとしても、そもそもバージョンを選べません。最新のPreview版はAPIを直接利用するしかないと思った方がいいと思います。
このため、本記事のリポジトリには性格の違うコンソールが2つ入っています。
| 何を使うか | 到達できる API 版 | 用途 | |
|---|---|---|---|
| SDK コンソール | 公式 SDK Azure.AI.VoiceLive
|
2026-01-01-previewまで |
本番利用. 安定した機能の利用する場合。 |
| Core コンソール | 自作の wire クライアント | 2026-06-01-preview |
最新のプレビュー機能を検証する場合 |
以降の検証は、断りがない限り Core コンソールでの結果です。
2026-06-01-preview の機能
6月版で追加された機能
本記事の主題です。2026-04-10 の上に積まれたプレビュー機能を、実機で確認した結果が次のとおりです。
| 機能 | 何をするものか | 検証結果 |
|---|---|---|
| WebSocket アバター |
output_protocol=websocket を指定すると、アバター映像が response.video.delta イベントで同じ WebSocket に流れてくる。WebRTC/SDP が不要になる |
〇 |
| Smart end-of-turn detection | 入力音声を直接処理して発話の終わりを判定する新モード | 〇 |
parallel_tool_calls |
1ターン内で複数のツールを並列に呼び出す | 〇 |
azure-realtime-native voice |
azure-realtime モデル専用のボイス(ava ほか11種) |
〇 |
| Client-side echo cancellation reference | エコー除去の参照信号に、サーバ内部の TTS ではなく実際に再生された音を使う | 〇 |
| Hosted agent invocation events | Foundry のエージェントをセッションのツールとして呼ぶ(foundry_agent)。 |
〇 |
| Pre-generated assistant message | 決めておいたテキストをモデルに生成させず TTS だけで発話する | 〇 |
| WebRTC 音声接続の追加イベント | ブラウザ/モバイルから音声を WebRTC で直結する経路(/calls)を追加 |
〇 |
| Streaming text input |
input_text.delta / .done でテキストを増分入力する。Pre-generated assistant messageのストリーミング版. |
× |
Streaming text input だけが現時点では動きませんでした。 テキストをストリーミングで送ることで読み上げをリアルタイムで実施する機能のようなのですが、最初に送信データを開く手段が提示されていないため実施できませんでした。本来はこの機能の開始を宣言することで内部管理用のIDが取得でき、そのID情報を使ってテキストをストリーミングする仕様のようです。そのアイテムをクライアント側から開く手順が、ドキュメントにもサンプルにも存在しません。ただ、サーバ側には機能実装済みのためIDに関するエラーが通知されていました。
現時点でクライアントから同じ目的を達するには、Pre-generated assistant message(文章を一括でおくる) を使うことになります。
azure-realtime-native voice は動作しましたが、azure-realtime モデルは tools に対応していません。また利用できるリージョンが限られます。詳細は後述します。
それ以外の機能(GA含)
6月版だけを見ても全体像が分からないので、それ以前から使えるものを以下に整理してみました。
| 機能 | 状況 |
|---|---|
| 音声リアルタイム会話(STT + LLM + TTS) | GA。2025-10-01 から |
| ターン検出(server VAD / semantic VAD) | GA |
| Function calling(tools) | GA。AIモデル用 |
| Avatar(WebRTC 映像) | GA |
新 Agent 接続(agent-name) |
2026-04-10 で GA 昇格 |
| MCP サーバ統合 | 2026-04-10 で GA 昇格 |
| Proactive messages(エージェントが先に話しかける) | 2026-04-10 で GA 昇格 |
| Auto-truncation(割り込み時の音声履歴切り詰め) | 2026-04-10 で GA 昇格 |
| OpenTelemetry トレース |
2026-04-10 で新規 GA |
画像入力(image_url) |
プレビュー。Model・Agent とも動作 |
Photo avatar(vasa-1) |
プレビュー。標準・カスタムとも動作 |
| Interim response(ツール処理などの待ち時間中にエージェントに応答させる) | プレビュー |
旧バージョンの非互換 : agent-id の廃止(2026年8月31日)
Foundry Agent Service のエージェントに接続する classic 方式(agent-id)は、2026年8月31日に廃止されます。Foundryのエージェント呼出しはagent-idからagent-nameに変更されています。agent-idは旧Microsoft Foundryでのエージェントの識別方法でした。新しいFoundryではエージェントの名前とバージョンで呼び出す方式に変割っています。
接続 URL のクエリパラメータの変更
| classic(廃止予定) | new(現行) | 備考 |
|---|---|---|
agent-id |
agent-name |
ID 指定から名前指定へ |
agent-project-name |
agent-project-name |
変更なし |
agent-access-token |
廃止 |
Authorization: Bearer で処理する |
| — | agent-version |
追加。エージェントのバージョンを固定できる |
| — | conversation-id |
追加。会話を継続できる |
| — | foundry-resource-override |
追加。別リソースを指定できる |
| — | agent-authentication-identity-client-id |
追加。マネージド ID を使う |
実際に URL を組み立てている箇所を並べると、差分がはっきりします。
classic (agent-id)
private Uri BuildAgentConnectionUri()
{
var baseUri = endpoint.TrimEnd('/').Replace("https://", "wss://").Replace("http://", "ws://");
var uri =
$"{baseUri}/voice-live/realtime?api-version={options.ApiVersion}&agent-project-name={AgentProjectName}&agent-id={AgentId}";
return new Uri(uri);
}
new (agent-name)
private Uri BuildAgentByNameConnectionUri()
{
var baseUri = endpoint.TrimEnd('/').Replace("https://", "wss://").Replace("http://", "ws://");
var uri =
$"{baseUri}/voice-live/realtime?api-version={options.ApiVersion}&agent-project-name={AgentProjectName}&agent-name={AgentName}";
if (!string.IsNullOrEmpty(AgentVersion))
{
uri += $"&agent-version={AgentVersion}";
}
return new Uri(uri);
}
呼び出し側は次のようになります。
var client = new VoiceLiveClient(endpoint, credential);
// classic: 2026-08-31 で廃止
var session = await client.StartAgentSessionAsync(projectName, agentId);
// new: agent-name を使う。agentVersion は任意
var session = await client.StartAgentSessionByNameAsync(
projectName,
agentName,
sessionOptions,
agentVersion: null);
カスタム WebSocket 実装でも、やることはパラメータの差し替えだけです。接続方式そのものが無くなるわけではないので、移行コストは大きくありません。
移行時の注意点
パラメータを差し替えるだけでは動かない箇所が2つあります。
1. Entra ID 認証が必須
新方式では API キー認証が使えません。agent-access-token が廃止され、Authorization: Bearer での認証に一本化されています。キー認証で動かしていた場合は、認証まわりの実装ごと差し替えることになります。ここが移行作業の実質的な本体です。
2. custom agent に instructions を送らない
Agent セッションでは、プロンプト・ツール・メモリをエージェント側(クラウド)で管理します。クライアントから instructions を送る設計になっていないため、AI Model セッションのつもりで書いていると噛み合いません。
AI Model セッションと Agent セッションは、認証もツールの実行場所も違います。Model はクライアントが宣言したツールを function_call として受け取ってローカルで実行しますが、Agent ではツールはエージェント側で管理・実行されます。同じ感覚で移植すると動きません。
2026-06-01-preview版の検証時に困った話
公式ドキュメントの記述そのものが誤っている、あるいは食い違っているものがあり検証時に色々試していました。preview版なので一部使いやすさが少し足りていない、情報不足があるのは仕方がないですね。検証時にハマったことを2つ程参考までに上げておきます。
1. interim_response のキーはすべて snake_case
ツール処理などの待ち時間時にエージェントが応答する際の設定項目として interim_response があるのですが、公式 API リファレンスの JSON 例ではハイフン区切りで書かれています(interim-response / llm-interim-response)。これは誤記です。
正しくはすべて snake_case です。
{
"interim_response": {
"type": "llm_interim_response",
"triggers": ["latency", "tool"]
}
}
static_interim_response / llm_filler / static_filler も同様です。ハイフンで書くと単に無視されるため、失敗したかもわからない事態に。
2. 画像入力のフィールド名は image_url
画像を送るときのフィールド名が、SDK の型定義や一部ドキュメントと実サーバで食い違っています。実際に通るのは image_url です。
{
"type": "conversation.item.create",
"item": {
"type": "message",
"role": "user",
"content": [
{ "type": "input_image", "image_url": "data:image/jpeg;base64,..." }
]
}
}
この画像入力は以前 Foundry上のエージェントを利用する場合は失敗していましたが、現在は Model・Agent の両方で通ります(2026年8月に再確認)。
まとめ
2026-06-01-preview を実施に試してみました。
- 9機能のうち8つは動作しました。Streaming text input も「未対応」ではなく、プレビュー段階で使い方が未整備**という状況のようです
- 2026年6月プレビュー版は公式 SDK からは選べません。試すには Voice Live APIを直接扱うクライアントが必要です
-
agent-idは 2026年8月31日に廃止されます。 - エージェントの利用はEntra ID 認証必須になります。
- ドキュメントと実サーバの食い違いが複数あります。実機の挙動を正とするのが結果的に近道でした
本記事で試したいくつかの機能は別記事でも紹介していければと思っています。候補として以下の内容を考えています。
- Voice Live のアバターはどれを選ぶか(標準・写真・ビデオの使い分け)
- 30秒の音声で「自分の声」を作りエージェントに対応させる(Personal Voice)
- Hosted Agent を Voice Live のツールとして呼ぶ
- WebSocket アバターと WebRTC アバターの使い分け
- エコー除去の参照信号を client 側で作る