chore: import upstream snapshot with attribution
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:21:23 +08:00
commit b957a53def
5423 changed files with 863745 additions and 0 deletions
@@ -0,0 +1,6 @@
AZURE_AI_AGENT_PROJECT_CONNECTION_STRING = "<example-connection-string>"
AZURE_AI_AGENT_MODEL_DEPLOYMENT_NAME = "<example-model-deployment-name>"
AZURE_AI_AGENT_ENDPOINT = "<example-endpoint>"
AZURE_AI_AGENT_SUBSCRIPTION_ID = "<example-subscription-id>"
AZURE_AI_AGENT_RESOURCE_GROUP_NAME = "<example-resource-group-name>"
AZURE_AI_AGENT_PROJECT_NAME = "<example-project-name>"
@@ -0,0 +1,13 @@
## Azure AI Agents
For details on using Azure AI Agents within Semantic Kernel, see the [README](../../../getting_started_with_agents/azure_ai_agent/README.md) in the `getting_started_with_agents/azure_ai_agent` directory.
### Running the `azure_ai_agent_ai_search.py` Sample
Before running this sample, ensure you have a valid index configured in your Azure AI Search resource. This sample queries hotel data using the sample Azure AI Search hotels index.
For configuration details, refer to the comments in the sample script. For additional guidance, consult the [README](../../memory/azure_ai_search_hotel_samples/README.md), which provides step-by-step instructions for creating the sample index and generating vectors. This is one approach to setting up the index; you can also follow other tutorials, such as those on "Import and Vectorize Data" in your Azure AI Search resource.
### Requests and Rate Limits
For information on configuring rate limits or adjusting polling, refer [here](../../../getting_started_with_agents/azure_ai_agent/README.md#requests-and-rate-limits)
@@ -0,0 +1,160 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from azure.identity import AzureCliCredential
from semantic_kernel import Kernel
from semantic_kernel.agents import (
AzureAIAgent,
AzureAIAgentSettings,
ChatCompletionAgent,
ChatHistoryAgentThread,
)
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion
from semantic_kernel.filters import FunctionInvocationContext
"""
The following sample demonstrates how to create an Azure AI Agent Agent
and a ChatCompletionAgent use them as tools available for a Triage Agent
to delegate requests to the appropriate agent. A Function Invocation Filter
is used to show the function call content and the function result content so the caller
can see which agent was called and what the response was.
"""
# Define the auto function invocation filter that will be used by the kernel
async def function_invocation_filter(context: FunctionInvocationContext, next):
"""A filter that will be called for each function call in the response."""
if "messages" not in context.arguments:
await next(context)
return
print(f" Agent [{context.function.name}] called with messages: {context.arguments['messages']}")
await next(context)
print(f" Response from agent [{context.function.name}]: {context.result.value}")
async def chat(triage_agent: ChatCompletionAgent, thread: ChatHistoryAgentThread = None) -> bool:
"""
Continuously prompt the user for input and show the assistant's response.
Type 'exit' to exit.
"""
try:
user_input = input("User:> ")
except (KeyboardInterrupt, EOFError):
print("\n\nExiting chat...")
return False
if user_input.lower().strip() == "exit":
print("\n\nExiting chat...")
return False
response = await triage_agent.get_response(
messages=user_input,
thread=thread,
)
if response:
print(f"Agent :> {response}")
return True
async def main() -> None:
# Create and configure the kernel.
kernel = Kernel()
# The filter is used for demonstration purposes to show the function invocation.
kernel.add_filter("function_invocation", function_invocation_filter)
ai_agent_settings = AzureAIAgentSettings()
credential = AzureCliCredential()
async with (
AzureAIAgent.create_client(credential=credential, endpoint=ai_agent_settings.endpoint) as client,
):
# Create the agent definition
agent_definition = await client.agents.create_agent(
model=ai_agent_settings.model_deployment_name,
name="BillingAgent",
instructions=(
"You specialize in handling customer questions related to billing issues. "
"This includes clarifying invoice charges, payment methods, billing cycles, "
"explaining fees, addressing discrepancies in billed amounts, updating payment details, "
"assisting with subscription changes, and resolving payment failures. "
"Your goal is to clearly communicate and resolve issues specifically about payments and charges."
),
)
# Create the AzureAI Agent
billing_agent = AzureAIAgent(
client=client,
definition=agent_definition,
)
refund_agent = ChatCompletionAgent(
service=AzureChatCompletion(credential=credential),
name="RefundAgent",
instructions=(
"You specialize in addressing customer inquiries regarding refunds. "
"This includes evaluating eligibility for refunds, explaining refund policies, "
"processing refund requests, providing status updates on refunds, handling complaints related to "
"refunds, and guiding customers through the refund claim process. "
"Your goal is to assist users clearly and empathetically to successfully resolve their refund-related "
"concerns."
),
)
triage_agent = ChatCompletionAgent(
service=AzureChatCompletion(credential=credential),
kernel=kernel,
name="TriageAgent",
instructions=(
"Your role is to evaluate the user's request and forward it to the appropriate agent based on the "
"nature of the query. Forward requests about charges, billing cycles, payment methods, fees, or "
"payment issues to the BillingAgent. Forward requests concerning refunds, refund eligibility, "
"refund policies, or the status of refunds to the RefundAgent. Your goal is accurate identification "
"of the appropriate specialist to ensure the user receives targeted assistance."
),
plugins=[billing_agent, refund_agent],
)
thread: ChatHistoryAgentThread = None
print("Welcome to the chat bot!\n Type 'exit' to exit.\n Try to get some billing or refund help.")
chatting = True
while chatting:
chatting = await chat(triage_agent, thread)
"""
Sample Output:
I canceled my subscription but I was still charged.
Agent [BillingAgent] called with messages: I canceled my subscription but I was still charged.
Response from agent [BillingAgent]: I understand how concerning that can be. It's possible that the charge you
received is for a billing cycle that was initiated before your cancellation was processed. Here are a few
steps you can take:
1. **Check Cancellation Confirmation**: Make sure you received a confirmation of your cancellation.
This usually comes via email.
2. **Billing Cycle**: Review your billing cycle to confirm whether the charge aligns with your subscription terms.
If your billing is monthly, charges can occur even if you cancel before the period ends.
3. **Contact Support**: If you believe the charge was made in error, please reach out to customer support for
further clarification and to rectify the situation.
If you can provide more details about the subscription and when you canceled it, I can help you further understand
the charges.
Agent :> It's possible that the charge you received is for a billing cycle initiated before your cancellation was
processed. Please check if you received a cancellation confirmation, review your billing cycle, and contact
support for further clarification if you believe the charge was made in error. If you have more details,
I can help you understand the charges better.
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,178 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from typing import Annotated
from azure.identity.aio import AzureCliCredential
from semantic_kernel.agents import AzureAIAgent, AzureAIAgentSettings, AzureAIAgentThread
from semantic_kernel.contents import ChatMessageContent, FunctionCallContent, FunctionResultContent
from semantic_kernel.filters import (
AutoFunctionInvocationContext,
FilterTypes,
)
from semantic_kernel.functions import FunctionResult, kernel_function
from semantic_kernel.kernel import Kernel
"""
The following sample demonstrates how to create an Azure AI agent that answers
user questions. This sample demonstrates the basic steps to create an agent
and simulate a conversation with the agent.
This sample demonstrates how to create a filter that will be called for each
function call in the response. The filter can be used to modify the function
result or to terminate the function call. The filter can also be used to
log the function call or to perform any other action before or after the
function call.
"""
class MenuPlugin:
"""A sample Menu Plugin used for the concept sample."""
@kernel_function(description="Provides a list of specials from the menu.")
def get_specials(self) -> Annotated[str, "Returns the specials from the menu."]:
return """
Special Soup: Clam Chowder
Special Salad: Cobb Salad
Special Drink: Chai Tea
"""
@kernel_function(description="Provides the price of the requested menu item.")
def get_item_price(
self, menu_item: Annotated[str, "The name of the menu item."]
) -> Annotated[str, "Returns the price of the menu item."]:
return "$9.99"
# Define a kernel instance so we can attach the filter to it
kernel = Kernel()
# Define a list to store intermediate steps
intermediate_steps: list[ChatMessageContent] = []
# Define a callback function to handle intermediate step content messages
async def handle_intermediate_steps(message: ChatMessageContent) -> None:
intermediate_steps.append(message)
@kernel.filter(FilterTypes.AUTO_FUNCTION_INVOCATION)
async def auto_function_invocation_filter(context: AutoFunctionInvocationContext, next):
"""A filter that will be called for each function call in the response."""
print("\nAuto function invocation filter")
print(f"Function: {context.function.name}")
# if we don't call next, it will skip this function, and go to the next one
await next(context)
"""
Note: to simply return the unaltered function results, uncomment the `context.terminate = True` line and
comment out the lines starting with `result = context.function_result` through `context.terminate = True`.
context.terminate = True
For this sample, simply setting `context.terminate = True` will return the unaltered function result:
Auto function invocation filter
Function: get_specials
# Assistant: MenuPlugin-get_specials -
Special Soup: Clam Chowder
Special Salad: Cobb Salad
Special Drink: Chai Tea
"""
result = context.function_result
if "menu" in context.function.plugin_name.lower():
print("Altering the Menu plugin function result...\n")
context.function_result = FunctionResult(
function=result.function,
value="We are sold out, sorry!",
)
context.terminate = True
# Simulate a conversation with the agent
USER_INPUTS = ["What's the special food on the menu?", "What should I do then?"]
async def main() -> None:
ai_agent_settings = AzureAIAgentSettings.create()
async with (
AzureCliCredential() as creds,
AzureAIAgent.create_client(credential=creds) as client,
):
# 1. Create an agent on the Azure AI agent service
agent_definition = await client.agents.create_agent(
model=ai_agent_settings.model_deployment_name,
name="Host",
instructions="Answer the user's questions about the menu.",
)
# 2. Create a Semantic Kernel agent for the Azure AI agent
agent = AzureAIAgent(
kernel=kernel,
client=client,
definition=agent_definition,
plugins=[MenuPlugin()], # Add the plugin to the agent
)
# 3. Create a thread for the agent
# If no thread is provided, a new thread will be
# created and returned with the initial response
thread: AzureAIAgentThread = None
try:
for user_input in USER_INPUTS:
print(f"# User: {user_input}")
# 4. Invoke the agent with the specified message for response
async for response in agent.invoke(
messages=user_input, thread=thread, on_intermediate_message=handle_intermediate_steps
):
# 5. Print the response
print(f"# {response.name}: {response}")
thread = response.thread
finally:
# 6. Cleanup: Delete the thread and agent
await thread.delete() if thread else None
await client.agents.delete_agent(agent.id)
# Print the intermediate steps
print("\nIntermediate Steps:")
for msg in intermediate_steps:
if any(isinstance(item, FunctionResultContent) for item in msg.items):
for fr in msg.items:
if isinstance(fr, FunctionResultContent):
print(f"Function Result:> {fr.result} for function: {fr.name}")
elif any(isinstance(item, FunctionCallContent) for item in msg.items):
for fcc in msg.items:
if isinstance(fcc, FunctionCallContent):
print(f"Function Call:> {fcc.name} with arguments: {fcc.arguments}")
else:
print(f"{msg.role}: {msg.content}")
"""
Sample Output:
# User: What's the special food on the menu?
Auto function invocation filter
Function: get_specials
Altering the Menu plugin function result...
# Host: I'm sorry, but all the specials on the menu are currently sold out. If there's anything else you're
looking for, please let me know!
# User: What should I do then?
# Host: You might consider ordering from the regular menu items instead. If you need any recommendations or
information about specific items, such as prices or ingredients, feel free to ask!
Intermediate Steps:
Function Call:> MenuPlugin-get_specials with arguments: {}
Function Result:> We are sold out, sorry! for function: MenuPlugin-get_specials
AuthorRole.ASSISTANT: I'm sorry, but all the specials on the menu are currently sold out. If there's anything
else you're looking for, please let me know!
AuthorRole.ASSISTANT: You might consider ordering from the regular menu items instead. If you need any
recommendations or information about specific items, such as prices or ingredients, feel free to ask!
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,183 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from typing import Annotated
from azure.identity.aio import AzureCliCredential
from semantic_kernel.agents import AzureAIAgent, AzureAIAgentSettings, AzureAIAgentThread
from semantic_kernel.contents import ChatMessageContent, FunctionCallContent, FunctionResultContent
from semantic_kernel.filters import (
AutoFunctionInvocationContext,
FilterTypes,
)
from semantic_kernel.functions import FunctionResult, kernel_function
from semantic_kernel.kernel import Kernel
"""
The following sample demonstrates how to create an Azure AI agent that answers
user questions. This sample demonstrates the basic steps to create an agent
and simulate a streaming conversation with the agent.
This sample demonstrates how to create a filter that will be called for each
function call in the response. The filter can be used to modify the function
result or to terminate the function call. The filter can also be used to
log the function call or to perform any other action before or after the
function call.
"""
class MenuPlugin:
"""A sample Menu Plugin used for the concept sample."""
@kernel_function(description="Provides a list of specials from the menu.")
def get_specials(self) -> Annotated[str, "Returns the specials from the menu."]:
return """
Special Soup: Clam Chowder
Special Salad: Cobb Salad
Special Drink: Chai Tea
"""
@kernel_function(description="Provides the price of the requested menu item.")
def get_item_price(
self, menu_item: Annotated[str, "The name of the menu item."]
) -> Annotated[str, "Returns the price of the menu item."]:
return "$9.99"
# Define a kernel instance so we can attach the filter to it
kernel = Kernel()
# Define a list to store intermediate steps
intermediate_steps: list[ChatMessageContent] = []
# Define a callback function to handle intermediate step content messages
async def handle_intermediate_steps(message: ChatMessageContent) -> None:
intermediate_steps.append(message)
@kernel.filter(FilterTypes.AUTO_FUNCTION_INVOCATION)
async def auto_function_invocation_filter(context: AutoFunctionInvocationContext, next):
"""A filter that will be called for each function call in the response."""
print("\nAuto function invocation filter")
print(f"Function: {context.function.name}")
# if we don't call next, it will skip this function, and go to the next one
await next(context)
"""
Note: to simply return the unaltered function results, uncomment the `context.terminate = True` line and
comment out the lines starting with `result = context.function_result` through `context.terminate = True`.
context.terminate = True
For this sample, simply setting `context.terminate = True` will return the unaltered function result:
Auto function invocation filter
Function: get_specials
# Assistant: MenuPlugin-get_specials -
Special Soup: Clam Chowder
Special Salad: Cobb Salad
Special Drink: Chai Tea
"""
result = context.function_result
if "menu" in context.function.plugin_name.lower():
print("Altering the Menu plugin function result...\n")
context.function_result = FunctionResult(
function=result.function,
value="We are sold out, sorry!",
)
context.terminate = True
# Simulate a conversation with the agent
USER_INPUTS = ["What's the special food on the menu?", "What should I do then?"]
async def main() -> None:
ai_agent_settings = AzureAIAgentSettings.create()
async with (
AzureCliCredential() as creds,
AzureAIAgent.create_client(credential=creds) as client,
):
# 1. Create an agent on the Azure AI agent service
agent_definition = await client.agents.create_agent(
model=ai_agent_settings.model_deployment_name,
name="Host",
instructions="Answer the user's questions about the menu.",
)
# 2. Create a Semantic Kernel agent for the Azure AI agent
agent = AzureAIAgent(
kernel=kernel,
client=client,
definition=agent_definition,
plugins=[MenuPlugin()], # Add the plugin to the agent
)
# 3. Create a thread for the agent
# If no thread is provided, a new thread will be
# created and returned with the initial response
thread: AzureAIAgentThread = None
try:
for user_input in USER_INPUTS:
print(f"# User: {user_input}")
# 4. Invoke the agent with the specified message for response
first_chunk = True
async for response in agent.invoke_stream(
messages=user_input, thread=thread, on_intermediate_message=handle_intermediate_steps
):
# 5. Print the response
if first_chunk:
print(f"# {response.name}: ", end="", flush=True)
first_chunk = False
print(f"{response}", end="", flush=True)
thread = response.thread
print()
finally:
# 6. Cleanup: Delete the thread and agent
await thread.delete() if thread else None
await client.agents.delete_agent(agent.id)
# Print the intermediate steps
print("\nIntermediate Steps:")
for msg in intermediate_steps:
if any(isinstance(item, FunctionResultContent) for item in msg.items):
for fr in msg.items:
if isinstance(fr, FunctionResultContent):
print(f"Function Result:> {fr.result} for function: {fr.name}")
elif any(isinstance(item, FunctionCallContent) for item in msg.items):
for fcc in msg.items:
if isinstance(fcc, FunctionCallContent):
print(f"Function Call:> {fcc.name} with arguments: {fcc.arguments}")
else:
print(f"{msg.role}: {msg.content}")
"""
Sample Output:
# User: What's the special food on the menu?
Auto function invocation filter
Function: get_specials
Altering the Menu plugin function result...
# Host: I'm sorry, but all the specials on the menu are currently sold out. If there's anything else you're
looking for, please let me know!
# User: What should I do then?
# Host: You might consider ordering from the regular menu items instead. If you need any recommendations or
information about specific items, such as prices or ingredients, feel free to ask!
Intermediate Steps:
Function Call:> MenuPlugin-get_specials with arguments: {}
Function Result:> We are sold out, sorry! for function: MenuPlugin-get_specials
AuthorRole.ASSISTANT: I'm sorry, but all the specials on the menu are currently sold out. If there's anything
else you're looking for, please let me know!
AuthorRole.ASSISTANT: You might consider ordering from the regular menu items instead. If you need any
recommendations or information about specific items, such as prices or ingredients, feel free to ask!
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,139 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import logging
from azure.ai.agents.models import AzureAISearchTool
from azure.ai.projects.models import ConnectionType
from azure.identity.aio import AzureCliCredential
from semantic_kernel.agents import AzureAIAgent, AzureAIAgentSettings, AzureAIAgentThread
logging.basicConfig(level=logging.WARNING)
"""
The following sample demonstrates how to create a simple,
Azure AI agent that uses the Azure AI Search tool and the demo
hotels-sample-index to answer questions about hotels.
This sample requires:
- A "Standard" Agent Setup (choose the Python (Azure SDK) tab):
https://learn.microsoft.com/en-us/azure/ai-services/agents/quickstart
- An Azure AI Search index named 'hotels-sample-index' created in your
Azure AI Search service. You may follow this guide to create the index:
https://learn.microsoft.com/azure/search/search-get-started-portal
- You will need to make sure your Azure AI Agent project is set up with
the required Knowledge Source to be able to use the Azure AI Search tool.
Refer to the following link for information on how to do this:
https://learn.microsoft.com/en-us/azure/ai-services/agents/how-to/tools/azure-ai-search
Refer to the README for information about configuring the index to work
with the sample data model in Azure AI Search.
"""
# The name of the Azure AI Search index, rename as needed
AZURE_AI_SEARCH_INDEX_NAME = "hotels-sample-index"
async def main() -> None:
ai_agent_settings = AzureAIAgentSettings()
async with (
AzureCliCredential() as creds,
AzureAIAgent.create_client(credential=creds, endpoint=ai_agent_settings.endpoint) as client,
):
ai_search_conn_id = ""
async for connection in client.connections.list():
if connection.type == ConnectionType.AZURE_AI_SEARCH:
ai_search_conn_id = connection.id
break
ai_search = AzureAISearchTool(index_connection_id=ai_search_conn_id, index_name=AZURE_AI_SEARCH_INDEX_NAME)
# Create agent definition
agent_definition = await client.agents.create_agent(
model=ai_agent_settings.model_deployment_name,
instructions="Answer questions about hotels using your index.",
tools=ai_search.definitions,
tool_resources=ai_search.resources,
headers={"x-ms-enable-preview": "true"},
)
# Create the AzureAI Agent
agent = AzureAIAgent(
client=client,
definition=agent_definition,
)
# Create a thread for the agent
# If no thread is provided, a new thread will be
# created and returned with the initial response
thread: AzureAIAgentThread = None
user_inputs = [
"Which hotels are available with full-sized kitchens in Nashville, TN?",
"Fun hotels with free WiFi.",
]
try:
for user_input in user_inputs:
print(f"# User: '{user_input}'\n")
# Invoke the agent for the specified thread
async for response in agent.invoke(messages=user_input, thread=thread):
print(f"# Agent: {response}\n")
thread = response.thread
finally:
# Cleanup: Delete the thread and agent
await thread.delete() if thread else None
await client.agents.delete_agent(agent.id)
"""
Sample output:
# User: 'Which hotels are available with full-sized kitchens in Nashville, TN?'
# Agent: In Nashville, TN, there are several hotels available that feature full-sized kitchens:
1. **Extended-Stay Hotel Options**:
- Many extended-stay hotels offer suites equipped with full-sized kitchens, which include cookware and
appliances. These hotels are designed for longer stays, making them a great option for those needing more space
and kitchen facilities【3:0†source】【3:1†source】.
2. **Amenities Included**:
- Most of these hotels provide additional amenities like free Wi-Fi, laundry services, fitness centers, and some
have on-site dining options【3:1†source】【3:2†source】.
3. **Location**:
- The extended-stay hotels are often located near downtown Nashville, making it convenient for guests to
explore the vibrant local music scene while enjoying the comfort of a home-like
environment【3:0†source】【3:4†source】.
If you are looking for specific names or more detailed options, I can further assist you with that!
# User: 'Fun hotels with free WiFi.'
# Agent: Here are some fun hotels that offer free WiFi:
1. **Vibrant Downtown Hotel**:
- Located near the heart of downtown, this hotel offers a warm atmosphere with free WiFi and even provides a
delightful milk and cookies treat【7:2†source】.
2. **Extended-Stay Options**:
- These hotels often feature fun amenities such as a bowling alley, fitness center, and themed rooms. They also
provide free WiFi and are well-situated near local attractions【7:0†source】【7:1†source】.
3. **Luxury Hotel**:
- Ranked highly by Traveler magazine, this 5-star luxury hotel boasts the biggest rooms in the city, free WiFi,
espresso in the room, and flexible check-in/check-out options【7:1†source】.
4. **Budget-Friendly Hotels**:
- Several budget hotels offer free WiFi, breakfast, and shuttle services to nearby attractions and airports
while still providing a fun stay【7:3†source】.
These options ensure you stay connected while enjoying your visit! If you need more specific recommendations or
details, feel free to ask!
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,110 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from azure.ai.agents.models import BingGroundingTool
from azure.identity.aio import AzureCliCredential
from semantic_kernel.agents import AzureAIAgent, AzureAIAgentSettings, AzureAIAgentThread
from semantic_kernel.contents import (
AnnotationContent,
ChatMessageContent,
FunctionCallContent,
FunctionResultContent,
)
"""
The following sample demonstrates how to create an Azure AI agent that
uses the Bing grounding tool to answer a user's question.
Note: Please visit the following link to learn more about the Bing grounding tool:
https://learn.microsoft.com/en-us/azure/ai-services/agents/how-to/tools/bing-grounding?tabs=python&pivots=overview
"""
TASK = "Which team won the 2025 NCAA basketball championship?"
async def handle_intermediate_steps(message: ChatMessageContent) -> None:
for item in message.items or []:
if isinstance(item, FunctionResultContent):
print(f"Function Result:> {item.result} for function: {item.name}")
elif isinstance(item, FunctionCallContent):
print(f"Function Call:> {item.name} with arguments: {item.arguments}")
else:
print(f"{item}")
async def main() -> None:
async with (
AzureCliCredential() as creds,
AzureAIAgent.create_client(credential=creds) as client,
):
# 1. Enter your Bing Grounding Connection Name
bing_connection = await client.connections.get(name="<your-bing-grounding-connection-name>")
conn_id = bing_connection.id
# 2. Initialize agent bing tool and add the connection id
bing_grounding = BingGroundingTool(connection_id=conn_id)
# 3. Create an agent with Bing grounding on the Azure AI agent service
agent_definition = await client.agents.create_agent(
name="BingGroundingAgent",
instructions="Use the Bing grounding tool to answer the user's question.",
model=AzureAIAgentSettings().model_deployment_name,
tools=bing_grounding.definitions,
)
# 4. Create a Semantic Kernel agent for the Azure AI agent
agent = AzureAIAgent(
client=client,
definition=agent_definition,
)
# 5. Create a thread for the agent
# If no thread is provided, a new thread will be
# created and returned with the initial response
thread: AzureAIAgentThread | None = None
try:
print(f"# User: '{TASK}'")
# 6. Invoke the agent for the specified thread for response
async for response in agent.invoke(
messages=TASK, thread=thread, on_intermediate_message=handle_intermediate_steps
):
print(f"# {response.name}: {response}")
thread = response.thread
# 7. Show annotations
if any(isinstance(item, AnnotationContent) for item in response.items):
for annotation in response.items:
if isinstance(annotation, AnnotationContent):
print(
f"Annotation :> {annotation.url}, source={annotation.quote}, with "
f"start_index={annotation.start_index} and end_index={annotation.end_index}"
)
finally:
# 8. Cleanup: Delete the thread and agent
await thread.delete() if thread else None
await client.agents.delete_agent(agent.id)
"""
Sample Output:
# User: 'Which team won the 2025 NCAA basketball championship?'
Function Call:> bing_grounding with arguments:
{
'requesturl': 'https://api.bing.microsoft.com/v7.0/search?q=search(query:2025 NCAA basketball championship winner)',
'response_metadata': "{'market': 'en-US', 'num_docs_retrieved': 5, 'num_docs_actually_used': 5}"
}
# BingGroundingAgent: The team that won the 2025 NCAA men's basketball championship was the Florida Gators. They defeated the Houston Cougars with a final score of 65-63.
The championship game took place in San Antonio, Texas, and the Florida team was coached by Todd Golden. This victory made Florida the national champion for the 2024-25
NCAA Division I men's basketball season【3:0†source】【3:1†source】【3:2†source】.
Annotation :> https://en.wikipedia.org/wiki/2025_NCAA_Division_I_men%27s_basketball_championship_game, source=【3:0†source】, with start_index=357 and end_index=369
Annotation :> https://www.ncaa.com/history/basketball-men/d1, source=【3:1†source】, with start_index=369 and end_index=381
Annotation :> https://sports.yahoo.com/article/won-march-madness-2025-ncaa-100551421.html, source=【3:2†source】, with start_index=381 and end_index=393
""" # noqa: E501
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,117 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from azure.ai.agents.models import BingGroundingTool
from azure.identity.aio import AzureCliCredential
from semantic_kernel.agents import AzureAIAgent, AzureAIAgentSettings, AzureAIAgentThread
from semantic_kernel.contents import (
ChatMessageContent,
FunctionCallContent,
FunctionResultContent,
StreamingAnnotationContent,
)
"""
The following sample demonstrates how to create an Azure AI agent that
uses the Bing grounding tool to answer a user's question.
Additionally, the `on_intermediate_message` callback is used to handle intermediate messages
from the agent.
Note: Please visit the following link to learn more about the Bing grounding tool:
https://learn.microsoft.com/en-us/azure/ai-services/agents/how-to/tools/bing-grounding?tabs=python&pivots=overview
"""
TASK = "Which team won the 2025 NCAA basketball championship?"
intermediate_steps: list[ChatMessageContent] = []
async def handle_streaming_intermediate_steps(message: ChatMessageContent) -> None:
for item in message.items or []:
if isinstance(item, FunctionResultContent):
print(f"Function Result:> {item.result} for function: {item.name}")
elif isinstance(item, FunctionCallContent):
print(f"Function Call:> {item.name} with arguments: {item.arguments}")
else:
print(f"{item}")
async def main() -> None:
async with (
AzureCliCredential() as creds,
AzureAIAgent.create_client(credential=creds) as client,
):
# 1. Enter your Bing Grounding Connection Name
bing_connection = await client.connections.get(name="<your-bing-grounding-connection-name>")
conn_id = bing_connection.id
# 2. Initialize agent bing tool and add the connection id
bing_grounding = BingGroundingTool(connection_id=conn_id)
# 3. Create an agent with Bing grounding on the Azure AI agent service
agent_definition = await client.agents.create_agent(
name="BingGroundingAgent",
instructions="Use the Bing grounding tool to answer the user's question.",
model=AzureAIAgentSettings().model_deployment_name,
tools=bing_grounding.definitions,
)
# 4. Create a Semantic Kernel agent for the Azure AI agent
agent = AzureAIAgent(
client=client,
definition=agent_definition,
)
# 5. Create a thread for the agent
# If no thread is provided, a new thread will be
# created and returned with the initial response
thread: AzureAIAgentThread | None = None
try:
print(f"# User: '{TASK}'")
# 6. Invoke the agent for the specified thread for response
first_chunk = True
async for response in agent.invoke_stream(
messages=TASK, thread=thread, on_intermediate_message=handle_streaming_intermediate_steps
):
if first_chunk:
print(f"# {response.name}: ", end="", flush=True)
first_chunk = False
print(f"{response}", end="", flush=True)
thread = response.thread
# 7. Show annotations
if any(isinstance(item, StreamingAnnotationContent) for item in response.items):
print()
for annotation in response.items:
if isinstance(annotation, StreamingAnnotationContent):
print(
f"Annotation :> {annotation.url}, source={annotation.quote}, with "
f"start_index={annotation.start_index} and end_index={annotation.end_index}"
)
finally:
# 8. Cleanup: Delete the thread and agent
await thread.delete() if thread else None
await client.agents.delete_agent(agent.id)
"""
Sample Output:
# User: 'Which team won the 2025 NCAA basketball championship?'
Function Call:> bing_grounding with arguments: {'requesturl': 'https://api.bing.microsoft.com/v7.0/search?q=search(query: 2025 NCAA basketball championship winner)'}
Function Call:> bing_grounding with arguments: {'response_metadata': "{'market': 'en-US', 'num_docs_retrieved': 5, 'num_docs_actually_used': 5}"}
# BingGroundingAgent: The Florida Gators won the 2025 NCAA men's basketball championship. They defeated the Houston Cougars with a close score of 65-63 in the championship game held in San Antonio, Texas. This victory marked their third national title. Florida overcame a 12-point deficit during the game to claim the championship【3:0†source】
Annotation :> https://en.wikipedia.org/wiki/2025_NCAA_Division_I_men%27s_basketball_championship_game, source=None, with start_index=308 and end_index=320
【3:1†source】
Annotation :> https://www.ncaa.com/history/basketball-men/d1, source=None, with start_index=320 and end_index=332
【3:2†source】
Annotation :> https://sports.yahoo.com/article/florida-gators-win-2025-ncaa-034021303.html, source=None, with start_index=332 and end_index=344.
""" # noqa: E501
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,139 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from functools import reduce
from azure.ai.agents.models import CodeInterpreterTool
from azure.identity.aio import AzureCliCredential
from semantic_kernel.agents import AzureAIAgent, AzureAIAgentSettings, AzureAIAgentThread
from semantic_kernel.contents import ChatMessageContent, StreamingChatMessageContent
"""
The following sample demonstrates how to create an Azure AI agent that
uses the code interpreter tool and returns streaming responses to answer a coding question.
Additionally, the `on_intermediate_message` callback is used to handle intermediate messages
from the agent.
"""
TASK = "Use code to determine the values in the Fibonacci sequence that that are less then the value of 101."
intermediate_steps: list[ChatMessageContent] = []
async def handle_streaming_intermediate_steps(message: ChatMessageContent) -> None:
intermediate_steps.append(message)
async def main() -> None:
async with (
AzureCliCredential() as creds,
AzureAIAgent.create_client(credential=creds) as client,
):
# 1. Create an agent with a code interpreter on the Azure AI agent service
code_interpreter = CodeInterpreterTool()
agent_definition = await client.agents.create_agent(
model=AzureAIAgentSettings().model_deployment_name,
tools=code_interpreter.definitions,
tool_resources=code_interpreter.resources,
)
# 2. Create a Semantic Kernel agent for the Azure AI agent
agent = AzureAIAgent(
client=client,
definition=agent_definition,
)
# 3. Create a thread for the agent
# If no thread is provided, a new thread will be
# created and returned with the initial response
thread: AzureAIAgentThread | None = None
try:
print(f"# User: '{TASK}'")
# 4. Invoke the agent for the specified thread for response
is_code = False
last_role = None
async for response in agent.invoke_stream(
messages=TASK, thread=thread, on_intermediate_message=handle_streaming_intermediate_steps
):
current_is_code = response.metadata.get("code", False)
if current_is_code:
if not is_code:
print("\n\n```python")
is_code = True
print(response.content, end="", flush=True)
else:
if is_code:
print("\n```")
is_code = False
last_role = None
if hasattr(response, "role") and response.role is not None and last_role != response.role:
print(f"\n# {response.role}: ", end="", flush=True)
last_role = response.role
print(response.content, end="", flush=True)
thread = response.thread
if is_code:
print("```\n")
print()
finally:
# 6. Cleanup: Delete the thread and agent
await thread.delete() if thread else None
await client.agents.delete_agent(agent.id)
print("====================================================")
print("\nResponse complete:\n")
# Combine the intermediate `StreamingChatMessageContent` chunks into a single message
filtered_steps = [step for step in intermediate_steps if isinstance(step, StreamingChatMessageContent)]
streaming_full_completion: StreamingChatMessageContent = reduce(lambda x, y: x + y, filtered_steps)
# Grab the other messages that are not `StreamingChatMessageContent`
other_steps = [s for s in intermediate_steps if not isinstance(s, StreamingChatMessageContent)]
final_msgs = [streaming_full_completion] + other_steps
for msg in final_msgs:
print(f"{msg.content}")
r"""
Sample Output:
# User: 'Use code to determine the values in the Fibonacci sequence that that are less then the value of 101.'
```python
def fibonacci_sequence(limit):
fib_sequence = []
a, b = 0, 1
while a < limit:
fib_sequence.append(a)
a, b = b, a + b
return fib_sequence
# Get Fibonacci sequence values less than 101
fibonacci_values = fibonacci_sequence(101)
fibonacci_values
```
# AuthorRole.ASSISTANT: The values in the Fibonacci sequence that are less than 101 are:
\[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89\]
====================================================
Response complete:
def fibonacci_sequence(limit):
fib_sequence = []
a, b = 0, 1
while a < limit:
fib_sequence.append(a)
a, b = b, a + b
return fib_sequence
# Get Fibonacci sequence values less than 101
fibonacci_values = fibonacci_sequence(101)
fibonacci_values
The values in the Fibonacci sequence that are less than 101 are:
\[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89\]
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,94 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from azure.identity.aio import AzureCliCredential
from semantic_kernel.agents import AgentRegistry, AzureAIAgent, AzureAIAgentSettings
from semantic_kernel.contents.chat_message_content import ChatMessageContent
from semantic_kernel.contents.function_call_content import FunctionCallContent
from semantic_kernel.contents.function_result_content import FunctionResultContent
"""
The following sample demonstrates how to create an Azure AI agent that answers
user questions using the Azure AI Search tool.
The agent is created using a YAML declarative spec that configures the
Azure AI Search tool. The agent is then used to answer user questions
that required grounding context from the Azure AI Search index.
Note: the `AzureAISearchConnectionId` is in the format of:
/subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.MachineLearningServices/workspaces/<workspace>/connections/AzureAISearch
It can either be configured as an env var `AZURE_AI_AGENT_BING_CONNECTION_ID` or passed in as an extra to
`create_from_yaml`: extras={
"AzureAISearchConnectionId": "<azure_ai_search_connection_id>",
"AzureAISearchIndexName": "<azure_ai_search_index_name>"
}
"""
# Define the YAML string for the sample
spec = """
type: foundry_agent
name: AzureAISearchAgent
instructions: Answer questions using your index to provide grounding context.
description: This agent answers questions using AI Search to provide grounding context.
model:
id: ${AzureAI:ChatModelId}
options:
temperature: 0.4
tools:
- type: azure_ai_search
options:
tool_connections:
- ${AzureAI:AzureAISearchConnectionId}
index_name: ${AzureAI:AzureAISearchIndexName}
"""
settings = AzureAIAgentSettings() # ChatModelId comes from .env/env vars
async def main():
async with (
AzureCliCredential() as creds,
AzureAIAgent.create_client(credential=creds) as client,
):
try:
# Create the AzureAI Agent from the YAML spec
# Note: the extras can be provided in the short-format (shown below) or
# in the long-format (as shown in the YAML spec, with the `AzureAI:` prefix).
# The short-format is used here for brevity
agent: AzureAIAgent = await AgentRegistry.create_from_yaml(
yaml_str=spec,
client=client,
settings=settings,
extras={
"AzureAISearchConnectionId": "<azure-ai-search-connection-id>",
"AzureAISearchIndexName": "<azure-ai-search-index-name>",
},
)
# Define the task for the agent
TASK = "What is Semantic Kernel?"
print(f"# User: '{TASK}'")
# Define a callback function to handle intermediate messages
async def on_intermediate_message(message: ChatMessageContent):
if message.items:
for item in message.items:
if isinstance(item, FunctionCallContent):
print(f"# FunctionCallContent: arguments={item.arguments}")
elif isinstance(item, FunctionResultContent):
print(f"# FunctionResultContent: result={item.result}")
# Invoke the agent for the specified task
async for response in agent.invoke(messages=TASK, on_intermediate_message=on_intermediate_message):
print(f"# {response.name}: {response}")
finally:
# Cleanup: Delete the agent
await client.agents.delete_agent(agent.id)
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,82 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from azure.identity.aio import AzureCliCredential
from semantic_kernel.agents import AgentRegistry, AzureAIAgent, AzureAIAgentSettings
"""
The following sample demonstrates how to create an Azure AI agent that answers
user questions using the Bing Grounding tool.
The agent is created using a YAML declarative spec that configures the
Bing Grounding tool. The agent is then used to answer user questions
that require web search to answer correctly.
Note: the `BingConnectionId` is in the format of:
/subscriptions/<sub_id>/resourceGroups/<rg>/providers/Microsoft.MachineLearningServices/workspaces/<workspace>/connections/<bing_connection_id>
It can either be configured as an env var `AZURE_AI_AGENT_BING_CONNECTION_ID` or passed in as an extra to
`create_from_yaml`: extras={"BingConnectionId": "<bing_connection_id>"}
"""
# Define the YAML string for the sample
spec = """
type: foundry_agent
name: BingAgent
instructions: Answer questions using Bing to provide grounding context.
description: This agent answers questions using Bing to provide grounding context.
model:
id: ${AzureAI:ChatModelId}
options:
temperature: 0.4
tools:
- type: bing_grounding
options:
tool_connections:
- ${AzureAI:BingConnectionId}
"""
settings = AzureAIAgentSettings() # ChatModelId & BingConnectionId come from .env/env vars
async def main():
async with (
AzureCliCredential() as creds,
AzureAIAgent.create_client(credential=creds) as client,
):
try:
# Create the AzureAI Agent from the YAML spec
agent: AzureAIAgent = await AgentRegistry.create_from_yaml(
yaml_str=spec,
client=client,
settings=settings,
)
# Define the task for the agent
TASK = "Who won the 2025 NCAA basketball championship?"
print(f"# User: '{TASK}'")
# Invoke the agent for the specified task
async for response in agent.invoke(
messages=TASK,
):
print(f"# {response.name}: {response}")
finally:
# Cleanup: Delete the thread and agent
await client.agents.delete_agent(agent.id)
"""
Sample output:
# User: 'Who won the 2025 NCAA basketball championship?'
# BingAgent: The Florida Gators won the 2025 NCAA men's basketball championship, narrowly defeating the Houston
Cougars 65-63 in the final game. This marked Florida's first national title since
2007【3:5†source】【3:9†source】.
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,149 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from azure.ai.agents.models import FilePurpose
from azure.identity.aio import AzureCliCredential
from semantic_kernel.agents import AgentRegistry, AzureAIAgent, AzureAIAgentSettings
"""
The following sample demonstrates how to create an Azure AI agent that answers
user questions using the code interpreter tool.
The agent is then used to answer user questions that require code to be generated and
executed. The responses are handled in a streaming manner.
"""
# Define the YAML string for the sample
spec = """
type: foundry_agent
name: CodeInterpreterAgent
description: Agent with code interpreter tool.
instructions: >
Use the code interpreter tool to answer questions that require code to be generated
and executed.
model:
id: ${AzureAI:ChatModelId}
connection:
endpoint: ${AzureAI:Endpoint}
tools:
- type: code_interpreter
options:
file_ids:
- ${AzureAI:FileId1}
"""
settings = AzureAIAgentSettings() # ChatModelId & Endpoint come from env vars
async def main():
async with (
AzureCliCredential() as creds,
AzureAIAgent.create_client(credential=creds) as client,
):
# Create the CSV file path for the sample
csv_file_path = os.path.join(
os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))),
"resources",
"agent_assistant_file_manipulation",
"sales.csv",
)
try:
# Upload the CSV file to the agent service
file = await client.agents.files.upload_and_poll(file_path=csv_file_path, purpose=FilePurpose.AGENTS)
# Create the AzureAI Agent from the YAML spec
# Note: the extras can be provided in the short-format (shown below) or
# in the long-format (as shown in the YAML spec, with the `AzureAI:` prefix).
# The short-format is used here for brevity
agent: AzureAIAgent = await AgentRegistry.create_from_yaml(
yaml_str=spec,
client=client,
settings=settings,
extras={"FileId1": file.id},
)
# Define the task for the agent
TASK = "Give me the code to calculate the total sales for all segments."
print(f"# User: '{TASK}'")
# Invoke the agent for the specified task
is_code = False
last_role = None
async for response in agent.invoke_stream(
messages=TASK,
):
current_is_code = response.metadata.get("code", False)
if current_is_code:
if not is_code:
print("\n\n```python")
is_code = True
print(response.content, end="", flush=True)
else:
if is_code:
print("\n```")
is_code = False
last_role = None
if hasattr(response, "role") and response.role is not None and last_role != response.role:
print(f"\n# {response.role}: ", end="", flush=True)
last_role = response.role
print(response.content, end="", flush=True)
if is_code:
print("```\n")
print()
finally:
# Cleanup: Delete the thread and agent
await client.agents.delete_agent(agent.id)
await client.agents.files.delete(file.id)
"""
Sample output:
# User: 'Give me the code to calculate the total sales for all segments.'
# AuthorRole.ASSISTANT: Let me first examine the contents of the uploaded file to determine its structure. This
will allow me to create the appropriate code for calculating the total sales for all segments. Hang tight!
```python
import pandas as pd
# Load the uploaded file to examine its contents
file_path = '/mnt/data/assistant-3nXizu2EX2EwXikUz71uNc'
data = pd.read_csv(file_path)
# Display the first few rows and column names to understand the structure of the dataset
data.head(), data.columns
```
# AuthorRole.ASSISTANT: The dataset contains several columns, including `Segment`, `Sales`, and others such as
`Country`, `Product`, and date-related information. To calculate the total sales for all segments, we will:
1. Group the data by the `Segment` column.
2. Sum the `Sales` column for each segment.
3. Calculate the grand total of all sales across all segments.
Here is the code snippet for this task:
```python
# Group by 'Segment' and sum up 'Sales'
segment_sales = data.groupby('Segment')['Sales'].sum()
# Calculate the total sales across all segments
total_sales = segment_sales.sum()
print("Total Sales per Segment:")
print(segment_sales)
print(f"\nGrand Total Sales: {total_sales}")
```
Would you like me to execute this directly for the uploaded data?
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,96 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from azure.ai.agents.models import VectorStore
from azure.identity.aio import AzureCliCredential
from semantic_kernel.agents import AgentRegistry, AzureAIAgent, AzureAIAgentSettings
"""
The following sample demonstrates how to create an Azure AI agent that answers
user questions using the file search tool from a declarative spec.
"""
# Define the YAML string for the sample
spec = """
type: foundry_agent
name: FileSearchAgent
description: Agent with file search tool.
instructions: >
Use the file search tool to answer questions from the user.
model:
id: ${AzureAI:ChatModelId}
connection:
endpoint: ${AzureAI:Endpoint}
tools:
- type: file_search
options:
vector_store_ids:
- ${AzureAI:VectorStoreId}
"""
settings = AzureAIAgentSettings() # ChatModelId & Endpoint come from .env/env vars
async def main():
async with (
AzureCliCredential() as creds,
AzureAIAgent.create_client(credential=creds) as client,
):
# Read and upload the file to the Azure AI agent service
pdf_file_path = os.path.join(
os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))),
"resources",
"file_search",
"employees.pdf",
)
# Upload the pdf file to the agent service
file = await client.agents.files.upload_and_poll(file_path=pdf_file_path, purpose="assistants")
vector_store: VectorStore = await client.agents.vector_stores.create(file_ids=[file.id], name="my_vectorstore")
try:
# Create the AzureAI Agent from the YAML spec
# Note: the extras can be provided in the short-format (shown below) or
# in the long-format (as shown in the YAML spec, with the `AzureAI:` prefix).
# The short-format is used here for brevity
agent: AzureAIAgent = await AgentRegistry.create_from_yaml(
yaml_str=spec,
client=client,
settings=settings,
extras={"VectorStoreId": vector_store.id},
)
# Define the task for the agent
TASK = "Who can help me if I have a sales question?"
print(f"# User: '{TASK}'")
# Invoke the agent for the specified task
async for response in agent.invoke(
messages=TASK,
):
print(f"# {response.name}: {response}")
finally:
# Cleanup: Delete the agent, vector store, and file
await client.agents.delete_agent(agent.id)
await client.agents.vector_stores.delete(vector_store.id)
await client.agents.files.delete(file.id)
"""
Sample output:
# User: 'Who can help me if I have a sales question?'
# FileSearchAgent: If you have a sales question, you may contact the following individuals:
1. **Hicran Bea** - Sales Manager
2. **Mariam Jaslyn** - Sales Representative
3. **Angelino Embla** - Sales Representative
This information comes from the employee records【4:0†source】.
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,90 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from typing import Annotated
from azure.identity.aio import AzureCliCredential
from semantic_kernel.agents import AgentRegistry, AzureAIAgent, AzureAIAgentSettings, AzureAIAgentThread
from semantic_kernel.functions.kernel_function_decorator import kernel_function
"""
The following sample demonstrates how to create an Azure AI agent that answers
user questions. The sample shows how to load a declarative spec from a file.
The plugins/functions must already exist in the kernel.
They are not created declaratively via the spec.
"""
class MenuPlugin:
"""A sample Menu Plugin used for the concept sample."""
@kernel_function(description="Provides a list of specials from the menu.")
def get_specials(self) -> Annotated[str, "Returns the specials from the menu."]:
return """
Special Soup: Clam Chowder
Special Salad: Cobb Salad
Special Drink: Chai Tea
"""
@kernel_function(description="Provides the price of the requested menu item.")
def get_item_price(
self, menu_item: Annotated[str, "The name of the menu item."]
) -> Annotated[str, "Returns the price of the menu item."]:
return "$9.99"
async def main():
async with (
AzureCliCredential() as creds,
AzureAIAgent.create_client(credential=creds) as client,
):
try:
# Define the YAML file path for the sample
file_path = os.path.join(
os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))),
"resources",
"declarative_spec",
"spec.yaml",
)
# Create the AzureAI Agent from the YAML spec
agent: AzureAIAgent = await AgentRegistry.create_from_file(
file_path,
plugins=[MenuPlugin()],
client=client,
settings=AzureAIAgentSettings(), # The Spec's ChatModelId & Endpoint come from .env/env vars
)
# Create the agent
user_inputs = [
"Hello",
"What is the special soup?",
"How much does that cost?",
"Thank you",
]
# Create a thread for the agent
# If no thread is provided, a new thread will be
# created and returned with the initial response
thread: AzureAIAgentThread | None = None
for user_input in user_inputs:
print(f"# User: '{user_input}'")
# Invoke the agent for the specified task
async for response in agent.invoke(
messages=user_input,
thread=thread,
):
print(f"# {response.name}: {response}")
# Store the thread for the next iteration
thread = response.thread
finally:
# Cleanup: Delete the thread and agent
await client.agents.delete_agent(agent.id) if agent else None
await thread.delete() if thread else None
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,196 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from azure.identity.aio import AzureCliCredential
from semantic_kernel.agents import AgentRegistry, AzureAIAgent, AzureAIAgentSettings
"""
The following sample demonstrates how to create an Azure AI agent that answers
user questions using the OpenAPI tool. The agent is then used to answer user
questions that leverage a free weather API.
"""
# Toggle between a JSON or a YAML OpenAPI spec
USE_JSON_OPENAPI_SPEC = True
json_openapi_spec = """
type: foundry_agent
name: WeatherAgent
instructions: Answer questions about the weather. For all other questions politely decline to answer.
description: This agent answers question about the weather.
model:
id: ${AzureAI:ChatModelId}
connection:
endpoint: ${AzureAI:Endpoint}
options:
temperature: 0.4
tools:
- type: openapi
id: GetCurrentWeather
description: Retrieves current weather data for a location based on wttr.in.
options:
specification: |
{
"openapi": "3.1.0",
"info": {
"title": "Get Weather Data",
"description": "Retrieves current weather data for a location based on wttr.in.",
"version": "v1.0.0"
},
"servers": [
{
"url": "https://wttr.in"
}
],
"auth": [],
"paths": {
"/{location}": {
"get": {
"description": "Get weather information for a specific location",
"operationId": "GetCurrentWeather",
"parameters": [
{
"name": "location",
"in": "path",
"description": "City or location to retrieve the weather for",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "format",
"in": "query",
"description": "Always use j1 value for this parameter",
"required": true,
"schema": {
"type": "string",
"default": "j1"
}
}
],
"responses": {
"200": {
"description": "Successful response",
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
}
},
"404": {
"description": "Location not found"
}
},
"deprecated": false
}
}
},
"components": {
"schemes": {}
}
}
"""
yaml_openapi_spec = """
type: foundry_agent
name: WeatherAgent
instructions: Answer questions about the weather. For all other questions politely decline to answer.
description: This agent answers question about the weather.
model:
id: ${AzureAI:ChatModelId}
options:
temperature: 0.4
tools:
- type: openapi
id: GetCurrentWeather
description: Retrieves current weather data for a location based on wttr.in.
options:
specification:
openapi: "3.1.0"
info:
title: "Get Weather Data"
description: "Retrieves current weather data for a location based on wttr.in."
version: "v1.0.0"
servers:
- url: "https://wttr.in"
auth: []
paths:
"/{location}":
get:
description: "Get weather information for a specific location"
operationId: "GetCurrentWeather"
parameters:
- name: "location"
in: "path"
description: "City or location to retrieve the weather for"
required: true
schema:
type: "string"
- name: "format"
in: "query"
description: "Always use j1 value for this parameter"
required: true
schema:
type: "string"
default: "j1"
responses:
"200":
description: "Successful response"
content:
text/plain:
schema:
type: "string"
"404":
description: "Location not found"
deprecated: false
components:
schemes: {}
"""
settings = AzureAIAgentSettings() # ChatModelId & Endpoint come from .env/env vars
async def main():
async with (
AzureCliCredential() as creds,
AzureAIAgent.create_client(credential=creds) as client,
):
try:
# Create the AzureAI Agent from the YAML spec
agent: AzureAIAgent = await AgentRegistry.create_from_yaml(
yaml_str=json_openapi_spec if USE_JSON_OPENAPI_SPEC else yaml_openapi_spec,
client=client,
settings=settings,
)
# Define the task for the agent
TASK = "What is the current weather in Seoul?"
print(f"# User: '{TASK}'")
# Invoke the agent for the specified task
async for response in agent.invoke(
messages=TASK,
):
print(f"# {response.name}: {response}")
finally:
# Cleanup: Delete the agent, vector store, and file
await client.agents.delete_agent(agent.id)
"""
Sample output:
# User: 'What is the current weather in Seoul?'
# WeatherAgent: The current weather in Seoul is 14°C (57°F) with "light drizzle." It feels like 13°C (55°F).
The humidity is at 81%, and there is heavy cloud cover (99%). The visibility is reduced to 2 km (1 mile),
and the wind is coming from the east at 11 km/h (7 mph)
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,72 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from azure.identity.aio import AzureCliCredential
from semantic_kernel.agents import AgentRegistry, AzureAIAgent
"""
The following sample demonstrates how to create an Azure AI Agent that invokes
a story generation task using a prompt template and a declarative spec.
"""
# Define the YAML string for the sample
spec = """
type: foundry_agent
name: StoryAgent
description: An agent that generates a story about a topic.
instructions: Tell a story about {{$topic}} that is {{$length}} sentences long.
model:
id: ${AzureAI:ChatModelId}
connection:
connection_string: ${AzureAI:Endpoint}
inputs:
topic:
description: The topic of the story.
required: true
default: Cats
length:
description: The number of sentences in the story.
required: true
default: 2
outputs:
output1:
description: The generated story.
template:
format: semantic-kernel
"""
async def main():
async with (
AzureCliCredential() as creds,
AzureAIAgent.create_client(credential=creds) as client,
):
try:
# Create the AzureAI Agent from the YAML spec
agent: AzureAIAgent = await AgentRegistry.create_from_yaml(
yaml_str=spec,
client=client,
)
# Invoke the agent for the specified task
async for response in agent.invoke(
messages=None,
):
print(f"# {response.name}: {response}")
finally:
# Cleanup: Delete the agent, vector store, and file
await client.agents.delete_agent(agent.id)
"""
Sample output:
# StoryAgent: Under the silvery moon, three mischievous cats tiptoed across the rooftop, chasing
shadows and sharing secret whispers. By dawn, they curled up together, purring softly, dreaming
of adventures yet to come.
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,69 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from azure.identity.aio import AzureCliCredential
from semantic_kernel.agents import AgentRegistry, AzureAIAgent
"""
The following sample demonstrates how to create an Azure AI agent based
on an existing agent ID.
"""
# Define the YAML string for the sample
spec = """
id: ${AzureAI:AgentId}
type: foundry_agent
instructions: You are helpful agent who always responds in French.
"""
async def main():
async with (
AzureCliCredential() as creds,
AzureAIAgent.create_client(credential=creds) as client,
):
try:
# Create the AzureAI Agent from the YAML spec
# Note: the extras can be provided in the short-format (shown below) or
# in the long-format (as shown in the YAML spec, with the `AzureAI:` prefix).
# The short-format is used here for brevity
agent: AzureAIAgent = await AgentRegistry.create_from_yaml(
yaml_str=spec,
client=client,
extras={"AgentId": "<my-agent-id>"}, # Specify the existing agent ID
)
# Define the task for the agent
TASK = "Why is the sky blue?"
print(f"# User: '{TASK}'")
# Invoke the agent for the specified task
async for response in agent.invoke(
messages=TASK,
):
print(f"# {response.name}: {response}")
finally:
# Cleanup: Delete the thread and agent
await client.agents.delete_agent(agent.id)
"""
Sample output:
# User: 'Why is the sky blue?'
# WeatherAgent: Le ciel est bleu à cause d'un phénomène appelé **diffusion de Rayleigh**. La lumière du
Soleil est composée de toutes les couleurs du spectre visible, mais lorsqu'elle traverse l'atmosphère
terrestre, elle entre en contact avec les molécules d'air et les particules présentes.
Les couleurs à courtes longueurs d'onde, comme le bleu et le violet, sont diffusées dans toutes les directions
beaucoup plus efficacement que les couleurs à longues longueurs d'onde, comme le rouge et l'orange. Bien que le
violet ait une longueur d'onde encore plus courte que le bleu, nos yeux sont moins sensibles à cette couleur,
et une partie du violet est également absorbée par la haute atmosphère. Ainsi, le bleu domine, donnant au ciel
sa couleur caractéristique.
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,155 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from azure.ai.agents.models import DeepResearchTool
from azure.identity.aio import AzureCliCredential
from semantic_kernel.agents import AzureAIAgent, AzureAIAgentSettings, AzureAIAgentThread
from semantic_kernel.contents import (
ChatMessageContent,
FunctionCallContent,
FunctionResultContent,
StreamingAnnotationContent,
)
"""
The following sample demonstrates how to create an AzureAIAgent along
with the Deep Research Tool. Please visit the following documentation for more info
on what is required to run the sample: https://aka.ms/agents-deep-research. Please pay
attention to the purple `Note` boxes in the Azure docs.
Note that when you use your Bing Connection ID, it needs to be the connection ID from the project, not the resource.
It has the following format:
'/subscriptions/<sub_id>/resourceGroups/<rg_name>/providers/<provider_name>/accounts/<account_name>/projects/<project_name>/connections/<connection_name>'
"""
TASK = (
"Research the current state of studies on orca intelligence and orca language, "
"including what is currently known about orcas' cognitive capabilities and communication systems."
)
async def handle_intermediate_messages(message: ChatMessageContent) -> None:
for item in message.items or []:
if isinstance(item, FunctionResultContent):
print(f"Function Result:> {item.result} for function: {item.name}")
elif isinstance(item, FunctionCallContent):
print(f"Function Call:> {item.name} with arguments: {item.arguments}")
elif isinstance(item, StreamingAnnotationContent):
label = item.title or item.url or "Annotation"
print(f"Annotation:> {label} ({item.citation_type}) -> {item.url}")
else:
print(f"{item}")
async def main() -> None:
async with (
AzureCliCredential() as creds,
AzureAIAgent.create_client(credential=creds) as client,
):
azure_ai_agent_settings = AzureAIAgentSettings()
# 1. Define the Deep Research tool
deep_research_tool = DeepResearchTool(
bing_grounding_connection_id=azure_ai_agent_settings.bing_connection_id,
deep_research_model=azure_ai_agent_settings.deep_research_model,
)
# 2. Create an agent with the tool on the Azure AI agent service
agent_definition = await client.agents.create_agent(
model="gpt-4o", # Deep Research requires the use of gpt-4o for scope clarification.
tools=deep_research_tool.definitions,
instructions="You are a helpful Agent that assists in researching scientific topics.",
)
# 3. Create a Semantic Kernel agent for the Azure AI agent
agent = AzureAIAgent(client=client, definition=agent_definition, name="DeepResearchAgent")
# 4. Create a thread for the agent
# If no thread is provided, a new thread will be
# created and returned with the initial response
thread: AzureAIAgentThread | None = None
try:
print(f"# User: '{TASK}'")
# 5. Invoke the agent for the specified thread for response
first_chunk = True
async for response in agent.invoke_stream(
messages=TASK,
thread=thread,
on_intermediate_message=handle_intermediate_messages,
):
if first_chunk:
print(f"# {response.name}: ", end="", flush=True)
first_chunk = False
# Print the text chunk
print(f"{response}", end="", flush=True)
# Print any streaming annotations that may arrive in this chunk
for item in response.items or []:
if isinstance(item, StreamingAnnotationContent):
label = item.title or item.url or (item.quote or "Annotation")
print(f"\n[Annotation] {label} -> {item.url}")
thread = response.thread
print()
finally:
# 6. Cleanup: Delete the thread, agent, and file
await thread.delete() if thread else None
await client.agents.delete_agent(agent.id)
"""
Sample Output:
# User: 'Research the current state of studies on orca intelligence and orca language, including what is
currently known about orcas' cognitive capabilities and communication systems.'
Function Call:> deep_research with arguments: {'input': '{"prompt": "Research the current state of studies on
orca intelligence and orca communication, focusing on their cognitive capabilities and language systems.
Provide an overview of key discoveries, critical experiments, and major conclusions about their
intelligence and communication systems. Prioritize primary research papers, reputable academic sources,
and recent updates in the field (from the past 5 years if available). Format as a structured report with
appropriate headings for clarity, and respond in English."}'}
# azure_agent_QhTQHlUs: Title: Current Studies on Orca Intelligence and Communication
Starting deep research...
The user's task is to research orca intelligence, focusing on cognitive capabilities and communication.
【1†Bing Search】
[Annotation] Bing Search: 'orca communication research 2020 killer whale cognitive study' -> https://www.bing.com/search?q=orca%20communication%20research%202020%20killer%20whale%20cognitive%20study
**Weighing options**
I'm examining the research on orca social dynamics, comparing a potential review to a recent journal article
on large-scale unsupervised clustering of orca calls.
**Investigating orca datasets**
OK, let me see. PDF, Interspeech 2020, "ORCA-CLEAN: A Deep Denoising Toolkit for Killer Whale Communication"
seems relevant. They focus on cognitive capabilities, language systems, and communication.
I'm considering if the PDF is relevant and may not need it. ResearchGate's content might need a login
to access. 【1†Bing Search】
[Annotation] Bing Search: '"Social Dynamics and Intelligence of Killer Whales (Orcinus orca)"' -> https://www.bing.com/search?q=%22Social%20Dynamics%20and%20Intelligence%20of%20Killer%20Whales%20%28Orcinus%20orca%29%22
**Evaluating sources**
I'm gathering info on "Social Dynamics and Intelligence of Killer Whales," weighing access to PDFs through
ResearchGate, and considering associated online references for credibility.
**Considering capabilities**
I'm piecing together the intricacies of killer whale creativity under chemical stimuli, as explored
in "Manitzas, Hill, et al 2022." Would love to learn more about their findings.
**Exploring external options**
I'm weighing opening the PDF directly or using an external search. 【1†Bing Search】
[Annotation] Bing Search: 'Manitzas Hill 2022 killer whale creativity cognitive abilities' -> https://www.bing.com/search?q=Manitzas%20Hill%202022%20killer%20whale%20creativity%20cognitive%20abilities
...
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,88 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from azure.ai.agents.models import CodeInterpreterTool, FilePurpose
from azure.identity.aio import AzureCliCredential
from semantic_kernel.agents import AzureAIAgent, AzureAIAgentSettings, AzureAIAgentThread
from semantic_kernel.contents.annotation_content import AnnotationContent
from semantic_kernel.contents.utils.author_role import AuthorRole
"""
The following sample demonstrates how to create a simple,
Azure AI agent that uses the code interpreter tool to answer
a coding question.
"""
async def main() -> None:
ai_agent_settings = AzureAIAgentSettings()
async with (
AzureCliCredential() as creds,
AzureAIAgent.create_client(credential=creds, endpoint=ai_agent_settings.endpoint) as client,
):
csv_file_path = os.path.join(
os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))),
"resources",
"agent_assistant_file_manipulation",
"sales.csv",
)
file = await client.agents.files.upload_and_poll(file_path=csv_file_path, purpose=FilePurpose.AGENTS)
code_interpreter = CodeInterpreterTool(file_ids=[file.id])
# Create agent definition
agent_definition = await client.agents.create_agent(
model=ai_agent_settings.model_deployment_name,
tools=code_interpreter.definitions,
tool_resources=code_interpreter.resources,
)
# Create the AzureAI Agent
agent = AzureAIAgent(
client=client,
definition=agent_definition,
)
# Create a thread for the agent
# If no thread is provided, a new thread will be
# created and returned with the initial response
thread: AzureAIAgentThread = None
user_inputs = [
"Which segment had the most sales?",
"List the top 5 countries that generated the most profit.",
"Create a tab delimited file report of profit by each country per month.",
]
try:
for user_input in user_inputs:
print(f"# User: '{user_input}'")
# Invoke the agent for the specified user input
async for response in agent.invoke(messages=user_input, thread=thread):
if response.role != AuthorRole.TOOL:
print(f"# Agent: {response}")
if len(response.items) > 0:
for item in response.items:
# Show Annotation Content if it exist
if isinstance(item, AnnotationContent):
print(f"\n`{item.quote}` => {item.file_id}")
response_content = await client.agents.get_file_content(file_id=item.file_id)
content_bytes = bytearray()
async for chunk in response_content:
content_bytes.extend(chunk)
tab_delimited_text = content_bytes.decode("utf-8")
print(tab_delimited_text)
thread = response.thread
finally:
# Cleanup: Delete the thread and agent
await thread.delete() if thread else None
await client.agents.delete_agent(agent.id)
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,121 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from azure.ai.agents.models import McpTool
from azure.identity.aio import AzureCliCredential
from semantic_kernel.agents import AzureAIAgent, AzureAIAgentSettings, AzureAIAgentThread
from semantic_kernel.contents import ChatMessageContent, FunctionCallContent, FunctionResultContent
"""
The following sample demonstrates how to create a simple, Azure AI agent that
uses the mcp tool to connect to an mcp server with streaming responses.
"""
TASK = "Please summarize the Azure REST API specifications Readme"
async def handle_intermediate_messages(message: ChatMessageContent) -> None:
for item in message.items or []:
if isinstance(item, FunctionResultContent):
print(f"Function Result:> {item.result} for function: {item.name}")
elif isinstance(item, FunctionCallContent):
print(f"Function Call:> {item.name} with arguments: {item.arguments}")
else:
print(f"{item}")
async def main() -> None:
async with (
AzureCliCredential() as creds,
AzureAIAgent.create_client(credential=creds) as client,
):
# 1. Define the MCP tool with the server URL
mcp_tool = McpTool(
server_label="github",
server_url="https://gitmcp.io/Azure/azure-rest-api-specs",
allowed_tools=[], # Specify allowed tools if needed
)
# Optionally you may configure to require approval
# Allowed values are "never" or "always"
mcp_tool.set_approval_mode("never")
# 2. Create an agent with the MCP tool on the Azure AI agent service
agent_definition = await client.agents.create_agent(
model=AzureAIAgentSettings().model_deployment_name,
tools=mcp_tool.definitions,
instructions="You are a helpful agent that can use MCP tools to assist users.",
)
# 3. Create a Semantic Kernel agent for the Azure AI agent
agent = AzureAIAgent(
client=client,
definition=agent_definition,
)
# 4. Create a thread for the agent
# If no thread is provided, a new thread will be
# created and returned with the initial response
thread: AzureAIAgentThread | None = None
try:
print(f"# User: '{TASK}'")
# 5. Invoke the agent for the specified thread for response
async for response in agent.invoke_stream(
messages=TASK,
thread=thread,
on_intermediate_message=handle_intermediate_messages,
):
print(f"{response}", end="", flush=True)
thread = response.thread
finally:
# 6. Cleanup: Delete the thread, agent, and file
await thread.delete() if thread else None
await client.agents.delete_agent(agent.id)
"""
Sample Output:
# User: 'Please summarize the Azure REST API specifications Readme'
Function Call:> fetch_azure_rest_api_docs with arguments: {}
The Azure REST API specifications Readme provides comprehensive documentation and guidelines for designing,
authoring, validating, and evolving Azure REST APIs. It covers key areas including:
1. Breaking changes and versioning: Guidelines to manage API changes that break backward compatibility, when to
increment API versions, and how to maintain smooth API evolution.
2. OpenAPI/Swagger specifications: How to author REST APIs using OpenAPI specification 2.0 (Swagger), including
structure, conventions, validation tools, and extensions used by AutoRest for generating client SDKs.
3. TypeSpec language: Introduction to TypeSpec, a powerful language for describing and generating REST API
specifications and client SDKs with extensibility to other API styles.
4. Directory structure and uniform versioning: Organizing service specifications by teams, resource provider
namespaces, and following uniform versioning to keep API versions consistent across documentation and SDKs.
5. Validation and tooling: Tools and processes like OAV, AutoRest, RESTler, and CI checks used to validate API
specs, generate SDKs, detect breaking changes, lint specifications, and test service contract accuracy.
6. Authoring best practices: Manual and automated guidelines for quality API spec authoring, including writing
effective descriptions, resource modeling, naming conventions, and examples.
7. Code generation configurations: How to configure readme files to generate SDKs for various languages
including .NET, Java, Python, Go, Typescript, and Azure CLI using AutoRest.
8. API Scenarios and testing: Defining API scenario test files for end-to-end REST API workflows, including
variables, ARM template integration, and usage of test-proxy for recording traffic.
9. SDK automation and release requests: Workflows for SDK generation validation, suppressing breaking change
warnings, and requesting official Azure SDK releases.
Overall, the Readme acts as a central hub providing references, guidelines, examples, and tools for maintaining
high-quality Azure REST API specifications and seamless SDK generation across multiple languages and
platforms. It ensures consistent API design, versioning, validation, and developer experience in the Azure
ecosystem.
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,132 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from typing import Annotated
from azure.identity.aio import AzureCliCredential
from semantic_kernel.agents import AzureAIAgent, AzureAIAgentSettings, AzureAIAgentThread
from semantic_kernel.contents import FunctionCallContent, FunctionResultContent
from semantic_kernel.contents.chat_message_content import ChatMessageContent
from semantic_kernel.functions import kernel_function
"""
This sample demonstrates how to create an Azure AI Agent and invoke it using the non-streaming `invoke()` method.
While `invoke()` returns only the final assistant message, the agent can optionally emit intermediate messages
(e.g., function calls and results) via a callback by supplying `on_intermediate_message`.
In this example, the agent is configured with a plugin that provides menu specials and item pricing. As the user
asks about the menu, the agent performs tool calls mid-invocation, and those intermediate steps are surfaced
via the callback function while the invocation is still in progress.
"""
# Define a sample plugin for the sample
class MenuPlugin:
"""A sample Menu Plugin used for the concept sample."""
@kernel_function(description="Provides a list of specials from the menu.")
def get_specials(self) -> Annotated[str, "Returns the specials from the menu."]:
return """
Special Soup: Clam Chowder
Special Salad: Cobb Salad
Special Drink: Chai Tea
"""
@kernel_function(description="Provides the price of the requested menu item.")
def get_item_price(
self, menu_item: Annotated[str, "The name of the menu item."]
) -> Annotated[str, "Returns the price of the menu item."]:
return "$9.99"
# This callback function will be called for each intermediate message,
# which will allow one to handle FunctionCallContent and FunctionResultContent.
# If the callback is not provided, the agent will return the final response
# with no intermediate tool call steps.
async def handle_intermediate_steps(message: ChatMessageContent) -> None:
for item in message.items or []:
if isinstance(item, FunctionResultContent):
print(f"Function Result:> {item.result} for function: {item.name}")
elif isinstance(item, FunctionCallContent):
print(f"Function Call:> {item.name} with arguments: {item.arguments}")
else:
print(f"{item}")
async def main() -> None:
ai_agent_settings = AzureAIAgentSettings()
async with (
AzureCliCredential() as creds,
AzureAIAgent.create_client(credential=creds, endpoint=ai_agent_settings.endpoint) as client,
):
AGENT_NAME = "Host"
AGENT_INSTRUCTIONS = "Answer questions about the menu."
# Create agent definition
agent_definition = await client.agents.create_agent(
model=ai_agent_settings.model_deployment_name,
name=AGENT_NAME,
instructions=AGENT_INSTRUCTIONS,
)
# Create the AzureAI Agent
agent = AzureAIAgent(
client=client,
definition=agent_definition,
plugins=[MenuPlugin()], # add the sample plugin to the agent
)
# Create a thread for the agent
# If no thread is provided, a new thread will be
# created and returned with the initial response
thread: AzureAIAgentThread = None
user_inputs = [
"Hello",
"What is the special soup?",
"How much does that cost?",
"Thank you",
]
try:
for user_input in user_inputs:
print(f"# User: '{user_input}'")
async for response in agent.invoke(
messages=user_input,
thread=thread,
on_intermediate_message=handle_intermediate_steps,
):
print(f"# Agent: {response}")
thread = response.thread
finally:
# Cleanup: Delete the thread and agent
await thread.delete() if thread else None
await client.agents.delete_agent(agent.id)
"""
Sample Output:
# User: 'Hello'
# Agent: Hi there! How can I assist you today?
# User: 'What is the special soup?'
Function Call:> MenuPlugin-get_specials with arguments: {}
Function Result:>
Special Soup: Clam Chowder
Special Salad: Cobb Salad
Special Drink: Chai Tea
for function: MenuPlugin-get_specials
# Agent: The special soup is Clam Chowder. Would you like to know anything else about the menu?
# User: 'How much does that cost?'
Function Call:> MenuPlugin-get_item_price with arguments: {"menu_item":"Clam Chowder"}
Function Result:> $9.99 for function: MenuPlugin-get_item_price
# Agent: The Clam Chowder costs $9.99. Let me know if you'd like assistance with anything else!
# User: 'Thank you'
# Agent: You're welcome! Enjoy your meal! 😊
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,134 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import logging
from typing import Annotated
from azure.identity.aio import AzureCliCredential
from semantic_kernel.agents import AzureAIAgent, AzureAIAgentSettings, AzureAIAgentThread
from semantic_kernel.contents import ChatMessageContent, FunctionCallContent, FunctionResultContent
from semantic_kernel.core_plugins import MathPlugin
from semantic_kernel.functions import kernel_function
"""
This sample demonstrates how to create an Azure AI Agent and use it with the streaming `invoke_stream()` method.
The agent returns assistant messages as a stream of incremental chunks. In addition, you can specify
an `on_intermediate_message` callback to receive fully-formed tool-related messages — such as function
calls and their results — while the assistant response is still being streamed.
In this example, the agent is configured with a plugin that provides menu specials and item pricing.
As the user interacts with the agent, tool messages (like function calls) are emitted via the callback,
while assistant replies stream back incrementally through the main response loop.
"""
logging.basicConfig(level=logging.DEBUG)
# Define a sample plugin for the sample
class MenuPlugin:
"""A sample Menu Plugin used for the concept sample."""
@kernel_function(description="Provides a list of specials from the menu.")
def get_specials(self) -> Annotated[str, "Returns the specials from the menu."]:
return """
Special Soup: Clam Chowder
Special Salad: Cobb Salad
Special Drink: Chai Tea
"""
@kernel_function(description="Provides the price of the requested menu item.")
def get_item_price(
self, menu_item: Annotated[str, "The name of the menu item."]
) -> Annotated[str, "Returns the price of the menu item."]:
return "$9.99"
# This callback function will be called for each intermediate message,
# which will allow one to handle FunctionCallContent and FunctionResultContent.
# If the callback is not provided, the agent will return the final response
# with no intermediate tool call steps.
async def handle_streaming_intermediate_steps(message: ChatMessageContent) -> None:
for item in message.items or []:
if isinstance(item, FunctionResultContent):
print(f"Function Result:> {item.result} for function: {item.name}")
elif isinstance(item, FunctionCallContent):
print(f"Function Call:> {item.name} with arguments: {item.arguments}")
else:
print(f"{item}")
async def main() -> None:
ai_agent_settings = AzureAIAgentSettings()
async with (
AzureCliCredential() as creds,
AzureAIAgent.create_client(credential=creds, endpoint=ai_agent_settings.endpoint) as client,
):
# Create agent definition
agent_definition = await client.agents.create_agent(
model=ai_agent_settings.model_deployment_name,
name="Host",
instructions="Answer questions from the user using your provided functions. You must invoke multiple functions to answer the user's questions. ", # noqa: E501
)
# Create the AzureAI Agent
agent = AzureAIAgent(
client=client,
definition=agent_definition,
plugins=[MenuPlugin(), MathPlugin()],
)
# Create a thread for the agent
# If no thread is provided, a new thread will be
# created and returned with the initial response
thread: AzureAIAgentThread = None
user_inputs = [
"What is the price of the special drink and the special food item added together?",
]
try:
for user_input in user_inputs:
print(f"# User: '{user_input}'")
first_chunk = True
async for response in agent.invoke_stream(
messages=user_input,
thread=thread,
on_intermediate_message=handle_streaming_intermediate_steps,
):
if first_chunk:
print(f"# {response.role}: ", end="", flush=True)
first_chunk = False
print(response.content, end="", flush=True)
thread = response.thread
print()
finally:
# Cleanup: Delete the thread and agent
await thread.delete() if thread else None
await client.agents.delete_agent(agent.id)
"""
Sample Output:
# User: 'What is the price of the special drink and then special food item added together?'
Function Call:> MenuPlugin-get_specials with arguments: {}
Function Result:>
Special Soup: Clam Chowder
Special Salad: Cobb Salad
Special Drink: Chai Tea
for function: MenuPlugin-get_specials
Function Call:> MenuPlugin-get_item_price with arguments: {"menu_item": "Chai Tea"}
Function Call:> MenuPlugin-get_item_price with arguments: {"menu_item": "Clam Chowder"}
Function Result:> $9.99 for function: MenuPlugin-get_item_price
Function Result:> $9.99 for function: MenuPlugin-get_item_price
Function Call:> MathPlugin-Add with arguments: {"input":9.99,"amount":9.99}
Function Result:> 19.98 for function: MathPlugin-Add
# AuthorRole.ASSISTANT: The price of the special drink, Chai Tea, is $9.99 and the price of the special food
item, Clam Chowder, is $9.99. Added together, the total price is $19.98.
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,111 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from azure.identity.aio import AzureCliCredential
from semantic_kernel.agents import AzureAIAgent, AzureAIAgentSettings
from semantic_kernel.functions import KernelArguments
from semantic_kernel.prompt_template import PromptTemplateConfig
"""
The following sample demonstrates how to create an Azure AI
agent using Azure OpenAI within Semantic Kernel.
It uses parameterized prompts and shows how to swap between
"semantic-kernel," "jinja2," and "handlebars" template formats,
This sample highlights the agent's prompt templates are managed
and how kernel arguments are passed in and used.
"""
# Define the inputs and styles to be used in the agent
inputs = [
("Home cooking is great.", None),
("Talk about world peace.", "iambic pentameter"),
("Say something about doing your best.", "e. e. cummings"),
("What do you think about having fun?", "old school rap"),
]
async def invoke_chat_completion_agent(agent: AzureAIAgent, inputs):
"""Invokes the given agent with each (input, style) in inputs."""
thread = None
for user_input, style in inputs:
print(f"[USER]: {user_input}\n")
# If style is specified, override the 'style' argument
argument_overrides = None
if style:
argument_overrides = KernelArguments(style=style)
# Stream agent responses
async for response in agent.invoke_stream(messages=user_input, thread=thread, arguments=argument_overrides):
print(f"{response.content}", end="", flush=True)
thread = response.thread
print("\n")
async def invoke_agent_with_template(template_str: str, template_format: str, default_style: str = "haiku"):
"""Creates an agent with the specified template and format, then invokes it using invoke_chat_completion_agent."""
# Configure the prompt template
prompt_config = PromptTemplateConfig(template=template_str, template_format=template_format)
ai_agent_settings = AzureAIAgentSettings()
async with (
AzureCliCredential() as creds,
AzureAIAgent.create_client(credential=creds, endpoint=ai_agent_settings.endpoint) as client,
):
# Create agent definition
agent_definition = await client.agents.create_agent(
model=ai_agent_settings.model_deployment_name,
name="MyPoetAgent",
)
# Create the AzureAI Agent
agent = AzureAIAgent(
client=client,
definition=agent_definition,
prompt_template_config=prompt_config,
arguments=KernelArguments(style=default_style),
)
await invoke_chat_completion_agent(agent, inputs)
async def main():
# 1) Using "semantic-kernel" format
print("\n===== SEMANTIC-KERNEL FORMAT =====\n")
semantic_kernel_template = """
Write a one verse poem on the requested topic in the style of {{$style}}.
Always state the requested style of the poem.
"""
await invoke_agent_with_template(
template_str=semantic_kernel_template,
template_format="semantic-kernel",
default_style="haiku",
)
# 2) Using "jinja2" format
print("\n===== JINJA2 FORMAT =====\n")
jinja2_template = """
Write a one verse poem on the requested topic in the style of {{style}}.
Always state the requested style of the poem.
"""
await invoke_agent_with_template(template_str=jinja2_template, template_format="jinja2", default_style="haiku")
# 3) Using "handlebars" format
print("\n===== HANDLEBARS FORMAT =====\n")
handlebars_template = """
Write a one verse poem on the requested topic in the style of {{style}}.
Always state the requested style of the poem.
"""
await invoke_agent_with_template(
template_str=handlebars_template, template_format="handlebars", default_style="haiku"
)
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,122 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from typing import Annotated
from azure.identity.aio import AzureCliCredential
from semantic_kernel.agents import AzureAIAgent, AzureAIAgentSettings, AzureAIAgentThread
from semantic_kernel.functions import kernel_function
"""
The following sample demonstrates how to create an Azure AI agent that answers
questions about a sample menu using a Semantic Kernel Plugin. After all questions
are answered, it retrieves and prints the messages from the thread.
"""
# Define a sample plugin for the sample
class MenuPlugin:
"""A sample Menu Plugin used for the concept sample."""
@kernel_function(description="Provides a list of specials from the menu.")
def get_specials(self) -> Annotated[str, "Returns the specials from the menu."]:
return """
Special Soup: Clam Chowder
Special Salad: Cobb Salad
Special Drink: Chai Tea
"""
@kernel_function(description="Provides the price of the requested menu item.")
def get_item_price(
self, menu_item: Annotated[str, "The name of the menu item."]
) -> Annotated[str, "Returns the price of the menu item."]:
return "$9.99"
# Simulate a conversation with the agent
USER_INPUTS = [
"Hello",
"What is the special soup?",
"How much does that cost?",
"Thank you",
]
async def main() -> None:
async with (
AzureCliCredential() as creds,
AzureAIAgent.create_client(credential=creds) as client,
):
# 1. Create an agent on the Azure AI agent service
agent_definition = await client.agents.create_agent(
model=AzureAIAgentSettings().model_deployment_name,
name="Host",
instructions="Answer questions about the menu.",
)
# 2. Create a Semantic Kernel agent for the Azure AI agent
agent = AzureAIAgent(
client=client,
definition=agent_definition,
plugins=[MenuPlugin()], # Add the plugin to the agent
)
# 3. Create a thread for the agent
# If no thread is provided, a new thread will be
# created and returned with the initial response
thread: AzureAIAgentThread | None = None
try:
for user_input in USER_INPUTS:
print(f"# User: {user_input}")
# 4. Invoke the agent for the specified thread for response
async for response in agent.invoke(
messages=user_input,
thread=thread,
):
print(f"# {response.name}: {response}")
thread = response.thread
finally:
# 5. Cleanup: Delete the thread and agent
# await thread.delete() if thread else None
await client.agents.delete_agent(agent.id)
print("*" * 50)
print("# Messages in the thread (asc order):\n")
async for msg in thread.get_messages(sort_order="asc"):
print(f"# {msg.role} for name={msg.name}: {msg.content}")
print("*" * 50)
await thread.delete() if thread else None
"""
# User: Hello
# Host: Hello! How can I assist you with the menu today?
# User: What is the special soup?
# Host: The special soup today is Clam Chowder. Would you like to know more about it or anything else
on the menu?
# User: How much does that cost?
# Host: The Clam Chowder costs $9.99. Would you like to order it or need information on other items?
# User: Thank you
# Host: You're welcome! If you have any more questions or need assistance with the menu, feel free to ask.
Enjoy your meal!
**************************************************
# Messages in the thread (asc order):
# AuthorRole.USER for name=asst_mXwZOwyJLxXGtaYKHizRH6Ip: Hello
# AuthorRole.ASSISTANT for name=asst_mXwZOwyJLxXGtaYKHizRH6Ip: Hello! How can I assist you with the menu today?
# AuthorRole.USER for name=asst_mXwZOwyJLxXGtaYKHizRH6Ip: What is the special soup?
# AuthorRole.ASSISTANT for name=asst_mXwZOwyJLxXGtaYKHizRH6Ip: The special soup today is Clam Chowder. Would
you like to know more about it or anything else on the menu?
# AuthorRole.USER for name=asst_mXwZOwyJLxXGtaYKHizRH6Ip: How much does that cost?
# AuthorRole.ASSISTANT for name=asst_mXwZOwyJLxXGtaYKHizRH6Ip: The Clam Chowder costs $9.99. Would you like to
order it or need information on other items?
# AuthorRole.USER for name=asst_mXwZOwyJLxXGtaYKHizRH6Ip: Thank you
# AuthorRole.ASSISTANT for name=asst_mXwZOwyJLxXGtaYKHizRH6Ip: You're welcome! If you have any more questions
or need assistance with the menu, feel free to ask. Enjoy your meal!
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,120 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from typing import Annotated
from azure.identity.aio import AzureCliCredential
from semantic_kernel.agents import AzureAIAgent, AzureAIAgentSettings, AzureAIAgentThread
from semantic_kernel.functions import kernel_function
"""
The following sample demonstrates how to create an Azure AI Agent
and use it with streaming responses. The agent is configured to use
a plugin that provides a list of specials from the menu and the price
of the requested menu item. The thread message ID is also printed as each
message is processed.
"""
# Define a sample plugin for the sample
class MenuPlugin:
"""A sample Menu Plugin used for the concept sample."""
@kernel_function(description="Provides a list of specials from the menu.")
def get_specials(self) -> Annotated[str, "Returns the specials from the menu."]:
return """
Special Soup: Clam Chowder
Special Salad: Cobb Salad
Special Drink: Chai Tea
"""
@kernel_function(description="Provides the price of the requested menu item.")
def get_item_price(
self, menu_item: Annotated[str, "The name of the menu item."]
) -> Annotated[str, "Returns the price of the menu item."]:
return "$9.99"
async def main() -> None:
ai_agent_settings = AzureAIAgentSettings()
async with (
AzureCliCredential() as creds,
AzureAIAgent.create_client(credential=creds, endpoint=ai_agent_settings.endpoint) as client,
):
AGENT_NAME = "Host"
AGENT_INSTRUCTIONS = "Answer questions about the menu."
# Create agent definition
agent_definition = await client.agents.create_agent(
model=ai_agent_settings.model_deployment_name,
name=AGENT_NAME,
instructions=AGENT_INSTRUCTIONS,
)
# Create the AzureAI Agent
agent = AzureAIAgent(
client=client,
definition=agent_definition,
plugins=[MenuPlugin()], # add the sample plugin to the agent
)
# Create a thread for the agent
# If no thread is provided, a new thread will be
# created and returned with the initial response
thread: AzureAIAgentThread = None
user_inputs = [
"Hello",
"What is the special soup?",
"How much does that cost?",
"Thank you",
]
try:
last_thread_msg_id = None
for user_input in user_inputs:
print(f"# User: '{user_input}'")
first_chunk = True
async for response in agent.invoke_stream(
messages=user_input,
thread=thread,
):
if first_chunk:
print(f"# {response.role}: ", end="", flush=True)
# Show the thread message id before the first text chunk
if "thread_message_id" in response.content.metadata:
current_id = response.content.metadata["thread_message_id"]
if current_id != last_thread_msg_id:
print(f"(thread message id: {current_id}) ", end="", flush=True)
last_thread_msg_id = current_id
first_chunk = False
print(response.content, end="", flush=True)
thread = response.thread
print()
finally:
# Cleanup: Delete the thread and agent
await thread.delete() if thread else None
await client.agents.delete_agent(agent.id)
"""
Sample Output:
# User: 'Hello'
# AuthorRole.ASSISTANT: (thread message id: msg_HZ2h4Wzbj7GEcnVCjnyEuYWT) Hello! How can I assist you with
the menu today?
# User: 'What is the special soup?'
# AuthorRole.ASSISTANT: (thread message id: msg_TSjkJK6hHJojIkPvF6uUofHD) The special soup today is
Clam Chowder. Would you like to know more about it or anything else from the menu?
# User: 'How much does that cost?'
# AuthorRole.ASSISTANT: (thread message id: msg_liwTpBFrB9JpCM1oM9EXKiwq) The Clam Chowder costs $9.99.
Is there anything else you'd like to know?
# User: 'Thank you'
# AuthorRole.ASSISTANT: (thread message id: msg_K6lpR3gYIHethXq17T6gJcxi) You're welcome!
If you have any more questions or need assistance, feel free to ask. Enjoy your meal!
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,93 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from enum import Enum
from azure.ai.agents.models import (
ResponseFormatJsonSchema,
ResponseFormatJsonSchemaType,
)
from azure.identity.aio import AzureCliCredential
from pydantic import BaseModel
from semantic_kernel.agents import (
AzureAIAgent,
AzureAIAgentSettings,
)
"""
The following sample demonstrates how to create an Azure AI Agent
and leverage the agent's ability to return structured outputs,
based on a user-defined Pydantic model.
"""
# Define a Pydantic model that represents the structured output from the agent
class Planets(str, Enum):
Earth = "Earth"
Mars = "Mars"
Jupyter = "Jupyter"
class Planet(BaseModel):
planet: Planets
mass: float
async def main():
ai_agent_settings = AzureAIAgentSettings()
async with (
AzureCliCredential() as creds,
AzureAIAgent.create_client(credential=creds, endpoint=ai_agent_settings.endpoint) as client,
):
# Create the agent definition
agent_definition = await client.agents.create_agent(
model=ai_agent_settings.model_deployment_name,
name="Assistant",
instructions="Extract the information about planets.",
response_format=ResponseFormatJsonSchemaType(
json_schema=ResponseFormatJsonSchema(
name="planet_mass",
description="Extract planet mass.",
schema=Planet.model_json_schema(),
)
),
)
# Create the AzureAI Agent
agent = AzureAIAgent(
client=client,
definition=agent_definition,
)
# Create a new thread for use with the assistant
# If no thread is provided, a new thread will be
# created and returned with the initial response
thread = None
user_inputs = ["The mass of the Mars is 6.4171E23 kg; the mass of the Earth is 5.972168E24 kg;"]
try:
for user_input in user_inputs:
print(f"# User: '{user_input}'")
async for response in agent.invoke(messages=user_input, thread=thread):
# The response returned is a Pydantic Model, so we can validate it using the
# model_validate_json method
response_model = Planet.model_validate_json(str(response.content))
print(f"# {response.role}: {response_model}")
thread = response.thread
finally:
await thread.delete() if thread else None
await client.agents.delete_agent(agent_definition.id)
"""
Sample Output:
# User: 'The mass of the Mars is 6.4171E23 kg; the mass of the Earth is 5.972168E24 kg;'
# AuthorRole.ASSISTANT: planet=<Planets.Earth: 'Earth'> mass=5.972168e+24
# AuthorRole.ASSISTANT: planet=<Planets.Mars: 'Mars'> mass=6.4171e+23
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,82 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from azure.ai.agents.models import TruncationObject
from azure.identity.aio import AzureCliCredential
from semantic_kernel.agents import (
AzureAIAgent,
AzureAIAgentSettings,
AzureAIAgentThread,
)
"""
The following sample demonstrates how to create an Azure AI Agent Agent
and configure a truncation strategy for the agent.
"""
USER_INPUTS = [
"Why is the sky blue?",
"What is the speed of light?",
"What have we been talking about?",
]
async def main() -> None:
ai_agent_settings = AzureAIAgentSettings.create()
async with (
AzureCliCredential() as creds,
AzureAIAgent.create_client(credential=creds, endpoint=ai_agent_settings.endpoint) as client,
):
# Create the agent definition
agent_definition = await client.agents.create_agent(
model=ai_agent_settings.model_deployment_name,
name="TruncateAgent",
instructions="You are a helpful assistant that answers user questions in one sentence.",
)
# Create the AzureAI Agent
agent = AzureAIAgent(
client=client,
definition=agent_definition,
)
thread: AzureAIAgentThread | None = None
# Options are "auto" or "last_messages"
# If using "last_messages", specify the number of messages to keep with `last_messages` kwarg
truncation_strategy = TruncationObject(type="last_messages", last_messages=2)
try:
for user_input in USER_INPUTS:
print(f"# User: {user_input}")
# 4. Invoke the agent with the specified message for response
response = await agent.get_response(
messages=user_input, thread=thread, truncation_strategy=truncation_strategy
)
print(f"# {response.name}: {response}")
thread = response.thread
finally:
# 6. Cleanup: Delete the thread and agent
await thread.delete() if thread else None
await client.agents.delete_agent(agent.id)
"""
Sample Output:
# User: Why is the sky blue?
# TruncateAgent: The sky appears blue because molecules in the Earth's atmosphere scatter sunlight in all
directions, and blue light is scattered more than other colors due to its shorter wavelength.
# User: What is the speed of light?
# TruncateAgent: The speed of light in a vacuum is approximately 299,792,458 meters per second
(or about 186,282 miles per second).
# User: What have we been talking about?
# TruncateAgent: I'm sorry, but I don't have access to previous interactions. Could you remind me what
we've been discussing?
"""
if __name__ == "__main__":
asyncio.run(main())