mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Merge branch 'main' into feature-azure-functions
This commit is contained in:
+14
-14
@@ -21,20 +21,20 @@ This directory contains samples demonstrating the capabilities of Microsoft Agen
|
||||
|
||||
| File | Description |
|
||||
|------|-------------|
|
||||
| [`getting_started/agents/azure_ai/azure_ai_basic.py`](./getting_started/agents/azure_ai/azure_ai_basic.py) | Azure AI Agent Basic Example |
|
||||
| [`getting_started/agents/azure_ai/azure_ai_with_azure_ai_search.py`](./getting_started/agents/azure_ai/azure_ai_with_azure_ai_search.py) | Azure AI Agent with Azure AI Search Example |
|
||||
| [`getting_started/agents/azure_ai/azure_ai_with_bing_grounding.py`](./getting_started/agents/azure_ai/azure_ai_with_bing_grounding.py) | Azure AI agent with Bing Grounding search for real-time web information |
|
||||
| [`getting_started/agents/azure_ai/azure_ai_with_code_interpreter.py`](./getting_started/agents/azure_ai/azure_ai_with_code_interpreter.py) | Azure AI Agent with Code Interpreter Example |
|
||||
| [`getting_started/agents/azure_ai/azure_ai_with_existing_agent.py`](./getting_started/agents/azure_ai/azure_ai_with_existing_agent.py) | Azure AI Agent with Existing Agent Example |
|
||||
| [`getting_started/agents/azure_ai/azure_ai_with_existing_thread.py`](./getting_started/agents/azure_ai/azure_ai_with_existing_thread.py) | Azure AI Agent with Existing Thread Example |
|
||||
| [`getting_started/agents/azure_ai/azure_ai_with_explicit_settings.py`](./getting_started/agents/azure_ai/azure_ai_with_explicit_settings.py) | Azure AI Agent with Explicit Settings Example |
|
||||
| [`getting_started/agents/azure_ai/azure_ai_with_file_search.py`](./getting_started/agents/azure_ai/azure_ai_with_file_search.py) | Azure AI agent with File Search capabilities |
|
||||
| [`getting_started/agents/azure_ai/azure_ai_with_function_tools.py`](./getting_started/agents/azure_ai/azure_ai_with_function_tools.py) | Azure AI Agent with Function Tools Example |
|
||||
| [`getting_started/agents/azure_ai/azure_ai_with_hosted_mcp.py`](./getting_started/agents/azure_ai/azure_ai_with_hosted_mcp.py) | Azure AI Agent with Hosted MCP Example |
|
||||
| [`getting_started/agents/azure_ai/azure_ai_with_local_mcp.py`](./getting_started/agents/azure_ai/azure_ai_with_local_mcp.py) | Azure AI Agent with Local MCP Example |
|
||||
| [`getting_started/agents/azure_ai/azure_ai_with_multiple_tools.py`](./getting_started/agents/azure_ai/azure_ai_with_multiple_tools.py) | Azure AI Agent with Multiple Tools Example |
|
||||
| [`getting_started/agents/azure_ai/azure_ai_with_openapi_tools.py`](./getting_started/agents/azure_ai/azure_ai_with_openapi_tools.py) | Azure AI agent with OpenAPI tools |
|
||||
| [`getting_started/agents/azure_ai/azure_ai_with_thread.py`](./getting_started/agents/azure_ai/azure_ai_with_thread.py) | Azure AI Agent with Thread Management Example |
|
||||
| [`getting_started/agents/azure_ai_agent/azure_ai_basic.py`](./getting_started/agents/azure_ai/azure_ai_basic.py) | Azure AI Agent Basic Example |
|
||||
| [`getting_started/agents/azure_ai_agent/azure_ai_with_azure_ai_search.py`](./getting_started/agents/azure_ai_agent/azure_ai_with_azure_ai_search.py) | Azure AI Agent with Azure AI Search Example |
|
||||
| [`getting_started/agents/azure_ai_agent/azure_ai_with_bing_grounding.py`](./getting_started/agents/azure_ai_agent/azure_ai_with_bing_grounding.py) | Azure AI agent with Bing Grounding search for real-time web information |
|
||||
| [`getting_started/agents/azure_ai_agent/azure_ai_with_code_interpreter.py`](./getting_started/agents/azure_ai_agent/azure_ai_with_code_interpreter.py) | Azure AI Agent with Code Interpreter Example |
|
||||
| [`getting_started/agents/azure_ai_agent/azure_ai_with_existing_agent.py`](./getting_started/agents/azure_ai_agent/azure_ai_with_existing_agent.py) | Azure AI Agent with Existing Agent Example |
|
||||
| [`getting_started/agents/azure_ai_agent/azure_ai_with_existing_thread.py`](./getting_started/agents/azure_ai_agent/azure_ai_with_existing_thread.py) | Azure AI Agent with Existing Thread Example |
|
||||
| [`getting_started/agents/azure_ai_agent/azure_ai_with_explicit_settings.py`](./getting_started/agents/azure_ai_agent/azure_ai_with_explicit_settings.py) | Azure AI Agent with Explicit Settings Example |
|
||||
| [`getting_started/agents/azure_ai_agent/azure_ai_with_file_search.py`](./getting_started/agents/azure_ai_agent/azure_ai_with_file_search.py) | Azure AI agent with File Search capabilities |
|
||||
| [`getting_started/agents/azure_ai_agent/azure_ai_with_function_tools.py`](./getting_started/agents/azure_ai_agent/azure_ai_with_function_tools.py) | Azure AI Agent with Function Tools Example |
|
||||
| [`getting_started/agents/azure_ai_agent/azure_ai_with_hosted_mcp.py`](./getting_started/agents/azure_ai_agent/azure_ai_with_hosted_mcp.py) | Azure AI Agent with Hosted MCP Example |
|
||||
| [`getting_started/agents/azure_ai_agent/azure_ai_with_local_mcp.py`](./getting_started/agents/azure_ai_agent/azure_ai_with_local_mcp.py) | Azure AI Agent with Local MCP Example |
|
||||
| [`getting_started/agents/azure_ai_agent/azure_ai_with_multiple_tools.py`](./getting_started/agents/azure_ai_agent/azure_ai_with_multiple_tools.py) | Azure AI Agent with Multiple Tools Example |
|
||||
| [`getting_started/agents/azure_ai_agent/azure_ai_with_openapi_tools.py`](./getting_started/agents/azure_ai_agent/azure_ai_with_openapi_tools.py) | Azure AI agent with OpenAPI tools |
|
||||
| [`getting_started/agents/azure_ai_agent/azure_ai_with_thread.py`](./getting_started/agents/azure_ai_agent/azure_ai_with_thread.py) | Azure AI Agent with Thread Management Example |
|
||||
|
||||
### Azure OpenAI
|
||||
|
||||
|
||||
@@ -1,25 +1,24 @@
|
||||
# Azure AI Agent Examples
|
||||
|
||||
This folder contains examples demonstrating different ways to create and use agents with the Azure AI chat client from the `agent_framework.azure` package.
|
||||
This folder contains examples demonstrating different ways to create and use agents with the Azure AI client from the `agent_framework.azure` package.
|
||||
|
||||
## Examples
|
||||
|
||||
| File | Description |
|
||||
|------|-------------|
|
||||
| [`azure_ai_basic.py`](azure_ai_basic.py) | The simplest way to create an agent using `ChatAgent` with `AzureAIAgentClient`. It automatically handles all configuration using environment variables. |
|
||||
| [`azure_ai_with_bing_grounding.py`](azure_ai_with_bing_grounding.py) | Shows how to use Bing Grounding search with Azure AI agents to find real-time information from the web. Demonstrates web search capabilities with proper source citations and comprehensive error handling. |
|
||||
| [`azure_ai_with_code_interpreter.py`](azure_ai_with_code_interpreter.py) | Shows how to use the HostedCodeInterpreterTool with Azure AI agents to write and execute Python code. Includes helper methods for accessing code interpreter data from response chunks. |
|
||||
| [`azure_ai_with_existing_agent.py`](azure_ai_with_existing_agent.py) | Shows how to work with a pre-existing agent by providing the agent ID to the Azure AI chat client. This example also demonstrates proper cleanup of manually created agents. |
|
||||
| [`azure_ai_with_existing_thread.py`](azure_ai_with_existing_thread.py) | Shows how to work with a pre-existing thread by providing the thread ID to the Azure AI chat client. This example also demonstrates proper cleanup of manually created threads. |
|
||||
| [`azure_ai_with_explicit_settings.py`](azure_ai_with_explicit_settings.py) | Shows how to create an agent with explicitly configured `AzureAIAgentClient` settings, including project endpoint, model deployment, credentials, and agent name. |
|
||||
| [`azure_ai_with_azure_ai_search.py`](azure_ai_with_azure_ai_search.py) | Demonstrates how to use Azure AI Search with Azure AI agents to search through indexed data. Shows how to configure search parameters, query types, and integrate with existing search indexes. |
|
||||
| [`azure_ai_with_file_search.py`](azure_ai_with_file_search.py) | Demonstrates how to use the HostedFileSearchTool with Azure AI agents to search through uploaded documents. Shows file upload, vector store creation, and querying document content. Includes both streaming and non-streaming examples. |
|
||||
| [`azure_ai_with_function_tools.py`](azure_ai_with_function_tools.py) | Demonstrates how to use function tools with agents. Shows both agent-level tools (defined when creating the agent) and query-level tools (provided with specific queries). |
|
||||
| [`azure_ai_with_hosted_mcp.py`](azure_ai_with_hosted_mcp.py) | Shows how to integrate Azure AI agents with hosted Model Context Protocol (MCP) servers for enhanced functionality and tool integration. Demonstrates remote MCP server connections and tool discovery. |
|
||||
| [`azure_ai_with_local_mcp.py`](azure_ai_with_local_mcp.py) | Shows how to integrate Azure AI agents with local Model Context Protocol (MCP) servers for enhanced functionality and tool integration. Demonstrates both agent-level and run-level tool configuration. |
|
||||
| [`azure_ai_with_multiple_tools.py`](azure_ai_with_multiple_tools.py) | Demonstrates how to use multiple tools together with Azure AI agents, including web search, MCP servers, and function tools. Shows coordinated multi-tool interactions and approval workflows. |
|
||||
| [`azure_ai_with_openapi_tools.py`](azure_ai_with_openapi_tools.py) | Demonstrates how to use OpenAPI tools with Azure AI agents to integrate external REST APIs. Shows OpenAPI specification loading, anonymous authentication, thread context management, and coordinated multi-API conversations using weather and countries APIs. |
|
||||
| [`azure_ai_basic.py`](azure_ai_basic.py) | The simplest way to create an agent using `AzureAIClient`. Demonstrates both streaming and non-streaming responses with function tools. Shows automatic agent creation and basic weather functionality. |
|
||||
| [`azure_ai_use_latest_version.py`](azure_ai_use_latest_version.py) | Demonstrates how to reuse the latest version of an existing agent instead of creating a new agent version on each instantiation using the `use_latest_version=True` parameter. |
|
||||
| [`azure_ai_with_azure_ai_search.py`](azure_ai_with_azure_ai_search.py) | Shows how to use Azure AI Search with Azure AI agents to search through indexed data and answer user questions with proper citations. Requires an Azure AI Search connection and index configured in your Azure AI project. |
|
||||
| [`azure_ai_with_code_interpreter.py`](azure_ai_with_code_interpreter.py) | Shows how to use the `HostedCodeInterpreterTool` with Azure AI agents to write and execute Python code for mathematical problem solving and data analysis. |
|
||||
| [`azure_ai_with_existing_agent.py`](azure_ai_with_existing_agent.py) | Shows how to work with a pre-existing agent by providing the agent name and version to the Azure AI client. Demonstrates agent reuse patterns for production scenarios. |
|
||||
| [`azure_ai_with_existing_conversation.py`](azure_ai_with_existing_conversation.py) | Demonstrates how to use an existing conversation created on the service side with Azure AI agents. Shows two approaches: specifying conversation ID at the client level and using AgentThread with an existing conversation ID. |
|
||||
| [`azure_ai_with_explicit_settings.py`](azure_ai_with_explicit_settings.py) | Shows how to create an agent with explicitly configured `AzureAIClient` settings, including project endpoint, model deployment, and credentials rather than relying on environment variable defaults. |
|
||||
| [`azure_ai_with_file_search.py`](azure_ai_with_file_search.py) | Shows how to use the `HostedFileSearchTool` with Azure AI agents to upload files, create vector stores, and enable agents to search through uploaded documents to answer user questions. |
|
||||
| [`azure_ai_with_hosted_mcp.py`](azure_ai_with_hosted_mcp.py) | Shows how to integrate hosted Model Context Protocol (MCP) tools with Azure AI Agent. |
|
||||
| [`azure_ai_with_response_format.py`](azure_ai_with_response_format.py) | Shows how to use structured outputs (response format) with Azure AI agents using Pydantic models to enforce specific response schemas. |
|
||||
| [`azure_ai_with_thread.py`](azure_ai_with_thread.py) | Demonstrates thread management with Azure AI agents, including automatic thread creation for stateless conversations and explicit thread management for maintaining conversation context across multiple interactions. |
|
||||
| [`azure_ai_with_image_generation.py`](azure_ai_with_image_generation.py) | Shows how to use the `ImageGenTool` with Azure AI agents to generate images based on text prompts. |
|
||||
| [`azure_ai_with_web_search.py`](azure_ai_with_web_search.py) | Shows how to use the `HostedWebSearchTool` with Azure AI agents to perform web searches and retrieve up-to-date information from the internet. |
|
||||
|
||||
## Environment Variables
|
||||
|
||||
@@ -28,27 +27,18 @@ Before running the examples, you need to set up your environment variables. You
|
||||
### Option 1: Using a .env file (Recommended)
|
||||
|
||||
1. Copy the `.env.example` file from the `python` directory to create a `.env` file:
|
||||
|
||||
```bash
|
||||
cp ../../.env.example ../../.env
|
||||
cp ../../../../.env.example ../../../../.env
|
||||
```
|
||||
|
||||
2. Edit the `.env` file and add your values:
|
||||
```
|
||||
|
||||
```env
|
||||
AZURE_AI_PROJECT_ENDPOINT="your-project-endpoint"
|
||||
AZURE_AI_MODEL_DEPLOYMENT_NAME="your-model-deployment-name"
|
||||
```
|
||||
|
||||
3. For samples using Bing Grounding search (like `azure_ai_with_bing_grounding.py` and `azure_ai_with_multiple_tools.py`), you'll also need:
|
||||
```
|
||||
BING_CONNECTION_ID="your-bing-connection-id"
|
||||
```
|
||||
|
||||
To get your Bing connection details:
|
||||
- Go to [Azure AI Foundry portal](https://ai.azure.com)
|
||||
- Navigate to your project's "Connected resources" section
|
||||
- Add a new connection for "Grounding with Bing Search"
|
||||
- Copy the ID
|
||||
|
||||
### Option 2: Using environment variables directly
|
||||
|
||||
Set the environment variables in your shell:
|
||||
@@ -56,7 +46,6 @@ Set the environment variables in your shell:
|
||||
```bash
|
||||
export AZURE_AI_PROJECT_ENDPOINT="your-project-endpoint"
|
||||
export AZURE_AI_MODEL_DEPLOYMENT_NAME="your-model-deployment-name"
|
||||
export BING_CONNECTION_ID="your-bing-connection-id"
|
||||
```
|
||||
|
||||
### Required Variables
|
||||
@@ -64,6 +53,24 @@ export BING_CONNECTION_ID="your-bing-connection-id"
|
||||
- `AZURE_AI_PROJECT_ENDPOINT`: Your Azure AI project endpoint (required for all examples)
|
||||
- `AZURE_AI_MODEL_DEPLOYMENT_NAME`: The name of your model deployment (required for all examples)
|
||||
|
||||
### Optional Variables
|
||||
## Authentication
|
||||
|
||||
- `BING_CONNECTION_ID`: Your Bing connection ID (required for `azure_ai_with_bing_grounding.py` and `azure_ai_with_multiple_tools.py`)
|
||||
All examples use `AzureCliCredential` for authentication by default. Before running the examples:
|
||||
|
||||
1. Install the Azure CLI
|
||||
2. Run `az login` to authenticate with your Azure account
|
||||
3. Ensure you have appropriate permissions to the Azure AI project
|
||||
|
||||
Alternatively, you can replace `AzureCliCredential` with other authentication options like `DefaultAzureCredential` or environment-based credentials.
|
||||
|
||||
## Running the Examples
|
||||
|
||||
Each example can be run independently. Navigate to this directory and run any example:
|
||||
|
||||
```bash
|
||||
python azure_ai_basic.py
|
||||
python azure_ai_with_code_interpreter.py
|
||||
# ... etc
|
||||
```
|
||||
|
||||
The examples demonstrate various patterns for working with Azure AI agents, from basic usage to advanced scenarios like thread management and structured outputs.
|
||||
|
||||
@@ -4,15 +4,15 @@ import asyncio
|
||||
from random import randint
|
||||
from typing import Annotated
|
||||
|
||||
from agent_framework.azure import AzureAIAgentClient
|
||||
from agent_framework.azure import AzureAIClient
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
from pydantic import Field
|
||||
|
||||
"""
|
||||
Azure AI Agent Basic Example
|
||||
|
||||
This sample demonstrates basic usage of AzureAIAgentClient to create agents with automatic
|
||||
lifecycle management. Shows both streaming and non-streaming responses with function tools.
|
||||
This sample demonstrates basic usage of AzureAIClient.
|
||||
Shows both streaming and non-streaming responses with function tools.
|
||||
"""
|
||||
|
||||
|
||||
@@ -28,14 +28,13 @@ async def non_streaming_example() -> None:
|
||||
"""Example of non-streaming response (get the complete result at once)."""
|
||||
print("=== Non-streaming Response Example ===")
|
||||
|
||||
# Since no Agent ID is provided, the agent will be automatically created
|
||||
# and deleted after getting a response
|
||||
# Since no Agent ID is provided, the agent will be automatically created.
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
AzureAIAgentClient(async_credential=credential).create_agent(
|
||||
name="WeatherAgent",
|
||||
AzureAIClient(async_credential=credential).create_agent(
|
||||
name="BasicWeatherAgent",
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
) as agent,
|
||||
@@ -50,19 +49,18 @@ async def streaming_example() -> None:
|
||||
"""Example of streaming response (get results as they are generated)."""
|
||||
print("=== Streaming Response Example ===")
|
||||
|
||||
# Since no Agent ID is provided, the agent will be automatically created
|
||||
# and deleted after getting a response
|
||||
# Since no Agent ID is provided, the agent will be automatically created.
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
AzureAIAgentClient(async_credential=credential).create_agent(
|
||||
name="WeatherAgent",
|
||||
AzureAIClient(async_credential=credential).create_agent(
|
||||
name="BasicWeatherAgent",
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
) as agent,
|
||||
):
|
||||
query = "What's the weather like in Portland?"
|
||||
query = "What's the weather like in Tokyo?"
|
||||
print(f"User: {query}")
|
||||
print("Agent: ", end="", flush=True)
|
||||
async for chunk in agent.run_stream(query):
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
from random import randint
|
||||
from typing import Annotated
|
||||
|
||||
from agent_framework.azure import AzureAIClient
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
from pydantic import Field
|
||||
|
||||
"""
|
||||
Azure AI Agent Latest Version Example
|
||||
|
||||
This sample demonstrates how to reuse the latest version of an existing agent
|
||||
instead of creating a new agent version on each instantiation. The first call creates a new agent,
|
||||
while subsequent calls with `use_latest_version=True` reuse the latest agent version.
|
||||
"""
|
||||
|
||||
|
||||
def get_weather(
|
||||
location: Annotated[str, Field(description="The location to get the weather for.")],
|
||||
) -> str:
|
||||
"""Get the weather for a given location."""
|
||||
conditions = ["sunny", "cloudy", "rainy", "stormy"]
|
||||
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
async with AzureCliCredential() as credential:
|
||||
async with (
|
||||
AzureAIClient(
|
||||
async_credential=credential,
|
||||
).create_agent(
|
||||
name="MyWeatherAgent",
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
) as agent,
|
||||
):
|
||||
# First query will create a new agent
|
||||
query = "What's the weather like in Seattle?"
|
||||
print(f"User: {query}")
|
||||
result = await agent.run(query)
|
||||
print(f"Agent: {result}\n")
|
||||
|
||||
# Create a new agent instance
|
||||
async with (
|
||||
AzureAIClient(
|
||||
async_credential=credential,
|
||||
# This parameter will allow to re-use latest agent version
|
||||
# instead of creating a new one
|
||||
use_latest_version=True,
|
||||
).create_agent(
|
||||
name="MyWeatherAgent",
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
) as agent,
|
||||
):
|
||||
query = "What's the weather like in Tokyo?"
|
||||
print(f"User: {query}")
|
||||
result = await agent.run(query)
|
||||
print(f"Agent: {result}\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -1,120 +1,49 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
|
||||
from agent_framework import ChatAgent, CitationAnnotation
|
||||
from agent_framework.azure import AzureAIAgentClient
|
||||
from azure.ai.agents.aio import AgentsClient
|
||||
from azure.ai.projects.aio import AIProjectClient
|
||||
from azure.ai.projects.models import ConnectionType
|
||||
from agent_framework.azure import AzureAIClient
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
|
||||
"""
|
||||
Azure AI Agent with Azure AI Search Example
|
||||
|
||||
This sample demonstrates how to create an Azure AI agent that uses Azure AI Search
|
||||
to search through indexed hotel data and answer user questions about hotels.
|
||||
This sample demonstrates usage of AzureAIClient with Azure AI Search
|
||||
to search through indexed data and answer user questions about it.
|
||||
|
||||
Prerequisites:
|
||||
1. Set AZURE_AI_PROJECT_ENDPOINT and AZURE_AI_MODEL_DEPLOYMENT_NAME environment variables
|
||||
1. Set AZURE_AI_PROJECT_ENDPOINT and AZURE_AI_MODEL_DEPLOYMENT_NAME environment variables.
|
||||
2. Ensure you have an Azure AI Search connection configured in your Azure AI project
|
||||
3. The search index "hotels-sample-index" should exist in your Azure AI Search service
|
||||
(you can create this using the Azure portal with sample hotel data)
|
||||
|
||||
NOTE: To ensure consistent search tool usage:
|
||||
- Include explicit instructions for the agent to use the search tool
|
||||
- Mention the search requirement in your queries
|
||||
- Use `tool_choice="required"` to force tool usage
|
||||
|
||||
More info on `query type` can be found here:
|
||||
https://learn.microsoft.com/en-us/python/api/azure-ai-agents/azure.ai.agents.models.aisearchindexresource?view=azure-python-preview
|
||||
and set AI_SEARCH_PROJECT_CONNECTION_ID and AI_SEARCH_INDEX_NAME environment variable.
|
||||
"""
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
"""Main function demonstrating Azure AI agent with raw Azure AI Search tool."""
|
||||
print("=== Azure AI Agent with Raw Azure AI Search Tool ===")
|
||||
|
||||
# Create the client and manually create an agent with Azure AI Search tool
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
AIProjectClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as project_client,
|
||||
AgentsClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as agents_client,
|
||||
):
|
||||
ai_search_conn_id = ""
|
||||
async for connection in project_client.connections.list():
|
||||
if connection.type == ConnectionType.AZURE_AI_SEARCH:
|
||||
ai_search_conn_id = connection.id
|
||||
break
|
||||
|
||||
# 1. Create Azure AI agent with the search tool
|
||||
azure_ai_agent = await project_client.agents.create_agent(
|
||||
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
|
||||
name="HotelSearchAgent",
|
||||
instructions=(
|
||||
"You are a helpful agent that searches hotel information using Azure AI Search. "
|
||||
"Always use the search tool and index to find hotel data and provide accurate information."
|
||||
),
|
||||
tools=[{"type": "azure_ai_search"}],
|
||||
tool_resources={
|
||||
AzureAIClient(async_credential=credential).create_agent(
|
||||
name="MySearchAgent",
|
||||
instructions="""You are a helpful assistant. You must always provide citations for
|
||||
answers using the tool and render them as: `[message_idx:search_idx†source]`.""",
|
||||
tools={
|
||||
"type": "azure_ai_search",
|
||||
"azure_ai_search": {
|
||||
"indexes": [
|
||||
{
|
||||
"index_connection_id": ai_search_conn_id,
|
||||
"index_name": "hotels-sample-index",
|
||||
"query_type": "vector",
|
||||
"project_connection_id": os.environ["AI_SEARCH_PROJECT_CONNECTION_ID"],
|
||||
"index_name": os.environ["AI_SEARCH_INDEX_NAME"],
|
||||
# For query_type=vector, ensure your index has a field with vectorized data.
|
||||
"query_type": "simple",
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
# 2. Create chat client with the existing agent
|
||||
chat_client = AzureAIAgentClient(agents_client=agents_client, agent_id=azure_ai_agent.id)
|
||||
|
||||
try:
|
||||
async with ChatAgent(
|
||||
chat_client=chat_client,
|
||||
# Additional instructions for this specific conversation
|
||||
instructions=("You are a helpful agent that uses the search tool and index to find hotel information."),
|
||||
) as agent:
|
||||
print("This agent uses raw Azure AI Search tool to search hotel data.\n")
|
||||
|
||||
# 3. Simulate conversation with the agent
|
||||
user_input = (
|
||||
"Use Azure AI search knowledge tool to find detailed information about a winter hotel."
|
||||
" Use the search tool and index." # You can modify prompt to force tool usage
|
||||
)
|
||||
print(f"User: {user_input}")
|
||||
print("Agent: ", end="", flush=True)
|
||||
|
||||
# Stream the response and collect citations
|
||||
citations: list[CitationAnnotation] = []
|
||||
async for chunk in agent.run_stream(user_input):
|
||||
if chunk.text:
|
||||
print(chunk.text, end="", flush=True)
|
||||
|
||||
# Collect citations from Azure AI Search responses
|
||||
for content in getattr(chunk, "contents", []):
|
||||
annotations = getattr(content, "annotations", [])
|
||||
if annotations:
|
||||
citations.extend(annotations)
|
||||
|
||||
print()
|
||||
|
||||
# Display collected citations
|
||||
if citations:
|
||||
print("\n\nCitations:")
|
||||
for i, citation in enumerate(citations, 1):
|
||||
print(f"[{i}] Reference: {citation.url}")
|
||||
|
||||
print("\n" + "=" * 50 + "\n")
|
||||
print("Hotel search conversation completed!")
|
||||
|
||||
finally:
|
||||
# Clean up the agent manually
|
||||
await project_client.agents.delete_agent(azure_ai_agent.id)
|
||||
) as agent,
|
||||
):
|
||||
query = "Tell me about insurance options"
|
||||
print(f"User: {query}")
|
||||
result = await agent.run(query)
|
||||
print(f"Result: {result}\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -2,57 +2,53 @@
|
||||
|
||||
import asyncio
|
||||
|
||||
from agent_framework import AgentRunResponse, ChatResponseUpdate, HostedCodeInterpreterTool
|
||||
from agent_framework.azure import AzureAIAgentClient
|
||||
from azure.ai.agents.models import (
|
||||
RunStepDeltaCodeInterpreterDetailItemObject,
|
||||
)
|
||||
from agent_framework import ChatResponse, HostedCodeInterpreterTool
|
||||
from agent_framework.azure import AzureAIClient
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
from openai.types.responses.response import Response as OpenAIResponse
|
||||
from openai.types.responses.response_code_interpreter_tool_call import ResponseCodeInterpreterToolCall
|
||||
|
||||
"""
|
||||
Azure AI Agent with Code Interpreter Example
|
||||
Azure AI Agent Code Interpreter Example
|
||||
|
||||
This sample demonstrates using HostedCodeInterpreterTool with Azure AI Agents
|
||||
This sample demonstrates using HostedCodeInterpreterTool with AzureAIClient
|
||||
for Python code execution and mathematical problem solving.
|
||||
"""
|
||||
|
||||
|
||||
def print_code_interpreter_inputs(response: AgentRunResponse) -> None:
|
||||
"""Helper method to access code interpreter data."""
|
||||
|
||||
print("\nCode Interpreter Inputs during the run:")
|
||||
if response.raw_representation is None:
|
||||
return
|
||||
for chunk in response.raw_representation:
|
||||
if isinstance(chunk, ChatResponseUpdate) and isinstance(
|
||||
chunk.raw_representation, RunStepDeltaCodeInterpreterDetailItemObject
|
||||
):
|
||||
print(chunk.raw_representation.input, end="")
|
||||
print("\n")
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
"""Example showing how to use the HostedCodeInterpreterTool with Azure AI."""
|
||||
print("=== Azure AI Agent with Code Interpreter Example ===")
|
||||
"""Example showing how to use the HostedCodeInterpreterTool with AzureAIClient."""
|
||||
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
AzureAIAgentClient(async_credential=credential) as chat_client,
|
||||
):
|
||||
agent = chat_client.create_agent(
|
||||
name="CodingAgent",
|
||||
instructions=("You are a helpful assistant that can write and execute Python code to solve problems."),
|
||||
AzureAIClient(async_credential=credential).create_agent(
|
||||
instructions="You are a helpful assistant that can write and execute Python code to solve problems.",
|
||||
tools=HostedCodeInterpreterTool(),
|
||||
)
|
||||
query = "Generate the factorial of 100 using python code, show the code and execute it."
|
||||
) as agent,
|
||||
):
|
||||
query = "Use code to get the factorial of 100?"
|
||||
print(f"User: {query}")
|
||||
response = await AgentRunResponse.from_agent_response_generator(agent.run_stream(query))
|
||||
print(f"Agent: {response}")
|
||||
# To review the code interpreter outputs, you can access
|
||||
# them from the response raw_representations, just uncomment the next line:
|
||||
# print_code_interpreter_inputs(response)
|
||||
result = await agent.run(query)
|
||||
print(f"Result: {result}\n")
|
||||
|
||||
if (
|
||||
isinstance(result.raw_representation, ChatResponse)
|
||||
and isinstance(result.raw_representation.raw_representation, OpenAIResponse)
|
||||
and len(result.raw_representation.raw_representation.output) > 0
|
||||
):
|
||||
# Find the first ResponseCodeInterpreterToolCall item
|
||||
code_interpreter_item = next(
|
||||
(
|
||||
item
|
||||
for item in result.raw_representation.raw_representation.output
|
||||
if isinstance(item, ResponseCodeInterpreterToolCall)
|
||||
),
|
||||
None,
|
||||
)
|
||||
|
||||
if code_interpreter_item is not None:
|
||||
generated_code = code_interpreter_item.code
|
||||
print(f"Generated code:\n{generated_code}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -4,55 +4,60 @@ import asyncio
|
||||
import os
|
||||
|
||||
from agent_framework import ChatAgent
|
||||
from agent_framework.azure import AzureAIAgentClient
|
||||
from azure.ai.agents.aio import AgentsClient
|
||||
from agent_framework.azure import AzureAIClient
|
||||
from azure.ai.projects.aio import AIProjectClient
|
||||
from azure.ai.projects.models import PromptAgentDefinition
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
|
||||
"""
|
||||
Azure AI Agent with Existing Agent Example
|
||||
|
||||
This sample demonstrates working with pre-existing Azure AI Agents by providing
|
||||
agent IDs, showing agent reuse patterns for production scenarios.
|
||||
agent name and version, showing agent reuse patterns for production scenarios.
|
||||
"""
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
print("=== Azure AI Chat Client with Existing Agent ===")
|
||||
|
||||
# Create the client
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
AIProjectClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as project_client,
|
||||
AgentsClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as agents_client,
|
||||
):
|
||||
azure_ai_agent = await project_client.agents.create_agent(
|
||||
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
|
||||
# Create remote agent with default instructions
|
||||
# These instructions will persist on created agent for every run.
|
||||
instructions="End each response with [END].",
|
||||
azure_ai_agent = await project_client.agents.create_version(
|
||||
agent_name="MyNewTestAgent",
|
||||
definition=PromptAgentDefinition(
|
||||
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
|
||||
# Setting specific requirements to verify that this agent is used.
|
||||
instructions="End each response with [END].",
|
||||
),
|
||||
)
|
||||
|
||||
chat_client = AzureAIAgentClient(agents_client=agents_client, agent_id=azure_ai_agent.id)
|
||||
chat_client = AzureAIClient(
|
||||
project_client=project_client,
|
||||
agent_name=azure_ai_agent.name,
|
||||
# Property agent_version is required for existing agents.
|
||||
# If this property is not configured, the client will try to create a new agent using
|
||||
# provided agent_name.
|
||||
# It's also possible to leave agent_version empty but set use_latest_version=True.
|
||||
# This will pull latest available agent version and use that version for operations.
|
||||
agent_version=azure_ai_agent.version,
|
||||
)
|
||||
|
||||
try:
|
||||
async with ChatAgent(
|
||||
chat_client=chat_client,
|
||||
# Instructions here are applicable only to this ChatAgent instance
|
||||
# These instructions will be combined with instructions on existing remote agent.
|
||||
# The final instructions during the execution will look like:
|
||||
# "'End each response with [END]. Respond with 'Hello World' only'"
|
||||
instructions="Respond with 'Hello World' only",
|
||||
) as agent:
|
||||
query = "How are you?"
|
||||
print(f"User: {query}")
|
||||
result = await agent.run(query)
|
||||
# Based on local and remote instructions, the result will be
|
||||
# 'Hello World [END]'.
|
||||
# Response that indicates that previously created agent was used:
|
||||
# "I'm here and ready to help you! How can I assist you today? [END]"
|
||||
print(f"Agent: {result}\n")
|
||||
finally:
|
||||
# Clean up the agent manually
|
||||
await project_client.agents.delete_agent(azure_ai_agent.id)
|
||||
await project_client.agents.delete_version(
|
||||
agent_name=azure_ai_agent.name, agent_version=azure_ai_agent.version
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
import asyncio
|
||||
import os
|
||||
from random import randint
|
||||
from typing import Annotated
|
||||
|
||||
from agent_framework.azure import AzureAIClient
|
||||
from azure.ai.projects.aio import AIProjectClient
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
from pydantic import Field
|
||||
|
||||
"""
|
||||
Azure AI Agent Existing Conversation Example
|
||||
|
||||
This sample demonstrates usage of AzureAIClient with existing conversation created on service side.
|
||||
"""
|
||||
|
||||
|
||||
def get_weather(
|
||||
location: Annotated[str, Field(description="The location to get the weather for.")],
|
||||
) -> str:
|
||||
"""Get the weather for a given location."""
|
||||
conditions = ["sunny", "cloudy", "rainy", "stormy"]
|
||||
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
|
||||
|
||||
|
||||
async def example_with_client() -> None:
|
||||
"""Example shows how to specify existing conversation ID when initializing Azure AI Client."""
|
||||
print("=== Azure AI Agent With Existing Conversation and Client ===")
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
AIProjectClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as project_client,
|
||||
):
|
||||
# Create a conversation using OpenAI client
|
||||
openai_client = await project_client.get_openai_client()
|
||||
conversation = await openai_client.conversations.create()
|
||||
conversation_id = conversation.id
|
||||
print(f"Conversation ID: {conversation_id}")
|
||||
|
||||
async with AzureAIClient(
|
||||
project_client=project_client,
|
||||
# Specify conversation ID on client level
|
||||
conversation_id=conversation_id,
|
||||
).create_agent(
|
||||
name="BasicAgent",
|
||||
instructions="You are a helpful agent.",
|
||||
tools=get_weather,
|
||||
) as agent:
|
||||
query = "What's the weather like in Seattle?"
|
||||
print(f"User: {query}")
|
||||
result = await agent.run(query)
|
||||
print(f"Agent: {result.text}\n")
|
||||
|
||||
query = "What was my last question?"
|
||||
print(f"User: {query}")
|
||||
result = await agent.run(query)
|
||||
print(f"Agent: {result.text}\n")
|
||||
|
||||
|
||||
async def example_with_thread() -> None:
|
||||
"""This example shows how to specify existing conversation ID with AgentThread."""
|
||||
print("=== Azure AI Agent With Existing Conversation and Thread ===")
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
AIProjectClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as project_client,
|
||||
AzureAIClient(project_client=project_client).create_agent(
|
||||
name="BasicAgent",
|
||||
instructions="You are a helpful agent.",
|
||||
tools=get_weather,
|
||||
) as agent,
|
||||
):
|
||||
# Create a conversation using OpenAI client
|
||||
openai_client = await project_client.get_openai_client()
|
||||
conversation = await openai_client.conversations.create()
|
||||
conversation_id = conversation.id
|
||||
print(f"Conversation ID: {conversation_id}")
|
||||
|
||||
# Create a thread with the existing ID
|
||||
thread = agent.get_new_thread(service_thread_id=conversation_id)
|
||||
|
||||
query = "What's the weather like in Seattle?"
|
||||
print(f"User: {query}")
|
||||
result = await agent.run(query, thread=thread)
|
||||
print(f"Agent: {result.text}\n")
|
||||
|
||||
query = "What was my last question?"
|
||||
print(f"User: {query}")
|
||||
result = await agent.run(query, thread=thread)
|
||||
print(f"Agent: {result.text}\n")
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
await example_with_client()
|
||||
await example_with_thread()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -6,7 +6,7 @@ from random import randint
|
||||
from typing import Annotated
|
||||
|
||||
from agent_framework import ChatAgent
|
||||
from agent_framework.azure import AzureAIAgentClient
|
||||
from agent_framework.azure import AzureAIClient
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
from pydantic import Field
|
||||
|
||||
@@ -27,28 +27,26 @@ def get_weather(
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
print("=== Azure AI Chat Client with Explicit Settings ===")
|
||||
|
||||
# Since no Agent ID is provided, the agent will be automatically created
|
||||
# and deleted after getting a response
|
||||
# Since no Agent ID is provided, the agent will be automatically created.
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
ChatAgent(
|
||||
chat_client=AzureAIAgentClient(
|
||||
chat_client=AzureAIClient(
|
||||
project_endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"],
|
||||
model_deployment_name=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
|
||||
async_credential=credential,
|
||||
agent_name="WeatherAgent",
|
||||
should_cleanup_agent=True, # Set to False if you want to disable automatic agent cleanup
|
||||
),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
) as agent,
|
||||
):
|
||||
result = await agent.run("What's the weather like in New York?")
|
||||
print(f"Result: {result}\n")
|
||||
query = "What's the weather like in New York?"
|
||||
print(f"User: {query}")
|
||||
result = await agent.run(query)
|
||||
print(f"Agent: {result}\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from agent_framework import ChatAgent, HostedFileSearchTool, HostedVectorStoreContent
|
||||
from agent_framework_azure_ai import AzureAIAgentClient
|
||||
from agent_framework.azure import AzureAIClient
|
||||
from azure.ai.agents.aio import AgentsClient
|
||||
from azure.ai.agents.models import FileInfo, VectorStore
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
|
||||
@@ -24,69 +26,50 @@ USER_INPUTS = [
|
||||
|
||||
async def main() -> None:
|
||||
"""Main function demonstrating Azure AI agent with file search capabilities."""
|
||||
client = AzureAIAgentClient(async_credential=AzureCliCredential())
|
||||
file: FileInfo | None = None
|
||||
vector_store: VectorStore | None = None
|
||||
|
||||
try:
|
||||
# 1. Upload file and create vector store
|
||||
pdf_file_path = Path(__file__).parent.parent / "resources" / "employees.pdf"
|
||||
print(f"Uploading file from: {pdf_file_path}")
|
||||
|
||||
file = await client.project_client.agents.files.upload_and_poll(
|
||||
file_path=str(pdf_file_path), purpose="assistants"
|
||||
)
|
||||
print(f"Uploaded file, file ID: {file.id}")
|
||||
|
||||
vector_store = await client.project_client.agents.vector_stores.create_and_poll(
|
||||
file_ids=[file.id], name="my_vectorstore"
|
||||
)
|
||||
print(f"Created vector store, vector store ID: {vector_store.id}")
|
||||
|
||||
# 2. Create file search tool with uploaded resources
|
||||
file_search_tool = HostedFileSearchTool(inputs=[HostedVectorStoreContent(vector_store_id=vector_store.id)])
|
||||
|
||||
# 3. Create an agent with file search capabilities
|
||||
# The tool_resources are automatically extracted from HostedFileSearchTool
|
||||
async with ChatAgent(
|
||||
chat_client=client,
|
||||
name="EmployeeSearchAgent",
|
||||
instructions=(
|
||||
"You are a helpful assistant that can search through uploaded employee files "
|
||||
"to answer questions about employees."
|
||||
),
|
||||
tools=file_search_tool,
|
||||
) as agent:
|
||||
# 4. Simulate conversation with the agent
|
||||
for user_input in USER_INPUTS:
|
||||
print(f"# User: '{user_input}'")
|
||||
response = await agent.run(user_input)
|
||||
print(f"# Agent: {response.text}")
|
||||
|
||||
# 5. Cleanup: Delete the vector store and file
|
||||
try:
|
||||
if vector_store:
|
||||
await client.project_client.agents.vector_stores.delete(vector_store.id)
|
||||
if file:
|
||||
await client.project_client.agents.files.delete(file.id)
|
||||
except Exception:
|
||||
# Ignore cleanup errors to avoid masking issues
|
||||
pass
|
||||
finally:
|
||||
# 6. Cleanup: Delete the vector store and file in case of eariler failure to prevent orphaned resources.
|
||||
|
||||
# Refreshing the client is required since chat agent closes it
|
||||
client = AzureAIAgentClient(async_credential=AzureCliCredential())
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
AgentsClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as agents_client,
|
||||
AzureAIClient(async_credential=credential) as client,
|
||||
):
|
||||
try:
|
||||
if vector_store:
|
||||
await client.project_client.agents.vector_stores.delete(vector_store.id)
|
||||
if file:
|
||||
await client.project_client.agents.files.delete(file.id)
|
||||
except Exception:
|
||||
# Ignore cleanup errors to avoid masking issues
|
||||
pass
|
||||
# 1. Upload file and create vector store
|
||||
pdf_file_path = Path(__file__).parent.parent / "resources" / "employees.pdf"
|
||||
print(f"Uploading file from: {pdf_file_path}")
|
||||
|
||||
file = await agents_client.files.upload_and_poll(file_path=str(pdf_file_path), purpose="assistants")
|
||||
print(f"Uploaded file, file ID: {file.id}")
|
||||
|
||||
vector_store = await agents_client.vector_stores.create_and_poll(file_ids=[file.id], name="my_vectorstore")
|
||||
print(f"Created vector store, vector store ID: {vector_store.id}")
|
||||
|
||||
# 2. Create file search tool with uploaded resources
|
||||
file_search_tool = HostedFileSearchTool(inputs=[HostedVectorStoreContent(vector_store_id=vector_store.id)])
|
||||
|
||||
# 3. Create an agent with file search capabilities
|
||||
# The tool_resources are automatically extracted from HostedFileSearchTool
|
||||
async with ChatAgent(
|
||||
chat_client=client,
|
||||
name="EmployeeSearchAgent",
|
||||
instructions=(
|
||||
"You are a helpful assistant that can search through uploaded employee files "
|
||||
"to answer questions about employees."
|
||||
),
|
||||
tools=file_search_tool,
|
||||
) as agent:
|
||||
# 4. Simulate conversation with the agent
|
||||
for user_input in USER_INPUTS:
|
||||
print(f"# User: '{user_input}'")
|
||||
response = await agent.run(user_input)
|
||||
print(f"# Agent: {response.text}")
|
||||
finally:
|
||||
await client.close()
|
||||
# 5. Cleanup: Delete the vector store and file in case of earlier failure to prevent orphaned resources.
|
||||
if vector_store:
|
||||
await agents_client.vector_stores.delete(vector_store.id)
|
||||
if file:
|
||||
await agents_client.files.delete(file.id)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -3,23 +3,42 @@
|
||||
import asyncio
|
||||
from typing import Any
|
||||
|
||||
from agent_framework import AgentProtocol, AgentThread, HostedMCPTool
|
||||
from agent_framework.azure import AzureAIAgentClient
|
||||
from agent_framework import AgentProtocol, AgentRunResponse, AgentThread, ChatMessage, HostedMCPTool
|
||||
from agent_framework.azure import AzureAIClient
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
|
||||
"""
|
||||
Azure AI Agent with Hosted MCP Example
|
||||
|
||||
This sample demonstrates integration of Azure AI Agents with hosted Model Context Protocol (MCP)
|
||||
servers, including user approval workflows for function call security.
|
||||
This sample demonstrates integrating hosted Model Context Protocol (MCP) tools with Azure AI Agent.
|
||||
"""
|
||||
|
||||
|
||||
async def handle_approvals_with_thread(query: str, agent: "AgentProtocol", thread: "AgentThread"):
|
||||
"""Here we let the thread deal with the previous responses, and we just rerun with the approval."""
|
||||
from agent_framework import ChatMessage
|
||||
async def handle_approvals_without_thread(query: str, agent: "AgentProtocol") -> AgentRunResponse:
|
||||
"""When we don't have a thread, we need to ensure we return with the input, approval request and approval."""
|
||||
|
||||
result = await agent.run(query, thread=thread, store=True)
|
||||
result = await agent.run(query, store=False)
|
||||
while len(result.user_input_requests) > 0:
|
||||
new_inputs: list[Any] = [query]
|
||||
for user_input_needed in result.user_input_requests:
|
||||
print(
|
||||
f"User Input Request for function from {agent.name}: {user_input_needed.function_call.name}"
|
||||
f" with arguments: {user_input_needed.function_call.arguments}"
|
||||
)
|
||||
new_inputs.append(ChatMessage(role="assistant", contents=[user_input_needed]))
|
||||
user_approval = input("Approve function call? (y/n): ")
|
||||
new_inputs.append(
|
||||
ChatMessage(role="user", contents=[user_input_needed.create_response(user_approval.lower() == "y")])
|
||||
)
|
||||
|
||||
result = await agent.run(new_inputs, store=False)
|
||||
return result
|
||||
|
||||
|
||||
async def handle_approvals_with_thread(query: str, agent: "AgentProtocol", thread: "AgentThread") -> AgentRunResponse:
|
||||
"""Here we let the thread deal with the previous responses, and we just rerun with the approval."""
|
||||
|
||||
result = await agent.run(query, thread=thread)
|
||||
while len(result.user_input_requests) > 0:
|
||||
new_input: list[Any] = []
|
||||
for user_input_needed in result.user_input_requests:
|
||||
@@ -34,36 +53,64 @@ async def handle_approvals_with_thread(query: str, agent: "AgentProtocol", threa
|
||||
contents=[user_input_needed.create_response(user_approval.lower() == "y")],
|
||||
)
|
||||
)
|
||||
result = await agent.run(new_input, thread=thread, store=True)
|
||||
result = await agent.run(new_input, thread=thread)
|
||||
return result
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
"""Example showing Hosted MCP tools for a Azure AI Agent."""
|
||||
async def run_hosted_mcp_without_approval() -> None:
|
||||
"""Example showing MCP Tools without approval."""
|
||||
# Since no Agent ID is provided, the agent will be automatically created.
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
AzureAIAgentClient(async_credential=credential) as chat_client,
|
||||
):
|
||||
agent = chat_client.create_agent(
|
||||
name="DocsAgent",
|
||||
instructions="You are a helpful assistant that can help with microsoft documentation questions.",
|
||||
AzureAIClient(async_credential=credential).create_agent(
|
||||
name="MyLearnDocsAgent",
|
||||
instructions="You are a helpful assistant that can help with Microsoft documentation questions.",
|
||||
tools=HostedMCPTool(
|
||||
name="Microsoft Learn MCP",
|
||||
url="https://learn.microsoft.com/api/mcp",
|
||||
approval_mode="never_require",
|
||||
),
|
||||
)
|
||||
) as agent,
|
||||
):
|
||||
query = "How to create an Azure storage account using az cli?"
|
||||
print(f"User: {query}")
|
||||
result = await handle_approvals_without_thread(query, agent)
|
||||
print(f"{agent.name}: {result}\n")
|
||||
|
||||
|
||||
async def run_hosted_mcp_with_approval_and_thread() -> None:
|
||||
"""Example showing MCP Tools with approvals using a thread."""
|
||||
print("=== MCP with approvals and with thread ===")
|
||||
|
||||
# Since no Agent ID is provided, the agent will be automatically created.
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
AzureAIClient(async_credential=credential).create_agent(
|
||||
name="MyApiSpecsAgent",
|
||||
instructions="You are a helpful agent that can use MCP tools to assist users.",
|
||||
tools=HostedMCPTool(
|
||||
name="api-specs",
|
||||
url="https://gitmcp.io/Azure/azure-rest-api-specs",
|
||||
approval_mode="always_require",
|
||||
),
|
||||
) as agent,
|
||||
):
|
||||
thread = agent.get_new_thread()
|
||||
# First query
|
||||
query1 = "How to create an Azure storage account using az cli?"
|
||||
print(f"User: {query1}")
|
||||
result1 = await handle_approvals_with_thread(query1, agent, thread)
|
||||
print(f"{agent.name}: {result1}\n")
|
||||
print("\n=======================================\n")
|
||||
# Second query
|
||||
query2 = "What is Microsoft Agent Framework?"
|
||||
print(f"User: {query2}")
|
||||
result2 = await handle_approvals_with_thread(query2, agent, thread)
|
||||
print(f"{agent.name}: {result2}\n")
|
||||
query = "Please summarize the Azure REST API specifications Readme"
|
||||
print(f"User: {query}")
|
||||
result = await handle_approvals_with_thread(query, agent, thread)
|
||||
print(f"{agent.name}: {result}\n")
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
print("=== Azure AI Agent with Hosted MCP Tools Example ===\n")
|
||||
|
||||
await run_hosted_mcp_without_approval()
|
||||
await run_hosted_mcp_with_approval_and_thread()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
from pathlib import Path
|
||||
|
||||
import aiofiles
|
||||
from agent_framework import DataContent
|
||||
from agent_framework.azure import AzureAIClient
|
||||
from azure.ai.projects.models import ImageGenTool
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
|
||||
"""
|
||||
Azure AI Agent With Image Generation
|
||||
|
||||
This sample demonstrates basic usage of AzureAIClient to create an agent
|
||||
that can generate images based on user requirements.
|
||||
|
||||
Pre-requisites:
|
||||
- Make sure to set up the AZURE_AI_PROJECT_ENDPOINT and AZURE_AI_MODEL_DEPLOYMENT_NAME
|
||||
environment variables before running this sample.
|
||||
"""
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
# Since no Agent ID is provided, the agent will be automatically created.
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
AzureAIClient(async_credential=credential).create_agent(
|
||||
name="ImageGenAgent",
|
||||
instructions="Generate images based on user requirements.",
|
||||
tools=[ImageGenTool(quality="low", size="1024x1024")],
|
||||
) as agent,
|
||||
):
|
||||
query = "Generate an image of Microsoft logo."
|
||||
print(f"User: {query}")
|
||||
result = await agent.run(
|
||||
query,
|
||||
# These additional options are required for image generation
|
||||
additional_chat_options={
|
||||
"extra_headers": {"x-ms-oai-image-generation-deployment": "gpt-image-1"},
|
||||
},
|
||||
)
|
||||
print(f"Agent: {result}\n")
|
||||
|
||||
# Save the image to a file
|
||||
print("Downloading generated image...")
|
||||
image_data = [
|
||||
content
|
||||
for content in result.messages[0].contents
|
||||
if isinstance(content, DataContent) and content.media_type == "image/png"
|
||||
]
|
||||
if image_data and image_data[0]:
|
||||
# Save to the same directory as this script
|
||||
filename = "microsoft.png"
|
||||
current_dir = Path(__file__).parent.resolve()
|
||||
file_path = current_dir / filename
|
||||
async with aiofiles.open(file_path, "wb") as f:
|
||||
await f.write(image_data[0].get_data_bytes())
|
||||
|
||||
print(f"Image downloaded and saved to: {file_path}")
|
||||
else:
|
||||
print("No image data found in the agent response.")
|
||||
|
||||
"""
|
||||
Sample output:
|
||||
User: Generate an image of Microsoft logo.
|
||||
Agent: Here is the Microsoft logo image featuring its iconic four quadrants.
|
||||
|
||||
Downloading generated image...
|
||||
Image downloaded and saved to: .../microsoft.png
|
||||
"""
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,54 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
|
||||
from agent_framework.azure import AzureAIClient
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
|
||||
"""
|
||||
Azure AI Agent Response Format Example
|
||||
|
||||
This sample demonstrates basic usage of AzureAIClient with response format,
|
||||
also known as structured outputs.
|
||||
"""
|
||||
|
||||
|
||||
class ReleaseBrief(BaseModel):
|
||||
feature: str
|
||||
benefit: str
|
||||
launch_date: str
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
"""Example of using response_format property."""
|
||||
|
||||
# Since no Agent ID is provided, the agent will be automatically created.
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
AzureAIClient(async_credential=credential).create_agent(
|
||||
name="ProductMarketerAgent",
|
||||
instructions="Return launch briefs as structured JSON.",
|
||||
) as agent,
|
||||
):
|
||||
query = "Draft a launch brief for the Contoso Note app."
|
||||
print(f"User: {query}")
|
||||
result = await agent.run(
|
||||
query,
|
||||
# Specify type to use as response
|
||||
response_format=ReleaseBrief,
|
||||
)
|
||||
|
||||
if isinstance(result.value, ReleaseBrief):
|
||||
release_brief = result.value
|
||||
print("Agent:")
|
||||
print(f"Feature: {release_brief.feature}")
|
||||
print(f"Benefit: {release_brief.benefit}")
|
||||
print(f"Launch date: {release_brief.launch_date}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -4,16 +4,15 @@ import asyncio
|
||||
from random import randint
|
||||
from typing import Annotated
|
||||
|
||||
from agent_framework import AgentThread, ChatAgent
|
||||
from agent_framework.azure import AzureAIAgentClient
|
||||
from agent_framework.azure import AzureAIClient
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
from pydantic import Field
|
||||
|
||||
"""
|
||||
Azure AI Agent with Thread Management Example
|
||||
|
||||
This sample demonstrates thread management with Azure AI Agents, comparing
|
||||
automatic thread creation with explicit thread management for persistent context.
|
||||
This sample demonstrates thread management with Azure AI Agent, showing
|
||||
persistent conversation capabilities using service-managed threads as well as storing messages in-memory.
|
||||
"""
|
||||
|
||||
|
||||
@@ -26,44 +25,42 @@ def get_weather(
|
||||
|
||||
|
||||
async def example_with_automatic_thread_creation() -> None:
|
||||
"""Example showing automatic thread creation (service-managed thread)."""
|
||||
"""Example showing automatic thread creation."""
|
||||
print("=== Automatic Thread Creation Example ===")
|
||||
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
ChatAgent(
|
||||
chat_client=AzureAIAgentClient(async_credential=credential),
|
||||
AzureAIClient(async_credential=credential).create_agent(
|
||||
name="BasicWeatherAgent",
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
) as agent,
|
||||
):
|
||||
# First conversation - no thread provided, will be created automatically
|
||||
first_query = "What's the weather like in Seattle?"
|
||||
print(f"User: {first_query}")
|
||||
first_result = await agent.run(first_query)
|
||||
print(f"Agent: {first_result.text}")
|
||||
query1 = "What's the weather like in Seattle?"
|
||||
print(f"User: {query1}")
|
||||
result1 = await agent.run(query1)
|
||||
print(f"Agent: {result1.text}")
|
||||
|
||||
# Second conversation - still no thread provided, will create another new thread
|
||||
second_query = "What was the last city I asked about?"
|
||||
print(f"\nUser: {second_query}")
|
||||
second_result = await agent.run(second_query)
|
||||
print(f"Agent: {second_result.text}")
|
||||
query2 = "What was the last city I asked about?"
|
||||
print(f"\nUser: {query2}")
|
||||
result2 = await agent.run(query2)
|
||||
print(f"Agent: {result2.text}")
|
||||
print("Note: Each call creates a separate thread, so the agent doesn't remember previous context.\n")
|
||||
|
||||
|
||||
async def example_with_thread_persistence() -> None:
|
||||
"""Example showing thread persistence across multiple conversations."""
|
||||
print("=== Thread Persistence Example ===")
|
||||
print("Using the same thread across multiple conversations to maintain context.\n")
|
||||
async def example_with_thread_persistence_in_memory() -> None:
|
||||
"""
|
||||
Example showing thread persistence across multiple conversations.
|
||||
In this example, messages are stored in-memory.
|
||||
"""
|
||||
print("=== Thread Persistence Example (In-Memory) ===")
|
||||
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
ChatAgent(
|
||||
chat_client=AzureAIAgentClient(async_credential=credential),
|
||||
AzureAIClient(async_credential=credential).create_agent(
|
||||
name="BasicWeatherAgent",
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
) as agent,
|
||||
@@ -72,81 +69,80 @@ async def example_with_thread_persistence() -> None:
|
||||
thread = agent.get_new_thread()
|
||||
|
||||
# First conversation
|
||||
first_query = "What's the weather like in Tokyo?"
|
||||
print(f"User: {first_query}")
|
||||
first_result = await agent.run(first_query, thread=thread)
|
||||
print(f"Agent: {first_result.text}")
|
||||
query1 = "What's the weather like in Tokyo?"
|
||||
print(f"User: {query1}")
|
||||
result1 = await agent.run(query1, thread=thread, store=False)
|
||||
print(f"Agent: {result1.text}")
|
||||
|
||||
# Second conversation using the same thread - maintains context
|
||||
second_query = "How about London?"
|
||||
print(f"\nUser: {second_query}")
|
||||
second_result = await agent.run(second_query, thread=thread)
|
||||
print(f"Agent: {second_result.text}")
|
||||
query2 = "How about London?"
|
||||
print(f"\nUser: {query2}")
|
||||
result2 = await agent.run(query2, thread=thread, store=False)
|
||||
print(f"Agent: {result2.text}")
|
||||
|
||||
# Third conversation - agent should remember both previous cities
|
||||
third_query = "Which of the cities I asked about has better weather?"
|
||||
print(f"\nUser: {third_query}")
|
||||
third_result = await agent.run(third_query, thread=thread)
|
||||
print(f"Agent: {third_result.text}")
|
||||
query3 = "Which of the cities I asked about has better weather?"
|
||||
print(f"\nUser: {query3}")
|
||||
result3 = await agent.run(query3, thread=thread, store=False)
|
||||
print(f"Agent: {result3.text}")
|
||||
print("Note: The agent remembers context from previous messages in the same thread.\n")
|
||||
|
||||
|
||||
async def example_with_existing_thread_id() -> None:
|
||||
"""Example showing how to work with an existing thread ID from the service."""
|
||||
"""
|
||||
Example showing how to work with an existing thread ID from the service.
|
||||
In this example, messages are stored on the server.
|
||||
"""
|
||||
print("=== Existing Thread ID Example ===")
|
||||
print("Using a specific thread ID to continue an existing conversation.\n")
|
||||
|
||||
# First, create a conversation and capture the thread ID
|
||||
existing_thread_id = None
|
||||
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
ChatAgent(
|
||||
chat_client=AzureAIAgentClient(async_credential=credential),
|
||||
AzureAIClient(async_credential=credential).create_agent(
|
||||
name="BasicWeatherAgent",
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
) as agent,
|
||||
):
|
||||
# Start a conversation and get the thread ID
|
||||
thread = agent.get_new_thread()
|
||||
first_query = "What's the weather in Paris?"
|
||||
print(f"User: {first_query}")
|
||||
first_result = await agent.run(first_query, thread=thread)
|
||||
print(f"Agent: {first_result.text}")
|
||||
|
||||
query1 = "What's the weather in Paris?"
|
||||
print(f"User: {query1}")
|
||||
result1 = await agent.run(query1, thread=thread)
|
||||
print(f"Agent: {result1.text}")
|
||||
|
||||
# The thread ID is set after the first response
|
||||
existing_thread_id = thread.service_thread_id
|
||||
print(f"Thread ID: {existing_thread_id}")
|
||||
|
||||
if existing_thread_id:
|
||||
print("\n--- Continuing with the same thread ID in a new agent instance ---")
|
||||
if existing_thread_id:
|
||||
print("\n--- Continuing with the same thread ID in a new agent instance ---")
|
||||
|
||||
# Create a new agent instance but use the existing thread ID
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
ChatAgent(
|
||||
chat_client=AzureAIAgentClient(thread_id=existing_thread_id, async_credential=credential),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
) as agent,
|
||||
):
|
||||
# Create a thread with the existing ID
|
||||
thread = AgentThread(service_thread_id=existing_thread_id)
|
||||
async with (
|
||||
AzureAIClient(async_credential=credential).create_agent(
|
||||
name="BasicWeatherAgent",
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
) as agent,
|
||||
):
|
||||
# Create a thread with the existing ID
|
||||
thread = agent.get_new_thread(service_thread_id=existing_thread_id)
|
||||
|
||||
second_query = "What was the last city I asked about?"
|
||||
print(f"User: {second_query}")
|
||||
second_result = await agent.run(second_query, thread=thread)
|
||||
print(f"Agent: {second_result.text}")
|
||||
print("Note: The agent continues the conversation from the previous thread.\n")
|
||||
query2 = "What was the last city I asked about?"
|
||||
print(f"User: {query2}")
|
||||
result2 = await agent.run(query2, thread=thread)
|
||||
print(f"Agent: {result2.text}")
|
||||
print("Note: The agent continues the conversation from the previous thread by using thread ID.\n")
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
print("=== Azure AI Chat Client Agent Thread Management Examples ===\n")
|
||||
print("=== Azure AI Agent Thread Management Examples ===\n")
|
||||
|
||||
await example_with_automatic_thread_creation()
|
||||
await example_with_thread_persistence()
|
||||
await example_with_thread_persistence_in_memory()
|
||||
await example_with_existing_thread_id()
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
|
||||
from agent_framework import HostedWebSearchTool
|
||||
from agent_framework.azure import AzureAIClient
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
|
||||
"""
|
||||
Azure AI Agent With Web Search
|
||||
|
||||
This sample demonstrates basic usage of AzureAIClient to create an agent
|
||||
that can perform web searches using the HostedWebSearchTool.
|
||||
|
||||
Pre-requisites:
|
||||
- Make sure to set up the AZURE_AI_PROJECT_ENDPOINT and AZURE_AI_MODEL_DEPLOYMENT_NAME
|
||||
environment variables before running this sample.
|
||||
"""
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
# Since no Agent ID is provided, the agent will be automatically created.
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
AzureAIClient(async_credential=credential).create_agent(
|
||||
name="WebsearchAgent",
|
||||
instructions="You are a helpful assistant that can search the web",
|
||||
tools=[HostedWebSearchTool()],
|
||||
) as agent,
|
||||
):
|
||||
query = "What's the weather today in Seattle?"
|
||||
print(f"User: {query}")
|
||||
result = await agent.run(query)
|
||||
print(f"Agent: {result}\n")
|
||||
|
||||
"""
|
||||
Sample output:
|
||||
User: What's the weather today in Seattle?
|
||||
Agent: Here is the updated weather forecast for Seattle: The current temperature is approximately 57°F,
|
||||
mostly cloudy conditions, with light winds and a chance of rain later tonight. Check out more details
|
||||
at the [National Weather Service](https://forecast.weather.gov/zipcity.php?inputstring=Seattle%2CWA).
|
||||
"""
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,69 @@
|
||||
# Azure AI Agent Examples
|
||||
|
||||
This folder contains examples demonstrating different ways to create and use agents with the Azure AI chat client from the `agent_framework.azure` package.
|
||||
|
||||
## Examples
|
||||
|
||||
| File | Description |
|
||||
|------|-------------|
|
||||
| [`azure_ai_basic.py`](azure_ai_basic.py) | The simplest way to create an agent using `ChatAgent` with `AzureAIAgentClient`. It automatically handles all configuration using environment variables. |
|
||||
| [`azure_ai_with_bing_grounding.py`](azure_ai_with_bing_grounding.py) | Shows how to use Bing Grounding search with Azure AI agents to find real-time information from the web. Demonstrates web search capabilities with proper source citations and comprehensive error handling. |
|
||||
| [`azure_ai_with_code_interpreter.py`](azure_ai_with_code_interpreter.py) | Shows how to use the HostedCodeInterpreterTool with Azure AI agents to write and execute Python code. Includes helper methods for accessing code interpreter data from response chunks. |
|
||||
| [`azure_ai_with_existing_agent.py`](azure_ai_with_existing_agent.py) | Shows how to work with a pre-existing agent by providing the agent ID to the Azure AI chat client. This example also demonstrates proper cleanup of manually created agents. |
|
||||
| [`azure_ai_with_existing_thread.py`](azure_ai_with_existing_thread.py) | Shows how to work with a pre-existing thread by providing the thread ID to the Azure AI chat client. This example also demonstrates proper cleanup of manually created threads. |
|
||||
| [`azure_ai_with_explicit_settings.py`](azure_ai_with_explicit_settings.py) | Shows how to create an agent with explicitly configured `AzureAIAgentClient` settings, including project endpoint, model deployment, credentials, and agent name. |
|
||||
| [`azure_ai_with_azure_ai_search.py`](azure_ai_with_azure_ai_search.py) | Demonstrates how to use Azure AI Search with Azure AI agents to search through indexed data. Shows how to configure search parameters, query types, and integrate with existing search indexes. |
|
||||
| [`azure_ai_with_file_search.py`](azure_ai_with_file_search.py) | Demonstrates how to use the HostedFileSearchTool with Azure AI agents to search through uploaded documents. Shows file upload, vector store creation, and querying document content. Includes both streaming and non-streaming examples. |
|
||||
| [`azure_ai_with_function_tools.py`](azure_ai_with_function_tools.py) | Demonstrates how to use function tools with agents. Shows both agent-level tools (defined when creating the agent) and query-level tools (provided with specific queries). |
|
||||
| [`azure_ai_with_hosted_mcp.py`](azure_ai_with_hosted_mcp.py) | Shows how to integrate Azure AI agents with hosted Model Context Protocol (MCP) servers for enhanced functionality and tool integration. Demonstrates remote MCP server connections and tool discovery. |
|
||||
| [`azure_ai_with_local_mcp.py`](azure_ai_with_local_mcp.py) | Shows how to integrate Azure AI agents with local Model Context Protocol (MCP) servers for enhanced functionality and tool integration. Demonstrates both agent-level and run-level tool configuration. |
|
||||
| [`azure_ai_with_multiple_tools.py`](azure_ai_with_multiple_tools.py) | Demonstrates how to use multiple tools together with Azure AI agents, including web search, MCP servers, and function tools. Shows coordinated multi-tool interactions and approval workflows. |
|
||||
| [`azure_ai_with_openapi_tools.py`](azure_ai_with_openapi_tools.py) | Demonstrates how to use OpenAPI tools with Azure AI agents to integrate external REST APIs. Shows OpenAPI specification loading, anonymous authentication, thread context management, and coordinated multi-API conversations using weather and countries APIs. |
|
||||
| [`azure_ai_with_thread.py`](azure_ai_with_thread.py) | Demonstrates thread management with Azure AI agents, including automatic thread creation for stateless conversations and explicit thread management for maintaining conversation context across multiple interactions. |
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Before running the examples, you need to set up your environment variables. You can do this in one of two ways:
|
||||
|
||||
### Option 1: Using a .env file (Recommended)
|
||||
|
||||
1. Copy the `.env.example` file from the `python` directory to create a `.env` file:
|
||||
```bash
|
||||
cp ../../.env.example ../../.env
|
||||
```
|
||||
|
||||
2. Edit the `.env` file and add your values:
|
||||
```
|
||||
AZURE_AI_PROJECT_ENDPOINT="your-project-endpoint"
|
||||
AZURE_AI_MODEL_DEPLOYMENT_NAME="your-model-deployment-name"
|
||||
```
|
||||
|
||||
3. For samples using Bing Grounding search (like `azure_ai_with_bing_grounding.py` and `azure_ai_with_multiple_tools.py`), you'll also need:
|
||||
```
|
||||
BING_CONNECTION_ID="your-bing-connection-id"
|
||||
```
|
||||
|
||||
To get your Bing connection details:
|
||||
- Go to [Azure AI Foundry portal](https://ai.azure.com)
|
||||
- Navigate to your project's "Connected resources" section
|
||||
- Add a new connection for "Grounding with Bing Search"
|
||||
- Copy the ID
|
||||
|
||||
### Option 2: Using environment variables directly
|
||||
|
||||
Set the environment variables in your shell:
|
||||
|
||||
```bash
|
||||
export AZURE_AI_PROJECT_ENDPOINT="your-project-endpoint"
|
||||
export AZURE_AI_MODEL_DEPLOYMENT_NAME="your-model-deployment-name"
|
||||
export BING_CONNECTION_ID="your-bing-connection-id"
|
||||
```
|
||||
|
||||
### Required Variables
|
||||
|
||||
- `AZURE_AI_PROJECT_ENDPOINT`: Your Azure AI project endpoint (required for all examples)
|
||||
- `AZURE_AI_MODEL_DEPLOYMENT_NAME`: The name of your model deployment (required for all examples)
|
||||
|
||||
### Optional Variables
|
||||
|
||||
- `BING_CONNECTION_ID`: Your Bing connection ID (required for `azure_ai_with_bing_grounding.py` and `azure_ai_with_multiple_tools.py`)
|
||||
@@ -0,0 +1,82 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
from random import randint
|
||||
from typing import Annotated
|
||||
|
||||
from agent_framework.azure import AzureAIAgentClient
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
from pydantic import Field
|
||||
|
||||
"""
|
||||
Azure AI Agent Basic Example
|
||||
|
||||
This sample demonstrates basic usage of AzureAIAgentClient to create agents with automatic
|
||||
lifecycle management. Shows both streaming and non-streaming responses with function tools.
|
||||
"""
|
||||
|
||||
|
||||
def get_weather(
|
||||
location: Annotated[str, Field(description="The location to get the weather for.")],
|
||||
) -> str:
|
||||
"""Get the weather for a given location."""
|
||||
conditions = ["sunny", "cloudy", "rainy", "stormy"]
|
||||
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
|
||||
|
||||
|
||||
async def non_streaming_example() -> None:
|
||||
"""Example of non-streaming response (get the complete result at once)."""
|
||||
print("=== Non-streaming Response Example ===")
|
||||
|
||||
# Since no Agent ID is provided, the agent will be automatically created
|
||||
# and deleted after getting a response
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
AzureAIAgentClient(async_credential=credential).create_agent(
|
||||
name="WeatherAgent",
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
) as agent,
|
||||
):
|
||||
query = "What's the weather like in Seattle?"
|
||||
print(f"User: {query}")
|
||||
result = await agent.run(query)
|
||||
print(f"Agent: {result}\n")
|
||||
|
||||
|
||||
async def streaming_example() -> None:
|
||||
"""Example of streaming response (get results as they are generated)."""
|
||||
print("=== Streaming Response Example ===")
|
||||
|
||||
# Since no Agent ID is provided, the agent will be automatically created
|
||||
# and deleted after getting a response
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
AzureAIAgentClient(async_credential=credential).create_agent(
|
||||
name="WeatherAgent",
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
) as agent,
|
||||
):
|
||||
query = "What's the weather like in Portland?"
|
||||
print(f"User: {query}")
|
||||
print("Agent: ", end="", flush=True)
|
||||
async for chunk in agent.run_stream(query):
|
||||
if chunk.text:
|
||||
print(chunk.text, end="", flush=True)
|
||||
print("\n")
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
print("=== Basic Azure AI Chat Client Agent Example ===")
|
||||
|
||||
await non_streaming_example()
|
||||
await streaming_example()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
|
||||
from agent_framework import ChatAgent, CitationAnnotation
|
||||
from agent_framework.azure import AzureAIAgentClient
|
||||
from azure.ai.agents.aio import AgentsClient
|
||||
from azure.ai.projects.aio import AIProjectClient
|
||||
from azure.ai.projects.models import ConnectionType
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
|
||||
"""
|
||||
Azure AI Agent with Azure AI Search Example
|
||||
|
||||
This sample demonstrates how to create an Azure AI agent that uses Azure AI Search
|
||||
to search through indexed hotel data and answer user questions about hotels.
|
||||
|
||||
Prerequisites:
|
||||
1. Set AZURE_AI_PROJECT_ENDPOINT and AZURE_AI_MODEL_DEPLOYMENT_NAME environment variables
|
||||
2. Ensure you have an Azure AI Search connection configured in your Azure AI project
|
||||
3. The search index "hotels-sample-index" should exist in your Azure AI Search service
|
||||
(you can create this using the Azure portal with sample hotel data)
|
||||
|
||||
NOTE: To ensure consistent search tool usage:
|
||||
- Include explicit instructions for the agent to use the search tool
|
||||
- Mention the search requirement in your queries
|
||||
- Use `tool_choice="required"` to force tool usage
|
||||
|
||||
More info on `query type` can be found here:
|
||||
https://learn.microsoft.com/en-us/python/api/azure-ai-agents/azure.ai.agents.models.aisearchindexresource?view=azure-python-preview
|
||||
"""
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
"""Main function demonstrating Azure AI agent with raw Azure AI Search tool."""
|
||||
print("=== Azure AI Agent with Raw Azure AI Search Tool ===")
|
||||
|
||||
# Create the client and manually create an agent with Azure AI Search tool
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
AIProjectClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as project_client,
|
||||
AgentsClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as agents_client,
|
||||
):
|
||||
ai_search_conn_id = ""
|
||||
async for connection in project_client.connections.list():
|
||||
if connection.type == ConnectionType.AZURE_AI_SEARCH:
|
||||
ai_search_conn_id = connection.id
|
||||
break
|
||||
|
||||
# 1. Create Azure AI agent with the search tool
|
||||
azure_ai_agent = await agents_client.create_agent(
|
||||
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
|
||||
name="HotelSearchAgent",
|
||||
instructions=(
|
||||
"You are a helpful agent that searches hotel information using Azure AI Search. "
|
||||
"Always use the search tool and index to find hotel data and provide accurate information."
|
||||
),
|
||||
tools=[{"type": "azure_ai_search"}],
|
||||
tool_resources={
|
||||
"azure_ai_search": {
|
||||
"indexes": [
|
||||
{
|
||||
"index_connection_id": ai_search_conn_id,
|
||||
"index_name": "hotels-sample-index",
|
||||
"query_type": "vector",
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
# 2. Create chat client with the existing agent
|
||||
chat_client = AzureAIAgentClient(agents_client=agents_client, agent_id=azure_ai_agent.id)
|
||||
|
||||
try:
|
||||
async with ChatAgent(
|
||||
chat_client=chat_client,
|
||||
# Additional instructions for this specific conversation
|
||||
instructions=("You are a helpful agent that uses the search tool and index to find hotel information."),
|
||||
) as agent:
|
||||
print("This agent uses raw Azure AI Search tool to search hotel data.\n")
|
||||
|
||||
# 3. Simulate conversation with the agent
|
||||
user_input = (
|
||||
"Use Azure AI search knowledge tool to find detailed information about a winter hotel."
|
||||
" Use the search tool and index." # You can modify prompt to force tool usage
|
||||
)
|
||||
print(f"User: {user_input}")
|
||||
print("Agent: ", end="", flush=True)
|
||||
|
||||
# Stream the response and collect citations
|
||||
citations: list[CitationAnnotation] = []
|
||||
async for chunk in agent.run_stream(user_input):
|
||||
if chunk.text:
|
||||
print(chunk.text, end="", flush=True)
|
||||
|
||||
# Collect citations from Azure AI Search responses
|
||||
for content in getattr(chunk, "contents", []):
|
||||
annotations = getattr(content, "annotations", [])
|
||||
if annotations:
|
||||
citations.extend(annotations)
|
||||
|
||||
print()
|
||||
|
||||
# Display collected citations
|
||||
if citations:
|
||||
print("\n\nCitations:")
|
||||
for i, citation in enumerate(citations, 1):
|
||||
print(f"[{i}] Reference: {citation.url}")
|
||||
|
||||
print("\n" + "=" * 50 + "\n")
|
||||
print("Hotel search conversation completed!")
|
||||
|
||||
finally:
|
||||
# Clean up the agent manually
|
||||
await agents_client.delete_agent(azure_ai_agent.id)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
|
||||
from agent_framework import AgentRunResponse, ChatResponseUpdate, HostedCodeInterpreterTool
|
||||
from agent_framework.azure import AzureAIAgentClient
|
||||
from azure.ai.agents.models import (
|
||||
RunStepDeltaCodeInterpreterDetailItemObject,
|
||||
)
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
|
||||
"""
|
||||
Azure AI Agent with Code Interpreter Example
|
||||
|
||||
This sample demonstrates using HostedCodeInterpreterTool with Azure AI Agents
|
||||
for Python code execution and mathematical problem solving.
|
||||
"""
|
||||
|
||||
|
||||
def print_code_interpreter_inputs(response: AgentRunResponse) -> None:
|
||||
"""Helper method to access code interpreter data."""
|
||||
|
||||
print("\nCode Interpreter Inputs during the run:")
|
||||
if response.raw_representation is None:
|
||||
return
|
||||
for chunk in response.raw_representation:
|
||||
if isinstance(chunk, ChatResponseUpdate) and isinstance(
|
||||
chunk.raw_representation, RunStepDeltaCodeInterpreterDetailItemObject
|
||||
):
|
||||
print(chunk.raw_representation.input, end="")
|
||||
print("\n")
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
"""Example showing how to use the HostedCodeInterpreterTool with Azure AI."""
|
||||
print("=== Azure AI Agent with Code Interpreter Example ===")
|
||||
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
AzureAIAgentClient(async_credential=credential) as chat_client,
|
||||
):
|
||||
agent = chat_client.create_agent(
|
||||
name="CodingAgent",
|
||||
instructions=("You are a helpful assistant that can write and execute Python code to solve problems."),
|
||||
tools=HostedCodeInterpreterTool(),
|
||||
)
|
||||
query = "Generate the factorial of 100 using python code, show the code and execute it."
|
||||
print(f"User: {query}")
|
||||
response = await AgentRunResponse.from_agent_response_generator(agent.run_stream(query))
|
||||
print(f"Agent: {response}")
|
||||
# To review the code interpreter outputs, you can access
|
||||
# them from the response raw_representations, just uncomment the next line:
|
||||
# print_code_interpreter_inputs(response)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,57 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
|
||||
from agent_framework import ChatAgent
|
||||
from agent_framework.azure import AzureAIAgentClient
|
||||
from azure.ai.agents.aio import AgentsClient
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
|
||||
"""
|
||||
Azure AI Agent with Existing Agent Example
|
||||
|
||||
This sample demonstrates working with pre-existing Azure AI Agents by providing
|
||||
agent IDs, showing agent reuse patterns for production scenarios.
|
||||
"""
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
print("=== Azure AI Chat Client with Existing Agent ===")
|
||||
|
||||
# Create the client
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
AgentsClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as agents_client,
|
||||
):
|
||||
azure_ai_agent = await agents_client.create_agent(
|
||||
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
|
||||
# Create remote agent with default instructions
|
||||
# These instructions will persist on created agent for every run.
|
||||
instructions="End each response with [END].",
|
||||
)
|
||||
|
||||
chat_client = AzureAIAgentClient(agents_client=agents_client, agent_id=azure_ai_agent.id)
|
||||
|
||||
try:
|
||||
async with ChatAgent(
|
||||
chat_client=chat_client,
|
||||
# Instructions here are applicable only to this ChatAgent instance
|
||||
# These instructions will be combined with instructions on existing remote agent.
|
||||
# The final instructions during the execution will look like:
|
||||
# "'End each response with [END]. Respond with 'Hello World' only'"
|
||||
instructions="Respond with 'Hello World' only",
|
||||
) as agent:
|
||||
query = "How are you?"
|
||||
print(f"User: {query}")
|
||||
result = await agent.run(query)
|
||||
# Based on local and remote instructions, the result will be
|
||||
# 'Hello World [END]'.
|
||||
print(f"Agent: {result}\n")
|
||||
finally:
|
||||
# Clean up the agent manually
|
||||
await agents_client.delete_agent(azure_ai_agent.id)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
from random import randint
|
||||
from typing import Annotated
|
||||
|
||||
from agent_framework import ChatAgent
|
||||
from agent_framework.azure import AzureAIAgentClient
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
from pydantic import Field
|
||||
|
||||
"""
|
||||
Azure AI Agent with Explicit Settings Example
|
||||
|
||||
This sample demonstrates creating Azure AI Agents with explicit configuration
|
||||
settings rather than relying on environment variable defaults.
|
||||
"""
|
||||
|
||||
|
||||
def get_weather(
|
||||
location: Annotated[str, Field(description="The location to get the weather for.")],
|
||||
) -> str:
|
||||
"""Get the weather for a given location."""
|
||||
conditions = ["sunny", "cloudy", "rainy", "stormy"]
|
||||
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
print("=== Azure AI Chat Client with Explicit Settings ===")
|
||||
|
||||
# Since no Agent ID is provided, the agent will be automatically created
|
||||
# and deleted after getting a response
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
ChatAgent(
|
||||
chat_client=AzureAIAgentClient(
|
||||
project_endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"],
|
||||
model_deployment_name=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
|
||||
async_credential=credential,
|
||||
agent_name="WeatherAgent",
|
||||
should_cleanup_agent=True, # Set to False if you want to disable automatic agent cleanup
|
||||
),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
) as agent,
|
||||
):
|
||||
result = await agent.run("What's the weather like in New York?")
|
||||
print(f"Result: {result}\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,91 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
from pathlib import Path
|
||||
|
||||
from agent_framework import ChatAgent, HostedFileSearchTool, HostedVectorStoreContent
|
||||
from agent_framework.azure import AzureAIAgentClient
|
||||
from azure.ai.agents.models import FileInfo, VectorStore
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
|
||||
"""
|
||||
The following sample demonstrates how to create a simple, Azure AI agent that
|
||||
uses a file search tool to answer user questions.
|
||||
"""
|
||||
|
||||
|
||||
# Simulate a conversation with the agent
|
||||
USER_INPUTS = [
|
||||
"Who is the youngest employee?",
|
||||
"Who works in sales?",
|
||||
"I have a customer request, who can help me?",
|
||||
]
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
"""Main function demonstrating Azure AI agent with file search capabilities."""
|
||||
client = AzureAIAgentClient(async_credential=AzureCliCredential())
|
||||
file: FileInfo | None = None
|
||||
vector_store: VectorStore | None = None
|
||||
|
||||
try:
|
||||
# 1. Upload file and create vector store
|
||||
pdf_file_path = Path(__file__).parent.parent / "resources" / "employees.pdf"
|
||||
print(f"Uploading file from: {pdf_file_path}")
|
||||
|
||||
file = await client.agents_client.files.upload_and_poll(file_path=str(pdf_file_path), purpose="assistants")
|
||||
print(f"Uploaded file, file ID: {file.id}")
|
||||
|
||||
vector_store = await client.agents_client.vector_stores.create_and_poll(
|
||||
file_ids=[file.id], name="my_vectorstore"
|
||||
)
|
||||
print(f"Created vector store, vector store ID: {vector_store.id}")
|
||||
|
||||
# 2. Create file search tool with uploaded resources
|
||||
file_search_tool = HostedFileSearchTool(inputs=[HostedVectorStoreContent(vector_store_id=vector_store.id)])
|
||||
|
||||
# 3. Create an agent with file search capabilities
|
||||
# The tool_resources are automatically extracted from HostedFileSearchTool
|
||||
async with ChatAgent(
|
||||
chat_client=client,
|
||||
name="EmployeeSearchAgent",
|
||||
instructions=(
|
||||
"You are a helpful assistant that can search through uploaded employee files "
|
||||
"to answer questions about employees."
|
||||
),
|
||||
tools=file_search_tool,
|
||||
) as agent:
|
||||
# 4. Simulate conversation with the agent
|
||||
for user_input in USER_INPUTS:
|
||||
print(f"# User: '{user_input}'")
|
||||
response = await agent.run(user_input)
|
||||
print(f"# Agent: {response.text}")
|
||||
|
||||
# 5. Cleanup: Delete the vector store and file
|
||||
try:
|
||||
if vector_store:
|
||||
await client.agents_client.vector_stores.delete(vector_store.id)
|
||||
if file:
|
||||
await client.agents_client.files.delete(file.id)
|
||||
except Exception:
|
||||
# Ignore cleanup errors to avoid masking issues
|
||||
pass
|
||||
finally:
|
||||
# 6. Cleanup: Delete the vector store and file in case of earlier failure to prevent orphaned resources.
|
||||
|
||||
# Refreshing the client is required since chat agent closes it
|
||||
client = AzureAIAgentClient(async_credential=AzureCliCredential())
|
||||
try:
|
||||
if vector_store:
|
||||
await client.agents_client.vector_stores.delete(vector_store.id)
|
||||
if file:
|
||||
await client.agents_client.files.delete(file.id)
|
||||
except Exception:
|
||||
# Ignore cleanup errors to avoid masking issues
|
||||
pass
|
||||
finally:
|
||||
await client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,70 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
from typing import Any
|
||||
|
||||
from agent_framework import AgentProtocol, AgentRunResponse, AgentThread, HostedMCPTool
|
||||
from agent_framework.azure import AzureAIAgentClient
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
|
||||
"""
|
||||
Azure AI Agent with Hosted MCP Example
|
||||
|
||||
This sample demonstrates integration of Azure AI Agents with hosted Model Context Protocol (MCP)
|
||||
servers, including user approval workflows for function call security.
|
||||
"""
|
||||
|
||||
|
||||
async def handle_approvals_with_thread(query: str, agent: "AgentProtocol", thread: "AgentThread") -> AgentRunResponse:
|
||||
"""Here we let the thread deal with the previous responses, and we just rerun with the approval."""
|
||||
from agent_framework import ChatMessage
|
||||
|
||||
result = await agent.run(query, thread=thread, store=True)
|
||||
while len(result.user_input_requests) > 0:
|
||||
new_input: list[Any] = []
|
||||
for user_input_needed in result.user_input_requests:
|
||||
print(
|
||||
f"User Input Request for function from {agent.name}: {user_input_needed.function_call.name}"
|
||||
f" with arguments: {user_input_needed.function_call.arguments}"
|
||||
)
|
||||
user_approval = input("Approve function call? (y/n): ")
|
||||
new_input.append(
|
||||
ChatMessage(
|
||||
role="user",
|
||||
contents=[user_input_needed.create_response(user_approval.lower() == "y")],
|
||||
)
|
||||
)
|
||||
result = await agent.run(new_input, thread=thread, store=True)
|
||||
return result
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
"""Example showing Hosted MCP tools for a Azure AI Agent."""
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
AzureAIAgentClient(async_credential=credential) as chat_client,
|
||||
):
|
||||
agent = chat_client.create_agent(
|
||||
name="DocsAgent",
|
||||
instructions="You are a helpful assistant that can help with microsoft documentation questions.",
|
||||
tools=HostedMCPTool(
|
||||
name="Microsoft Learn MCP",
|
||||
url="https://learn.microsoft.com/api/mcp",
|
||||
),
|
||||
)
|
||||
thread = agent.get_new_thread()
|
||||
# First query
|
||||
query1 = "How to create an Azure storage account using az cli?"
|
||||
print(f"User: {query1}")
|
||||
result1 = await handle_approvals_with_thread(query1, agent, thread)
|
||||
print(f"{agent.name}: {result1}\n")
|
||||
print("\n=======================================\n")
|
||||
# Second query
|
||||
query2 = "What is Microsoft Agent Framework?"
|
||||
print(f"User: {query2}")
|
||||
result2 = await handle_approvals_with_thread(query2, agent, thread)
|
||||
print(f"{agent.name}: {result2}\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,154 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
from random import randint
|
||||
from typing import Annotated
|
||||
|
||||
from agent_framework import AgentThread, ChatAgent
|
||||
from agent_framework.azure import AzureAIAgentClient
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
from pydantic import Field
|
||||
|
||||
"""
|
||||
Azure AI Agent with Thread Management Example
|
||||
|
||||
This sample demonstrates thread management with Azure AI Agents, comparing
|
||||
automatic thread creation with explicit thread management for persistent context.
|
||||
"""
|
||||
|
||||
|
||||
def get_weather(
|
||||
location: Annotated[str, Field(description="The location to get the weather for.")],
|
||||
) -> str:
|
||||
"""Get the weather for a given location."""
|
||||
conditions = ["sunny", "cloudy", "rainy", "stormy"]
|
||||
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
|
||||
|
||||
|
||||
async def example_with_automatic_thread_creation() -> None:
|
||||
"""Example showing automatic thread creation (service-managed thread)."""
|
||||
print("=== Automatic Thread Creation Example ===")
|
||||
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
ChatAgent(
|
||||
chat_client=AzureAIAgentClient(async_credential=credential),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
) as agent,
|
||||
):
|
||||
# First conversation - no thread provided, will be created automatically
|
||||
first_query = "What's the weather like in Seattle?"
|
||||
print(f"User: {first_query}")
|
||||
first_result = await agent.run(first_query)
|
||||
print(f"Agent: {first_result.text}")
|
||||
|
||||
# Second conversation - still no thread provided, will create another new thread
|
||||
second_query = "What was the last city I asked about?"
|
||||
print(f"\nUser: {second_query}")
|
||||
second_result = await agent.run(second_query)
|
||||
print(f"Agent: {second_result.text}")
|
||||
print("Note: Each call creates a separate thread, so the agent doesn't remember previous context.\n")
|
||||
|
||||
|
||||
async def example_with_thread_persistence() -> None:
|
||||
"""Example showing thread persistence across multiple conversations."""
|
||||
print("=== Thread Persistence Example ===")
|
||||
print("Using the same thread across multiple conversations to maintain context.\n")
|
||||
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
ChatAgent(
|
||||
chat_client=AzureAIAgentClient(async_credential=credential),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
) as agent,
|
||||
):
|
||||
# Create a new thread that will be reused
|
||||
thread = agent.get_new_thread()
|
||||
|
||||
# First conversation
|
||||
first_query = "What's the weather like in Tokyo?"
|
||||
print(f"User: {first_query}")
|
||||
first_result = await agent.run(first_query, thread=thread)
|
||||
print(f"Agent: {first_result.text}")
|
||||
|
||||
# Second conversation using the same thread - maintains context
|
||||
second_query = "How about London?"
|
||||
print(f"\nUser: {second_query}")
|
||||
second_result = await agent.run(second_query, thread=thread)
|
||||
print(f"Agent: {second_result.text}")
|
||||
|
||||
# Third conversation - agent should remember both previous cities
|
||||
third_query = "Which of the cities I asked about has better weather?"
|
||||
print(f"\nUser: {third_query}")
|
||||
third_result = await agent.run(third_query, thread=thread)
|
||||
print(f"Agent: {third_result.text}")
|
||||
print("Note: The agent remembers context from previous messages in the same thread.\n")
|
||||
|
||||
|
||||
async def example_with_existing_thread_id() -> None:
|
||||
"""Example showing how to work with an existing thread ID from the service."""
|
||||
print("=== Existing Thread ID Example ===")
|
||||
print("Using a specific thread ID to continue an existing conversation.\n")
|
||||
|
||||
# First, create a conversation and capture the thread ID
|
||||
existing_thread_id = None
|
||||
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
ChatAgent(
|
||||
chat_client=AzureAIAgentClient(async_credential=credential),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
) as agent,
|
||||
):
|
||||
# Start a conversation and get the thread ID
|
||||
thread = agent.get_new_thread()
|
||||
first_query = "What's the weather in Paris?"
|
||||
print(f"User: {first_query}")
|
||||
first_result = await agent.run(first_query, thread=thread)
|
||||
print(f"Agent: {first_result.text}")
|
||||
|
||||
# The thread ID is set after the first response
|
||||
existing_thread_id = thread.service_thread_id
|
||||
print(f"Thread ID: {existing_thread_id}")
|
||||
|
||||
if existing_thread_id:
|
||||
print("\n--- Continuing with the same thread ID in a new agent instance ---")
|
||||
|
||||
# Create a new agent instance but use the existing thread ID
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
ChatAgent(
|
||||
chat_client=AzureAIAgentClient(thread_id=existing_thread_id, async_credential=credential),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
) as agent,
|
||||
):
|
||||
# Create a thread with the existing ID
|
||||
thread = AgentThread(service_thread_id=existing_thread_id)
|
||||
|
||||
second_query = "What was the last city I asked about?"
|
||||
print(f"User: {second_query}")
|
||||
second_result = await agent.run(second_query, thread=thread)
|
||||
print(f"Agent: {second_result.text}")
|
||||
print("Note: The agent continues the conversation from the previous thread.\n")
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
print("=== Azure AI Chat Client Agent Thread Management Examples ===\n")
|
||||
|
||||
await example_with_automatic_thread_creation()
|
||||
await example_with_thread_persistence()
|
||||
await example_with_existing_thread_id()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
+4
-6
@@ -1,7 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import os
|
||||
import asyncio
|
||||
import os
|
||||
|
||||
from agent_framework import ChatAgent, MCPStreamableHTTPTool
|
||||
from agent_framework.azure import AzureOpenAIResponsesClient
|
||||
@@ -18,13 +18,14 @@ servers.
|
||||
# --- Below code uses Microsoft Learn MCP server over Streamable HTTP ---
|
||||
# --- Users can set these environment variables, or just edit the values below to their desired local MCP server
|
||||
MCP_NAME = os.environ.get("MCP_NAME", "Microsoft Learn MCP") # example name
|
||||
MCP_URL = os.environ.get("MCP_URL", "https://learn.microsoft.com/api/mcp") # example endpoint
|
||||
MCP_URL = os.environ.get("MCP_URL", "https://learn.microsoft.com/api/mcp") # example endpoint
|
||||
|
||||
# Environment variables for Azure OpenAI Responses authentication
|
||||
# AZURE_OPENAI_ENDPOINT="<your-azure openai-endpoint>"
|
||||
# AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME="<your-deployment-name>"
|
||||
# AZURE_OPENAI_API_VERSION="<your-api-version>" # e.g. "2025-03-01-preview"
|
||||
|
||||
|
||||
async def main():
|
||||
"""Example showing local MCP tools for a Azure OpenAI Responses Agent."""
|
||||
# AuthN: use Azure CLI
|
||||
@@ -38,16 +39,13 @@ async def main():
|
||||
|
||||
agent: ChatAgent = responses_client.create_agent(
|
||||
name="DocsAgent",
|
||||
instructions=(
|
||||
"You are a helpful assistant that can help with Microsoft documentation questions."
|
||||
),
|
||||
instructions=("You are a helpful assistant that can help with Microsoft documentation questions."),
|
||||
)
|
||||
|
||||
# Connect to the MCP server (Streamable HTTP)
|
||||
async with MCPStreamableHTTPTool(
|
||||
name=MCP_NAME,
|
||||
url=MCP_URL,
|
||||
|
||||
) as mcp_tool:
|
||||
# First query — expect the agent to use the MCP tool if it helps
|
||||
q1 = "How to create an Azure storage account using az cli?"
|
||||
|
||||
+13
-15
@@ -2,7 +2,7 @@
|
||||
|
||||
import asyncio
|
||||
|
||||
from agent_framework import HostedWebSearchTool
|
||||
from agent_framework import ChatAgent, HostedWebSearchTool
|
||||
from agent_framework.openai import OpenAIChatClient
|
||||
|
||||
"""
|
||||
@@ -14,34 +14,32 @@ for real-time information retrieval and current data access.
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
client = OpenAIChatClient(model_id="gpt-4o-search-preview")
|
||||
|
||||
message = "What is the current weather? Do not ask for my current location."
|
||||
# Test that the client will use the web search tool with location
|
||||
# Test that the agent will use the web search tool with location
|
||||
additional_properties = {
|
||||
"user_location": {
|
||||
"country": "US",
|
||||
"city": "Seattle",
|
||||
}
|
||||
}
|
||||
|
||||
agent = ChatAgent(
|
||||
chat_client=OpenAIChatClient(model_id="gpt-4o-search-preview"),
|
||||
instructions="You are a helpful assistant that can search the web for current information.",
|
||||
tools=[HostedWebSearchTool(additional_properties=additional_properties)],
|
||||
)
|
||||
|
||||
message = "What is the current weather? Do not ask for my current location."
|
||||
stream = False
|
||||
print(f"User: {message}")
|
||||
|
||||
if stream:
|
||||
print("Assistant: ", end="")
|
||||
async for chunk in client.get_streaming_response(
|
||||
message,
|
||||
tools=[HostedWebSearchTool(additional_properties=additional_properties)],
|
||||
tool_choice="auto",
|
||||
):
|
||||
async for chunk in agent.run_stream(message):
|
||||
if chunk.text:
|
||||
print(chunk.text, end="")
|
||||
print("")
|
||||
else:
|
||||
response = await client.get_response(
|
||||
message,
|
||||
tools=[HostedWebSearchTool(additional_properties=additional_properties)],
|
||||
tool_choice="auto",
|
||||
)
|
||||
response = await agent.run(message)
|
||||
print(f"Assistant: {response}")
|
||||
|
||||
|
||||
|
||||
+10
-11
@@ -2,7 +2,7 @@
|
||||
|
||||
import asyncio
|
||||
|
||||
from agent_framework import HostedFileSearchTool, HostedVectorStoreContent
|
||||
from agent_framework import ChatAgent, HostedFileSearchTool, HostedVectorStoreContent
|
||||
from agent_framework.openai import OpenAIResponsesClient
|
||||
|
||||
"""
|
||||
@@ -46,22 +46,21 @@ async def main() -> None:
|
||||
stream = False
|
||||
print(f"User: {message}")
|
||||
file_id, vector_store = await create_vector_store(client)
|
||||
|
||||
agent = ChatAgent(
|
||||
chat_client=client,
|
||||
instructions="You are a helpful assistant that can search through files to find information.",
|
||||
tools=[HostedFileSearchTool(inputs=vector_store)],
|
||||
)
|
||||
|
||||
if stream:
|
||||
print("Assistant: ", end="")
|
||||
async for chunk in client.get_streaming_response(
|
||||
message,
|
||||
tools=[HostedFileSearchTool(inputs=vector_store)],
|
||||
tool_choice="auto",
|
||||
):
|
||||
async for chunk in agent.run_stream(message):
|
||||
if chunk.text:
|
||||
print(chunk.text, end="")
|
||||
print("")
|
||||
else:
|
||||
response = await client.get_response(
|
||||
message,
|
||||
tools=[HostedFileSearchTool(inputs=vector_store)],
|
||||
tool_choice="auto",
|
||||
)
|
||||
response = await agent.run(message)
|
||||
print(f"Assistant: {response}")
|
||||
await delete_vector_store(client, file_id, vector_store.vector_store_id)
|
||||
|
||||
|
||||
+13
-15
@@ -2,7 +2,7 @@
|
||||
|
||||
import asyncio
|
||||
|
||||
from agent_framework import HostedWebSearchTool
|
||||
from agent_framework import ChatAgent, HostedWebSearchTool
|
||||
from agent_framework.openai import OpenAIResponsesClient
|
||||
|
||||
"""
|
||||
@@ -14,34 +14,32 @@ for direct real-time information retrieval and current data access.
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
client = OpenAIResponsesClient()
|
||||
|
||||
message = "What is the current weather? Do not ask for my current location."
|
||||
# Test that the client will use the web search tool with location
|
||||
# Test that the agent will use the web search tool with location
|
||||
additional_properties = {
|
||||
"user_location": {
|
||||
"country": "US",
|
||||
"city": "Seattle",
|
||||
}
|
||||
}
|
||||
|
||||
agent = ChatAgent(
|
||||
chat_client=OpenAIResponsesClient(),
|
||||
instructions="You are a helpful assistant that can search the web for current information.",
|
||||
tools=[HostedWebSearchTool(additional_properties=additional_properties)],
|
||||
)
|
||||
|
||||
message = "What is the current weather? Do not ask for my current location."
|
||||
stream = False
|
||||
print(f"User: {message}")
|
||||
|
||||
if stream:
|
||||
print("Assistant: ", end="")
|
||||
async for chunk in client.get_streaming_response(
|
||||
message,
|
||||
tools=[HostedWebSearchTool(additional_properties=additional_properties)],
|
||||
tool_choice="auto",
|
||||
):
|
||||
async for chunk in agent.run_stream(message):
|
||||
if chunk.text:
|
||||
print(chunk.text, end="")
|
||||
print("")
|
||||
else:
|
||||
response = await client.get_response(
|
||||
message,
|
||||
tools=[HostedWebSearchTool(additional_properties=additional_properties)],
|
||||
tool_choice="auto",
|
||||
)
|
||||
response = await agent.run(message)
|
||||
print(f"Assistant: {response}")
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user