All skills
microsoft avatar

/microsoft-foundry

@04110d9
by microsoftmicrosoft/skills3.1k stars
351

Build, deploy, evaluate, optimize, fine-tune, and manage Microsoft Foundry agents, models, and resources end to end. USE FOR: foundry, azd ai agent, azd provision/deploy, hosted agent scaffold/develop/run/deploy/troubleshoot, prompt agent create, create agent, update agent, add tool to agent, invoke agent, agent.yaml, agent insights, pull agent insights, evaluate agent, batch eval, continuous eval, continuous monitoring, agent CI/CD, optimize prompt, improve prompt, prompt optimizer, optimize agent instructions, Agent Optimizer scaffold, dataset curation from traces, deploy model, model fine-tuning (SFT/DPO/RFT), Foundry project, RBAC, role assignment, permissions, quota, capacity, region, deployment failure, AI Services, create Foundry resource, knowledge index, customize deployment, onboard, availability, training-data, grader, distillation, large file upload. DO NOT USE FOR: Azure Functions, App Service, general Azure deploy (use azure-deploy), general Azure prep (use azure-prepare).

Use this Skill: https://skilld.dev/gh/microsoft/skills/microsoft-foundry

This session only. Nothing lands on disk.

foundry-agentcreatequick-start-hosted.md

≈6k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Quick Start: Hosted Foundry Agent

Opinionated happy-path for first-time users creating their first Foundry hosted agent. Safe defaults, minimal decisions.

When to Use This Skill

Use this when the request is to create a new Foundry hosted agent end-to-end — scaffold, provision, deploy, and smoke-test. Common overrides (language, region, sample, topic, existing project, existing model) are fine. This skill supports only the responses and invocations protocols. When working on existing agents, using container deploy, using the activity protocol, or handling anything else not covered here, stop and read create-hosted.md.

Quick Reference

Property Standard path Override
Sample Foundry hosted agent samples for the chosen language (azd ai agent sample list --language <lang> --output json) User may name a different sample
Model version Whatever the sample's manifest declares If user supplies a model version, edit azure.yaml. If user supplies a model deployment without model version, follow Foundry Model Reference to query model-related data. If provision fails, follow Foundry Model Reference to query model-related data.
Model quota Skip the quota pre-check If provision fails, follow Foundry Model Reference to query model-related data.
Stops at Deployed agent + remote smoke invoke + eval generation submitted —

Workflow

Walk through every step in order.

Step 1 — Verify the environment

Run the bundled read-only Copilot app entry preflight without asking for approval; it locates the app's Copilot CLI and reports whether the microsoft-foundry canvas plugin needs installation:

./scripts/check-copilot-app-entry.sh     # macOS / Linux
./scripts/check-copilot-app-entry.ps1    # Windows (pwsh)

Act on the summary prefixes:

  • [OK] -- nothing to do.
  • [WARN] -- non-blocking; continue.
  • [ACTION] -- try to resolve by using the exact plugin install command emitted by the preflight; ask before installing in interactive mode, and install directly in non-interactive mode.
    • On successful installation, you MUST print: "The microsoft-foundry canvas extension is installed and will be available in a new session." Then rerun the preflight.
    • If installation is declined or fails, warn and continue; do not retry.

Then run the bundled verification script:

./scripts/verify-environment.sh     # macOS / Linux
./scripts/verify-environment.ps1    # Windows (pwsh)

Act on the summary prefixes:

  • [OK] -- nothing to do.
  • [WARN] -- non-blocking; continue.
  • [ACTION] -- resolve first, then rerun the script. If az or azd is missing, ask before installing in interactive mode; install directly in non-interactive mode. For how to install azd, see https://learn.microsoft.com/en-us/azure/developer/azure-developer-cli/install-azd. In any mode, never run az login or azd auth login; stop and ask the user to log in manually before any init, provision, or deploy command. Missing azure.ai.agents / azure.ai.projects extensions may be resolved with azd extension install <name>.

Step 2 — Collect necessary information

Before asking, resolve values from the user's request, the workspace, azure.yaml, the Step 1 verification output, and azd env get-values. For each row, do not ask when its When to skip condition is met. Ask for all remaining applicable values in one AskUserQuestion round. Do not ask for values that are already resolved or irrelevant to the requested change. Populate each question with the default option below.

Value When to skip Default option Notes
Project / agent name The user provided one, or the existing code already defines one. Project: ai-project-<random>; agent: the selected sample's agent name Generate <random> using 6-8 lowercase alphanumeric characters. Pass the agent name to azd ai agent init with --agent-name; it sets the service key and agent name in azure.yaml. For a new Foundry project, set the project name after init with azd env set AZURE_AI_PROJECT_NAME "<project-name>" before running azd provision.
Language The user provided one, or the existing code already determines it. Python Supported languages: Python and .NET.
Subscription The active azd environment already contains the intended AZURE_SUBSCRIPTION_ID. Active Azure subscription: <subscription-name> (<subscription-id>) Resolve both values with az account show --query "{name:name,id:id}" -o json; the ID must be a subscription GUID.
Region The active azd environment already contains the intended AZURE_LOCATION, or this change does not provision regional resources. northcentralus Azure resource location.
Foundry project The workspace or azd environment is already configured with a Foundry project, or the user provided one. New Foundry project Offer a new or existing project. For a new project, do not pass --project-id; azd provision creates it. For an existing project, use its ARM resource ID with azd ai agent init --project-id.
Foundry model deployment The user provided one. Official sample's model selection If the user specifies a model deployment, collect its deployment name.
Deploy mode Always — resolve without asking. code Container deploy is not supported in this quick start. To use container deploy, follow create-hosted.md.

If the user supplied only a Foundry project endpoint (not an ARM ID), resolve the ARM ID before Step 4:

./scripts/resolve-project-id.sh --endpoint "<foundry-project-endpoint>"     # macOS / Linux
./scripts/resolve-project-id.ps1 -Endpoint "<foundry-project-endpoint>"     # Windows (pwsh)

Use the returned id value. Never guess or construct the ARM ID from the endpoint.

When creating a new agent in an existing Foundry project, verify that the selected Foundry model deployment exists by running:

az cognitiveservices account deployment list \
  --resource-group "<rg-name>" \
  --name "<foundry-account-name>" \
  --output table

Step 3 — Pick the sample

azd ai agent sample list --language <lang> --output json

--language here takes the short form (python, dotnetCsharp) — not the runtime token (python_3_13 fails with unknown language). The runtime tokens are only used in Step 4's azd ai agent init --runtime ....

Capture the manifestUrl.

Important: Always select the best-matching sample from azd ai agent sample list for the capabilities the user explicitly requested. Use advanced tool samples only when the user explicitly asks for external actions, APIs, tools, connectors, or data lookup. Starting with the right sample helps ensure that the implementation follows the established code patterns and best practices for that type of Foundry hosted agent. If azd ai agent sample list does not return a suitable sample, choose one from the official Foundry samples repository and construct the manifest URL from its exact azure.yaml path, following the URL format returned by azd ai agent sample list.

You should pick only one sample for azd ai agent init, but you can browse multiple samples relevant to user's task as code reference.

Important: When users want to create new LangChain/LangGraph agents, you MUST read and follow LangChain and LangGraph hosting before selecting a sample or changing agent code.

Step 4 needs --runtime and --entry-point values. These are CLI args, not fields in the manifest — use these standard defaults for the chosen language:

Language --runtime --entry-point
Python python_3_13 main.py
.NET dotnet_10 MyAgent.dll

Step 4 — Scaffold the agent

Run azd ai agent init. azd ai agent init is sufficient to create new Foundry projects (or reuse an existing one) and create new Foundry agents. By default, you do not need to run azd init unless the user has specific initialization requirements.

Pass --deploy-mode code by default to use code deploy.

azd ai agent init --no-prompt \
  -m "<manifestUrl>" \
  --deploy-mode code \
  --runtime python_3_13 \
  --entry-point main.py \
  --agent-name "<agent-name>"

After the azd ai agent init completes, go to the project folder and write the subscription and region collected in Step 2 to the active azd environment:

azd env set AZURE_SUBSCRIPTION_ID "<subscription-id>"
azd env set AZURE_LOCATION "<region>"

When creating a new Foundry project, also set its name before provisioning:

azd env set AZURE_AI_PROJECT_NAME "<project-name>"

Values you must substitute from Step 3 — do not pass placeholders or guesses:

  • --runtime: exactly one of python_3_13, python_3_14, dotnet_10 (the bare value python fails with --runtime must be one of: python_3_13, python_3_14, dotnet_10).
  • --entry-point: the entry-point file the sample declares (e.g. main.py, not app.py — a wrong value scaffolds correctly but breaks local run and deploy).

If using an existing Foundry project, add --project-id "<arm-id>".

⏳ May take time — init resolves the model catalog server-side. Wait for the prompt to return; do not interrupt.

init writes azure.yaml (appending the agent service), src/<agent-name>/.agentignore, and the sample source files under src/<agent-name>/.

Important: Do not chain azd env set after azd ai agent init on the same command line. The init command may scaffold the project into a subfolder, so run azd env set only after initialization completes and after changing to the scaffolded project directory.

Step 5 — Customize the scaffolded sample (per user's original intent)

The scaffold is a generic working sample. Edit only what the user's original prompt asked for — touch tools, dependencies, or model config only when the user explicitly asked for external actions, APIs, tools, connectors, data lookup, or a specific model.

Typical changes:

  • The agent service's description: in azure.yaml — update it to match the user's intent (this also feeds Step 13 eval generation).
  • src/<agent-name>/<entry-point> — update the system prompt / instructions to match the user's intent.

Only when the user explicitly asked for it:

  • Add or modify tool / function-calling code in <entry-point>.
  • Add dependencies to pyproject.toml / requirements.txt (Python) or *.csproj (.NET).
  • Change the model in azure.yaml services.ai-project.deployments[] before Step 8 provision.

If the user's original prompt was generic (no specific agent purpose described), skip customization and ship the sample as-is.

Step 6 — Write the agent instruction file (required)

Do not skip this. The project needs a marker in its AGENTS.md (or CLAUDE.md in Claude Code) so future prompts reload this skill. If no such file exists, create it with the marker below. If the file already exists, weave the marker into the existing content naturally so it matches the file's structure and tone, rather than bluntly appending a standalone line that reads as out of place. Never overwrite the file or create a second one.

This project was built with the microsoft-foundry skill. Before working on or answering questions about foundry agents, read the microsoft-foundry skill first.

Step 7 — Sanity-check the scaffold

Verify all four before continuing. If any check fails, pick one recovery path, then re-verify:

Check Expected If failed
azure.yaml services.ai-project.deployments[] Non-empty array with name, model.{name,format,version}, sku.{name,capacity} Model resolution deferred — use recovery
Agent service environmentVariables AZURE_AI_MODEL_DEPLOYMENT_NAME (in azure.yaml) Literal name or ${AZURE_AI_MODEL_DEPLOYMENT_NAME} substitution If literal {{AZURE_AI_MODEL_DEPLOYMENT_NAME}} (double braces): use recovery
Agent service codeConfiguration.entryPoint: (in azure.yaml) Matches a real file in src/<agent-name>/ (e.g. main.py and main.py exists) If mismatch (e.g. entryPoint: app.py but only main.py exists): edit azure.yaml to the real filename, then re-verify. Most often caused by passing a wrong --entry-point in Step 4.
azure.yaml services: keys Only one <agent-name> entry If <agent-name>-2 exists: init was re-run; use recovery

Recovery paths (pick based on whether Step 5 has already customized src/<agent-name>/):

  1. Hand-fix in place (use when Step 5 customization is already done — preserves user code) — edit azure.yaml services.ai-project.deployments[] to add the model block, replace {{AZURE_AI_MODEL_DEPLOYMENT_NAME}} in the agent service's environmentVariables with ${AZURE_AI_MODEL_DEPLOYMENT_NAME}, then azd env set AZURE_AI_MODEL_DEPLOYMENT_NAME <deployment-name>.
  2. Clean re-init (use only when Step 5 has not run yet — destructive: deletes src/<agent-name>/) — delete src/<agent-name>/, remove the services.<agent-name>: block from azure.yaml, re-run Step 4.
  3. Interactive overwrite (loses Step 5 edits — re-resolves the model from the original manifest) — re-run Step 4 without --no-prompt. When the collision prompt appears, arrow-up to "Overwrite existing" (default is not overwrite).

Never azd env set AI_PROJECT_DEPLOYMENTS '[...]' (single-escaped JSON breaks Bicep parse). Never az cognitiveservices account deployment create against this account (creates the deployment outside the azd lifecycle).

If recovery still fails → escape to create-hosted.md.

Step 8 — Provision Azure resources

🚦 Project-selection gate (align with Step 2). Only azd provision a new project when the user asked to create one. If the user gave an existing project, skip provision and use it. If the user didn't mention a project at all, stop and ask first — don't silently provision a new one.

azd provision --no-state --no-prompt

--no-state skips the existing-deployment check; safe here because the golden path starts from a fresh environment (Step 4). Keep it for this quickstart; you can omit it later when re-provisioning the same environment.

⏳ May take time — creates the resource group, Foundry account + project, model deployment, App Insights, Log Analytics. Wait for the prompt to return; do not interrupt.

Step 9 — Wire local env vars

azd env get-values

Capture FOUNDRY_PROJECT_ENDPOINT and AZURE_AI_MODEL_DEPLOYMENT_NAME. Write src/<agent-name>/.env:

FOUNDRY_PROJECT_ENDPOINT=https://<account>.services.ai.azure.com/api/projects/<project-name>
AZURE_AI_MODEL_DEPLOYMENT_NAME=<deployment-name>

Keep .env out of the deploy package: make sure src/<agent-name>/.agentignore lists .env (add it if missing).

Also mirror them into the azd env (so azd ai agent run injects the right values — it reads azd env before .env):

azd env set AZURE_AI_PROJECT_ENDPOINT "<endpoint>"
azd env set AZURE_AI_MODEL_DEPLOYMENT_NAME "<deployment-name>"

Step 10 — Local smoke test

Set up a venv with uv installed first. azd ai agent run installs Python dependencies on first start; with an activated venv that has uv available, it uses uv (seconds) instead of plain pip (minutes).

Important: the venv must live in src/<agent-name>/ (next to pyproject.toml / requirements.txt). azd ai agent run resolves the venv relative to the service source directory; a venv at the project root is ignored and azd silently creates a second one without uv, wasting the speedup.

Private package index: If the sample has a uv.lock, the user has the UV_DEFAULT_INDEX environment variable set to a private index, and public PyPI is unreachable, azd ai agent run fails with uv.lock needs to be updated. Back up uv.lock first, then run uv lock in src/<agent-name>/ and continue the local test. The re-locked file is for local run only; see Step 11 before deploying.

Python:

cd src/<agent-name>
python -m venv .venv
# Activate the venv — pick the line for your shell:
.\.venv\Scripts\Activate.ps1                    # Windows pwsh
source .venv/bin/activate                       # macOS / Linux
python -m pip install uv
cd -                                             # back to project root for the azd commands below

.NET: no pre-install step — azd ai agent run runs dotnet restore itself on first start.

The examples below use the default port 8088. Confirm it is free; if occupied, choose another port and add the same --port <n> to both run and invoke --local below. Run the agent locally. For Python, do this with the service-dir venv still activated — activation is what lets azd ai agent run find uv for the fast dependency install. azd ai agent run is the local server — a foreground process holding the selected port that must stay alive from start, through every invoke --local, until you explicitly stop it.

Start it in a managed background session your shell tool can poll and stop (most tools detect a long-running foreground process and return a session/shell id — use that id). Do not use job operators (bash &, nohup, start /B, popped windows): on Linux/macOS the child gets SIGHUP and dies when its parent bash exits, so the next command sees could not connect even though ss from inside the same bash just showed :8088 bound.

azd ai agent run --no-client

Readiness gate — required before local invocation.

  • Start checking TCP connections to localhost:<port> immediately after launching the agent in the background; retry failed connections every 2–5 seconds.
  • In the same loop, check whether the azd ai agent run process has exited. If it exited, stop polling immediately, read its output, and fix that specific cause (for example, a dependency install failure) before restarting.
  • Keep each startup wait at 5 seconds or less, including sleeps and shell-tool output reads.
  • Proceed to the smoke invocation as soon as TCP connects, keeping the server running.
  • If the startup timeout expires before a connection succeeds, inspect the server logs and resolve the cause before retrying.

Smoke-invoke (local):

azd ai agent invoke --local "<short representative prompt for the agent's purpose>"

Stop the local server via the managed session's stop primitive before continuing — a lingering process holds files in the project and breaks later cleanup.

Step 11 — Deploy

Once local invocation succeeds, if the user does not explicitly ask to deploy, tell them the agent is ready and ask if they want to deploy.

If you re-ran uv lock against a private index in Step 10, the remote build cannot use that lock. If dependencies did not change, restore the backed-up uv.lock before deploying. If dependencies changed, tell the user uv.lock must be regenerated against public PyPI before deploying.

To deploy:

azd deploy --no-prompt

⏳ May take time — zips src/<agent-name>/ (respecting .agentignore), uploads to Foundry, builds runtime remotely, registers agent version. Wait for the prompt to return; do not interrupt.

Step 12 — Verify + remote smoke

azd ai agent show --output json

Expect "status": "active" (or "deployed") and an agent_endpoints map.

Remote invoke (billed):

azd ai agent invoke "<short representative prompt>"

Run the smoke invocation only as part of the requested deployment or test.

Step 13 — Submit eval suite generation (async, fire-and-forget)

⚠️ Pre-summary gate. Do not write the Step 14 final summary until this step has been submitted. The eval suite is part of the deployment artifact; skipping it ships an incomplete result.

Directly submit the eval suite generation asynchronously, do not ask the user for confirmation.

Read the agent service's description: from azure.yaml (the value you set in Step 5) and pass it as --gen-instruction:

azd ai agent eval generate --gen-instruction "<agent service description>" --no-wait --no-prompt

Expected output:

Eval generate submitted (async)
   dataset generation: datagen-<id> (queued)
   evaluator generation: evaluatorgen-<id> (in_progress)
   Config written to: src/<agent-name>/eval.yaml
   When ready, run:
     azd ai agent eval run

Generation runs server-side and takes several minutes. Tell the user:

"Eval suite generation submitted. Run azd ai agent eval run whenever you're ready — it'll wait for generation to finish and execute the eval in one step."

Run azd ai agent eval run only after the user explicitly agrees.

Step 14 — Final summary

Produce a concise summary covering: agent name/version/status/endpoints, a Playground link, the resources created, the eval suite generation submission, and the three follow-up commands below. Read playground_url directly from azd ai agent show --output json. If it is absent, construct the Playground URL from azd env get-values:

https://ai.azure.com/nextgen/r/{encodedSubId},{resourceGroup},,{accountName},{projectName}/build/agents/{agentName}/build?version={agentVersion}

encodedSubId = URL-safe base64 of the subscription GUID, padding stripped:

python -c "import base64,uuid;print(base64.urlsafe_b64encode(uuid.UUID('<SUBSCRIPTION_ID>').bytes).rstrip(b'=').decode())"

Three follow-up commands to include:

azd ai agent invoke "<follow-up message>"   # chat with the deployed agent (billed)
azd ai agent eval run                       # finalize + run the eval suite (Step 13)
azd down                                    # tear down all resources when done

Error Handling

Symptom Fix
azd ai agent init fails with --runtime must be one of: python_3_13, python_3_14, dotnet_10 You passed a bare value like python. Use the full runtime token (e.g. python_3_13).
azd ai agent init fails with --entry-point is required when using --deploy-mode code with --no-prompt Pass --entry-point <filename> matching the entry-point file the sample declares (from Step 3).
codeConfiguration.entryPoint doesn't match any file in src/<agent-name>/ You guessed the entry-point in Step 4. Edit the agent service in azure.yaml to the real filename (verify with ls src/<agent-name>/). No re-init needed.
azd deploy postdeploy hook fails with missing AZURE_TENANT_ID Run az account show --query tenantId -o tsv and azd env set AZURE_TENANT_ID <tenant-id>, then re-run azd deploy --no-prompt. The deployed agent version from the first deploy is still valid; the postdeploy hook just registers env vars.
Scaffold sanity check fails (Step 7) Pick a recovery path from Step 7. If still failing → create-hosted.md.
Local invoke returns model 404 / wrong deployment Stale AZURE_AI_MODEL_DEPLOYMENT_NAME in azd env overrides .env. Re-run Step 9 to sync both.
Anything else Escape to create-hosted.md.

Escape Hatch

If any step fails in a way not covered above, the output looks unexpected, or the user's request drifts outside what this quickstart covers → stop improvising. Read create-hosted.md and follow its full workflow.

Source: SKILL.md on GitHub

2 warnings3d4 checks · Risk SAFE
  • Gen Agent Trust Hub3d

    This skill provides a comprehensive environment for managing the end-to-end lifecycle of AI agents, models, and infrastructure on Microsoft Foundry. It includes sub-skills for deployment, evaluation, fine-tuning, and troubleshooting. The skill utilizes dynamic code execution and shell command wrappers, which are used within the context of local development and cloud orchestration. All external resources and dependencies originate from trusted organizations and well-known services.

  • Socket3d

    2 alerts: gptSecurity, gptAnomaly

  • Snyk3d

    Risk: LOW · No issues

  • Runlayer7mo

    36/36 files flagged

Signed by skilld at 04110d9. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 20 hours ago.

Activeupdated last week
metadata
{
  "author": "Microsoft",
  "version": "1.2.26"
}

README badge

README badge for microsoft/skills/microsoft-foundry