0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Azure AI Foundry Voice Live APIをAIAgentで使う実装解説

Last updated at Posted at 2025-08-13

Voice Live APIのAI Agent機能について調べてみました

本記事では、Azure AI FoundryのVoice Live APIをAI Agent(AIエージェント)モードで活用するための実装方法について紹介したいと思います。前回の記事では、AI Modelモードでの基本的なVoice Live APIの利用方法を説明しましたが、今回はより高度な機能であるAI Agentモードに焦点を当てます。

現時点(2025/08/15)では、Voice Live APIはパブリックプレビューで提供されています。このため、実運用として利用することはできません。また、現在の仕様も今後変更になる可能性があります。

1. Azure AI Foundryとは

Azure AI Foundryは、開発者がAIをアプリケーションに組み込むためのオープンで柔軟、かつ安全なプラットフォームです。1,900以上のオープンソースモデルと独自モデルが提供され、それを効率的に管理することが可能です。
また、最近AIエージェントを管理する為の「Azure AI Agent Service」が提供されました。これによりAzure AI Foundry上でAI モデルを管理するだけではなく、様々な用途に応じて調整、機能拡張されたAI エージェントを開発~運用まで可能になりました。
今回は「Azure AI Agent Service」の中で提供されているパブリックプレビュー版の機能の1つ「Voice Live API」についての話になります。

Voice Live APIについての概要については以前まとめた記事を参考にして下さい。

前回記事にしたころはAI Agentの呼出しはまだ未提供だったのですが最近使えるようになりました。

AI Agent機能とAI Modelとの違い

AI Model Mode

前回解説したAI Modelモードは、Azure AI Foundryの標準的な生成AIモデル(GPT-4o等)と直接対話する機能です。基本的な音声会話機能を提供しますが、エージェントの性格や専門知識は限定的です。

AI Agent Mode

AI Agentモードは、Azure AI Foundry上で事前に設定したカスタムエージェントを利用します。このエージェントには以下のような特徴があります:

  • 専門知識の設定: 特定の分野に特化した知識を持たせることができます
  • カスタムプロンプト: エージェントの性格や回答スタイルを詳細に設定できます
  • ツール連携: Function Callingなどの機能を組み込むことができます
  • 一貫性のある対話: 設定した性格やルールを維持した対話が可能です

Voice Live API仕様(AI Agent Mode)

AI Agentモードでは、AI Modelモードと同様にWebSocket通信を使用します.

接続URL

AI Agentモードでは以下の追加パラメータが必要です:

wss://{endpoint}/voice-live/realtime?api-version={version}&agent-project-name={projectName}&agent-id={agentId}&agent-access-token={token}

必要なパラメータ:

  • agent-project-name: Azure AI Foundryのプロジェクト名
  • agent-id: 利用するエージェントのID
  • agent-access-token: エージェント用のアクセストークン(Azure AI Foundryの?)
公式サイトの説明からagent-access-tokenにはAzure AI FoundryのAPI Keyで問題ないようです。
クイック スタート: Azure AI Foundry Agent Service を使用して音声ライブ リアルタイム音声エージェントを作成する (プレビュー)](https://learn.microsoft.com/ja-jp/azure/ai-services/speech-service/voice-live-agents-quickstart?wt.mc_id=WDIT-MVP-5003104)

認証方法

AI Agentモードでは2つの認証方法をサポートしています:

  1. APIキー認証: ヘッダーにapi-keyを設定
  2. Entra ID認証: Authorization: Bearer {token}を設定
現在はAPIキーの認証ではサーバに接続することが出来ません。Entra IDを利用します。

2. まずは動かしてみましょう

まずは簡単に動作をさせてみましょう。最初にAzure AI Foundryのリソースから作成します。

環境構築 : Azure AI Foundryの準備

まずはAzure AI Foundryのリソースから作成します。手順については以前作成した記事を参考にして下さい。ここではリソース作成後の作業として今回ように使うAI Agentを作成する手順を記載します。

以降はエージェントを作成する手順です。

  1. Azure AI Foundryポータルにアクセスします。
  2. 上部メニューから先ほど作成したAI Foundryプロジェクトを選択し、左メニューからエージェントを選択します
  3. Nextボタンを押すとエージェントのベースとなるモデルの選択画面が表示されます。好みのモデルを選択し[Confirm]ボタンを押します。
  4. デプロイするモデルの設定を行います。必要に応じて調整してDeployボタンを押してモデルを作成します。
  5. 正常にデプロイが完了するとエージェントも生成されます。
  6. 生成されたエージェントを選択するとカスタマイズが可能です。Azure AI Foundryではエージェントの名前、説明のほかにも、Instruction(プロンプト)、利用する知識やツールの設定等もこの画面で行います。
[Try in playground]をクリックすると文字ベースのチャット画面が表示され、テキストベースで動作を確認することが可能です。

必要な情報の収集

作成が完了後、コンソールアプリで利用する各種環境情報を収集します。
AI Agent機能を利用するために以下の情報が必要になるので、ポータルから収集します。

  • Azure AI Service endpoint: Azure AI FoundryのエンドポイントURL
  • Azure AI Foundry - ProjectName: Azure AI Foundryのプロジェクト名
  • API Key: AzureAIFoundryのAPIキー

ポータルでの動作確認

実装などをせずにどのような形で対話ができるか確認したい場合はポータルが便利です。


先ほど作成したAIエージェントのSetupの最下部に[Go to Voice Live playground]をクリックします。


Playgroundに移動すると上記のような画面になります。中央下にあるStartボタンをおすと先ほど作成したエージェントと対話することが可能です。

次にVoice Live APIを利用してコンソールアプリからAI エージェントと会話するサンプルコードを試します。

WebSocket通信を使ったサンプルアプリでの動作確認

サンプルコードは以下のGithubに格納しています。以降の手順はこのサンプルをビルドして動作確認するまでを紹介します。

まずは、リポジトリをクローンします。

PS C:\ > git clone https://github.com/TakahiroMiyaura/VoiceLiveAPISamples.git
PS C:\ > cd VoiceLiveAPISamples

事前設定とビルド

次に先ほど控えていた各種値をアプリが使えるように情報の設定を行います。
User Secretsを使用して必要な設定を行います:

PS D:\VoiceLiveAPISamples> dotnet user-secrets init --project src\VoiceLiveConsoleApp
PS D:\VoiceLiveAPISamples> dotnet user-secrets set "Identity:AzureEndpoint" "<Token request url(ex:https://ai.azure.com/.default)>" --project src\VoiceLiveConsoleApp
PS D:\VoiceLiveAPISamples> dotnet user-secrets set "AzureAIFoundry:AgentProjectName" "<your Azure AI Foundry Project Name>" --project src\VoiceLiveConsoleApp
PS D:\VoiceLiveAPISamples> dotnet user-secrets set "VoiceLiveAPI:AzureEndpoint" "<your Azure AI Services Endpoint>" --project src\VoiceLiveConsoleApp
PS D:\VoiceLiveAPISamples> dotnet user-secrets set "AzureAIFoundry:AgentId" "<your Azure AI Agent Id>" --project src\VoiceLiveConsoleApp
PS D:\VoiceLiveAPISamples> dotnet user-secrets set "AzureAIFoundry:AgentAccessToken" "<Azure AI Foundry API Key>" --project src\VoiceLiveConsoleApp
PS D:\VoiceLiveAPISamples> dotnet user-secrets set "AzureAIFoundry:ApiKey" "<Azure AI Foundry API Key>" --project src\VoiceLiveConsoleApp

後は、プロジェクトをビルドします。

PS D:\hoge\VoiceLiveAPISamples > dotnet build src\VoiceLiveConsoleApp

ビルドが完了したら実行してみましょう。

アプリケーションの実行

アプリケーションを実行する際ですが、今回はEntra IDを利用した認証を利用します。現時点のパブリックプレビュー版ではAIエージェントとの接続にAPIKEYを用いても成功しませんでした。
(AI Modelを使う場合は接続可能)

  1. Azure AI Foundryリソースにアクセスできるユーザで認証を実施する
  2. アプリケーションを起動
  3. 接続モードで「2. AI Agent Mode」を選択
  4. 認証方法を選択(APIキーまたはEntra ID)
  5. マイクでの音声入力開始

認証については以下のコマンドを入力します。もしAzure CLIが入っていない場合はインストールしてください。コマンドを実行するとブラウザが起動し、MSアカウントのログイン画面が表示されます。いつも通りログインを行ってしばらくするとコンソール側にAzureサブスクリプション等の情報が出力されログインが完了します。

PS D:\hoge\VoiceLiveAPISamples > az login

後はビルドしたアプリを実行します。

PS D:\hoge\VoiceLiveAPISamples > .\src\VoiceLiveConsoleApp\bin\Debug\net8.0\VoiceLiveConsoleApp.exe

アプリを起動するとモードを選択するようになっていますので[AI Agent Mode],[Entra ID (DefaultAzureCredential)]の順で選択します。WebSocket通信が開き処理が開始されます。接続に成功すると、自動的にマイクからの音声待機状態になっています。何かエージェントと会話してください。応答が返ってくるはずです。なお、起動直後はスピーカーへの音声出力がオフになっているので、キーボードの「p」を押してオンにして下さい。こちらからの応答が音声で出力されます。パフォーマンスによっては音が途切れ途切れになるかもしれません。特に長い文章が送られてきた場合に発生します。まだ、サンプルアプリの調整が十分ではない為でサービスとしては正しく処理されています。

Choose connection mode:
1. AI Model Mode
2. AI Agent Mode
Enter your choice (1 or 2): 2

Choose authentication method:
1. API Key
2. Entra ID (DefaultAzureCredential)
Enter your choice (1 or 2): 2

操作コマンド

  • R: 録音開始/停止
  • P: 再生開始/停止
  • M: モード切り替え
  • C: 音声キューのクリア
  • S: 詳細状態表示
  • Q: 終了

実際に動かして理解するVoice Live API

実際動かしてみて色々気づきを得る物が多かったのでその点を解説行きたいと思います。

イベントの流れ

今回はシンプルに音声会話部分を使う実装なので、function callingや、情報の添付は行っていない状態のメッセージフローになります。

ポイントは以下の点です。

  1. Websocket開始後に必ず(変更にかかわらず)session.updateを送る
  2. modalitiesパラメータの設定に応じて音声とテキストでの応答を変更できる。
  3. ユーザの会話の切れ目は無音時間と文節から判断するモードがある

1. Websocket開始後に必ず(変更にかかわらず)session.updateを送る
WebCocket接続を開始すると自動的にセッションが作成されるのですが、その後session.updateを送る必要があります。これを送っていない状態で以降の処理を実行するとSocket通信がとじられてしまい動作しません。
変更しない場合は以下のメッセージをサーバに対しておくります。

{
    "type": "session.update",
    "session" : {}
}

2. modalitiesパラメータの設定に応じて音声とテキストでの応答を変更できる。
エージェントからの応答についてはtext,audioの2種類を利用することができます。いずれもリアルタイム応答可能になっています。デフォルトは両方がせっていされます。
変更する場合はsession.updateで更新します。

{
    "type": "session.update",
    "session" : {
        "modalities" : ["text","audio"]
    }
}

3. ユーザの会話の切れ目は無音時間と文節から判断するモードがある
Voice Live APIではユーザの音声をリアルタイムでサーバに送信し、文章の区切りを検出すると文字起こしが実施され、エージェントで処理が行われます。この際の文章の区切りには2種類のパターンがあります。

  • server_vad:無音に基づいて判断する
  • semantic_vad : ユーザの発話に基づいて判断する

3. おまけ:サンプルコードの解説

Voice Live APIにはあまり関係ないのですが、サンプルコードの実装についても紹介します。Voice Live APIを使う際の参考にしていただければ幸いです。

今回のサンプルアプリ実装に当たっては以下のパッケージを利用しています。

Package Name Version
Microsoft.Extensions.Logging 9.0.8
NAudio 2.2.1
System.Text.Json 9.0.7
Azure.Identity 1.14.2
Microsoft.Extensions.Configuration 9.0.7
Microsoft.Extensions.Configuration.UserSecrets 9.0.7

VoiceLiveAPIClientBaseクラス(基底クラス)

Voice Live APIの共通機能をVoiceLiveAPIClientBase抽象クラスで実装しています。このクラスがWebSocket通信、メッセージ処理、イベント管理などの核となる機能を担当します。派生クラスは接続先URL作成など固有処理の一部を実装しています。

WebSocket通信管理
サービスへの接続から応答メッセージ待機までの一連のフローはConnectAsyncメソッドで実装しています。処理そのものはシンプルです。最初にVoice Live サービスへの接続を行います。接続後、サーバからの応答をループ出待機します。

src/VoiceLiveAPI/Clients/VoiceLiveAPIClientBase.cs
public abstract class VoiceLiveAPIClientBase : IDisposable
{
    protected ClientWebSocket WebSocket;
    protected CancellationTokenSource CancellationTokenSource;
   
    public virtual async Task ConnectAsync(ClientSessionUpdate sessionUpdated)
    {
        await SetupAuthenticationAsync();
        var uri = BuildConnectionUri();
        await WebSocket.ConnectAsync(new Uri(uri), CancellationTokenSource.Token);
        ReceiveTask = ReceiveLoop();
    }
}

メッセージ受信ループとイベントディスパッチ

ReceiveLoopメソッドは、WebSocketからのメッセージを連続的に受信し、適切なイベントハンドラに振り分けます。

src/VoiceLiveAPI/Clients/VoiceLiveAPIClientBase.cs
private async Task ReceiveLoop()
{
    var buffer = new byte[1024];
    var messageBuffer = new StringBuilder();

    try
    {
        while (WebSocket.State == WebSocketState.Open &&
               !CancellationTokenSource.Token.IsCancellationRequested)
        {
            var result = await WebSocket.ReceiveAsync(
                new ArraySegment<byte>(buffer), CancellationTokenSource.Token);

            if (result.MessageType == WebSocketMessageType.Text)
            {
                var messageChunk = Encoding.UTF8.GetString(buffer, 0, result.Count);
                messageBuffer.Append(messageChunk);

                // メッセージが完全に受信されたら処理
                if (result.EndOfMessage)
                {
                    var completeMessage = messageBuffer.ToString();
                    messageBuffer.Clear();
                    ProcessMessage(completeMessage);
                }
            }
        }
    }
    catch (Exception ex) when (!CancellationTokenSource.Token.IsCancellationRequested)
    {
        LogError($"Receive loop error: {ex.Message}", ex);
    }
}

受信したメッセージはProcessMessageメソッドで処理され、メッセージタイプに応じて適切なハンドラが呼び出されます。このイベントディスパッチシステムにより、以下のような流れでメッセージが処理されます:

  1. WebSocketからメッセージ受信: ReceiveLoopでリアルタイムに受信
  2. JSONパース: 受信したテキストをJSONオブジェクトとして解析
  3. メッセージタイプ判定: typeフィールドからメッセージ種別を特定
  4. ハンドラ実行: 対応するハンドラのHandleAsyncメソッドを呼び出し
  5. イベント発火: ハンドラ内で適切な.NETイベントを発火

例えば、音声データ受信時の処理をする場合はVoiceLiveAPIClientBaseのイベントプロパティに対象処理を登録します。

src/VoiceLiveConsoleApp/Program.cs
// response.audio.deltaメッセージを受信した場合
// ResponseAudioDeltaHandlerが実行され、OnAudioDeltaReceivedイベントが発火
client.OnAudioDeltaReceived += response =>
{
    var pcmData = Convert.FromBase64String(response.delta);
    if (pcmData.Length > 0)
    {
        waveProvider.AddSamples(pcmData, 0, pcmData.Length);
    }
};

VoiceLiveAPIClientBaseクラスでは、登録したイベントを管理しています。先ほどの音声データ受信時の処理ではresponse.audio.deltaに呼び出す処理として、登録されます。

src/VoiceLiveAPI/Clients/VoiceLiveAPIClientBase.cs
// メッセージハンドラの辞書
private readonly Dictionary<string, IVoiceLiveHandler> messageHandlers = new();

// ハンドラの登録
protected void RegisterMessageHandler(IVoiceLiveHandler handler)
{
    messageHandlers[handler.MessageType] = handler;
}

サーバから応答メッセージが届いた際、メッセージタイプをチェックし、ユーザが登録した処理を照合し該当するイベントを呼び出して処理を行います。

// メッセージ処理
private async void ProcessMessage(string message)
{
    using var document = JsonDocument.Parse(message);
    var messageType = document.RootElement.GetProperty("type").GetString();
   
    if (messageHandlers.TryGetValue(messageType, out var handler))
    {
        await handler.HandleAsync(document.RootElement);
    }
}

基底クラスでは、response.audio.delta以外にも、Voice Live APIの各種イベントを用意しています。

現時点での制約、調査不足なところ。

・API KEYでのアクセスができない。
・Fuction Callingの通知が発生しない
・AVATARの仕様が不明

8. まとめ

本記事では、Azure AI FoundryのVoice Live APIをAI Agentモードで利用するための実装方法について解説しました。AI Agentモードを使用することで、より専門的で一貫性のある音声対話エージェントを構築することができます。
AI Modelモードとの主な違いは接続パラメータと認証方法ですが、音声データの送受信処理は共通しているため、既存の
本サンプルコードはGitHubで公開されており、実際のコードを参考にしながら実装を進めることができます。

参考リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?