Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Use the Azure Developer CLI (azd) to deploy a hosted text agent and a voice wrapper in Microsoft Foundry Agent Service. The hosted agent handles conversation logic and model calls. Voice Live handles speech recognition, turn detection, speech synthesis, and playback interruption.
This workflow uses the Voice Live Bridge basic Python sample. Its azure.yaml defines both agents. You don't need to create the wrapper separately.
Important
Items marked (preview) in this article are currently in public preview. This preview is provided without a service-level agreement, and we don't recommend it for production workloads. Certain features might not be supported or might have constrained capabilities. For more information, see Supplemental Terms of Use for Microsoft Azure Previews.
Prerequisites
- Azure Developer CLI version 1.32.0 or later and the Foundry extensions. Check that the extension exposes the public-preview voice CLI options.
- An authenticated
azdsession. Runazd auth loginbefore initialization. - The Azure permissions needed to provision Foundry resources.
- Access to voice agents and hosted agents in the selected subscription and region.
- Model availability and sufficient quota for the
gpt-5.4-minideployment declared in the sample. - A voice client, such as the Foundry voice playground where available, and a microphone and speakers to test a spoken conversation.
Initialize the sample
This walkthrough creates a new Foundry project. To reuse an existing project and model deployment, follow the sample's existing-project instructions instead. Don't apply the new-project provisioning steps below to a shared project.
In PowerShell, create an empty directory and initialize from the public sample manifest:
mkdir hosted-voice-quickstart
cd hosted-voice-quickstart
$sample = "https://github.com/microsoft-foundry/foundry-samples/" +
"blob/main/samples/python/hosted-agents/bring-your-own/" +
"voice-agent-target-agent/basic/azure.yaml"
azd ai agent init -m $sample
When prompted, select your tenant and subscription, create a new Foundry project, and select a supported region. Review the sample's model selection before continuing.
Change to the generated directory that contains azure.yaml:
cd voice-live-bridge-basic-python
Review the target and voice wrapper
The sample declares two azure.ai.agent services:
| Service | Responsibility |
|---|---|
voice-live-bridge-basic-python |
The kind: hosted target. It receives text and control events through Voice Live Bridge Protocol 1.0 over invocations_ws, then streams model responses as text. |
voice-live-bridge-basic-python-voice |
The kind: voice wrapper. It configures the managed audio experience and references the hosted target through conversationEngine. |
The wrapper includes these fields under services in azure.yaml:
voice-live-bridge-basic-python-voice:
host: azure.ai.agent
kind: voice
name: voice-live-bridge-basic-python-voice
uses:
- ai-project
- voice-live-bridge-basic-python
conversationEngine:
type: hosted_agent
name: voice-live-bridge-basic-python
store: false
The uses dependency deploys the target before the wrapper. conversationEngine.name is the hosted target's service name in azure.yaml. The optional conversationEngine.version defaults to deployed, which selects the target version deployed by the current azd environment.
The wrapper and hosted target must have different Foundry agent names. Keep their name values distinct even if you rename the sample's services.
Keep model calls, instructions, and tools in the hosted target. Configure audio, voice output, and the greeting on the wrapper. Don't use the older modelType: hosted_agent or targetAgent settings.
The target must declare invocations_ws version 1.0.0, with voiceLiveCompatible: "true" and bridgeProtocolVersion: "1.0" in its metadata. The sample already supplies these settings.
This wrapper workflow doesn't replace custom audio pipelines hosted through invocations_ws. In this sample, the hosted target exchanges text and control events with Voice Live rather than processing caller audio itself.
For field details, see the voice service configuration reference.
Provision and deploy both agents
From the generated project directory, provision the Foundry project and the model declared in azure.yaml:
azd provision
Set the model deployment name that the hosted target reads at runtime:
azd env set AZURE_AI_MODEL_DEPLOYMENT_NAME gpt-5.4-mini
This variable selects the deployment used by the hosted target. It doesn't create or rename a model deployment.
Deploy all services so that azd deploys both the target and the wrapper:
azd deploy
Inspect both agents and confirm that their deployed versions are active:
azd ai agent show voice-live-bridge-basic-python
azd ai agent show voice-live-bridge-basic-python-voice
For model-backed turns, confirm that the hosted agent's identity has the Cognitive Services OpenAI User role, or equivalent inherited model-inference permissions, on the parent Foundry resource.
Test the voice wrapper
Connect your voice client to voice-live-bridge-basic-python-voice, not to the hosted target. The caller uses the wrapper's voice endpoint; Voice Live exchanges Bridge Protocol events with the hosted target.
Use the Foundry voice playground where available. To use the SDK client, adapt the quickstart's storage-enabled example as described in this section.
Adapt the SDK client for storage-disabled sessions
Complete the Python SDK package installation and environment setup. Set FOUNDRY_PROJECT_ENDPOINT to your deployed project's endpoint and FOUNDRY_VOICE_AGENT_NAME to voice-live-bridge-basic-python-voice. Use the existing wrapper; don't run the quickstart's agent-creation examples.
Copy talk_to_voice_agent.py from Talk to the agent. The wrapper uses store: false, so a persisted conversation ID isn't required for a successful voice response. Remove this storage-only check from the copied script:
if not conversation_id:
raise RuntimeError("No persisted conversation ID was returned.")
Keep the response-status check, the audio_chunks check, and the code that writes reply.wav. Remove the final print(f"Conversation id: {conversation_id}") line. Skip the quickstart's Read the conversation back section. Don't enable store: true just to satisfy the example's storage checks. The adapted script still saves response audio locally in reply.wav.
Check text and audio
For the /help check in the copied SDK script, set the outgoing message's text value to /help.
- Send
/helpas a text turn. Confirm that the response containsCommands:. This checks the sample's command path without making a model call. - Ask a short question to exercise the target's model deployment.
- Send a spoken turn. Confirm that input transcription, response text, and audible output are present.
- Speak while the agent responds, and check interruption behavior.
An active agent or a successful text response alone doesn't establish that the audio path works.
azd ai agent invoke doesn't generate Voice Live conversations. Selecting the voice wrapper returns portal guidance, not a voice session. For local Bridge Protocol checks, use the sample's protocol smoke client.
Troubleshoot
| Symptom | Action |
|---|---|
Initialization reports not logged in. |
Sign in with azd auth login, and run initialization again. |
The extension doesn't recognize the voice options or conversationEngine. |
Check the installed extension's voice support before continuing. |
| Wrapper deployment can't resolve its target. | Check that conversationEngine.name matches the hosted service name, that uses includes it, and that the target is active. |
/help works, but model-backed turns fail. |
Check the target's AZURE_AI_MODEL_DEPLOYMENT_NAME, model availability, and managed identity permissions for model inference. |
The target reports protocol_mismatch. |
Check Bridge Protocol 1.0 compatibility. The Bridge Protocol version is distinct from the invocations_ws transport version. |
Clean up resources
Warning
azd down deletes the resource group and all resources created for this environment. Don't use it to clean up individual agents in a shared project.
For the new project created by this walkthrough, run:
azd down
Related content
For related configuration and development workflows, see: