SaveMyCert
Log in
5 of 5 free questions left today·for 30 a day
AI-103 practice

AI-103 sample questions — 25 answered and explained

25 AI-103 sample questions written to the official Microsoft Certified: Azure AI Apps and Agents Developer Associate exam guide, grouped by exam domain and weighted like the real exam. Each shows the correct answer, why every other option is wrong, and the lesson that teaches it. None of them repeat the examples on the other AI-103 practice pages.

On this page
25
answers included
Full bank
558
on the practice page
Domains
5
weighted like the exam
Free, no account
5/day
a free account allows 30 a day

Domain 1: Plan and manage an Azure AI solution

28% of the AI-103 exam, so 7 of the 25 questions on this page.

Question 1Plan and manage an Azure AI solution

A search index's vector field holds embeddings created with text-embedding-3-small (1,536 dimensions). To improve relevance, a developer switches the query code to text-embedding-3-large and passes dimensions=1536 so the query vectors fit the field. Queries now run without errors, but results are close to random. What should the developer do to use the larger model?

Choose one.

  • a
    Raise k_nearest_neighbors on queries against the vector field

    More neighbours from mismatched vectors are still mismatched. The query and document vectors are not comparable, so widening the search does not restore relevance.

  • b
    Enable a semantic ranker model to reorder the results

    The semantic ranker reorders whatever the first stage returns. If retrieval returns the wrong documents, reranking cannot recover the right ones.

  • c
    Re-embed all documents with the large model in a new field Correct

    Query and document vectors must come from the same model. Re-embedding the corpus with text-embedding-3-large, into a field sized for it, makes the vectors comparable again.

  • d
    Switch the vector field's algorithm from HNSW to exhaustive KNN

    Exhaustive KNN improves recall for the same vectors by comparing against every one, but it still compares vectors from two different models.

The concept

Embeddings from different models live in different vector spaces. Matching dimensions alone does not make them comparable.

Why that’s the answer

The trap is the dimensions parameter. text-embedding-3-large can return a shortened 1,536-dimension vector, so the query fits the field and no error appears. But those vectors come from a different model than the stored ones, so distances between them are meaningless. The fix is to embed documents and queries with the same model, which means re-embedding the corpus (and sizing the field for the chosen dimensions). Recall tweaks and reranking operate on top of a broken comparison.

How to reason it out
  1. Notice that the error disappeared but relevance collapsed: a silent mismatch.
  2. Recall that query and document vectors must come from the same embedding model.
  3. Recognise that shortening dimensions changes size, not the vector space.
  4. Pick the option that re-embeds the corpus with the new model.

Exam tip: Changing embedding models means re-embedding the whole corpus; matching dimensions is not enough.

AI-103: Choose Foundry Models, Retrieval Methods and Agent Tools — the lesson that teaches this.

Question 2Plan and manage an Azure AI solution

A company's internal assistant receives everything from one-line lookups to complex analysis requests. The team wants each request answered by the least expensive model that can still handle it well, without writing or maintaining their own logic to pick a model per request, and their app should call a single deployment. What should they deploy in Microsoft Foundry?

Choose one.

  • a
    A model router deployment with default settings Correct

    Model router is a single deployment that analyses each prompt and sends it to a suitable underlying model, using cheaper models when they are sufficient.

  • b
    Two model deployments picked by a classifier prompt

    Two deployments with a classifier prompt can work, but the team would be writing and maintaining the model-selection logic they want to avoid, across two endpoints.

  • c
    A provisioned throughput deployment of gpt-5

    Provisioned throughput reserves capacity for one model; every request still goes to that model whatever its complexity.

  • d
    A fine-tuned gpt-5-mini deployment on Standard

    Fine-tuning adapts one model to a task; it does not choose between models per request.

The concept

Model router is a deployable Foundry model that routes each prompt in real time to a suitable underlying LLM, trading off quality and cost behind one endpoint.

Why that’s the answer

The requirements are per-request model selection, no custom model-selection code and one deployment. Model router meets all three. A pair of deployments with a classifier prompt delivers per-request selection but is the hand-built selection logic the team wants to avoid. Provisioned throughput and fine-tuning both keep every request on a single model.

How to reason it out
  1. Note the need for different models on different requests.
  2. Note the constraint: no custom model-selection code and a single deployment.
  3. Choose the managed routing deployment.

Exam tip: Per-request model selection behind one deployment, without your own selection code: model router.

AI-103: Choose Foundry Models, Retrieval Methods and Agent Tools — the lesson that teaches this.

Question 3Plan and manage an Azure AI solution

A legal team uses a model router deployment with the default settings. Most requests work, but requests that include very long contracts intermittently fail with a context-length error, even though some models the router can use accept far longer inputs. The team wants to keep using the router. What should they configure?

Choose one.

  • a
    Set the routing mode to Quality so the router favours larger models

    Quality mode picks the highest-rated model for the prompt, not the one with the largest context window, so long prompts can still be routed to a model that cannot hold them.

  • b
    Use a custom deployment with a model subset of long-context models Correct

    The router's effective context limit is the smallest underlying model's. A model subset limited to long-context models makes every routing choice able to accept the contracts.

  • c
    Enable session affinity so related requests stay on one model

    Session affinity keeps related turns on the same eligible model for caching; it does not change which models are eligible or their context limits.

  • d
    Turn on Auto-update so new router versions are picked up

    Auto-update changes the set of underlying models as versions change; it does nothing to guarantee long-context support for these requests.

The concept

Model router's effective context window is that of the smallest model in its routing pool; a model subset controls which models are eligible.

Why that’s the answer

Two facts combine here. First, a request larger than some underlying models' context windows succeeds only if it happens to be routed to a model that can hold it, which explains the intermittent failures. Second, a custom deployment can restrict routing to a model subset, so every eligible model supports the needed context. Quality mode is the tempting answer, but it optimises answer quality rather than context size. Session affinity and auto-update solve different problems.

How to reason it out
  1. Read the symptom: intermittent context errors only on long inputs.
  2. Recall that the router's context limit is set by its smallest underlying model.
  3. Find the control that changes which models are eligible: the model subset.
  4. Reject settings that change selection preference or versioning but not eligibility.

Exam tip: Context errors through model router: restrict the model subset to models that fit the input.

AI-103: Choose Foundry Models, Retrieval Methods and Agent Tools — the lesson that teaches this.

Question 4Plan and manage an Azure AI solution

An HR team wants a chatbot that answers employee questions from about 2,000 internal policy documents. The documents change every week, and each answer must show which document it came from. Which approach should the developer use?

Choose one.

  • a
    Fine-tune a chat model on the policy documents each week

    Weekly fine-tuning is slow and costly, the model can still blend old and new policy, and it cannot cite the document an answer came from.

  • b
    Add policy Q&A pairs to the system prompt as few-shot examples

    Few-shot examples shape answer style, but a fixed set of pairs cannot cover 2,000 documents, goes stale when policies change weekly and gives no citation to a source document.

  • c
    Index the policy documents in Azure AI Search and use RAG Correct

    Retrieval-augmented generation pulls the current passages at question time, so weekly changes show up after re-indexing and each answer can cite its source.

  • d
    Connect the chatbot to Grounding with Bing Search for answers

    Grounding with Bing Search retrieves public web content; internal HR policies are not on the public web, so it cannot ground or cite them.

The concept

Retrieval-augmented generation (RAG) grounds answers in your own content at query time; fine-tuning changes model behaviour but does not keep facts current or provide citations.

Why that’s the answer

Three requirements point to RAG: private content, weekly change and citations. Re-indexing keeps the grounding data current, and retrieved chunks carry their source document. Fine-tuning bakes knowledge into weights, which is slow to refresh and cannot cite sources. Few-shot examples in the prompt shape style but cannot hold 2,000 changing documents, and web grounding cannot reach internal content.

How to reason it out
  1. Note the content is private and changes often.
  2. Note the need for citations to the source document.
  3. Choose grounding at query time over changing the model's weights.

Exam tip: Private, changing content with citations: RAG, not fine-tuning.

AI-103: Choose Foundry Models, Retrieval Methods and Agent Tools — the lesson that teaches this.

Question 5Plan and manage an Azure AI solution

A law firm's memo assistant already uses RAG, and evaluations show it retrieves the correct clauses for almost every request. Partners complain that the drafts still ignore the firm's strict memo structure and formal tone, even with several examples in the prompt. The firm has 3,000 partner-approved memos. What should the developer do next?

Choose one.

  • a
    Send more retrieved memo chunks to the model per request

    Retrieval is already accurate; sending more chunks adds tokens but does nothing to teach the memo structure or tone.

  • b
    Enable the semantic ranker on the memo search queries

    The semantic ranker improves the order of retrieved results, which is not the problem here.

  • c
    Switch the deployment to a reasoning model such as o4-mini

    A reasoning model improves multistep logic, but it does not learn the firm's memo structure or house tone; prompt examples would still be the only guidance on style.

  • d
    Fine-tune the model on the firm's 3,000 earlier memos Correct

    Supervised fine-tuning on thousands of approved examples teaches a consistent output structure and tone that prompt examples alone did not achieve.

The concept

Fine-tuning adjusts how a model responds (format, tone, style); RAG supplies what it should know. They solve different problems and are often combined.

Why that’s the answer

Evaluations rule out retrieval: the right clauses arrive. The remaining failure is output style, and prompt examples have not fixed it. A large set of approved memos is exactly the training data supervised fine-tuning needs to teach a consistent structure and tone. Sending more chunks and adding semantic ranking tune retrieval, which already works, and a reasoning model improves logic rather than house style.

How to reason it out
  1. Separate the two failure types: what the model knows versus how it writes.
  2. Use the evidence that retrieval is accurate to rule out retrieval changes.
  3. Choose fine-tuning on approved examples to fix persistent format and tone problems.

Exam tip: Right facts, wrong format or tone after prompting: fine-tune on approved examples.

AI-103: Choose Foundry Models, Retrieval Methods and Agent Tools — the lesson that teaches this.

Question 6Plan and manage an Azure AI solution

A parts distributor's search uses vector search over embeddings of product descriptions. Natural-language queries such as "seal for a leaking dishwasher door" work well, but when engineers type exact part numbers such as XJ-4471-B, the right part rarely appears. Both kinds of query must work from one search box. What should the developer configure?

Choose one.

  • a
    Hybrid queries that send the text and its vector together Correct

    A hybrid query runs keyword and vector search in parallel and merges the results with Reciprocal Rank Fusion, so exact codes match through keywords and descriptions through vectors.

  • b
    A larger embedding model and a re-embedded index

    Embeddings capture meaning, not exact strings; a larger model still struggles to match an arbitrary code like a part number.

  • c
    The semantic ranker on the existing vector queries

    The semantic ranker only reorders the documents the vector query returned. If the part is missing from those results, reranking cannot add it.

  • d
    A higher k_nearest_neighbors value on the vector queries

    Returning more vector neighbours widens the net by similarity, but exact identifiers still have no reliable semantic neighbours.

The concept

Hybrid search combines full-text (keyword) and vector queries in one request and fuses the rankings with Reciprocal Rank Fusion (RRF).

Why that’s the answer

Vector search excels at meaning but is weak on exact tokens like part numbers, product codes and names. Keyword search is the reverse. A hybrid query runs both and merges them with RRF, so one search box handles both query types. Reranking, more neighbours or a bigger embedding model all stay inside vector-only retrieval.

How to reason it out
  1. Identify which queries fail: exact identifiers.
  2. Recall that keyword search matches exact tokens and vector search matches meaning.
  3. Choose the option that runs both and fuses the results.

Exam tip: Exact codes plus natural language: hybrid search with RRF.

AI-103: Choose Foundry Models, Retrieval Methods and Agent Tools — the lesson that teaches this.

Question 7Plan and manage an Azure AI solution

A developer queries an Azure AI Search index that has an integrated vectorizer on the contentVector field. Exact policy numbers in user questions are not being matched.results = search_client.search( search_text=None, vector_queries=[VectorizableTextQuery( text=question, k_nearest_neighbors=50, fields="contentVector")], query_type="semantic", semantic_configuration_name="default", top=5)Which change makes the request a hybrid query?

Choose one.

  • a
    Set query_type="full" in the search call

    query_type="full" switches the keyword parser to Lucene syntax, but with search_text=None there is still no keyword query to run, and the semantic reranking would be lost.

  • b
    Set exhaustive=True in VectorizableTextQuery

    exhaustive=True makes the vector query compare against every vector instead of using the approximate index, but it is still vector-only.

  • c
    Set search_text=question in the search call Correct

    Supplying the same text as search_text adds a full-text query alongside the vector query, and the two result sets are merged, which is a hybrid query.

  • d
    Set k_nearest_neighbors=200 for text=question

    Asking for more nearest neighbours for the same text enlarges the vector candidate set, but no keyword matching takes place.

The concept

In Azure AI Search, a request becomes hybrid when it carries both search_text (full-text) and one or more vector_queries.

Why that’s the answer

The snippet is a vector query with semantic reranking, and search_text=None means no keyword query runs, which is why exact policy numbers are missed. Setting search_text to the user's text adds a full-text query in the same request; the service fuses both rankings with RRF and then semantic-reranks the merged results. The other changes adjust parsing or vector recall but never add keyword matching.

How to reason it out
  1. Read the request: vector query present, search_text is None.
  2. Recall that hybrid means full-text plus vector in one request.
  3. Pick the change that adds the full-text part.

Exam tip: Hybrid query = search_text + vector_queries in the same request.

AI-103: Choose Foundry Models, Retrieval Methods and Agent Tools — the lesson that teaches this.

Domain 2: Implement generative AI and agentic solutions

33% of the AI-103 exam, so 9 of the 25 questions on this page.

Question 8Implement generative AI and agentic solutions

A retailer deployed Llama-3.3-70B-Instruct in Foundry and calls it through v1 chat completions with a tools array that describes a get_order_status function. The model answers in prose and never returns a tool call. The team needs structured tool calls and wants to keep its existing chat completions code. What should the team do?

Choose one.

  • a
    Set tool_choice to "required" on each model call

    tool_choice steers models that can call tools. It cannot add tool calling to a model that doesn't support it.

  • b
    Switch to a model whose catalog card lists tool calling Correct

    The model card for Llama-3.3-70B-Instruct lists tool calling as not supported, so the fix is a model whose card says it supports tools, such as Mistral-Large-3 or a GPT model.

  • c
    Send the same call to the Responses API without other changes

    Changing the API surface keeps the same model, which still lacks tool calling, and it breaks the requirement to keep the chat completions code.

  • d
    Describe the function in the system prompt instead

    Prompting for a function-like answer yields free text that must be parsed, not the structured tool calls the team requires.

The concept

Tool calling is a per-model capability listed on each model's catalog card.

Why that’s the answer

The Foundry catalog lists Llama-3.3-70B-Instruct with 'Tool calling: No'. Request settings such as tool_choice only steer a model that already supports tools, and the Responses API doesn't add the capability. Prompting the model to imitate a call produces text, not structured tool calls. Choose a model that lists tool calling, such as Mistral-Large-3 or a GPT deployment.

How to reason it out
  1. Note the symptom: tools are sent but never called.
  2. Check the model card: tool calling not supported.
  3. Reject request-level settings that can't add a capability.
  4. Pick a tool-calling model and keep the chat completions code.

Exam tip: Check the model card for tool calling before designing a tool-augmented flow.

AI-103: Build Generative Apps with Foundry — Models, RAG, Tools and Evaluation — the lesson that teaches this.

Question 9Implement generative AI and agentic solutions

A support app uses client.responses.create for a chat experience. When a user asks "What's the return window?" and then "Does that apply to sale items?", the second answer ignores the first question. The app sends only the newest message on each call. What is the simplest fix?

Choose one.

  • a
    Set store to false on each responses.create call

    Turning storage off prevents the service from keeping responses, which is the opposite of what chaining by ID needs.

  • b
    Raise max_output_tokens so the answer keeps more context

    max_output_tokens caps the length of the reply; it has no effect on which earlier turns the model sees.

  • c
    Pass previous_response_id with the prior response's ID Correct

    previous_response_id chains the new request to the stored earlier response, so the model sees the earlier turn.

  • d
    Set temperature to 0 so the follow-up stays consistent

    Temperature changes sampling randomness, not memory. The earlier question is still missing from the request.

The concept

The Responses API keeps multi-turn context by chaining requests to stored responses.

Why that’s the answer

Each Responses API call is independent unless you link it. Passing previous_response_id=response.id tells the service to include the prior turn; alternatively you can carry the previous output items into the next input yourself. Storage settings, output length and temperature don't add the missing turn.

How to reason it out
  1. Diagnose: each call carries only the newest message.
  2. Recall the Responses chaining parameter: previous_response_id.
  3. Reject settings that change length, randomness or storage.

Exam tip: Chain Responses turns with previous_response_id (or carry the prior output items yourself).

AI-103: Build Generative Apps with Foundry — Models, RAG, Tools and Evaluation — the lesson that teaches this.

Question 10Implement generative AI and agentic solutions

A manufacturer's app retrieves five chunks from an Azure AI Search index of equipment manuals and sends them to a chat model with the user's question. Engineers report two problems: some answers include steps that appear in no manual, and they can't tell which manual an answer came from. Which TWO changes address both problems? (Select TWO.)

Choose TWO.

  • a
    Prefix each chunk with its source ID and require that ID after each claim Correct

    Labelling each chunk and requiring the ID per claim gives engineers a citation they can check against the manual.

  • b
    Raise k from 5 to 50 chunks per question to give the model more text

    More chunks add tokens and noise; they do not stop the model from adding unsupported steps or show where answers came from.

  • c
    Restrict the model to the supplied chunks and have it say when they lack the answer Correct

    An explicit answer-from-sources instruction with a 'not found' path reduces steps invented from the model's general knowledge.

  • d
    Fine-tune the chat model on the full set of equipment manuals and drop the retrieval step

    Fine-tuning shapes style and format but bakes content into weights, which removes traceability to a specific manual and doesn't stop invented steps.

  • e
    Switch the vector query from HNSW to exhaustive KNN for exact neighbours

    Exhaustive KNN changes how neighbours are found, not how the model uses them, so fabrication and missing sources remain.

The concept

The augmentation step of RAG controls whether answers stay grounded in retrieved content and remain traceable to it.

Why that’s the answer

Retrieval already supplies relevant chunks; the problems are in how the prompt uses them. Labelling chunks with source IDs and asking for the ID after each claim gives citations, and instructing the model to answer only from the supplied sources, with an explicit 'I don't know' path, curbs additions from general knowledge. More chunks, exhaustive search or fine-tuning change retrieval or weights, not grounding behaviour.

How to reason it out
  1. Separate the two failures: unsupported content and missing provenance.
  2. Fix provenance by labelling chunks and requiring citations.
  3. Fix unsupported content with an answer-from-sources instruction and a not-found path.
  4. Reject changes that only alter retrieval volume or model weights.

Exam tip: Grounded RAG prompts label sources, demand citations and give the model permission to say it doesn't know.

AI-103: Build Generative Apps with Foundry — Models, RAG, Tools and Evaluation — the lesson that teaches this.

Question 11Implement generative AI and agentic solutions

A RAG chat app searches an Azure AI Search index with the user's latest message, then sends the results and the chat history to a model. A user asks "What is the warranty on the X200 drill?" and then "And for the X300?". The second answer is wrong because the retrieved chunks are about unrelated products. What should the developer change?

Choose one.

  • a
    Use the full chat history as the search text for each new question

    Searching with the whole history mixes the X200 and the X300 terms and grows with each turn, so results drift toward older topics.

  • b
    Enable the semantic ranker to reorder the follow-up's results by meaning

    The semantic ranker reranks what the query found; with a query of 'And for the X300?' the candidate set is already off target.

  • c
    Rewrite the follow-up into a standalone query before running the search Correct

    A rewritten query such as 'X300 drill warranty' carries the context the follow-up omits, so retrieval returns the right chunks.

  • d
    Pass previous_response_id so the model remembers the earlier question

    The model would see the earlier turn, but retrieval runs before the model call and still searches with the context-free follow-up.

The concept

In multi-turn RAG, retrieval and generation are separate steps, and the retrieval query must carry the conversation's context.

Why that’s the answer

Retrieval happens before generation, so giving the model history (previous_response_id) cannot fix what the search returned. And a follow-up like 'And for the X300?' lacks the noun phrase the index needs. The standard fix is query rewriting: a quick model call condenses the history and latest message into a standalone query, which is then searched. Dumping the whole history into the search text adds noise, and the semantic ranker only reorders a bad candidate set.

How to reason it out
  1. Notice that only follow-up questions fail.
  2. Recall that the search step sees just the latest message.
  3. Fix the query, not the model's memory: rewrite it into a standalone question.
  4. Reject reranking and history dumps, which don't repair the query.

Exam tip: Rewrite follow-ups into standalone queries before retrieval; model memory doesn't fix the search.

AI-103: Build Generative Apps with Foundry — Models, RAG, Tools and Evaluation — the lesson that teaches this.

Question 12Implement generative AI and agentic solutions

An app pushes documents into an Azure AI Search index with embeddings it computes itself by using a text-embedding-3-large deployment. The index has no vectorizer. At query time the app calls search() with VectorizableTextQuery(text=question, k_nearest_neighbors=5, fields="contentVector"), and the request fails. The index definition must not change. What should the app do?

Choose one.

  • a
    Embed the question with text-embedding-3-large and pass it in VectorizedQuery Correct

    Without a vectorizer the app must supply the query vector itself, and it must come from the model that produced the document vectors.

  • b
    Embed the question with text-embedding-3-small and pass it in VectorizedQuery

    The query shape is right, but vectors from a different embedding model aren't comparable with the stored ones, so results would be meaningless.

  • c
    Add an Azure OpenAI vectorizer to the vector profile of the contentVector field

    A vectorizer would make text queries work, but it changes the index definition, which the requirement rules out.

  • d
    Keep VectorizableTextQuery and set exhaustive=True on the same vector query

    Exhaustive KNN changes the neighbour search algorithm; the text still needs a vectorizer to become a vector.

The concept

A vector query needs a query vector: either the index's vectorizer creates it from text, or the app supplies one from the same embedding model.

Why that’s the answer

Two facts decide this. A text vector query (VectorizableTextQuery, kind 'text') works only when a vectorizer is assigned to the field; this index has none and must not change. So the app must embed the question itself and send VectorizedQuery. Microsoft's guidance is to use the same embedding model for queries as for the indexed content, so text-embedding-3-large, not text-embedding-3-small. Exhaustive search doesn't remove the need for a vector.

How to reason it out
  1. Read the constraint: no index changes, so no vectorizer.
  2. Recall that text vector queries need a vectorizer.
  3. Switch to VectorizedQuery with an app-computed vector.
  4. Use the same embedding model that built the index.

Exam tip: No vectorizer means VectorizedQuery with a vector from the same embedding model as the index.

AI-103: Build Generative Apps with Foundry — Models, RAG, Tools and Evaluation — the lesson that teaches this.

Question 13Implement generative AI and agentic solutions

A RAG app for HR policies runs a vector-only query with k set to 5 and passes every result to the model. When an employee asks "What's the weather in Seattle?", the app still retrieves five policy chunks and the model writes an answer that mixes them in. What explains why five chunks come back?

Choose one.

  • a
    The semantic ranker promoted low-scoring chunks back into the top five results

    The scenario uses a vector-only query, and the semantic ranker reorders results rather than adding matches that weren't found.

  • b
    Keyword search matched common words such as "what" in the policy chunks

    The query is vector-only, so no keyword matching takes place, and stopwords like 'what' don't drive full-text relevance anyway.

  • c
    A vector query returns the k nearest chunks even when none is a close match Correct

    Nearest-neighbour search always returns k results if k documents exist; unrelated queries simply get low similarity scores.

  • d
    The HNSW graph is stale and returns cached neighbours from an earlier query

    HNSW is an approximate nearest-neighbour index, but it doesn't return cached results from earlier queries.

The concept

Vector search finds nearest neighbours, and there is always a nearest neighbour, however distant.

Why that’s the answer

Azure AI Search documents that vector queries return k results whenever at least k documents exist, even for nonsensical or off-topic queries, because the algorithm returns the closest vectors whatever their similarity. Mitigations include grounding instructions that let the model decline, a hybrid query, or a minimum similarity threshold (preview) on pure vector queries. The other options describe features that aren't in play or don't behave that way.

How to reason it out
  1. Note that the query is vector-only.
  2. Recall that nearest-neighbour search always fills k slots.
  3. Plan a mitigation: a decline instruction or a similarity threshold.

Exam tip: Vector search always returns k neighbours; relevance has to be judged downstream.

AI-103: Build Generative Apps with Foundry — Models, RAG, Tools and Evaluation — the lesson that teaches this.

Question 14Implement generative AI and agentic solutions

A team is starting a new grounded chat app in Microsoft Foundry. Its design copies an older sample that grounds Azure OpenAI chat completions by adding an Azure AI Search entry to the request's data_sources field. That feature was retired in October 2026. Which approach does Microsoft recommend for answering questions over the team's documents instead?

Choose one.

  • a
    data_sources with an Azure Cosmos DB vector source

    A different data source still uses the retired On Your Data request extension, so the request no longer works.

  • b
    Weekly fine-tuning of the chat model on the files

    Fine-tuning changes model behaviour and format, but it doesn't ground answers in current documents or provide citations.

  • c
    data_sources with the newest dated api-version

    A newer api-version doesn't bring back a retired feature; the data_sources extension is gone whichever version calls it.

  • d
    A Foundry IQ knowledge base the app calls directly Correct

    For corpus Q&A, Microsoft's migration guidance is to call a Foundry IQ knowledge base directly, adding Foundry Agent Service only when tools or workflows are needed.

The concept

Azure OpenAI On Your Data (the data_sources request extension) is retired; Microsoft points corpus Q&A to Foundry IQ knowledge bases.

Why that’s the answer

The On Your Data reference states the feature retired on 14 October 2026 and is no longer supported. For corpus Q&A, Microsoft recommends calling a Foundry IQ knowledge base directly, and adding Foundry Agent Service only when the app needs tools, actions or workflows. Classic RAG (retrieving from Azure AI Search in your own code and adding the results to the prompt) is also a generally available alternative. Swapping the data source or api-version keeps the retired extension, and fine-tuning isn't a grounding mechanism.

How to reason it out
  1. Recognise the data_sources field as Azure OpenAI On Your Data.
  2. Recall that the feature is retired, for every api-version and data source.
  3. Choose Microsoft's recommended path for corpus Q&A: a Foundry IQ knowledge base.

Exam tip: On Your Data is retired: ground new apps with Foundry IQ (or your own retrieval step).

AI-103: Build Generative Apps with Foundry — Models, RAG, Tools and Evaluation — the lesson that teaches this.

Question 15Implement generative AI and agentic solutions

An order-tracking app uses function calling with the Responses API. Complete the code so the model receives the function result.response = client.responses.create( model="orders-gpt", input=question, tools=tools ) for item in response.output: if item.type == "function_call": result = get_order_status(**json.loads(item.arguments)) final = client.responses.create( model="orders-gpt", previous_response_id=response.id, input=[{ "type": "function_call_output", FIELD, "output": json.dumps(result), }], )Which key-value pair should replace FIELD?

Choose one.

  • a
    "call_id": item.call_id Correct

    A function_call_output is matched to its request by call_id, and item.call_id is the identifier the model generated for that call.

  • b
    "id": item.id

    item.id identifies the function_call output item itself; a function_call_output must carry a call_id field that references the call.

  • c
    "tool_call_id": item.id

    tool_call_id is the Chat Completions tool-message field; the Responses API function_call_output uses call_id, and item.id is the wrong identifier anyway.

  • d
    "call_id": response.id

    The field name is right, but response.id identifies the whole response and already goes in previous_response_id; it doesn't say which call this result answers.

The concept

In function calling, the app returns each result as a function_call_output that references the call_id of the model's function_call item.

Why that’s the answer

The model's output contains function_call items with name, arguments and call_id. After the app runs the function, it sends a function_call_output item whose call_id field carries the same value, usually chaining with previous_response_id. tool_call_id is the Chat Completions equivalent and isn't accepted on a Responses input item, item.id is the output item's own ID, and response.id is used only for chaining.

How to reason it out
  1. Find the item the model produced: type function_call.
  2. Use the Responses API field that links a result to a call: call_id.
  3. Fill it with the call's own identifier, item.call_id.
  4. Keep response.id for previous_response_id and tool_call_id for Chat Completions.

Exam tip: Return function results as function_call_output with the matching call_id.

AI-103: Build Generative Apps with Foundry — Models, RAG, Tools and Evaluation — the lesson that teaches this.

Question 16Implement generative AI and agentic solutions

A developer adds a function definition for check_stock to a Responses API request and expects the inventory API to be called when users ask about stock. The model's output contains a function_call item with sensible arguments, but the inventory API logs show no requests. What does the application need to do?

Choose one.

  • a
    Put the inventory API's URL in the function definition for the model

    A function tool definition has a name, description and JSON Schema parameters; the service doesn't call URLs for function tools.

  • b
    Set tool_choice to "required" so that the service executes check_stock

    tool_choice forces the model to produce a tool call, but the call is still returned to the app to execute.

  • c
    Run check_stock in the app and send its result back to the model Correct

    With function calling, the model only proposes the call; the application executes it and returns the output for the model to use.

  • d
    Enable parallel_tool_calls so that the function runs on the server side

    parallel_tool_calls lets the model propose several calls in one turn; execution still happens in the application.

The concept

Function calling is a contract: the model emits structured call requests, and the client application executes them.

Why that’s the answer

The model returns a function_call item (name, JSON arguments, call_id). Nothing calls the API until the application runs the function and submits a function_call_output item. tool_choice and parallel_tool_calls shape what the model proposes, not who executes it. Server-side execution of HTTP APIs is a different feature: the OpenAPI tool on Foundry agents.

How to reason it out
  1. Note the evidence: function_call items exist, but the API isn't called.
  2. Recall who executes function tools: the application.
  3. Return the result as function_call_output so the model can answer.

Exam tip: The model asks; your code calls the function and hands back the result.

AI-103: Build Generative Apps with Foundry — Models, RAG, Tools and Evaluation — the lesson that teaches this.

Domain 3: Implement computer vision solutions

13% of the AI-103 exam, so 3 of the 25 questions on this page.

Question 17Implement computer vision solutions

A sportswear brand wants sora-2 clips for a campaign. The first design sends a press photo of the brand's sponsored athlete, a well-known public figure, as input_reference, with a prompt that names the athlete. The generations fail. The brand still wants clips that feature its running shoes. What should the developer do?

Choose one.

  • a
    Keep the athlete photo and remove the athlete's name from the text prompt

    Input images that contain human faces are rejected, so the photo still fails even with the name removed.

  • b
    Use a shoe-only product photo and describe an unnamed fictional runner Correct

    Sora 2 cannot generate real people, including public figures, and rejects reference images with human faces; a product photo plus a fictional runner stays within both rules.

  • c
    Keep the athlete photo and crop it tightly around the athlete's face

    Cropping to the face makes the image more clearly a human face, which is exactly what is rejected.

  • d
    Generate a clip without the photo, then remix it to add the athlete in

    Remix still applies the content rules, and real people, including public figures, cannot be generated.

The concept

Sora 2 enforces content rules on prompts and reference images.

Why that’s the answer

The Sora 2 API currently rejects real people, including public figures, and rejects input images that contain human faces; it also rejects copyrighted characters and music. A product-only reference image with a prompt about an unnamed, fictional runner meets the campaign goal within those rules. Removing the name or cropping the photo keeps a face in the input, and a remix is still a generation subject to the same restrictions.

How to reason it out
  1. List the inputs: a face in the reference image and a named real person in the prompt.
  2. Recall both restrictions: no real people, no human faces in input images.
  3. Keep the business goal (the product) and drop what the rules reject.

Exam tip: Sora 2 rejects real people and face images as input; build clips around products and fictional characters.

AI-103: Image and Video Generation and Editing in Foundry — GPT-image, FLUX and Sora 2 — the lesson that teaches this.

Question 18Implement computer vision solutions

A studio has a completed eight-second sora-2 clip that the client likes. The client asks for one change: warmer colours. The framing, camera motion and scene timing must stay as they are. What should the developer do?

Choose one.

  • a
    Call videos.create with the original prompt plus a warmer colour palette

    A new generation starts from scratch, so framing and motion can change even with the same prompt.

  • b
    Call videos.remix with the clip's video ID and a prompt for warmer colours Correct

    Remix reuses a completed video's structure, motion and framing and applies a targeted change described in the new prompt.

  • c
    Call videos.create with a frame from the clip passed as input_reference

    A reference image only anchors the first frame; the rest of the clip is generated again and its motion is not kept.

  • d
    Call images.edit on each exported frame with a warm-tone prompt and mask

    Editing frames one by one is a large custom job and gives no guarantee of consistency from frame to frame.

The concept

Remix edits a completed Sora 2 video while keeping its structure.

Why that’s the answer

videos.remix takes the ID of a completed video and a new prompt. The service keeps the original video's framework, scene transitions and visual layout and applies the requested change. Regenerating, even from a frame of the clip, produces a new composition, and editing frames as images is a heavy custom workflow with no temporal consistency.

How to reason it out
  1. Note the constraint: keep framing, motion and timing.
  2. Recall that remix reuses a completed video's structure.
  3. Send the video ID with a prompt describing only the change.

Exam tip: To change a finished Sora 2 clip without re-shooting it, remix its video ID.

AI-103: Image and Video Generation and Editing in Foundry — GPT-image, FLUX and Sora 2 — the lesson that teaches this.

Question 19Implement computer vision solutions

A team calls a FLUX.1-Kontext-pro deployment through the OpenAI-compatible Image API from its regression tests. The tests compare new outputs with stored ones, so the team needs a fixed seed for every request. The team is willing to change how the tests call the model. Which request should the tests send?

Choose one.

  • a
    POST to /providers/blackforestlabs/v1/FLUX.1-Kontext-pro with seed in the JSON body

    The BFL endpoint uses the model path, which differs from the model ID; FLUX.1-Kontext-pro is the ID, flux-kontext-pro is the path.

  • b
    POST to /openai/v1/images/generations with seed added to the existing JSON body

    The Image API route accepts the OpenAI image parameters; seed and the other FLUX-specific controls are available only through the BFL provider API.

  • c
    POST to /providers/blackforestlabs/v1/flux-kontext-pro with seed in the JSON body Correct

    seed is one of the extra parameters exposed only by the BFL provider-specific API, and that API addresses the model by its model path, flux-kontext-pro.

  • d
    POST to /openai/v1/images/generations for a gpt-image-1 deployment, adding seed

    The GPT-image models offer no seed control, so switching models does not give repeatable outputs.

The concept

FLUX models in Foundry have two routes, and only the BFL provider API exposes the fine-grained controls.

Why that’s the answer

FLUX models can be called through the OpenAI-compatible Image API (FLUX.1-Kontext-pro and FLUX-1.1-pro only) or through the BFL provider-specific API at https://<resource>.api.cognitive.microsoft.com/providers/blackforestlabs/v1/<model-path>?api-version=preview. Only the BFL route exposes seed, aspect_ratio, safety_tolerance and similar parameters. Its URL uses the model path (flux-kontext-pro), which is not the model ID (FLUX.1-Kontext-pro). Two facts decide: the route that has seed, and the right path on that route.

How to reason it out
  1. Identify the control needed: a fixed seed.
  2. Recall that seed is exposed only by the BFL provider API, not the Image API.
  3. Recall that the BFL URL uses the model path, not the model ID.
  4. Reject switching to a GPT-image model, which has no seed.

Exam tip: FLUX fine controls (seed, aspect_ratio, safety_tolerance) live on the BFL route, addressed by model path.

AI-103: Image and Video Generation and Editing in Foundry — GPT-image, FLUX and Sora 2 — the lesson that teaches this.

Domain 4: Implement text analysis solutions

13% of the AI-103 exam, so 3 of the 25 questions on this page.

Question 20Implement text analysis solutions

A product team is building a new feedback dashboard. For each customer comment it needs an overall sentiment and a tone label: sarcastic, frustrated, appreciative or neutral. Labels must arrive as JSON for the dashboard. What should you use?

Choose one.

  • a
    Azure Language sentiment analysis with opinion mining enabled per comment

    The service returns positive, negative, neutral or mixed sentiment and aspect opinions. It has no tone labels such as sarcastic or appreciative.

  • b
    Azure AI Content Safety text analysis with the four harm categories enabled

    Content Safety scores harm categories such as hate and violence. It doesn't classify sentiment or conversational tone.

  • c
    A language model with a schema that has a sentiment field and a tone enum Correct

    A prompted model can judge tone labels such as sarcasm, and a schema returns both fields in the shape the dashboard needs.

  • d
    Azure Language key phrase extraction with each phrase mapped to a tone label

    Key phrases are the main topics of the text. Mapping them to tone would need custom logic and wouldn't capture sarcasm.

The concept

Language models can classify custom labels such as tone that prebuilt sentiment services don't offer.

Why that’s the answer

Prebuilt sentiment analysis returns a fixed sentiment scale and aspect opinions, and it's a legacy Azure Language capability. Tone categories such as sarcastic or appreciative are custom labels, which a prompted language model can assign, with a schema to return them as JSON. Content Safety and key phrase extraction answer different questions.

How to reason it out
  1. List the outputs: sentiment plus a custom tone label, as JSON.
  2. Check whether a prebuilt service offers those tone labels.
  3. Choose a prompted model with an output schema.

Exam tip: Custom labels like tone come from a prompted model with a schema; prebuilt sentiment has a fixed scale.

AI-103: Text Analysis, PII, Content Safety and Translation with Foundry — the lesson that teaches this.

Question 21Implement text analysis solutions

An existing review-analysis app calls Azure Language sentiment analysis through the Python TextAnalyticsClient. Product managers now want to see which product features each review praises or criticizes, for example the battery as negative and the screen as positive, with the fewest code changes. What should you do?

Choose one.

  • a
    Call recognize_entities on each review and score the entities with analyze_sentiment

    Entity recognition finds named entities, not product features in general, and scoring each one separately takes much more code.

  • b
    Call analyze_sentiment with model_version="latest" and read each sentence label

    The model version doesn't add aspects. Sentence sentiment says a sentence is negative, not which feature it's about.

  • c
    Call analyze_sentiment with show_opinion_mining=True and read the mined opinions Correct

    Opinion mining adds aspect-based results to each sentence: targets such as battery or screen and the opinions about them, each with a sentiment.

  • d
    Call extract_key_phrases on each review and pass the phrases to analyze_sentiment

    Scoring isolated phrases loses the context that links an opinion to its feature, and it adds a second call per phrase.

The concept

Opinion mining is aspect-based sentiment analysis in Azure Language.

Why that’s the answer

Sentiment analysis returns document and sentence sentiment. Setting show_opinion_mining=True adds mined opinions: each target (an aspect such as battery) with its assessments and their sentiment. That answers the per-feature question in one flag. Sentiment analysis is a legacy Azure Language capability, supported for existing implementations like this one.

How to reason it out
  1. Identify the need: sentiment per product feature, not per sentence.
  2. Recall the aspect-based option of sentiment analysis.
  3. Prefer the one-flag change over multi-call workarounds.

Exam tip: Per-aspect sentiment in Azure Language is opinion mining: show_opinion_mining=True.

AI-103: Text Analysis, PII, Content Safety and Translation with Foundry — the lesson that teaches this.

Question 22Implement text analysis solutions

A community forum screens posts with Azure AI Content Safety text analysis before publishing them. The moderation policy now says violence at severity 5 and above is rejected while severity 4 is allowed, but every response returns only the values 0, 2, 4 or 6. What should you change in the analyze request?

Choose one.

  • a
    Set outputType to FourSeverityLevels

    Four levels is the default that returns 0, 2, 4 and 6, which is what the forum gets today.

  • b
    Set categories to the Violence category

    Limiting the categories reduces what is analyzed but doesn't change the granularity of the severity scale.

  • c
    Set haltOnBlocklistHit to false

    This setting only decides whether harm analysis continues after a blocklist match. It doesn't affect the severity scale.

  • d
    Set outputType to EightSeverityLevels Correct

    With eight levels the service returns severities 0 to 7, so a threshold between 4 and 5 can be applied.

The concept

Content Safety returns severity on a four-level or eight-level scale.

Why that’s the answer

The text analysis API returns severities as 0, 2, 4 and 6 by default (FourSeverityLevels). Setting outputType to EightSeverityLevels returns 0 to 7, which a policy that separates 4 from 5 needs. Category selection and blocklist behaviour don't change the scale.

How to reason it out
  1. Notice the returned values are only even numbers.
  2. Recall the default four-level output.
  3. Switch to the eight-level output for finer thresholds.

Exam tip: Need thresholds between 0, 2, 4 and 6? Ask for EightSeverityLevels.

AI-103: Text Analysis, PII, Content Safety and Translation with Foundry — the lesson that teaches this.

Domain 5: Implement information extraction solutions

13% of the AI-103 exam, so 3 of the 25 questions on this page.

Question 23Implement information extraction solutions

A developer adds the Azure Content Understanding skill to a blob indexer's skillset with the input shown. Every run reports that the skill's file_data input is missing, although the blobs are readable and other skills receive /document/content."inputs": [ { "name": "file_data", "source": "/document/file_data" } ]What should the developer change?

Choose one.

  • a
    Set allowSkillsetToReadFileData to true in the indexer's configuration Correct

    This indexer setting creates the /document/file_data node holding the original file downloaded from Blob Storage, which is what the skill's file_data input expects.

  • b
    Set imageAction to generateNormalizedImages in the indexer's configuration

    imageAction creates the normalized_images node for image skills. It doesn't expose the original file to a skill.

  • c
    Set dataToExtract to contentAndMetadata in the indexer's configuration

    That setting controls what document cracking extracts into content and metadata, not whether the raw file is passed to skills.

  • d
    Set parsingMode to text in the indexer's configuration

    Text parsing mode reads each blob as plain text into content. It doesn't create the file_data node either.

The concept

Layout skills read the original file through /document/file_data, which exists only when allowSkillsetToReadFileData is true.

Why that’s the answer

The Azure Content Understanding and Document Layout skills analyze the whole original file, not the cracked text. For blob sources the file reaches them through the /document/file_data node, which the indexer creates only when its allowSkillsetToReadFileData parameter is true. The other indexer settings control text extraction, image extraction or parsing granularity and leave file_data missing.

How to reason it out
  1. Read the error: the file_data node doesn't exist.
  2. Recall which indexer parameter creates /document/file_data.
  3. Set allowSkillsetToReadFileData to true.
  4. Re-run the indexer.

Exam tip: No /document/file_data? Set allowSkillsetToReadFileData to true on the indexer.

AI-103: Build Retrieval and Grounding Pipelines with Azure AI Search — the lesson that teaches this.

Question 24Implement information extraction solutions

A legal-research agent cites chunks from long PDFs. Each citation must show the page range a chunk came from, chunks may run across page breaks so clauses stay whole, and figures must be kept for display beside answers. You're designing a new skillset. Which configuration meets the requirements?

Choose one.

  • a
    Document Layout skill in text mode, extractionOptions ["images", "locationMetadata"]

    Document Layout can return page numbers and images, but its text chunks stay within the bounds of a page, so a clause that crosses a page break is split.

  • b
    Content Understanding skill, extractionOptions ["images", "locationMetadata"] Correct

    It returns each chunk with a page range (pageNumberFrom and pageNumberTo), lets chunks span pages, and extracts images with their locations.

  • c
    Content Understanding skill, extractionOptions ["images"]

    Images are extracted, but without locationMetadata the chunks carry no page information to cite.

  • d
    Document Layout skill in text mode, extractionOptions ["images"]

    Without locationMetadata the chunks carry no page numbers, and Document Layout text chunks stay within one page, so clauses split at page breaks.

The concept

Page-range citations need locationMetadata; chunks that span pages need the Content Understanding skill.

Why that’s the answer

Two requirements combine here. Citing a page range needs the extractionOptions value locationMetadata, which adds page information (pageNumberFrom and pageNumberTo) to each chunk. Keeping clauses whole across page breaks needs chunks that can span pages, which the Content Understanding skill supports and the Document Layout skill doesn't, because its text chunks stay within the bounds of a page. Only the Content Understanding skill with both images and locationMetadata meets all three needs; each other option misses either the page data or cross-page chunks.

How to reason it out
  1. Split the requirements: page ranges, cross-page chunks, kept figures.
  2. Recall that locationMetadata adds page data to chunks.
  3. Recall which skill allows chunks to span pages.
  4. Combine both in one skill configuration.

Exam tip: Citations with page ranges across page breaks: Content Understanding skill plus locationMetadata.

AI-103: Build Retrieval and Grounding Pipelines with Azure AI Search — the lesson that teaches this.

Question 25Implement information extraction solutions

A skillset chunks 5 PDFs into 100 chunks and uses index projections to write them to one index. The index ends up with 105 documents, and 5 of them have empty chunk and vector fields that sometimes reach the model as useless context. What should you change?

Choose one.

  • a
    Set projectionMode to includeIndexingParentDocuments

    This is the default that produced the problem: it adds a parent document per file alongside the chunks.

  • b
    Set projectionMode to skipIndexingParentDocuments in the projections Correct

    This mode indexes only the chunk documents, so no parent documents with empty chunk fields are added.

  • c
    Add a mapping for parent_id to the index projection's selector list

    The parent key is generated by the projection and must not be mapped by hand, and a mapping wouldn't stop parent documents from being indexed.

  • d
    Set the indexer's parsingMode to jsonArray for the chunked output

    jsonArray parses JSON arrays in source files. It doesn't apply to chunks created by a skill.

The concept

skipIndexingParentDocuments keeps parent-only documents out of a chunk index.

Why that’s the answer

Index projections write each chunk as its own search document. By default (includeIndexingParentDocuments) the indexer also writes one document per source file whose chunk fields are null, which is how 5 files and 100 chunks become 105 documents. Setting projectionMode to skipIndexingParentDocuments leaves only the uniform chunk documents, which Microsoft recommends when chunks are the search target.

How to reason it out
  1. Count the extra documents: one per source file.
  2. Recall the default projection mode includes parents.
  3. Switch to skipIndexingParentDocuments.
  4. Re-run the indexer.

Exam tip: Chunk index with stray empty documents? projectionMode = skipIndexingParentDocuments.

AI-103: Build Retrieval and Grounding Pipelines with Azure AI Search — the lesson that teaches this.

Keep going with AI-103

AI-103 practice by domain

AI-103 sample questions: your questions

No. Real exam questions are confidential. These are original questions written to the skills in the official AI-103 exam guide, so they test the same knowledge in the same style without being copies of the exam.

Source

The domains and weights on this page come from the official AI-103 exam guide.