ERW CommandPMO

AI-103 CERTIFICATION BOOTCAMP

Developing AI Apps and Agents on Azure — Build it, run it, name it exactly.

← Course home
40 sessions · 45 minutes each · 8 weeks at your own pace · One track: your own Azure subscription
WEEK 4 OF 8 · RUNNING AGENTS: AUTONOMY, OBSERVABILITY, QUOTAS AND THE MID-COURSE REVIEW · SESSIONS 16–20
This week’s assessments: Practice Exam 1 — Mid-Course after Session 20
Every session: the exact names Microsoft uses · one assignment marked against a published rubric · pass mark 70 · Certificate: capstone at 70+ and the marked Final at 700+
B · Implement generative AI and agentic solutions · 30–35%SESSION 16
Autonomy with safeguards and approvals; reflection and self-critique loops
Session 16 of 40 · 45-minute session
Skills measured — Microsoft’s wording
  • Build autonomous or semiautonomous workflows with safeguards and approval flow controls
  • Implement model reflection, chain-of-thought evaluations, and self-critique loops

Why This Matters

So far your agents have mostly read things. The moment an agent can do something (issue a refund, close a ticket, change a record), the question stops being “is the answer good?” and becomes “who allowed that?”. AI-103 expects you to know where Foundry lets a person approve a tool call before it runs, how to keep a loop from running for ever, and how a model can check and improve its own work. At work, this is the difference between an agent your risk committee signs off and one it switches off. Today you build an approval gate and a capped self-critique loop, and you see both work.

IN YOUR SUBSCRIPTION
Creates
One model deployment on Global Standard (redeploy it as in Session 4 if you deleted yours), and two short-lived prompt agent versions in your project: one with the Microsoft Learn MCP Server from Session 14, and your Session 13 function-calling agent with an approval gate added (Session 13’s clean-up deleted it, so you rebuild it with build_agent.py). A local approvals.jsonl audit file. No new Azure resource types.
Cost
Billed per token on the Global Standard deployment. Tool results add to the model’s context, and a self-critique loop multiplies calls: three rounds can mean seven model calls for one reply. Check the Microsoft Foundry pricing page for your model; your Session 1 budget alert is your safety net.
Clean-up
mcp_approval.py ends with delete_version. If you rebuilt the Session 13 agent, run its cleanup.py and delete_file.sh again, which also remove its vector store and file. Confirm in the Foundry portal that no test agent remains. Then delete the model deployment: Build → Models → open the deployment → delete, or az cognitiveservices account deployment delete --deployment-name <name> -n <resource> -g rg-ai103. Keep rg-ai103 and the project.
The 45-Minute Session
7:00 – 19:00
Hands-on: turn MCP approval into a control
  • Session 14 wired require_approval into a tools agent. Today you turn it into a control you could defend to an auditor. The setting takes "always" (the default), "never", or a dictionary that names tools: {"always": [...]} for the tools that need approval, or {"never": [...]} for the tools that do not. allowed_tools limits which of the server’s tools the agent can use at all, and server_label identifies the server to the agent.
  • The flow is the same as in Session 14: an mcp_approval_request item carries the server label, tool name and arguments; you answer with an mcp_approval_response holding the approval_request_id and approve, chained with previous_response_id. What is new here: every decision is written to an audit file with who made it and when, the rounds are capped, and the rejection path is tested.
  • The script follows Learn’s MCP how-to and uses the Microsoft Learn MCP Server, which needs no project connection. Like Sessions 12 to 14, it names the agent on each request with agent_reference in extra_body. The audit record is my addition, not a Foundry feature: in production it would go to your logging system.
  • pythonmcp_approval.pytype it yourself
    import datetime, getpass, json, os
    from azure.identity import DefaultAzureCredential
    from azure.ai.projects import AIProjectClient
    from azure.ai.projects.models import PromptAgentDefinition, MCPTool
    from openai.types.responses.response_input_param import McpApprovalResponse
    
    project = AIProjectClient(endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
                              credential=DefaultAzureCredential())
    openai = project.get_openai_client()
    agent = project.agents.create_version(
        agent_name="approval-agent",
        definition=PromptAgentDefinition(
            model=os.environ["FOUNDRY_MODEL_NAME"],
            instructions="Use the mslearn tools for Microsoft product questions. "
                         "If a tool call is rejected, say so and answer without it.",
            tools=[MCPTool(server_label="mslearn",
                           server_url="https://learn.microsoft.com/api/mcp",
                           require_approval="always")],
        ),
    )
    ref = {"agent_reference": {"name": agent.name, "type": "agent_reference"}}
    def review(item):  # show the proposed call, ask a person, keep an audit record
        print(f"{item.server_label} wants {item.name} with {item.arguments}")
        ok = input("Approve? (y/N): ").strip().lower() == "y"
        record = {"time": datetime.datetime.now().isoformat(), "reviewer": getpass.getuser(),
                  "request_id": item.id, "tool": item.name, "approved": ok}
        with open("approvals.jsonl", "a") as log:
            log.write(json.dumps(record) + "\n")
        return McpApprovalResponse(type="mcp_approval_response",
                                   approve=ok, approval_request_id=item.id)
    response = openai.responses.create(input="How do I delete a Foundry project?",
                                       extra_body=ref)
    for _ in range(5):                                    # cap the approval rounds
        approvals = [review(i) for i in response.output if i.type == "mcp_approval_request"]
        if not approvals:
            break
        response = openai.responses.create(input=approvals,
                                           previous_response_id=response.id, extra_body=ref)
    print(response.output_text)
    project.agents.delete_version(agent_name=agent.name, agent_version=agent.version)
    WHAT YOU SHOULD SEE
    mslearn wants <tool-name> with <the arguments the model proposed>
    Approve? (y/N): n
    <an answer that says the lookup was declined>
  • Run it twice, approving once and rejecting once, then open approvals.jsonl. Read how the agent answers without its tool: that behaviour is part of your design.
  • THE EXAM LINE

    require_approval defaults to "always". The response then carries an mcp_approval_request; you reply with an mcp_approval_response holding approval_request_id and approve, linked by previous_response_id.

  • Learn is blunt about MCP risk: third parties create the remote servers, and Microsoft doesn’t test or verify them. Review and log what you share. At the time of writing, non-streaming MCP tool calls time out after 100 seconds.
Reject at least once. An approval flow you have only ever approved is an untested approval flow.
26:00 – 36:00
Reflection: generate, critique, revise, with a cap
  • Think of a hospital discharge letter (illustrative). A junior doctor drafts it, the registrar checks it against a checklist and sends it back with notes, and after two rounds it goes to the consultant. That is a self-critique loop with an escalation path.
  • The Azure Architecture Center calls this a maker-checker loop: one agent proposes, another checks against defined criteria and sends feedback until it approves or an iteration limit is reached. Other names you may see: evaluator-optimizer, generator-verifier, critic loops and reflection loops.
  • The same guidance sets three conditions: clear acceptance criteria, an iteration cap, and a defined fallback when the cap is reached, such as a human reviewer or a quality warning alongside the best result.
  • pythoncritique_loop.pytype it yourself
    import os
    from azure.identity import DefaultAzureCredential
    from azure.ai.projects import AIProjectClient
    
    project = AIProjectClient(endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
                              credential=DefaultAzureCredential())
    openai = project.get_openai_client()
    MODEL = os.environ["FOUNDRY_MODEL_NAME"]
    MAX_ROUNDS = 3
    CRITERIA = ("1. Under 120 words. 2. States the refund amount and the date. "
                "3. Promises nothing beyond the refund. 4. Polite, plain English.")
    TASK = "Write a reply to a customer whose refund of 40 units was approved today."
    
    draft = openai.responses.create(model=MODEL, input=TASK).output_text
    for round_no in range(1, MAX_ROUNDS + 1):
        critique = openai.responses.create(
            model=MODEL,
            instructions="You are a strict reviewer. Check the draft against each "
                         "criterion. Reply APPROVED if every criterion passes; "
                         "otherwise list each failure on its own line.",
            input=f"Criteria:\n{CRITERIA}\n\nDraft:\n{draft}",
        ).output_text
        print(f"--- Round {round_no} critique ---\n{critique}")
        if critique.strip().startswith("APPROVED") and len(draft.split()) < 120:
            break
        draft = openai.responses.create(
            model=MODEL,
            instructions="Revise the draft to fix every listed failure. "
                         "Return only the revised draft.",
            input=f"Task: {TASK}\n\nDraft:\n{draft}\n\nFailures:\n{critique}",
        ).output_text
    else:
        print("Cap reached: route the last draft to a human reviewer.")
    print(f"--- Final draft ---\n{draft}")
    WHAT YOU SHOULD SEE
    --- Round 1 critique ---
    <the failures the reviewer found, one per line>
    --- Round 2 critique ---
    APPROVED
    --- Final draft ---
    <the revised reply>
  • Notice the word count is checked in code, not by the model: anything a rule can test belongs in a rule, as in Session 15. And give the checker different blind spots where you can, for example your small model from Session 5.
  • THE EXAM LINE

    Maker-checker (reflection) loops need clear acceptance criteria, an iteration cap, and a fallback when the cap is reached, such as escalation to a human reviewer.

A loop without a cap is not reflection. It is an open-ended bill.
40:00 – 45:00
Wrap-up: write it down, then build the assignment
  • Write down: the four approval mechanisms; the require_approval values and item names; why a function tool’s gate is in your code; the maker-checker conditions; and when chain of thought prompting fits.
  • Your assignment is a workflow that pauses for approval before a consequential tool call, plus a capped self-critique loop, with evidence of both.
  • Clean-up: confirm the agent versions are gone, delete the model deployment, and keep rg-ai103 for Session 17, where we trace an agent like these.
  • If the MCP call never produces an approval request (a firewall, an unreachable server, a timeout), send me the exact error the same day and use the function-tool gate for the assignment.
Autonomy is earned one approved action at a time. Build the gate first and widen it later.

The exact names

As Microsoft prints them — the exam and the marker both expect these, letter for letter.
require_approvalparameterSets which MCP tool calls need approval: always (the default), never, or named tools.Learn →
mcp_approval_requestconceptThe response item type that says an MCP tool call is waiting for approval.Learn →
mcp_approval_responseconceptThe input item type you send back to approve or reject the call.Learn →
approval_request_idparameterLinks your approval response to the request item it answers.Learn →
Human in the loopfeatureA Foundry workflow template that asks the user a question and waits before continuing.Learn →
Ask a questionportalThe workflow node that pauses and waits for the user’s input or approval.Learn →
approval_modeparameterAgent Framework’s tool setting; always_require makes a function wait for human approval.Learn →
user_input_requestsconceptWhere an Agent Framework run lists the tool calls waiting for approval.Learn →
maker-checker loopconceptOne agent proposes, another checks against criteria and sends it back until approved or capped.Learn →
iteration capconceptThe limit that stops a refinement loop, with a defined fallback when it is reached.Learn →
Chain of thought promptingconceptAsking a non-reasoning model to work step by step and show every step.Learn →
reasoning summaryfeatureThe supported way to see a summary of a reasoning model’s chain of thought.Learn →
output_tokens_details.reasoning_tokensparameterWhere a Responses API response reports how many reasoning tokens were used.Learn →
Every name in the course is on one printable page: download the AI-103 cheat sheet (PDF).
Key Terms

Approval gate

A point where a tool call waits for a human decision, which is then recorded, before anything changes.

Reasoning tokens

Tokens a reasoning model uses to think. They never appear in the answer but are billed as output tokens.

Self-Check — Before You Submit
1. A logistics firm’s agent uses an MCP server that offers get_shipment and cancel_shipment (illustrative names). Cancellations must be approved by a person; lookups must not slow users down. How do you configure the tool?
  • A. require_approval="never"
  • B. require_approval="always"
  • C. require_approval={"always": ["cancel_shipment"]}
  • D. Remove the MCP tool and rely on the agent’s instructions
C. require_approval={"always": ["cancel_shipment"]} — The dictionary form requires approval only for the named tool, so lookups run freely while cancellations wait. "always" is safe but slows every lookup, and instructions alone are not an approval control.
2. In a function-calling agent built on Foundry Agent Service, where does the approval gate for a consequential function belong?
  • A. In your application code, before it executes the function and returns the function_call_output
  • B. In the agent’s instructions, asking the model to confirm first
  • C. In the model deployment’s guardrail
  • D. In the agent’s version_selector
A. In your application code, before it executes the function and returns the function_call_output — Learn states that your app executes the function and returns the output, so your code decides whether it runs. A polite instruction to the model can be ignored; code cannot be talked round.
3. Your maker-checker loop sometimes never approves a draft and keeps calling the model. What does Microsoft’s guidance tell you to add?
  • A. A higher temperature for the checker
  • B. A prompt asking a reasoning model for its raw chain of thought
  • C. A second checker that always approves
  • D. An iteration cap, plus a fallback such as escalation to a human reviewer
D. An iteration cap, plus a fallback such as escalation to a human reviewer — The Architecture Center requires an iteration cap and a defined fallback when the cap is reached. Asking a reasoning model for raw reasoning is unsupported and does not stop the loop running.

Today’s Assignment

Build an agent workflow that pauses for human approval before a consequential tool call, add a capped self-critique loop, and show both working.
  • Pick a real task from your work (label invented details as illustrative) that has at least one read-only step and one consequential step. In 60–100 words, say which step needs approval and why.
  • Build the approval gate: either mcp_approval.py with require_approval (use the dictionary form if your server offers both kinds of tool), or your Session 13 function-calling agent with the gate from gate.py. Run it twice, approving once and rejecting once, and keep an audit record of both decisions.
  • Build a self-critique loop from critique_loop.py for an output your task produces. Write at least three acceptance criteria, keep MAX_ROUNDS at 3 or fewer, check anything countable in code, and define what happens when the cap is reached.
  • Explain (300–700 words): where your gate sits and why; what the agent did after the rejection; what the critic caught; how you would log approvals for an audit; and whether your model suits chain of thought prompting or a reasoning summary.
  • Include your full code with endpoints and deployment names read from environment variables. Never include keys, secrets or credentials, and crop keys and endpoints out of every screenshot.
  • Delete the agent versions and the model deployment afterwards, and say that you did.
Evidence to include
  • Terminal output of both approval runs, showing the approval request (or your gate prompt), your decision and the agent’s final answer, plus the audit records.
  • Terminal output of the self-critique loop, showing at least one critique and the final draft, or the cap message.
  • A screenshot of the agent in the Foundry portal before deletion, showing its tool, with keys and endpoints cropped out.
Names your answer must use exactly
require_approval mcp_approval_request maker-checker loop iteration cap Chain of thought prompting reasoning summary
Never include a key, a connection string or a token. Crop them out of every screenshot. If one is exposed, the letter will tell you to rotate it.
How this is marked — the rubric
The approval gate works: a consequential call pauses, one approval and one rejection are shown, and the rejection is handled sensibly30
The self-critique loop has written acceptance criteria, an iteration cap and a fallback, and the critique visibly changes the draft25
Uses the exact names from this session’s names box for the tool, parameters and response items20
Evidence: terminal output for both runs and the loop, and the portal screenshot with keys cropped; clean-up stated25
Total · pass mark 70100
Submitting session 16
Write your answer in Word or Google Docs, with your screenshots pasted in. The top of the document must carry the line Session: 16 (the template has it ready, under the Course line), or the submission is refused. Upload the Word file (.docx), or switch to the Google Doc tab and paste your document’s share link.
Marked against the rubric above and returned as a written letter by email; the mark appears on your progress page. Do the self-check above before you submit.
Skills Covered
Human-in-the-loop approvalsMCP tool approvalGating function toolsMaker-checker loopsChain-of-thought evaluation
Tick it once you have submitted.Next: Session 17 →
B · Implement generative AI and agentic solutions · 30–35%SESSION 17
Observability: tracing, token analytics, safety signals, latency; agent error analysis
Session 17 of 40 · 45-minute session
Skills measured — Microsoft’s wording
  • Integrate monitoring into deployed agents, evaluate agent behavior, and perform error analysis
  • Set up observability by implementing tracing, token analytics, safety signals, and latency breakdowns

Why This Matters

When an agent gives a wrong answer in production, “it worked when I tested it” is not an explanation. You need to see what happened: which tool it called, with which arguments, how long each step took, how many tokens it burned, and whether a safety control fired. AI-103 tests exactly that, down to the package names, the environment variable that switches tracing on, where traces are stored and the role needed to read them. At work, tracing turns a vague complaint into a fix you can prove. Today you trace your agent, read its spans, and learn to analyse an error rather than guess at it.

IN YOUR SUBSCRIPTION
Creates
An Application Insights resource connected to your project, created or connected from the project’s Traces page, plus whatever the portal creates alongside it: check Resource groups → rg-ai103 afterwards and note every new resource. Also a Global Standard model deployment and a short-lived traced agent version.
Cost
Billed. Model calls are billed per token. Learn’s Azure Monitor cost page says log data ingestion is the largest part of most Azure Monitor bills, and workspace-based Application Insights is billed through Log Analytics for ingestion and retention; standard platform metrics carry no charge. Traces are data, so a handful of test runs is cheap and a production firehose is not. Check the Azure Monitor pricing page.
Clean-up
The script deletes its agent version. Delete the model deployment at the end (Build → Models, or az cognitiveservices account deployment delete). Keep Application Insights connected: Session 19 needs it, Session 24 can use it, and the Session 40 capstone needs tracing again. Session 20 decides whether it stays. Keep rg-ai103.
The 45-Minute Session
7:00 – 14:00
Connect Application Insights and find the Traces tab
  • In the Foundry portal (New Foundry toggle on), open your project, select Agents in the left navigation, then Traces at the top. On the right, select Connect to create or connect an Application Insights resource.
  • The alternative route is the one you used for Azure AI Search in Session 10: Manage → Project details → Connected resources → Add connection → Application Insights.
  • At the time of writing, Learn says tracing is generally available for prompt and hosted agents, while workflow and external agents are in preview. The Traces tab lets you search, filter and sort traces from the last 90 days, and step through each span.
  • For one conversation, search by Response ID or Trace ID, then open the Conversation ID to review the history, tokens, ordered actions, run steps and tool calls.
  • Treat traces as production telemetry. Learn’s advice: never put secrets, credentials or tokens in prompts, tool arguments or span attributes; redact or minimise personal data; apply the same access controls and retention you use for logs.
Connect it once, per project, before the incident. Nobody enjoys wiring up telemetry while the phone is ringing.
26:00 – 34:00
Token analytics, safety signals and latency breakdowns
  • Token analytics. Each model span carries token counts, your code can print response.usage.output_tokens, and the agent’s Monitor tab charts token usage over time. Remember from Session 16 that reasoning tokens are billed as output tokens even though you never see them.
  • Latency breakdowns. Learn’s performance page gives the formula: TTLT = TTFT + (TBT × Tokens Generated), where TTFT is time to first token, TBT is time between tokens and TTLT is time to last token. The matching Azure Monitor metrics are Time to Response, Time Between Tokens and Time to Last Byte. In a trace, span durations show whether the time went to the model or to a tool.
  • Illustrative: a hospital’s appointment agent feels slow. The trace shows most of each request inside the execute_tool span for the booking system, not in the model. The fix is in the booking API, not the prompt.
  • SignalWhere you read itWhat it tells you
    Token usageSpan attributes in Traces; response.usage; the agent’s Monitor tabWhat drives cost, and which prompts or tool results are bloated
    LatencySpan durations; Time to Response, Time Between Tokens and Time to Last Byte metricsWhether the model, a tool or the network is slow
    Safety signalsBlocked Volume and Harmful Volume Detected metrics; safety evaluators such as builtin.violenceHow often content filters act on your traffic, and whether outputs are unsafe
    Run success rateThe agent’s Monitor tabLearn says a rate below 95% warrants investigation
  • The Agent Monitoring Dashboard brings these together. In the Foundry portal select Build, select your agent, then the Monitor tab: summary cards, then charts for token usage, latency, run success rate, evaluation metrics and red teaming results. Learn adds that latency above 10 seconds may point to throttling, complex tool calls or network issues.
A number without a time range is a rumour. Always note the range you were looking at.
41:00 – 45:00
Wrap-up: the names, the assignment and clean-up
  • Write down: the three core observability capabilities; trace, span and attribute; invoke_agent and execute_tool; the install line; the environment variable and its ordering rule; where traces are stored and the role needed to read them; the latency formula; and the two groups of agent evaluators.
  • Your assignment is a traced run with an error analysed and fixed, with evidence from the Traces tab.
  • Clean-up: the script deletes its agent version; delete the model deployment. Keep Application Insights connected for Session 19. Leave content recording off.
  • If traces never appear after ten minutes, check the ordering rule, your connection, and the Log Analytics Reader role, in that order. Then send me the details the same day.
Evidence beats description, and a trace is the best evidence an agent can give you.

The exact names

As Microsoft prints them — the exam and the marker both expect these, letter for letter.
AIProjectInstrumentorclassTurns on GenAI tracing for Foundry SDK and OpenAI Responses calls when you call instrument().Learn →
azure-monitor-opentelemetrypackageThe package that exports OpenTelemetry traces to Azure Monitor Application Insights.Learn →
configure_azure_monitormethodSends your app’s spans to the Application Insights resource named by a connection string.Learn →
get_application_insights_connection_stringmethodReads the connection string of the project’s connected Application Insights resource.Learn →
AZURE_EXPERIMENTAL_ENABLE_GENAI_TRACINGsettingMust be true before instrument() is called, or no GenAI spans are produced.Learn →
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENTsettingRecords message content and tool arguments in spans. Off by default; development use only.Learn →
trace_functionmethodA decorator that creates a span for each call to your own function.Learn →
Log Analytics ReaderroleThe role needed on the connected Application Insights resource to query traces.Learn →
execute_toolconceptThe span name that records a tool execution inside an agent trace.Learn →
Agent Monitoring DashboardportalThe agent’s Monitor tab: token usage, latency, run success rate, evaluations and red teaming.Learn →
Time to ResponseconceptThe Azure Monitor latency metric for streaming requests: time to the first response chunk.Learn →
Task AdherenceconceptA system evaluator: did the agent follow the rules and constraints in its instructions?Learn →
Tool Call AccuracyconceptA process evaluator: did the agent make the right tool calls with correct parameters?Learn →
Cluster analysisfeatureGroups evaluation samples with similar problems so you can spot recurring errors (preview).Learn →
Every name in the course is on one printable page: download the AI-103 cheat sheet (PDF).
Key Terms

Span

One timed operation inside a trace, such as a model call or a tool execution, with its attributes.

Error analysis

Finding the failing step in real runs, naming its root cause, fixing one thing and proving the fix with a new trace.

Self-Check — Before You Submit
1. A developer calls AIProjectInstrumentor().instrument() and configure_azure_monitor, runs the agent, and no GenAI spans appear. A warning was logged. What is the most likely cause?
  • A. The model deployment is Global Standard
  • B. AZURE_EXPERIMENTAL_ENABLE_GENAI_TRACING was not set to true before instrument() was called
  • C. Content recording was left off
  • D. The agent has no function tools
B. AZURE_EXPERIMENTAL_ENABLE_GENAI_TRACING was not set to true before instrument() was called — Learn says the variable must be true before instrument() is called, or instrumentation isn’t enabled and a warning is logged. Content recording only controls whether message content is captured, not whether spans exist.
2. A colleague can open your project but gets an authorisation error when viewing traces. Which role should you check first on the connected Application Insights resource?
  • A. Log Analytics Reader
  • B. Foundry Account Owner
  • C. Cognitive Services Contributor
  • D. Cost Management Reader
A. Log Analytics Reader — Learn lists Log Analytics Reader on the connected Application Insights resource as the role needed to query telemetry, plus Privileged Monitoring Data Reader if tables are protected. The other roles govern resources, deployments or costs, not trace queries.
3. A hospital’s scheduling agent is slow, and the team must know whether the model or the booking tool is responsible. What should they look at?
  • A. The Blocked Volume metric
  • B. The TPM quota on the Quota page
  • C. A higher max_output_tokens value
  • D. The trace, comparing the duration of the execute_tool span with the model call
D. The trace, comparing the duration of the execute_tool span with the model call — Span durations in a trace show where the time went, step by step. Blocked Volume counts content-filter rejections, and quota explains throttling, not which step of a working request is slow.

Today’s Assignment

Trace your agent, introduce or find a real error, analyse it from the trace, fix it, and prove the fix with a second trace.
  • Connect Application Insights to your project and adapt traced_agent.py to your Session 13 agent (add File Search back if you recreate its vector store), keeping endpoints and deployment names in environment variables.
  • Run it once successfully. Then introduce one realistic error (a schema that does not match the function, a tool that raises, or instructions that stop the tool being used) or use a real one you hit, and run it again.
  • Find the failure in the Traces tab. Write the analysis: symptom, the failing span, root cause in one sentence, the single change you made, and what the fixed trace shows.
  • Compare the failed and fixed runs on output tokens and on the duration of the model and tool spans, and say what drove any difference.
  • Explain (300–700 words) the steps above, plus what you would and would not record in production, and why. Leave content recording off unless the data is invented test data.
  • Never include keys, secrets, credentials or connection strings. Crop the connection string, keys and endpoints out of every screenshot. Delete the model deployment afterwards and say so.
Evidence to include
  • A screenshot of the failing trace in the Traces tab with the span tree expanded, sensitive values cropped.
  • A screenshot of the fixed trace showing the tool span succeeding, with durations or token counts visible.
  • Terminal output of the failed and the fixed runs.
Names your answer must use exactly
AIProjectInstrumentor configure_azure_monitor AZURE_EXPERIMENTAL_ENABLE_GENAI_TRACING execute_tool Log Analytics Reader Tool Call Accuracy
Never include a key, a connection string or a token. Crop them out of every screenshot. If one is exposed, the letter will tell you to rotate it.
How this is marked — the rubric
Tracing works end to end and both runs appear in the Traces tab, with the agent correlated25
The error analysis names the failing span and a one-sentence root cause, and the fix is a single change proven by a second trace30
Uses the exact package, class, setting and span names from this session’s names box20
Evidence: both trace screenshots and both terminal outputs, with no keys or connection strings visible; clean-up stated25
Total · pass mark 70100
Submitting session 17
Write your answer in Word or Google Docs, with your screenshots pasted in. The top of the document must carry the line Session: 17 (the template has it ready, under the Course line), or the submission is refused. Upload the Word file (.docx), or switch to the Google Doc tab and paste your document’s share link.
Marked against the rubric above and returned as a written letter by email; the mark appears on your progress page. Do the self-check above before you submit.
Skills Covered
Agent tracing with OpenTelemetryApplication Insights for FoundryToken and latency analysisSafety signalsAgent error analysis
Tick it once you have submitted.Next: Session 18 →
A · Plan and manage an Azure AI solution · 25–30%SESSION 18
Quotas, scaling, rate limits and cost footprints
Session 18 of 40 · 45-minute session
Skills measured — Microsoft’s wording
  • Manage quotas, scaling, rate limits, and cost footprints for model and agent workloads

Why This Matters

Two things end AI projects that work perfectly in testing: a wall of 429 errors at nine on Monday morning, and an invoice nobody predicted. Both are about capacity. AI-103 expects you to know how quota is assigned, how tokens-per-minute and requests-per-minute limits are enforced, what to do with a 429, when provisioned throughput is the right answer, and where to read what you have spent. At work, you will be asked “can it take the load, and what will it cost?” long before anyone asks about prompts. Today you read your own quota, handle throttling in code and trace spend back to your project.

IN YOUR SUBSCRIPTION
Creates
One model deployment on Global Standard with a deliberately small capacity (1 unit, as in Session 4), so that a short burst can trigger throttling. You read quota, usage and costs; nothing else is created.
Cost
Billed per token. The retry script sends 20 very short requests with a small output cap, plus any retries. Do not create a provisioned deployment for practice: Learn says hourly billing for provisioned throughput is based on the PTUs deployed, regardless of tokens consumed. For rates, use the Microsoft Foundry pricing page and the Azure pricing calculator.
Clean-up
Delete the deployment when your evidence is saved: Build → Models → delete, or az cognitiveservices account deployment delete --deployment-name <name> -n <resource> -g rg-ai103. Deleting deployments first also frees their quota allocation. Keep rg-ai103.
The 45-Minute Session
9:00 – 16:00
See your quota, and ask for more
  • In the Foundry portal, select Manage in the upper-right navigation, then Quota. There are two tabs: Token per minute for standard deployments and Provisioned throughput unit for provisioned ones. Select a deployment to see its details, use the pencil icon in the Actions column to change its allocation, and use Request quota in the upper-right corner to ask for more. Learn says changes can take up to 15 minutes to apply.
  • From the command line, the Azure CLI shows your quota usage for a region, and the deployment itself shows the capacity it holds.
  • bashquota.shtype it yourself
    # Quota usage in your region: name, current value and limit
    az cognitiveservices usage list -l <your-region> -o table
    
    # The capacity (TPM units) and type of one deployment
    az cognitiveservices account deployment show \
        --deployment-name "<your-deployment-name>" \
        -n <your-foundry-resource-name> \
        -g rg-ai103 \
        --query "sku"
    WHAT YOU SHOULD SEE
    <one row per quota: its name, current value and limit>
    {
      "capacity": 1,
      "name": "GlobalStandard"
    }
  • Learn also documents a REST usages API whose entries are named like {Provider}.{DeploymentType}.{Model}, with currentValue and limit. Look at quota per deployment, not only per subscription: Learn recommends rebalancing allocations across deployments based on observed usage.
  • A clean-up detail with a quota twist: the portal will not delete a resource while it still has deployments, and deleting deployments first frees their quota. Delete a resource by some other route with deployments still on it, and Learn says the quota stays unavailable for 48 hours, until the resource is purged.
Request quota before launch week, with numbers. “We might need more” is not a capacity plan.
27:00 – 35:00
Scaling with provisioned throughput
  • Standard deployments share inference capacity across customers, so throughput can vary with demand. Provisioned throughput holds a fixed amount of processing capacity for your deployment alone, whether or not requests are being made. Provisioned throughput units (PTUs) measure it; the same PTU quota can deploy any supported model, and Learn notes minimum deployment sizes vary by model.
  • Learn’s signals for choosing it: predictable traffic, latency-sensitive requirements, production-scale volume where per-token billing becomes expensive, and real-time scenarios such as chat, copilots and agents.
  • When a provisioned deployment is fully used, it returns 429. The Provisioned-managed Utilization V2 metric shows PTUs consumed against PTUs deployed. Spillover is an optional setting that sends overflow requests to a standard deployment in the same Foundry resource, for all requests or per request with the x-ms-spillover-deployment header.
  • Standard (pay per token)Provisioned (PTUs)
    CapacityShared pool, limited by your TPM allocationReserved for your deployment
    BillingPer token processedHourly per PTU deployed, used or not; Azure Reservations can discount the PTU meter
    When it throttlesRate limit reached, or a temporary adjustment on the shared poolUtilization at 100%; spillover can absorb overflow
    SKUs to recogniseGlobalStandard, DataZoneStandard, StandardGlobalProvisionedManaged, DataZoneProvisionedManaged, ProvisionedManaged
  • Azure Reservations give a discount on the PTU billing meter for one-month or one-year terms, scoped to a deployment type. The trap: Learn says reservations don’t guarantee capacity. Create the deployments first to confirm capacity exists, then buy the reservation.
  • THE EXAM LINE

    Provisioned throughput reserves PTUs and bills hourly whether used or not. Azure Reservations discount the PTU meter but don't guarantee capacity. Spillover routes overflow to a standard deployment in the same resource.

Buy provisioned throughput for traffic you can forecast, not for traffic you hope for.
41:00 – 45:00
Wrap-up: the capacity plan and clean-up
  • Write down: the four things quota is assigned by; how TPM becomes a rate limit and sets RPM; what counts towards the estimate; retry-after-ms and max_retries; the retry-versus-escalate table; PTUs, spillover and what reservations do not do; and the Cost analysis path and the project tag.
  • Your assignment is a capacity and cost plan for a real workload, with working retry code.
  • Clean-up: delete the small deployment once your evidence is saved. Nothing else was created. Keep rg-ai103.
  • If Quota or Cost analysis shows nothing, check your role and tell me the same day; a missing permission is a blocker.
Capacity is a design decision. Make it on purpose, write it down, and revisit it when traffic changes.

The exact names

As Microsoft prints them — the exam and the marker both expect these, letter for letter.
Tokens-per-Minute (TPM)conceptThe unit of quota; a deployment’s TPM allocation is also its token rate limit.Learn →
Requests-Per-Minute (RPM)conceptThe request rate limit, set in proportion to a deployment’s TPM.Learn →
Request quotaportalThe button on Manage → Quota for asking for more standard quota.Learn →
retry-after-mssettingThe 429 response header giving the recommended wait, in milliseconds, before retrying.Learn →
max_retriesparameterThe openai client setting for built-in retries with exponential backoff; the default is two.Learn →
RateLimitErrorclassThe openai package exception raised for a 429 response.Learn →
az cognitiveservices usage listcliShows quota usages for Cognitive Services, including Foundry, in a region.Learn →
Provisioned throughput units (PTUs)tierThe unit of reserved model processing capacity for provisioned deployments.Learn →
SpilloverfeatureSends overflow from a full provisioned deployment to a standard deployment in the same resource.Learn →
x-ms-spillover-deploymentsettingThe request header that controls spillover for an individual request.Learn →
Azure ReservationsfeatureOne-month or one-year discounts on the PTU meter; they don’t guarantee capacity.Learn →
Cost analysisportalThe Cost Management view of spend, groupable by meter and filterable by tag.Learn →
Cost Management ReaderroleA role that lets you view costs and usage data.Learn →
Every name in the course is on one printable page: download the AI-103 cheat sheet (PDF).
Key Terms

Exponential backoff

Waiting longer after each failed attempt, usually doubling the delay, with random jitter so clients do not retry together.

Cost footprint

Everything a workload spends, including tool calls, retries, loops and reasoning tokens, not just the visible answer.

Self-Check — Before You Submit
1. A Lagos bank’s chatbot gets 429 errors although Azure Monitor shows token usage well below the deployment’s TPM. Every request sets a very large max_tokens. What is the most likely cause?
  • A. The deployment type is Data Zone Standard
  • B. Rate limiting uses an estimate that includes max_tokens, so each request reserves far more than it uses
  • C. Usage metrics only update once a day
  • D. Content filtering is blocking the requests
B. Rate limiting uses an estimate that includes max_tokens, so each request reserves far more than it uses — Learn explains that the rate-limit estimate includes max_tokens, while usage metrics show billed tokens, so an oversized max_tokens throttles traffic that looks light. Content filtering produces blocked responses, not 429s.
2. Which statement about Azure Reservations for provisioned throughput is correct?
  • A. They reserve capacity in a region
  • B. They replace the need for PTU quota
  • C. They discount the PTU billing meter but don’t guarantee capacity
  • D. They apply only to Global Standard deployments
C. They discount the PTU billing meter but don’t guarantee capacity — Learn says reservations are a financial discount on the PTU meter and don’t guarantee capacity, so you create deployments first. Standard deployments are billed per token and are not what reservations discount.
3. A logistics firm’s tracking assistant has predictable traffic, needs consistently low latency, and sees frequent 429s on a Standard deployment. What does Learn point to?
  • A. Provisioned throughput, optionally with spillover to a standard deployment
  • B. Global Batch, for a 24-hour turnaround
  • C. A higher max_retries value and nothing else
  • D. Deleting and recreating the deployment every morning
A. Provisioned throughput, optionally with spillover to a standard deployment — Learn recommends considering provisioned throughput for latency-sensitive workloads with frequent 429s and predictable traffic. More retries only hide throttling, and batch is for asynchronous work, not real-time chat.

Today’s Assignment

Write a capacity and cost plan for a real model or agent workload, backed by your own quota readings and working retry code.
  • Describe the workload (an organisation you know; label invented details as illustrative): users, peak requests per minute, and your estimate of prompt and completion tokens per request, including tool calls and any self-critique rounds. Calculate the TPM it needs and show the arithmetic.
  • Read your quota in Manage → Quota and with az cognitiveservices usage list. State the limit for your model and deployment type, your current allocation, and whether you would request more.
  • Choose Standard or provisioned throughput (with or without spillover), and justify it against Learn’s criteria. Do not quote prices; name the pricing page or calculator you would use.
  • Run retry.py against a small deployment. Explain your backoff settings, why the built-in retries are switched off, what retry-after-ms is for, and when you would escalate instead of retrying.
  • Open Cost analysis grouped by Meter (or filtered by the project tag), name three cost drivers of your workload and one way to reduce each. Keep the explanation to 300–700 words.
  • Never include keys, secrets or credentials; crop subscription IDs if you prefer. Delete the deployment afterwards and say so.
Evidence to include
  • A screenshot of the Quota page or the output of az cognitiveservices usage list for your region.
  • Terminal output of retry.py, including any 429 retry lines, or a clear note that none occurred and at what capacity.
  • A screenshot of Cost analysis grouped by Meter or filtered by the project tag.
Names your answer must use exactly
Tokens-per-Minute (TPM) Requests-Per-Minute (RPM) retry-after-ms max_retries Provisioned throughput units (PTUs) Cost analysis
Never include a key, a connection string or a token. Crop them out of every screenshot. If one is exposed, the letter will tell you to rotate it.
How this is marked — the rubric
The TPM estimate is calculated from stated assumptions and the Standard-or-provisioned choice is justified against Learn’s criteria30
The retry code works, disables double retries and backs off with jitter; the retry-versus-escalate reasoning is correct25
Uses the exact names from this session’s names box for limits, headers, parameters and portal views20
Evidence: quota reading, retry output and a Cost analysis screenshot, with no keys visible; clean-up stated25
Total · pass mark 70100
Submitting session 18
Write your answer in Word or Google Docs, with your screenshots pasted in. The top of the document must carry the line Session: 18 (the template has it ready, under the Course line), or the submission is refused. Upload the Word file (.docx), or switch to the Google Doc tab and paste your document’s share link.
Marked against the rubric above and returned as a written letter by email; the mark appears on your progress page. Do the self-check above before you submit.
Skills Covered
TPM and RPM quotas429 handling and retriesProvisioned throughputCost analysisCapacity planning
Tick it once you have submitted.Next: Session 19 →
A · Plan and manage an Azure AI solution · 25–30%SESSION 19
Monitoring models and data: drift, safety events, grounding, index health, relevance
Session 19 of 40 · 45-minute session
Skills measured — Microsoft’s wording
  • Monitor model performance, drift, safety events, and grounding quality
  • Monitor data ingestion quality, search index health, and relevance performance

Why This Matters

RAG apps and agents rarely fail loudly. An indexer quietly skips new files, answers drift away from the source documents, content filters start firing more often, and nobody notices until a customer does. AI-103 asks you to monitor both halves of the system: the model (performance, drift, safety events, grounding quality) and the data behind it (ingestion quality, index health, relevance). You need the exact metric names and where each is read. At work, a monitoring runbook is what lets someone other than you keep the system healthy. Today you read real metrics, check an indexer from code and switch on continuous evaluation.

IN YOUR SUBSCRIPTION
Creates
An evaluation and a continuous evaluation rule in your project, and optionally a diagnostic setting on your Foundry resource. You also need a Global Standard deployment, an agent in the project (recreate your Session 13 agent and keep it until Session 20), and an Azure AI Search service with an indexer. Session 7 pushed documents straight into its index, so it had no indexer: recreate the Basic service as in Session 10, add a storage account (Microsoft.Storage/storageAccounts) with a blob container holding three or four of your own files, and run the Import data wizard over it.
Cost
Billed. Continuous evaluation runs evaluators on sampled responses, which uses model calls; the script caps it with max_hourly_runs. Platform metrics are free, but a diagnostic setting that sends logs to Log Analytics adds ingestion charges. Azure AI Search on the dedicated pricing model bills until the service is deleted, and the storage account bills for what it stores. Check the Microsoft Foundry, Azure AI Search, Storage and Azure Monitor pricing pages.
Clean-up
Switch the rule off by running continuous_eval.py again with enabled=False. Remove any diagnostic setting you added (Monitoring → Diagnostic settings). Delete the model deployment. Leave the agent, the search service, the storage account and Application Insights for Session 20, which is the full clean-up.
The 45-Minute Session
8:00 – 17:00
Model performance and safety events in Azure Monitor
  • In the Azure portal, search for Monitor, select Metrics, choose your Foundry resource as the scope (resource type Foundry Tools), then pick metrics and split them by dimensions such as ModelDeploymentName or StatusCode. In the Foundry portal, Build → Models → a deployment → Monitor gives a per-deployment view.
  • Learn’s pages disagree slightly on that Foundry portal path: the model-monitoring page still says Models + endpoints, while the newer cost page uses Build → Models. Follow what your portal shows.
  • Every metric has a display name and a REST name, and the CLI wants the REST name: Processed Inference Tokens is TokenTransaction, Azure OpenAI Requests is AzureOpenAIRequests, Blocked Volume is RAIRejectedRequests, and Harmful Volume Detected is RAIHarmfulRequests.
  • bashmetrics.shtype it yourself
    # The resource ID of your Foundry resource
    id=$(az cognitiveservices account show \
        -n <your-foundry-resource-name> -g rg-ai103 --query id -o tsv)
    
    # Tokens processed and requests made, hourly for the last day, per deployment
    az monitor metrics list --resource $id \
        --metrics TokenTransaction AzureOpenAIRequests \
        --dimension ModelDeploymentName \
        --interval PT1H --offset 1d --aggregation Total -o table
    
    # Safety events: calls rejected by, or flagged by, content filtering
    az monitor metrics list --resource $id \
        --metrics RAIRejectedRequests RAIHarmfulRequests \
        --interval PT1H --offset 1d --aggregation Total -o table
    WHAT YOU SHOULD SEE
    <a table of timestamps and totals per metric, one series per deployment>
  • Blocked Volume counts calls rejected by the content filter; Harmful Volume Detected counts calls detected as harmful whether blocked or only annotated. A rise in either is a safety event worth a look. For provisioned deployments, Provisioned-managed Utilization V2 at 100% or more means 429s.
  • To keep logs, open the Foundry resource in the Azure portal, select Monitoring → Diagnostic settings → Add diagnostic setting, choose log categories such as RequestResponse and Audit, tick AllMetrics, choose Send to Log Analytics workspace, and save. Logs you ingest are logs you pay for.
Use the portal to explore and the CLI to prove. A command you can rerun is a better runbook step than a screenshot.
27:00 – 37:00
Data ingestion quality and search index health
  • If you have no indexer yet, open the search service’s Overview page, select Import data, and point the wizard at your blob container; it creates a data source, an index and an indexer. Session 25 builds this properly. Then open the Indexers list, select Refresh, then select an indexer. The Indexer summary chart shows documents processed in recent runs, and Execution details lists up to 50 recent runs. Open one to see its times, Docs Succeeded, Errors and Warnings.
  • The trap: a run can show success even though some documents failed, as long as the errors stay under the indexer’s Max failed items setting. Always read the errors and warnings, not just the status.
  • From code, SearchIndexerClient.get_indexer_status returns the overall status, the last result and the execution history. Keyless access for indexer operations needs a role such as Search Service Contributor, and the service’s API access control must allow role-based access.
  • pythonindexer_status.pytype it yourself
    import os
    from azure.identity import DefaultAzureCredential
    from azure.search.documents.indexes import SearchIndexerClient
    
    # AZURE_SEARCH_SERVICE_ENDPOINT is the variable name Learn's Python readme uses.
    # Export it with the same URL as SEARCH_ENDPOINT from Session 7.
    client = SearchIndexerClient(os.environ["AZURE_SEARCH_SERVICE_ENDPOINT"],
                                 DefaultAzureCredential())
    
    for indexer in client.get_indexers():
        status = client.get_indexer_status(indexer.name)
        print(f"{status.name}: {status.status}, "
              f"{len(status.execution_history)} runs in history")
        last = status.last_result
        if last:
            print(f"  last run: {last.status}, ended {last.end_time}")
            print(f"  items {last.item_count}, failed {last.failed_item_count}, "
                  f"errors {len(last.errors)}, warnings {len(last.warnings)}")
            if last.error_message:
                print(f"  top-level error: {last.error_message}")
    WHAT YOU SHOULD SEE
    <indexer-name>: running, <n> runs in history
      last run: success, ended <time>
      items <n>, failed <n>, errors <n>, warnings <n>
  • Index health lives in the search service’s metrics: Document processed count and Skill execution invocation count (both split by a Failed dimension), Search Latency, Search queries per second, Throttled search queries percentage, Storage usage and Vector Storage usage. Learn’s suggested alerts include Search Latency, throttled queries, storage usage and compute usage.
  • THE EXAM LINE

    An indexer run can report success while documents failed, if errors stay under Max failed items. Check Docs Succeeded, errors and warnings; the status API returns lastResult and up to 50 runs of executionHistory.

Check ingestion before relevance. Most “the search got worse” tickets are really “the new files never arrived”.
41:00 – 45:00
Wrap-up: the runbook, and what stays running
  • Write down: the monitoring table with its exact names; display versus REST names; continuous versus scheduled evaluation; the Max failed items trap; and the two score ranges.
  • Your assignment is a monitoring runbook for your RAG solution, naming each metric or evaluator and where it is read, with evidence from your own resources.
  • Clean-up: switch the continuous evaluation rule off with enabled=False, remove any diagnostic setting you added, and delete the model deployment. Everything else waits for Session 20, where we clean up the whole course so far.
  • If the Monitor tab stays empty after traffic, work through Learn’s checklist, then send me what you found the same day.
Monitoring is a habit, not a dashboard. Put a weekly ten-minute check in your diary and keep it.

The exact names

As Microsoft prints them — the exam and the marker both expect these, letter for letter.
Azure OpenAI RequestsconceptThe metric counting calls to the API, splittable by deployment and status code.Learn →
Processed Inference TokensconceptThe metric for prompt plus generated tokens; REST name TokenTransaction.Learn →
Blocked VolumeconceptThe metric counting calls rejected by the content filter.Learn →
Harmful Volume DetectedconceptThe metric counting calls the content filter detected as harmful, blocked or annotated.Learn →
Diagnostic settingsportalWhere you route a resource’s logs and metrics to a destination such as Log Analytics.Learn →
Continuous evaluationfeatureQuality and safety evaluation of production traffic at a sampled rate.Learn →
Scheduled evaluationfeatureEvaluation on a schedule against test datasets, to detect system drift.Learn →
ContinuousEvaluationRuleActionclassThe rule action that runs an evaluation on agent responses, with an hourly cap.Learn →
max_hourly_runsparameterCaps how many continuous evaluation runs happen per hour; extra runs are skipped.Learn →
get_indexer_statusmethodReturns an indexer’s current status and execution history from Python.Learn →
Docs SucceededportalThe count of documents indexed in a run, shown in the indexer’s execution details.Learn →
Throttled search queries percentageconceptThe AI Search metric for the share of queries that were throttled.Learn →
@search.rerankerScoreconceptThe semantic ranker’s relevance score, from 0.00 to 4.00.Learn →
Max failed itemssettingThe error count below which an indexer run still reports success.Learn →
Every name in the course is on one printable page: download the AI-103 cheat sheet (PDF).
Key Terms

Resource logs

Detailed records of a resource’s operations, kept only once a diagnostic setting routes them to a destination.

Indexer execution history

The recent runs of an Azure AI Search indexer, up to 50, each with its status, counts, errors and warnings.

Self-Check — Before You Submit
1. A public agency’s RAG assistant is missing last week’s documents. The nightly indexer shows a successful run. What should you check next?
  • A. The Blocked Volume metric
  • B. The run’s execution details: Docs Succeeded, errors and warnings
  • C. The semantic ranker’s score range
  • D. The TPM quota of the chat deployment
B. The run’s execution details: Docs Succeeded, errors and warnings — A run can succeed while individual documents fail, as long as errors stay under Max failed items, so the execution details are where missing files show up. Blocked Volume concerns content filtering on model calls, not ingestion.
2. Which approach detects gradual drift in answer quality over several months?
  • A. Continuous evaluation on a sample of production traffic only
  • B. The Harmful Volume Detected metric
  • C. Scheduled evaluation against the same fixed test dataset, comparing scores over time
  • D. A diagnostic setting sending Audit logs to Log Analytics
C. Scheduled evaluation against the same fixed test dataset, comparing scores over time — Learn describes scheduled evaluation with test datasets as the way to detect system drift. Continuous evaluation samples live traffic, whose questions change, so its scores mix drift with changing inputs.
3. You must report how many requests the content filter rejected, per deployment, over the last day. Which metric do you use?
  • A. Processed Inference Tokens split by ModelName
  • B. Azure OpenAI Requests with no split
  • C. Throttled search queries percentage
  • D. Blocked Volume, split by ModelDeploymentName
D. Blocked Volume, split by ModelDeploymentName — Blocked Volume counts calls rejected by the content filter and supports splitting by ModelDeploymentName. Throttled search queries percentage belongs to Azure AI Search and measures throttling, not filtering.

Today’s Assignment

Write a monitoring runbook for your RAG solution that names each metric or evaluator exactly, says where it is read and what to do when it breaches, backed by readings from your own resources.
  • Describe your RAG solution from Session 7 or 13 in 60–100 words: the model deployment, the search service and index, the indexer and the agent or app.
  • Build a runbook table with one row each for model performance, safety events, grounding quality, drift, ingestion quality, index health and relevance. For each give the exact metric or evaluator name, where it is read (portal path or command), a threshold or alert condition you choose, and the first action when it breaches.
  • Take real readings: run metrics.sh for at least two metrics, run indexer_status.py against your indexer, and run continuous_eval.py with a low max_hourly_runs, then send the agent some traffic.
  • Explain (300–700 words) how you would tell ingestion problems from relevance problems, how you would detect drift, and what your monitoring costs to run (logs, evaluations, the search service), without quoting prices.
  • Include your code with endpoints read from environment variables. Never include keys, secrets, credentials or connection strings; crop them and your endpoints from screenshots.
  • Switch the rule off with enabled=False, remove any diagnostic setting you added, delete the model deployment, and say so.
Evidence to include
  • Output of metrics.sh (or a Metrics explorer screenshot) for at least two metrics.
  • Output of indexer_status.py, or a screenshot of the indexer’s execution details showing Docs Succeeded, errors and warnings.
  • A screenshot of the agent’s Monitor tab or the evaluation report after continuous evaluation ran.
Names your answer must use exactly
Processed Inference Tokens Blocked Volume Continuous evaluation Scheduled evaluation get_indexer_status Docs Succeeded Throttled search queries percentage
Never include a key, a connection string or a token. Crop them out of every screenshot. If one is exposed, the letter will tell you to rotate it.
How this is marked — the rubric
The runbook covers all seven areas, and each row has a correct signal, where it is read, a threshold and a first action35
Uses the exact metric, evaluator, class and method names from this session’s names box, including REST names where a command needs them20
The explanation separates ingestion from relevance problems and gives a sound method for detecting drift20
Evidence: metric output, indexer status and a Monitor tab or report screenshot, with no keys visible; clean-up stated25
Total · pass mark 70100
Submitting session 19
Write your answer in Word or Google Docs, with your screenshots pasted in. The top of the document must carry the line Session: 19 (the template has it ready, under the Course line), or the submission is refused. Upload the Word file (.docx), or switch to the Google Doc tab and paste your document’s share link.
Marked against the rubric above and returned as a written letter by email; the mark appears on your progress page. Do the self-check above before you submit.
Skills Covered
Azure Monitor metricsSafety event monitoringContinuous evaluationIndexer and index healthRelevance monitoring
Tick it once you have submitted.Next: Session 20 →
Review · every domainSESSION 20
Mid-course review: every name so far, and practice exam 1
Session 20 of 40 · 45-minute session

Why This Matters

You are halfway. Nineteen sessions have covered every objective in the two heaviest domains except security, CI/CD, responsible AI and governance, which Week 5 teaches. Before Practice Exam 1, this session does three honest things. It drills every objective so far against Microsoft’s own wording and turns the gaps into a written weak-spot register. It teaches exam technique from Microsoft’s own pages, not folklore. And it cleans up your subscription, because four weeks of labs leave things running that you have forgotten. Skip the register and you are guessing where your gaps are.

IN YOUR SUBSCRIPTION
Creates
Nothing new. You list everything created in Sessions 1 to 19 and delete what you no longer need.
Cost
Today stops idle charges. Learn’s cost pages name the usual suspects: an Azure AI Search service on dedicated pricing bills until deleted; provisioned and fine-tuned deployments bill while deployed; Log Analytics bills for data it ingests and keeps. Check Cost analysis tomorrow.
Clean-up
This session is the clean-up: deployments first, then the resources in the decision table. Keep rg-ai103 with its Foundry resource and project for Week 5, or delete the whole group (Resource groups → rg-ai103 → Delete resource group) and recreate it, with its Foundry resource and project, as in Session 2, before Session 21. The project endpoint will then be new, so update FOUNDRY_PROJECT_ENDPOINT.
The 45-Minute Session
5:00 – 12:00
Drill 1: Domain A objectives covered so far
  • Objective (Microsoft’s wording)SessionSay it without notes
    Choose an appropriate model for each task, including large language models (LLMs), small language models, multimodal models, and Foundry Tools1When does a Foundry Tool beat an LLM? Where do you compare models?
    Choose the appropriate Foundry services for generative tasks, grounding, vector search, agent workflows, or multimodal processing; Choose an appropriate method for retrieval and indexing2Which service generates, acts, finds, extracts? Hybrid versus semantic ranker? Classic RAG or agentic retrieval?
    Choose appropriate memory, tool, and knowledge integration services for agent solutions11Which built-in tool fits each need? How is state kept?
    Design Azure infrastructure for AI apps and agent-based solutions; Choose appropriate deployment options3Basic versus standard agent setup; Serverless API versus Managed compute; Global Standard versus Data Zone Standard
    Configure model and agent deployments4Deployment name versus model name; version update policies; agent versions
    Manage quotas, scaling, rate limits, and cost footprints for model and agent workloads18What quota is assigned by; what counts towards TPM; 429 handling; PTUs
    Monitor model performance, drift, safety events, and grounding quality19Which metric counts filter rejections? How is drift detected?
    Monitor data ingestion quality, search index health, and relevance performance19Why can a successful indexer run lose documents?
  • THE EXAM LINE

    The study guide says most questions cover generally available features, and the exam may include preview features if they are commonly used. Learn the current name first, and know which features Learn marks as preview.

  • Watch the renamed names as you drill: Foundry Tools and the Foundry roles replaced older names recently, and questions are written around the current ones.
If two options differ by a single word, that word is the question. Find it before you read anything else.
20:00 – 28:00
Exam technique, from Microsoft’s own pages
  • Scoring. Scores run from 1 to 1,000; 700 passes. Most multi-part questions give one point per correct component, so partial answers earn marks. Some questions may be unscored, and you will not know which.
  • Time. Microsoft’s table gives role-based associate exams without labs 100 minutes (120 in the seat), and those that may contain labs 120 minutes (140 in the seat). Most exams have 40–60 questions. Check your exam’s details page when you book.
  • Breaks. Five minutes of break time are built into the exam time, and you cannot take a break in the middle of a lab or a problem-solution question set.
  • THE EXAM LINE

    The score is scaled, so 700 of 1,000 may not be 70% of the points. There is no penalty for guessing, so never leave a question blank. After a break, you cannot return to questions you viewed before it.

  • Question types. Microsoft shows short videos of active screen, build list, case studies, drag and drop, hot area, multiple choice and labs, but doesn’t say which formats a given exam uses. Try them in the exam sandbox linked from the study guide.
  • Microsoft Learn during the exam. Associate exams give you learn.microsoft.com, except Q&A, Practice Assessments and your profile, with no extra time. Microsoft says that if you use it for every question you won’t finish, by design. Knowing which page holds which name is what makes it useful.
  • Practice. Microsoft offers a free Practice Assessment for AI-103, and warns that its questions are not the exam’s.
  • My own technique, not Microsoft’s: read the last sentence first, underline every constraint (GA only, EU data, keyless, lowest cost), and strike out options that name something that does not exist.
Budget two minutes a question. If one takes five, mark it, answer your best guess and move on.
39:00 – 45:00
Wrap-up: Practice Exam 1, your register and Week 5
  • Practice Exam 1 opens now: 40 questions in 80 minutes, covering Sessions 1 to 19. That is two minutes a question, the same pace as the marked Final. Sit it after today’s drill and before Session 21, in one sitting, closed book, with Coach Ritchie switched off.
  • The pass mark is 70, and you may resit. Add every question you got wrong to your register, with the page that repairs it.
  • Your assignment is the weak-spot register, plus evidence that unused resources were deleted.
  • Week 5 covers security, CI/CD, responsible AI, governance and ingestion. If you deleted rg-ai103, recreate it with its Foundry resource and project, as in Session 2, before Session 21, and update FOUNDRY_PROJECT_ENDPOINT.
  • If a deletion fails or costs still climb after two days, send me the resource name and the error the same day.
Halfway is where courses are won. Fix the Reds this week, while there is still room in the plan.

The exact names

As Microsoft prints them — the exam and the marker both expect these, letter for letter.
Global StandardtierPay-per-token deployment type that may process data in any Azure region. Confused with Data Zone Standard.Learn →
Data Zone StandardtierPay-per-token deployment type that keeps processing inside a data zone such as the EU.Learn →
Serverless APIfeatureThe preferred deployment option, billed by tokens or PTUs. Confused with Managed compute.Learn →
Managed computefeatureDeployment option billed hourly per accelerator SKU, for models not offered serverless.Learn →
standard agent setupsettingAgent data kept in your own Cosmos DB, Storage and AI Search, not Microsoft-managed storage.Learn →
Foundry UserroleThe least-privilege developer role on a project, formerly Azure AI User.Learn →
Hybrid searchfeatureKeyword and vector queries in one request, merged with RRF. Not the same as the semantic ranker.Learn →
Semantic rankerfeatureRe-ranks results a query has already retrieved; it does not retrieve on its own.Learn →
Agentic retrievalfeatureLLM-assisted query planning across sources for agents. Confused with classic RAG.Learn →
previous_response_idparameterChains a Responses call to an earlier one. Confused with a conversation object.Learn →
Tokens-per-Minute (TPM)conceptThe unit of quota and of a deployment’s rate limit. Confused with billed tokens.Learn →
require_approvalparameterMCP tool approval setting, default always. Function tools are gated in your own code instead.Learn →
AIProjectInstrumentorclassEnables Foundry tracing, only if the tracing environment variable is set first.Learn →
builtin.groundednesssettingDetects fabrication against the given context. Confused with relevance to the query.Learn →
Every name in the course is on one printable page: download the AI-103 cheat sheet (PDF).
Key Terms

Scaled score

A score converted to a 1–1,000 scale. Microsoft says 700 may not equal 70% of the points.

Purge

Permanently removing a soft-deleted resource so its name is free again. It cannot be undone.

Self-Check — Before You Submit
1. Every weekday at 9:00, a manufacturer’s support app gets 429 errors for about ten minutes. The deployment’s TPM is low and the subscription has unused quota for that model in the region. What is the best first response?
  • A. Switch the deployment to Global Batch
  • B. Turn on the semantic ranker
  • C. Raise the deployment’s TPM allocation within the quota, and retry with backoff that honours retry-after-ms
  • D. Set the version update policy to NoAutoUpgrade
C. Raise the deployment’s TPM allocation within the quota, and retry with backoff that honours retry-after-ms — Unused quota can be allocated to the deployment, and backoff handles the remaining bursts. Global Batch is for asynchronous jobs with a long turnaround, which does not suit a live support app.
2. During the exam you have three questions marked for review and decide to take a break. What happens to those questions?
  • A. You can no longer return to them, even though they are marked for review
  • B. They are automatically scored as correct
  • C. They are moved to the end of the exam
  • D. The timer pauses until you return to them
A. You can no longer return to them, even though they are marked for review — Microsoft’s exam experience page says that once a break starts, you cannot return to questions you viewed before it, even unanswered or marked ones. Review them before you pause, because the timer does not stop for you.
3. You delete a Foundry resource with the CLI while it still has a provisioned deployment. Which statement is true?
  • A. Billing stops immediately and the name is free
  • B. The resource is purged at once and cannot be recovered
  • C. The provisioned deployment moves to another resource
  • D. The resource is soft-deleted for 48 hours and provisioned deployment charges continue until it is purged
D. The resource is soft-deleted for 48 hours and provisioned deployment charges continue until it is purged — Learn says deleted resources can be recovered for 48 hours and provisioned deployment charges continue until purge, which is why you delete deployments first. Nothing is purged unless you purge it.

Today’s Assignment

Write a weak-spot register covering every objective taught in Sessions 1 to 19, with the Learn page that repairs each gap, and prove that the resources you no longer need have been deleted.
  • Drill every row of the two drill tables closed book, and mark each objective Green (explained with exact names), Amber (partly) or Red (could not).
  • Write a register row for every Amber and Red objective, at least five rows in total (add your weakest Greens if needed): the objective in Microsoft’s wording; exactly what you got wrong; the exact names to learn; the full learn.microsoft.com URL that repairs it; and the re-drill date.
  • Read each repair page, re-drill the objective, and record whether the row turned Green.
  • Run inventory.sh before and after your clean-up. For every resource, say whether you kept or deleted it and why, based on idle cost, and whether you purged anything.
  • Explain (300–700 words): your three weakest areas and your plan before Practice Exam 1; your exam-day plan for time, breaks, guessing and Learn access, citing Microsoft’s pages; and what you kept running.
  • Never include keys, secrets, credentials or connection strings. Crop subscription IDs and endpoints from screenshots if you prefer.
Evidence to include
  • The inventory output (resources and deployments) from before the clean-up.
  • The same output after the clean-up, plus the list-deleted output, showing what remains.
  • The register itself, with a working Learn URL on every row.
Names your answer must use exactly
Global Standard Data Zone Standard Foundry User Hybrid search Semantic ranker Agentic retrieval
Never include a key, a connection string or a token. Crop them out of every screenshot. If one is exposed, the letter will tell you to rotate it.
How this is marked — the rubric
The register covers every Amber and Red objective, each row names a specific gap and a Learn page that really repairs it, and re-drill results are recorded35
Uses the exact names from this session’s names box and Microsoft’s objective wording throughout20
Evidence: before and after inventory output shows unused resources deleted, with each keep-or-delete decision justified by idle cost30
The exam-day plan is specific and every claim about the exam matches Microsoft’s own pages15
Total · pass mark 70100
Submitting session 20
Write your answer in Word or Google Docs, with your screenshots pasted in. The top of the document must carry the line Session: 20 (the template has it ready, under the Course line), or the submission is refused. Upload the Word file (.docx), or switch to the Google Doc tab and paste your document’s share link.
Marked against the rubric above and returned as a written letter by email; the mark appears on your progress page. Do the self-check above before you submit.
ASSESSMENT NOW OPEN

Practice Exam 1 — Mid-Course opens now. Sit it before the next session. It is how you find out what has stuck, and practice papers may be resat as often as you like.

40 questions · 80 minutes · covers Sessions 1–19 · pass mark 70
Sit Practice Exam 1 →Closed book, no notes, and Coach Ritchie switches himself off while you sit it.
Skills Covered
Objective drillWeak-spot registerExam techniqueSubscription clean-upPractice Exam 1
Tick it once you have submitted.Next: Session 21 →
← Back to course home