Build a Grounded Package Upgrade Advisor with Microsoft-Decision-1
About the Microsoft Decision Model In October 2026, Microsoft announced Microsoft-Decision-1, the latest model for fast decision-scoring available on Microsoft Foundry. Unlike LLMs that generate textual outputs, decision models return structured outputs that allow software to immediately act on, without having to first interpret the response. The model accepts a state value which can be text or JSON. There are three question types based on the decision we need: Question Type Result Yes/No, true/false questions noul A probability from 0 through 1 Multiple Choice Questions choice One selection option and the probability for each option Questions related to ranking or grading score A value on an ordered scale and the probability for each level. Starts from 0 Use Case We will be building a simple application that decides whether a software package needs upgrading. An agent searches trusted sources (via Grounding with Bing Custom Search resource) for release notes and security advisories. A decision model then reads that evidence and says whether to upgrade, why, and how urgently. Pre-Requisites Azure Subscription Microsoft Foundry resource deployed in a resource group. Deploy the Microsoft-Decision-1 model, and gpt-4.1 model to power the agent A Grounding with Bing Custom Search resource Adding Sources to Bing Custom Search Go to the Bing Custom Search resource Click on Configurations in the left pane under the Resource Management section Create a new configuration and name it ‘documentations’. This is the Domain Name Add the following web addresses: https://docs.djangoproject.com/en/stable/releases https://www.djangoproject.com/weblog https://www.djangoproject.com/download https://pypi.org/project/django Save the configuration Add Bing Custom Search as a Tool to Foundry In the previous section, we made the tool. Now, we will add it to Foundry Steps: Click on Management Centre Click on Connected resources Click on + New Connection Choose Grounding with Bing Custom Search It will automatically show all the Bing Custom Search resources. Connect the one you created for this tutorial by choosing ‘Add Connection’ Click on the connection, and save the Id Creating the Foundry Agent Set up a .env file and populate the following information: ENDPOINT=<https://<your-foundry-resource-name>.services.ai.azure.com/providers/microsoft> (This is the decision model’s endpoint) PROJECT_ENDPOINT=https://<your-foundry-resource-name>.services.ai.azure.com/api/projects/proj-default DEPLOYMENT_NAME=<decision-model’s deployment name> CONN_ID=<Bing Custom Search Id we saved in the previous step> DOMAIN_NAME=documentations We create a foundry agent using the following code snippet and deploy it to Foundry. The file is called create_agent.py. Run this file to deploy the agent to foundry. import os from azure.identity import DefaultAzureCredential, InteractiveBrowserCredential from azure.ai.projects import AIProjectClient from azure.ai.projects.models import ( PromptAgentDefinition, BingCustomSearchPreviewTool, BingCustomSearchToolParameters, BingCustomSearchConfiguration, ) from dotenv import load_dotenv load_dotenv() PROMPT = """ You are a software upgrade research agent. Given a package name and installed version, use Bing Custom Search to find official release notes, security advisories, and support information. Summarize: - Security issues affecting the installed version and available fixes. - Whether the version is still supported. - Relevant breaking changes and upgrade requirements. Use only retrieved evidence and include source URLs. If applicability is unclear, say so. Do not treat missing evidence as proof that a version is safe. Return a JSON object with: - package - installed_version - summary - source_urls """ conn_id = os.getenv("CONN_ID") project_client = AIProjectClient( endpoint=os.getenv("PROJECT_ENDPOINT"), credential=DefaultAzureCredential() ) tool = BingCustomSearchPreviewTool( bing_custom_search_preview=BingCustomSearchToolParameters( search_configurations=[ BingCustomSearchConfiguration( project_connection_id=conn_id, instance_name=os.getenv("DOMAIN_NAME"), ) ] ) ) with project_client: agent = project_client.agents.create_version( agent_name="extract-news-agent", definition=PromptAgentDefinition( model="gpt-4.1", instructions=PROMPT, tools=[tool], ), ) print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") Setting up the Decision Model The following code sets up the decision model. The file is called model.py import os from azure.identity import DefaultAzureCredential, get_bearer_token_provider from dotenv import load_dotenv from typesafe_sdk import TypeSafeClient load_dotenv() ENDPOINT = os.getenv("ENDPOINT") DEPLOYMENT_NAME = os.getenv("DEPLOYMENT_NAME") def assess_upgrade(state: str): with DefaultAzureCredential() as credential: token_provider = get_bearer_token_provider( credential, "https://ai.azure.com/.default" ) with TypeSafeClient( api_key=token_provider(), base_url=ENDPOINT, model=DEPLOYMENT_NAME, timeout=60, ) as client: return client.system_one( state=state, questions={ "upgrade_needed": { "type": "noul", "instructions": ( "Does the supplied evidence indicate that the installed " "version needs an upgrade? Use only the supplied evidence. " "Missing evidence is not proof that no upgrade is needed." ), "criteria": { "true": ( "Evidence identifies an applicable security fix, " "end-of-support, or required compatibility upgrade." ), "false": ( "Evidence establishes that the installed version is " "supported and no applicable upgrade requirement exists." ), }, }, "reason": { "type": "choice", "instructions": ( "Choose the primary upgrade reason. If multiple apply, " "prioritize security-fix, then end-of-support, then " "compatibility. Choose insufficient-evidence if the " "installed version cannot be assessed reliably." ), "criteria": { "security-fix": ( "An official advisory explicitly affects the installed " "version and identifies a fix." ), "end-of-support": ( "The installed version no longer receives support." ), "compatibility": ( "An upgrade is required for the stated environment " "or application requirements." ), "routine-update": ( "Only optional improvements or routine fixes apply." ), "no-upgrade-needed": ( "Evidence supports retaining the installed version." ), "insufficient-evidence": ( "Evidence is missing, conflicting, or does not " "establish applicability to the installed version." ), }, }, "urgency": { "type": "score", "instructions": ( "Rate upgrade urgency using only verified applicability " "and impact in the supplied evidence. Do not assume an " "older version is vulnerable." ), "criteria": [ "Routine: no established urgent upgrade requirement.", "Planned: upgrade in a normal maintenance cycle.", "Urgent: applicable material security risk, unsupported " "version, or significant compatibility impact.", "Immediate: confirmed exposure to a critical issue or " "active exploitation relevant to the stated deployment.", ], }, }, ) def print_upgrade_decision(response): needed = response.nouls["upgrade_needed"] reason = response.choices["reason"] urgency = response.scores["urgency"] print(f"Upgrade-needed signal: {needed.noul:.1%}") print(f"Reason: {reason.choice} (confidence: {reason.confidence:.1%})") if reason.choice == "insufficient-evidence": print("Urgency: not actionable without more evidence") action = "gather more evidence" else: print(f"Urgency: {urgency.score:.2f} of 3") if needed.noul >= 0.5 and urgency.score >= 2: action = "prioritize upgrade review" elif needed.noul >= 0.5 or reason.choice != "no-upgrade-needed": action = "schedule upgrade review" else: action = "monitor" print(f"Action: {action}") We leverage all three types of questions in this code. “upgrade-needed” has a noul type associated to it, we return either true or false based on the agent’s output. “reason” has a choice type associated to it. We choose a reason for the upgrade. “urgency” has a score type associated to it. We define a criterion to decide the urgency. The score starts from 0 and can be a decimal. The instructions field tells the decision model how to judge the question, while criteria field defines the best possible answers. The print_upgrade_decision() function handles the output formatting: We print if the upgrade is needed (noul type) We print the reason (choice type) We print the action needed based on the urgency score (score type) Calling the Agent In this segment, we will watch the workflow in action! The following code snippet sends a query to the agent and returns a response. The file is called fetch_news.py from azure.identity import DefaultAzureCredential from azure.ai.projects import AIProjectClient from model import assess_upgrade, print_upgrade_decision import json import os from dotenv import load_dotenv load_dotenv() endpoint = os.environ["PROJECT_ENDPOINT"] agent_name = "extract-news-agent" user_message = "We use Django 4.2.0. Find official security advisories affecting this version and identify the fixed versions." # change this as per your needs with ( DefaultAzureCredential() as credential, AIProjectClient( endpoint=endpoint, credential=credential, allow_preview=True, ) as project_client, ): # Bind the OpenAI client to the existing agent endpoint. openai_client = project_client.get_openai_client(agent_name=agent_name) # GitHub Copilot preview agents require a conversation for every Responses turn. conversation = openai_client.conversations.create() response = openai_client.responses.create( conversation=conversation.id, input=[{"role": "user", "content": user_message}], ) raw_output = response.output[-1].content[0].text print(raw_output) news_item = json.loads(raw_output) summary = news_item["summary"] # Classify each news summary with the decision model decision = assess_upgrade(summary) print_upgrade_decision(decision) # print the decision The response contains a JSON object with these fields (we had defined this in our prompt while creating the agent): - package - installed_version - summary - source_urls In the snippet, we send the summary to the decision model and print the final decision. Sample output: Run the fetch_news.py file to get the output! Next Steps: Try it yourself! Clone the repository Extend the use case by: Scanning a real dependency file (requirements.txt, pyproject.toml, package.json) and ranking all packages by urgency. Outputting a report (Markdown or JSON) with the decision, reason, confidence and source URLs. Running it as a scheduled job or CI check that opens an issue or PR comment when an upgrade is urgent. References: Deploy and use Microsoft-Decision-1 in Microsoft Foundry - Microsoft Foundry | Microsoft Learn Microsoft-Decision-1: Our model for fast decision-making