├── .env ├── README.md ├── ai_agent_create.py ├── ai_agent_existing.py ├── multi-agent.py └── requirements.txt /.env: -------------------------------------------------------------------------------- 1 | AZURE_AI_AGENT_PROJECT_CONNECTION_STRING = "xxxxxxx" 2 | AZURE_AI_AGENT_MODEL_DEPLOYMENT_NAME = "xxxxx" 3 | SERP_API_KEY=xxxxxx 4 | SERP_ENDPOINT=https://serpapi.com/search.json 5 | AZURE_AI_PROJECT_CONNECTION_STRING=xxxxxxx 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Multi-Agent-Semantic-Kernel-Azure-Agent-Service-Python 2 | Multi-Agent AI Application(Python) that uses Semantic-Kernel along with Azure AI Agent Service in Azure Ai Foundry 3 | 4 | # Watch the Video for Step by Step Configuration 5 | 6 | [![Video Title](https://img.youtube.com/vi/bHVRrMCPzwM/0.jpg)](https://www.youtube.com/watch?v=bHVRrMCPzwM) 7 | -------------------------------------------------------------------------------- /ai_agent_create.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | from azure.identity.aio import DefaultAzureCredential 3 | from semantic_kernel.agents.azure_ai import AzureAIAgent, AzureAIAgentSettings 4 | 5 | 6 | async def main() -> None: 7 | # Create default agent settings (ensuring model_deployment_name is set via your environment). 8 | ai_agent_settings = AzureAIAgentSettings.create() 9 | 10 | async with ( 11 | DefaultAzureCredential() as creds, 12 | AzureAIAgent.create_client(credential=creds) as client, 13 | ): 14 | # 1. Create an agent on the Azure AI agent service. 15 | # This agent is named "TechSupportAdvisor" with instructions for providing technical support. 16 | agent_definition = await client.agents.create_agent( 17 | model=ai_agent_settings.model_deployment_name, 18 | name="TechSupportAdvisor", 19 | instructions="You are a helpful assistant that provides technical support regarding Azure services. Keep the answers short and concise", 20 | ) 21 | 22 | # 2. Create a Semantic Kernel agent using the retrieved agent definition. 23 | agent = AzureAIAgent(client=client, definition=agent_definition) 24 | 25 | # 3. Start a new conversation thread on the Azure AI agent service. 26 | thread = await client.agents.create_thread() 27 | 28 | try: 29 | # 4. Send a single query to the agent. 30 | user_query = "Can Azure App Services be integrated with Vnet?" 31 | await agent.add_chat_message(thread_id=thread.id, message=user_query) 32 | print(f"# User: {user_query}") 33 | 34 | # 5. Retrieve and print the agent's response. 35 | response = await agent.get_response(thread_id=thread.id) 36 | print(f"# TechSupportAdvisor: {response}") 37 | finally: 38 | # 6. Cleanup: Delete the conversation thread and the created agent. 39 | await client.agents.delete_thread(thread.id) 40 | await client.agents.delete_agent(agent.id) 41 | 42 | if __name__ == "__main__": 43 | asyncio.run(main()) 44 | -------------------------------------------------------------------------------- /ai_agent_existing.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | from azure.identity.aio import DefaultAzureCredential 3 | from semantic_kernel.agents.azure_ai import AzureAIAgent 4 | 5 | 6 | async def main() -> None: 7 | # Use asynchronous context managers to authenticate and create the client. 8 | async with ( 9 | DefaultAzureCredential() as creds, 10 | AzureAIAgent.create_client(credential=creds) as client, 11 | ): 12 | # 1. Retrieve the agent definition based on the assistant ID. 13 | # Replace "asst_MwpyijFo7T4MEzwvS8Pb5F98" with your actual assistant ID. 14 | agent_definition = await client.agents.get_agent( 15 | assistant_id="xxxxxxx", 16 | ) 17 | 18 | # 2. Create a Semantic Kernel agent using the retrieved definition. 19 | agent = AzureAIAgent(client=client, definition=agent_definition) 20 | 21 | # 3. Create a new conversation thread. 22 | thread = await client.agents.create_thread() 23 | 24 | try: 25 | # 4. Define the single query and add it as a chat message. 26 | user_query = "Can Azure App Services be integrated with Vnet?" 27 | await agent.add_chat_message(thread_id=thread.id, message=user_query) 28 | print(f"# User: {user_query}") 29 | 30 | # 5. Retrieve and print the agent's response. 31 | response = await agent.get_response(thread_id=thread.id) 32 | print(f"# Agent: {response}") 33 | finally: 34 | # 6. Cleanup: Delete the conversation thread. 35 | await client.agents.delete_thread(thread.id) 36 | # Note: The agent is not deleted so it can be reused later. 37 | 38 | if __name__ == "__main__": 39 | asyncio.run(main()) 40 | -------------------------------------------------------------------------------- /multi-agent.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import os 3 | import aiohttp 4 | from dotenv import load_dotenv 5 | 6 | from azure.identity.aio import DefaultAzureCredential 7 | from azure.ai.projects import AIProjectClient 8 | from semantic_kernel.agents.azure_ai import AzureAIAgent 9 | 10 | # Load configuration from .env file 11 | load_dotenv() 12 | 13 | # ----- Agent IDs Configuration ----- 14 | # Document Search Agent (Agent 1) 15 | AGENT1_ID = "xxxxx" 16 | 17 | # Web Search Agent (Agent 2) 18 | AGENT2_ID = "xxxxxx" 19 | 20 | # Summary Agent (Agent 3) 21 | AGENT3_ID = "xxxxxx" 22 | 23 | # ----- SERP API and Azure Project Configuration ----- 24 | SERP_API_KEY = os.environ.get("SERP_API_KEY") 25 | SERP_ENDPOINT = os.environ.get("SERP_ENDPOINT", "https://serpapi.com/search.json") 26 | PROJECT_CONN_STR = os.environ.get("AZURE_AI_PROJECT_CONNECTION_STRING") 27 | 28 | 29 | async def search_web(query: str) -> str: 30 | """ 31 | Perform a web search using the SERP API and return a combined snippet summary. 32 | """ 33 | params = { 34 | "api_key": SERP_API_KEY, 35 | "q": query, 36 | "location": "Australia", 37 | "hl": "en" 38 | } 39 | async with aiohttp.ClientSession() as session: 40 | async with session.get(SERP_ENDPOINT, params=params) as response: 41 | result = await response.json() 42 | snippets = [] 43 | if "organic_results" in result: 44 | for item in result["organic_results"]: 45 | snippet = item.get("snippet") 46 | if snippet: 47 | snippets.append(snippet) 48 | return "\n".join(snippets) if snippets else "No results found." 49 | 50 | 51 | async def main(): 52 | # Prompt the user for a query regarding planning/building permits 53 | user_query = input("Enter your query for planning and building permit info: ") 54 | 55 | # Initialize credentials and the Azure AI Projects client 56 | credential = DefaultAzureCredential() 57 | try: 58 | project_client = AIProjectClient.from_connection_string( 59 | conn_str=PROJECT_CONN_STR, 60 | credential=credential 61 | ) 62 | print("✅ Project client initialized.") 63 | except Exception as e: 64 | print(f"❌ Error initializing project client: {e}") 65 | return 66 | 67 | # Use the async context for proper cleanup of the credential and client 68 | async with credential, AzureAIAgent.create_client(credential=credential) as client: 69 | # Retrieve pre-created agent definitions for each role 70 | document_agent_def = await client.agents.get_agent(assistant_id=AGENT1_ID) 71 | web_agent_def = await client.agents.get_agent(assistant_id=AGENT2_ID) 72 | summary_agent_def = await client.agents.get_agent(assistant_id=AGENT3_ID) 73 | 74 | # Instantiate Semantic Kernel agent objects 75 | document_agent = AzureAIAgent(client=client, definition=document_agent_def) 76 | web_agent = AzureAIAgent(client=client, definition=web_agent_def) 77 | summary_agent = AzureAIAgent(client=client, definition=summary_agent_def) 78 | 79 | # ----- Agent 1: Document Search Agent ----- 80 | # Create a thread for Agent 1 and send the user's query as a chat message. 81 | thread1 = await client.agents.create_thread() 82 | await document_agent.add_chat_message( 83 | thread_id=thread1.id, 84 | message=user_query 85 | ) 86 | response_doc = await document_agent.get_response(thread_id=thread1.id) 87 | print("\n[Document Search Agent Response]") 88 | print(response_doc) 89 | 90 | # ----- Agent 2: Web Search Agent ----- 91 | # Perform a SERP API search with the user's query. 92 | web_results = await search_web(user_query) 93 | thread2 = await client.agents.create_thread() 94 | await web_agent.add_chat_message( 95 | thread_id=thread2.id, 96 | message=f"Web search results for '{user_query}':\n{web_results}" 97 | ) 98 | response_web = await web_agent.get_response(thread_id=thread2.id) 99 | print("\n[Web Search Agent Response]") 100 | print(response_web) 101 | 102 | # ----- Agent 3: Summary Agent ----- 103 | # Combine responses from Agent 1 and Agent 2 and send to Agent 3 for summarization. 104 | combined_info = ( 105 | f"Document Agent info: {response_doc}\n\n" 106 | f"Web Agent info: {response_web}" 107 | ) 108 | thread3 = await client.agents.create_thread() 109 | await summary_agent.add_chat_message( 110 | thread_id=thread3.id, 111 | message=combined_info 112 | ) 113 | response_summary = await summary_agent.get_response(thread_id=thread3.id) 114 | print("\n[Summary Agent Response]") 115 | print(response_summary) 116 | 117 | # ----- Optional Cleanup: Delete the conversation threads ----- 118 | for thread in [thread1, thread2, thread3]: 119 | try: 120 | await client.agents.delete_thread(thread.id) 121 | except Exception as e: 122 | print(f"❌ Error deleting thread {thread.id}: {e}") 123 | 124 | 125 | if __name__ == "__main__": 126 | asyncio.run(main()) 127 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | azure-ai-projects 2 | azure-identity 3 | semantic-kernel[azure] 4 | aiohttp 5 | python-dotenv --------------------------------------------------------------------------------