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.