Skip to content

Repository files navigation

Foundry Agent Service chat basic reference implementation

This reference implementation illustrates an approach running a chat application and an AI orchestration layer in a single region. It uses Foundry Agent Service to host the agent, with Azure OpenAI foundation models providing the inference. This repository directly supports the Basic end-to-end chat reference architecture on Microsoft Learn.

The reference implementation illustrates a basic example of a chat application. For a reference implementation that implements more enterprise requirements, please see the Microsoft Foundry Agent Service baseline reference implementation. That implementation addresses many of the production readiness changes identified in this code.

Architecture

The implementation covers the following scenarios:

Setting up Microsoft Foundry to host agents

Microsoft Foundry hosts the Foundry Agent Service as a capability. Foundry Agent Service's REST APIs are exposed as an internet facing endpoint.

Diagram that shows a basic chat architecture.

Download a Visio file of this architecture.

Workflow

The following workflow corresponds to the previous diagram:

  1. An application user interacts with a web application that contains chat functionality. They issue an HTTPS request to the App Service default domain on azurewebsites.net. This domain automatically points to the App Service built-in public IP address. The Transport Layer Security connection is established from the client directly to App Service. Azure fully manages the certificate.
  2. The App Service feature called Easy Auth ensures that the user who accesses the website is authenticated via Microsoft Entra ID.
  3. The chat application container running in App Service handles the request and renders a chat UI for the application user. The chat UI code connects to APIs that are also hosted in that same App Service instance. The API code connects to the workload's hosted agent through the Microsoft Agent Framework with the Foundry provider, which calls the agent's OpenAI-compatible Responses endpoint on Foundry Agent Service under the hood.
  4. The hosted agent runs in its platform-managed session sandbox and uses its web search tool to fetch grounding data for the query. The grounding data is added to the prompt that's sent to the Azure OpenAI model in the next step.
  5. Foundry Agent Service connects to an Azure OpenAI model deployed in the same project and sends the prompt that includes the relevant grounding data and chat context.
  6. Application Insights logs information about the original request to App Service and the call agent interactions.

Deploying a hosted agent into Foundry Agent Service

A hosted agent is your own code packaged as a containerized application and deployed to Foundry Agent Service. Unlike prompt-based agents (defined entirely through configuration), hosted agents give you full control over the agent logic, tools, and orchestration while the platform handles scaling, session state, and lifecycle.

The agent in this reference implementation uses the Microsoft Agent Framework with the Foundry provider and exposes an OpenAI-compatible /responses endpoint via the Responses protocol (version 2.0.0). It includes a web search tool for grounding answers with real-time information.

Agents can be created and versioned via the Foundry SDK, the REST API, or Azure Developer CLI. The creation and invocation of agents are data plane operations. Each agent is a source-controlled, versioned asset that you can deploy in a coordinated way with the rest of your workload's code. In this deployment guide, you'll build the agent as a container image into an Azure Container Registry and register it through the REST API to simulate a deployment pipeline which could have created the agent.

Invoking the hosted agent from .NET code hosted in an Azure Web App

A chat UI application is deployed into Azure App Service. The .NET code uses the Microsoft Agent Framework with the Foundry provider to connect to the workload's hosted agent. The endpoint for the agent is exposed over internet through Foundry.

Agent invocation at runtime uses a different API surface than agent lifecycle management. Hosted agents are invoked through their dedicated, agent-specific endpoint ({projectEndpoint}/agents/<agentName>/endpoint/protocols/openai), which the application derives from the project endpoint and the registered agent name. Multi-turn continuity is managed by Foundry Agent Service through hosted agent sessions: this reference implementation provisions a single shared session up front (pinned to a specific agent version), and all subsequent turns run in that same session so conversation state persists across turns. The active agent version is resolved by the endpoint's administrator-controlled version selector.

Deployment guide

Follow these instructions to deploy this example to your Azure subscription, try out what you've deployed, and learn how to clean up those resources.

Prerequisites

  • An Azure subscription

    • The subscription must have all of the resource providers used in this deployment registered.

      • Microsoft.CognitiveServices
      • Microsoft.ContainerRegistry
      • Microsoft.Insights
      • Microsoft.ManagedIdentity
      • Microsoft.OperationalInsights
      • Microsoft.Storage
    • The subscription must have the following quota available in the region you choose.

      • App Service Plans: P1v3 (AZ), 3 instances
      • OpenAI model: GPT-4.1 model deployment with 50k tokens per minute (TPM) capacity
  • Your deployment user must have the following permissions at the subscription scope.

    • Ability to assign Azure roles on newly created resource groups and resources. (E.g. User Access Administrator or Owner)
    • Ability to purge deleted AI services resources. (E.g. Contributor or Cognitive Services Contributor)
  • The Azure CLI installed

    If you're executing this from WSL, be sure the Azure CLI is installed in WSL and is not using the version installed in Windows. which az should show /usr/bin/az.

1. 🚀 Deploy the infrastructure

The following steps are required to deploy the infrastructure from the command line.

  1. In your shell, clone this repo and navigate to the root directory of this repository.

    git clone https://github.com/Azure-Samples/microsoft-foundry-basic
    cd microsoft-foundry-basic
  2. Log in and set your target subscription.

    az login
    az account set --subscription xxxxx
  3. Set the deployment location to one with available quota in your subscription.

    This deployment has been tested in the following locations: australiaeast, eastus, eastus2, francecentral, japaneast, southcentralus, swedencentral, switzerlandnorth, or uksouth. You might be successful in other locations as well.

    LOCATION=eastus2
  4. Set the base name value that will be used as part of the Azure resource names for the resources deployed in this solution.

    BASE_NAME=<base resource name, between 6 and 8 lowercase characters, all DNS names will include this text, so it must be unique.>
  5. Create a resource group and deploy the infrastructure.

    There is an optional tracking ID on this deployment. To opt out of its use, add the following parameter to the deployment code below: -p telemetryOptOut true.

    RESOURCE_GROUP=rg-chat-basic-${BASE_NAME}
    az group create -l $LOCATION -n $RESOURCE_GROUP
    
    PRINCIPAL_ID=$(az ad signed-in-user show --query id -o tsv)
    
    # This takes about 10 minutes to run.
    az deployment group create -f ./infra-as-code/bicep/main.bicep \
      -g $RESOURCE_GROUP \
      -p baseName=${BASE_NAME} \
      -p yourPrincipalId=$PRINCIPAL_ID

2. Deploy a hosted agent in Foundry Agent Service

To test this scenario, you'll deploy a hosted agent, your own code running as a containerized application on Microsoft-managed infrastructure. The agent uses the Microsoft Agent Framework with the Foundry provider and exposes an OpenAI-compatible /responses endpoint. It includes hosted web search for grounding answers with real-time information.

The agent source code lives in src/agent/ in this repository. You'll build it as a container image into the Azure Container Registry deployed in step 1, register that image with Foundry Agent Service via the REST API, and poll until the version is active.

2a. Build and push the agent image to ACR

The following command builds the agent from its Dockerfile using a remote Azure Container Registry build task (no local Docker install needed) and pushes the resulting image to the registry:

ACR_NAME="acr${BASE_NAME}"
ACR_LOGIN_SERVER="${ACR_NAME}.azurecr.io"

az acr build -r $ACR_NAME -t agent:latest --platform linux/amd64 ./src/agent

2b. Deploy the agent via the REST API

The following command registers the container image with Foundry Agent Service and creates a new version.

FOUNDRY_NAME="aif${BASE_NAME}"
FOUNDRY_PROJECT_NAME="projchat"
FOUNDRY_BASE_URL="https://${FOUNDRY_NAME}.services.ai.azure.com/api/projects/${FOUNDRY_PROJECT_NAME}"
API_VERSION="2025-11-15-preview"
AGENT_NAME="baseline-chatbot-agent"

# Render the agent definition JSON (container-based hosted agent) from the source-controlled template.
# The Bing grounding connection is referenced by full resource ID because the agent identity
# can't resolve project connections by name at runtime.
BING_CONNECTION_ID="$(az cognitiveservices account show -n $FOUNDRY_NAME -g $RESOURCE_GROUP --query 'id' -o tsv)/projects/${FOUNDRY_PROJECT_NAME}/connections/bingaiagent"
sed "s|{{ACR_LOGIN_SERVER}}|${ACR_LOGIN_SERVER}|; s|{{BING_CONNECTION_ID}}|${BING_CONNECTION_ID}|" agents/chat-with-bing.json > /tmp/agent-definition.json

# Create the agent version (JSON body with the container image reference)
az rest --method POST \
  --url "${FOUNDRY_BASE_URL}/agents/${AGENT_NAME}/versions?api-version=${API_VERSION}" \
  --resource "https://ai.azure.com" \
  --body @/tmp/agent-definition.json

The Bicep deployment in step 1 already grants the Foundry project managed identity Container Registry Repository Reader on the container registry, so the agent runtime can pull its image. No manual role assignment is needed.

2c. Poll until the agent version is active

while true; do
  STATUS=$(az rest --method GET \
    --url "${FOUNDRY_BASE_URL}/agents/${AGENT_NAME}/versions?api-version=${API_VERSION}" \
    --resource "https://ai.azure.com" \
    --query "data[0].status" -o tsv)
  echo "Status: ${STATUS}"
  if [ "$STATUS" = "active" ]; then
    break
  fi
  if [ "$STATUS" = "failed" ]; then
    echo "Deployment failed. Check the Foundry portal for logs."
    exit 1
  fi
  sleep 10
done
echo "Agent is active!"

3. Test the agent from the Foundry portal in the playground

Here you'll test your hosted agent by invoking it directly from the Foundry portal agent playground chat experience.

  1. Navigate to the Foundry project named projchat and open the Foundry portal by clicking the Go to Foundry portal button (or go directly to https://ai.azure.com).

  2. In the top-right corner, click Build to open the Agents blade.

  3. Select the agent named 'baseline-chatbot-agent'. It should show status Active.

  4. Enter a question to the agent that would require grounding data through recent internet content, such as a notable recent event or the weather today in your location.

  5. A grounded response to your question should appear on the UI.

4. Deploy the chat front-end web app

Workloads build chat functionality into an application. Those interfaces usually call the agent's endpoint in Foundry Agent Service. This implementation comes with such an interface. You'll deploy it as a container image to Azure App Service using the Azure CLI.

  1. Build and push the ChatUI image to ACR, then restart the web app so it pulls the new image

    The web app is configured (in step 1) to run the chatui:latest image from the container registry, pulling it with its managed identity:

    az acr build -r $ACR_NAME -t chatui:latest --platform linux/amd64 ./src/chatui
    
    APPSERVICE_NAME=app-$BASE_NAME
    az webapp restart -g $RESOURCE_GROUP -n $APPSERVICE_NAME

The prior command may take a few minutes while the web app pulls the image and starts. If you receive a timeout error, you're safe to simply execute the command again.

5. Try it out! Test the deployed application that calls into the Foundry Agent Service

After the deployment is complete, you can try the deployed application by navigating to the Web App's URL in a web browser.

You can also execute the following from your workstation. Unfortunately, this command does not reliably work from Azure Cloud Shell.

az webapp browse -g $RESOURCE_GROUP -n $APPSERVICE_NAME

Once you're there, ask your solution a question. Your question should involve something that would only be known with real-time web search context, such as recent weather or events.

🧹 Clean up resources

Most Azure resources deployed in the prior steps will incur ongoing charges unless removed. Additionally, a few of the resources deployed go into a soft delete status which will restrict the ability to redeploy another resource with the same name and might not release quota. It's best to purge any soft deleted resources once you are done exploring. Use the following commands to delete the deployed resources and resource group and to purge each of the resources with soft delete.

Note: This will completely delete any data you may have included in this example and it will be unrecoverable.

# These deletes and purges take about 30 minutes to run.
az group delete -n $RESOURCE_GROUP -y

# Purge the soft delete resources
az cognitiveservices account purge -g $RESOURCE_GROUP -l $LOCATION -n aif${BASE_NAME}

Contributions

Please see our Contributor guide.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.

With ❤️ from Azure Patterns & Practices, Azure Architecture Center.

Used by

Contributors

Languages