From 3a53989d63e5379f23910f77a0d21b2801fb6525 Mon Sep 17 00:00:00 2001 From: Ryan Hill Date: Mon, 20 Oct 2025 10:02:26 -0400 Subject: [PATCH] Add notebook to create agent using semantic kernel --- .../4.BuildAgentUsingSemanticKernel.ipynb | 1398 +++++++++++++++++ 1 file changed, 1398 insertions(+) create mode 100644 notebooks/SemanticKernal/4.BuildAgentUsingSemanticKernel.ipynb diff --git a/notebooks/SemanticKernal/4.BuildAgentUsingSemanticKernel.ipynb b/notebooks/SemanticKernal/4.BuildAgentUsingSemanticKernel.ipynb new file mode 100644 index 0000000..1b4b991 --- /dev/null +++ b/notebooks/SemanticKernal/4.BuildAgentUsingSemanticKernel.ipynb @@ -0,0 +1,1398 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "0870bd08", + "metadata": {}, + "source": [ + "# Build an Intelligent Agent with Semantic Kernel\n", + "\n", + "## Workshop Overview\n", + "\n", + "Welcome to this hands-on tutorial where you'll learn how to build an **intelligent AI agent** using **Microsoft Semantic Kernel**!\n", + "\n", + "This notebook builds upon the RAG concepts from the previous Semantic Kernel tutorial and extends them to create a fully capable AI agent that can:\n", + "\n", + "- šŸ¤– **Auto-select tools** - Automatically choose which functions to call\n", + "- šŸ’­ **Maintain memory** - Remember conversation context and history\n", + "- šŸ”„ **Chain operations** - Combine multiple tools to solve complex tasks\n", + "- ⚔ **Stream responses** - Provide real-time feedback during processing\n", + "- 🧠 **Reason step-by-step** - Show its thinking process transparently\n", + "\n", + "### What You'll Build\n", + "\n", + "By the end of this tutorial, you'll have created an intelligent agent that can:\n", + "\n", + "1. **Search documents** automatically when questions require specific information\n", + "2. **Perform calculations** when mathematical operations are needed\n", + "3. **Handle utilities** like text processing, time queries, and formatting\n", + "4. **Remember conversations** and build upon previous interactions\n", + "5. **Chain multiple tools** together to solve complex multi-step problems\n", + "\n", + "### Agent Architecture in Semantic Kernel\n", + "\n", + "Unlike simple chatbots, **agents** are AI systems that can:\n", + "- **Perceive** their environment (through tools and data access)\n", + "- **Reason** about what actions to take (via function calling)\n", + "- **Act** on the environment (by executing tools and functions)\n", + "- **Learn** from interactions (through memory and context)\n", + "\n", + "**Semantic Kernel's agent approach:**\n", + "- āœ… **Unified orchestration** - One kernel manages all services and tools\n", + "- āœ… **Declarative tools** - Functions decorated with `@kernel_function`\n", + "- āœ… **Automatic function calling** - LLM decides which tools to use\n", + "- āœ… **Built-in memory** - Conversation state management\n", + "- āœ… **Extensible architecture** - Easy to add new capabilities\n", + "\n", + "### Prerequisites\n", + "\n", + "This tutorial assumes you've completed the **Semantic Kernel RAG tutorial**. We'll build upon:\n", + "- Kernel setup and Azure OpenAI configuration\n", + "- Plugin architecture and function decorators\n", + "- Vector embeddings and document search\n", + "- Auto function calling capabilities\n", + "\n", + "---\n", + "\n", + "Let's build an intelligent agent! šŸš€" + ] + }, + { + "cell_type": "markdown", + "id": "7f03240f", + "metadata": {}, + "source": [ + "## Section 1: Environment Setup and Dependencies\n", + "\n", + "Before building our agent, let's install the required packages and set up our environment.\n", + "\n", + "### What We'll Install:\n", + "\n", + "- **semantic-kernel** - Core AI orchestration SDK\n", + "- **python-dotenv** - Environment variable management \n", + "- **aiohttp** - Async HTTP client for web requests\n", + "- **numpy** - For numerical operations in tools\n", + "- **requests** - For web-based tool functions\n", + "\n", + "### Agent-Specific Features:\n", + "\n", + "Our agent will have enhanced capabilities beyond the basic RAG system:\n", + "- **Multiple tool plugins** - Search, calculation, utility functions\n", + "- **Conversation memory** - Maintain state across interactions \n", + "- **Streaming responses** - Real-time response generation\n", + "- **Multi-step reasoning** - Chain tool calls together\n", + "\n", + "Let's get started!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "134be0f1", + "metadata": {}, + "outputs": [], + "source": [ + "# Install required packages for agent development\n", + "%pip install semantic-kernel python-dotenv\n", + "%pip install aiohttp requests\n", + "%pip install numpy\n", + "%pip install faiss-cpu" + ] + }, + { + "cell_type": "markdown", + "id": "e73bcb38", + "metadata": {}, + "source": [ + "## Section 2: Initialize Semantic Kernel with Azure OpenAI Services\n", + "\n", + "Let's set up our kernel with all the services our agent will need.\n", + "\n", + "### Agent Kernel Architecture\n", + "\n", + "Our agent kernel will include:\n", + "1. **Chat Completion Service** - For reasoning and conversation\n", + "2. **Text Embedding Service** - For semantic search capabilities\n", + "3. **Multiple Plugins** - Tools the agent can use\n", + "4. **Memory Management** - Conversation state tracking\n", + "5. **Auto Function Calling** - Autonomous tool selection\n", + "\n", + "This creates a complete agent runtime environment!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7b816add", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "from dotenv import load_dotenv\n", + "from datetime import datetime\n", + "import asyncio\n", + "\n", + "# Import Semantic Kernel components\n", + "from semantic_kernel import Kernel\n", + "from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion, AzureTextEmbedding\n", + "from semantic_kernel.connectors.ai.function_choice_behavior import FunctionChoiceBehavior\n", + "from semantic_kernel.functions import KernelArguments\n", + "\n", + "# Load environment variables\n", + "load_dotenv()\n", + "\n", + "# Create the agent kernel\n", + "agent_kernel = Kernel()\n", + "\n", + "# Add Azure OpenAI Chat Completion service\n", + "chat_completion = AzureChatCompletion(\n", + " service_id=\"agent_chat\",\n", + " api_key=os.getenv(\"AZURE_OPENAI_API_KEY\"),\n", + " endpoint=os.getenv(\"AZURE_OPENAI_ENDPOINT\"),\n", + " deployment_name=os.getenv(\"AZURE_OPENAI_DEPLOYMENT_NAME\"),\n", + ")\n", + "agent_kernel.add_service(chat_completion)\n", + "\n", + "# Add Azure Text Embedding service for search capabilities\n", + "text_embedding = AzureTextEmbedding(\n", + " service_id=\"agent_embedding\",\n", + " api_key=os.getenv(\"AZURE_OPENAI_API_KEY\"),\n", + " endpoint=os.getenv(\"AZURE_OPENAI_ENDPOINT\"),\n", + " deployment_name=os.getenv(\"AZURE_OPENAI_ADA_DEPLOYMENT\")\n", + ")\n", + "agent_kernel.add_service(text_embedding)\n", + "\n", + "print(\"āœ“ Agent Kernel initialized with Azure OpenAI services\")\n", + "print(\"āœ“ Chat completion service added\")\n", + "print(\"āœ“ Text embedding service added\")\n", + "print(\"āœ“ Ready to build agent capabilities!\")" + ] + }, + { + "cell_type": "markdown", + "id": "21e24045", + "metadata": {}, + "source": [ + "## Section 3: Create Tool Functions for the Agent\n", + "\n", + "Now let's build a comprehensive toolkit for our agent! We'll create multiple plugins that give our agent diverse capabilities.\n", + "\n", + "### Agent Tool Architecture\n", + "\n", + "Our agent will have access to several categories of tools:\n", + "\n", + "1. **SearchPlugin** - Web search and information retrieval\n", + "2. **CalculatorPlugin** - Mathematical operations and computations \n", + "3. **UtilityPlugin** - Text processing, time queries, and formatting\n", + "4. **DocumentPlugin** - Vector search through knowledge base\n", + "\n", + "Each tool is a **@kernel_function** that the agent can automatically choose to use based on the user's request.\n", + "\n", + "### Why Multiple Tools Matter\n", + "\n", + "Real-world agents need diverse capabilities:\n", + "- **Search** when users ask about current events or external information\n", + "- **Calculate** when mathematical operations are required\n", + "- **Process text** when formatting or analysis is needed\n", + "- **Query documents** when domain-specific knowledge is required\n", + "\n", + "Let's build these tools!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a142badd", + "metadata": {}, + "outputs": [], + "source": [ + "import math\n", + "import requests\n", + "import json\n", + "from typing import Union\n", + "from semantic_kernel.functions import kernel_function\n", + "\n", + "# 1. Calculator Plugin - Mathematical operations\n", + "class CalculatorPlugin:\n", + " \"\"\"Plugin providing mathematical calculation capabilities for the agent.\"\"\"\n", + " \n", + " @kernel_function(\n", + " name=\"calculate\",\n", + " description=\"Performs mathematical calculations. Supports +, -, *, /, **, sqrt, sin, cos, tan, log\"\n", + " )\n", + " def calculate(self, expression: str) -> str:\n", + " \"\"\"Safely evaluates mathematical expressions.\"\"\"\n", + " try:\n", + " # Replace common math functions\n", + " safe_expr = expression.lower()\n", + " safe_expr = safe_expr.replace(\"sqrt(\", \"math.sqrt(\")\n", + " safe_expr = safe_expr.replace(\"sin(\", \"math.sin(\")\n", + " safe_expr = safe_expr.replace(\"cos(\", \"math.cos(\")\n", + " safe_expr = safe_expr.replace(\"tan(\", \"math.tan(\")\n", + " safe_expr = safe_expr.replace(\"log(\", \"math.log(\")\n", + " safe_expr = safe_expr.replace(\"pi\", \"math.pi\")\n", + " safe_expr = safe_expr.replace(\"e\", \"math.e\")\n", + " \n", + " # Evaluate safely (restricted namespace)\n", + " allowed_names = {\n", + " \"__builtins__\": {},\n", + " \"math\": math,\n", + " \"abs\": abs,\n", + " \"round\": round,\n", + " \"min\": min,\n", + " \"max\": max\n", + " }\n", + " result = eval(safe_expr, allowed_names)\n", + " return f\"Result: {result}\"\n", + " except Exception as e:\n", + " return f\"Calculation error: {str(e)}\"\n", + " \n", + " @kernel_function(\n", + " name=\"statistics\",\n", + " description=\"Calculates basic statistics (mean, median, mode, std dev) for a list of numbers\"\n", + " )\n", + " def statistics(self, numbers: str) -> str:\n", + " \"\"\"Calculates statistics for comma-separated numbers.\"\"\"\n", + " try:\n", + " num_list = [float(x.strip()) for x in numbers.split(\",\")]\n", + " \n", + " mean = sum(num_list) / len(num_list)\n", + " sorted_nums = sorted(num_list)\n", + " n = len(sorted_nums)\n", + " median = sorted_nums[n//2] if n % 2 == 1 else (sorted_nums[n//2-1] + sorted_nums[n//2]) / 2\n", + " \n", + " # Standard deviation\n", + " variance = sum((x - mean) ** 2 for x in num_list) / len(num_list)\n", + " std_dev = math.sqrt(variance)\n", + " \n", + " return f\"Statistics: Mean={mean:.2f}, Median={median:.2f}, Std Dev={std_dev:.2f}\"\n", + " except Exception as e:\n", + " return f\"Statistics error: {str(e)}\"\n", + "\n", + "\n", + "# 2. Utility Plugin - Text processing and general utilities\n", + "class UtilityPlugin:\n", + " \"\"\"Plugin providing text processing and utility functions for the agent.\"\"\"\n", + " \n", + " @kernel_function(\n", + " name=\"get_current_time\",\n", + " description=\"Returns the current date and time\"\n", + " )\n", + " def get_current_time(self) -> str:\n", + " \"\"\"Gets current timestamp.\"\"\"\n", + " now = datetime.now()\n", + " return f\"Current time: {now.strftime('%Y-%m-%d %H:%M:%S')}\"\n", + " \n", + " @kernel_function(\n", + " name=\"text_analysis\",\n", + " description=\"Analyzes text for word count, character count, and reading time estimate\"\n", + " )\n", + " def text_analysis(self, text: str) -> str:\n", + " \"\"\"Analyzes text properties.\"\"\"\n", + " words = len(text.split())\n", + " characters = len(text)\n", + " characters_no_spaces = len(text.replace(\" \", \"\"))\n", + " sentences = len([s for s in text.split(\".\") if s.strip()])\n", + " \n", + " # Estimate reading time (average 200 words per minute)\n", + " reading_time = words / 200\n", + " \n", + " return f\"Text Analysis: {words} words, {characters} chars ({characters_no_spaces} no spaces), {sentences} sentences, ~{reading_time:.1f} min read time\"\n", + " \n", + " @kernel_function(\n", + " name=\"format_text\",\n", + " description=\"Formats text in various ways: uppercase, lowercase, title case, or sentence case\"\n", + " )\n", + " def format_text(self, text: str, format_type: str = \"title\") -> str:\n", + " \"\"\"Formats text according to specified type.\"\"\"\n", + " format_type = format_type.lower()\n", + " \n", + " if format_type == \"upper\":\n", + " return text.upper()\n", + " elif format_type == \"lower\":\n", + " return text.lower()\n", + " elif format_type == \"title\":\n", + " return text.title()\n", + " elif format_type == \"sentence\":\n", + " return text.capitalize()\n", + " else:\n", + " return f\"Unknown format '{format_type}'. Use: upper, lower, title, or sentence\"\n", + "\n", + "\n", + "# 3. Search Plugin - Web search capabilities\n", + "class SearchPlugin:\n", + " \"\"\"Plugin providing web search capabilities for the agent.\"\"\"\n", + " \n", + " @kernel_function(\n", + " name=\"web_search\",\n", + " description=\"Searches the web for current information about a topic\"\n", + " )\n", + " def web_search(self, query: str) -> str:\n", + " \"\"\"Simulated web search function (replace with real API in production).\"\"\"\n", + " # In a real implementation, you'd use APIs like Bing Search, Google Custom Search, etc.\n", + " search_results = {\n", + " \"AI\": \"AI (Artificial Intelligence) refers to computer systems that can perform tasks typically requiring human intelligence. Recent developments include large language models like GPT-4, multimodal AI systems, and advances in computer vision.\",\n", + " \"machine learning\": \"Machine learning is a subset of AI focusing on algorithms that improve through experience. Current trends include transformer architectures, reinforcement learning, and neural network optimization techniques.\",\n", + " \"semantic kernel\": \"Semantic Kernel is Microsoft's SDK for integrating AI services into applications. It provides a plugin architecture for combining AI models, prompts, and native code into unified workflows.\",\n", + " \"weather\": \"Weather information varies by location and time. For accurate weather data, check local meteorological services or weather APIs like OpenWeatherMap.\",\n", + " \"news\": \"Current news covers various topics including technology, politics, science, and world events. For up-to-date news, consult reliable news sources and fact-checking services.\"\n", + " }\n", + " \n", + " # Find best match\n", + " query_lower = query.lower()\n", + " for keyword, info in search_results.items():\n", + " if keyword in query_lower:\n", + " return f\"Search results for '{query}': {info}\"\n", + " \n", + " return f\"Search results for '{query}': No specific information found in demo database. In production, this would query real search APIs.\"\n", + " \n", + " @kernel_function(\n", + " name=\"get_definition\",\n", + " description=\"Gets the definition of a term or concept\"\n", + " )\n", + " def get_definition(self, term: str) -> str:\n", + " \"\"\"Gets definition of a term.\"\"\"\n", + " definitions = {\n", + " \"agent\": \"An AI agent is an autonomous system that perceives its environment, makes decisions, and takes actions to achieve specific goals.\",\n", + " \"kernel\": \"In Semantic Kernel, a kernel is the central orchestrator that manages AI services, plugins, and functions.\",\n", + " \"plugin\": \"A plugin in Semantic Kernel is a collection of functions that extend the kernel's capabilities.\",\n", + " \"embedding\": \"An embedding is a vector representation of text that captures semantic meaning for similarity search.\",\n", + " \"rag\": \"RAG (Retrieval Augmented Generation) combines retrieval from knowledge sources with generative AI to provide accurate, grounded responses.\",\n", + " \"function calling\": \"Function calling enables AI models to automatically select and execute appropriate tools based on user requests.\"\n", + " }\n", + " \n", + " term_lower = term.lower()\n", + " if term_lower in definitions:\n", + " return f\"Definition of '{term}': {definitions[term_lower]}\"\n", + " else:\n", + " return f\"Definition not found for '{term}'. Try searching for more information.\"\n", + "\n", + "# Add plugins to the agent kernel\n", + "agent_kernel.add_plugin(CalculatorPlugin(), plugin_name=\"Calculator\")\n", + "agent_kernel.add_plugin(UtilityPlugin(), plugin_name=\"Utility\")\n", + "agent_kernel.add_plugin(SearchPlugin(), plugin_name=\"Search\")\n", + "\n", + "print(\"āœ“ Calculator Plugin added - Mathematical operations and statistics\")\n", + "print(\"āœ“ Utility Plugin added - Text processing and time functions\")\n", + "print(\"āœ“ Search Plugin added - Web search and definitions\")\n", + "print(\"āœ“ Agent now has access to diverse tool capabilities!\")" + ] + }, + { + "cell_type": "markdown", + "id": "b36f1b95", + "metadata": {}, + "source": [ + "## Section 4: Set up Vector Store and Document Collection\n", + "\n", + "Now let's add document search capabilities to our agent by setting up vector storage with embedded knowledge.\n", + "\n", + "### Agent Knowledge Base\n", + "\n", + "Our agent will have access to a curated knowledge base about AI and technology topics. This enables the agent to:\n", + "\n", + "- **Answer domain-specific questions** with accurate, source-grounded information\n", + "- **Distinguish between search and retrieval** - use web search for current events, document search for specific knowledge\n", + "- **Combine multiple information sources** - query documents and then perform calculations on the results\n", + "\n", + "### Integration with Existing Tools\n", + "\n", + "The document search capability works seamlessly with other tools:\n", + "- Search documents for AI concepts, then use calculator for related metrics\n", + "- Retrieve definitions from knowledge base, then format text appropriately\n", + "- Chain document retrieval with web search for comprehensive answers\n", + "\n", + "Let's set up the vector store!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "21e933ce", + "metadata": {}, + "outputs": [], + "source": [ + "from dataclasses import dataclass\n", + "from typing import Annotated\n", + "from semantic_kernel.data.vector import VectorStoreField, vectorstoremodel\n", + "from semantic_kernel.connectors.in_memory import InMemoryCollection\n", + "\n", + "# Define document model with vector store decorator\n", + "@vectorstoremodel(collection_name=\"agent_documents\")\n", + "@dataclass\n", + "class AgentDocument:\n", + " \"\"\"Document model for agent's knowledge base.\"\"\"\n", + " id: Annotated[str, VectorStoreField(\"key\")]\n", + " text: Annotated[str, VectorStoreField(\"data\")]\n", + " topic: Annotated[str, VectorStoreField(\"data\")] # Topic categorization\n", + " embedding: Annotated[\n", + " list[float] | None,\n", + " VectorStoreField(\n", + " \"vector\",\n", + " dimensions=1536,\n", + " embedding_generator=text_embedding\n", + " ),\n", + " ] = None\n", + "\n", + "# Enhanced knowledge base with more diverse content for the agent\n", + "AGENT_KNOWLEDGE_BASE = \"\"\"\n", + "Artificial Intelligence Agents are autonomous systems that can perceive their environment, make decisions, and take actions to achieve specific goals. Unlike traditional software, agents exhibit adaptive behavior and can learn from interactions. Modern AI agents combine large language models with tool access, enabling them to perform complex multi-step tasks like web search, data analysis, and workflow automation.\n", + "\n", + "Semantic Kernel Architecture provides a unified framework for building AI applications. The kernel acts as a central orchestrator managing multiple services including chat completion, embeddings, and memory. Plugins extend functionality through decorated functions, while the execution engine handles automatic function calling and prompt orchestration. This architecture enables developers to build sophisticated AI agents with minimal boilerplate code.\n", + "\n", + "Function Calling in AI Systems enables models to automatically select and execute appropriate tools based on user requests. This capability transforms static chatbots into dynamic agents capable of real-world task completion. The process involves the model analyzing user intent, selecting relevant functions from available tools, executing those functions, and integrating results into coherent responses.\n", + "\n", + "Vector Databases and Embeddings enable semantic search by converting text into high-dimensional numerical representations. Similar concepts cluster together in vector space, allowing for meaning-based rather than keyword-based search. This technology powers RAG systems, recommendation engines, and content discovery platforms by finding semantically related information even when exact keywords don't match.\n", + "\n", + "Machine Learning Operations (MLOps) encompasses the practices and tools for deploying, monitoring, and maintaining machine learning models in production. Key components include model versioning, automated testing, performance monitoring, and deployment pipelines. Effective MLOps ensures reliable, scalable, and maintainable AI systems that can adapt to changing requirements and data distributions.\n", + "\n", + "Natural Language Processing has evolved from rule-based systems to transformer architectures that achieve human-level performance on many tasks. Modern NLP combines statistical learning with neural networks to understand context, sentiment, and intent. Applications include translation, summarization, question answering, and conversational AI systems that can engage in complex multi-turn dialogues.\n", + "\n", + "Retrieval Augmented Generation (RAG) combines the knowledge stored in large language models with external information retrieval. This hybrid approach enables AI systems to access up-to-date information while maintaining the reasoning capabilities of foundation models. RAG systems typically involve document embedding, similarity search, and prompt augmentation to provide accurate, grounded responses.\n", + "\n", + "Transformer Architecture revolutionized deep learning through self-attention mechanisms that process sequences in parallel rather than sequentially. This innovation enables efficient training on large datasets and captures long-range dependencies in text, code, and other structured data. Transformers form the foundation of modern language models including GPT, BERT, and their successors.\n", + "\n", + "Agent Memory and State Management are crucial for maintaining context across multi-turn conversations and complex task execution. Memory systems can be episodic (remembering specific interactions), semantic (storing general knowledge), or procedural (maintaining workflow state). Effective memory management enables agents to build upon previous interactions and maintain coherent long-term behavior.\n", + "\n", + "Prompt Engineering involves designing inputs to language models that elicit desired behaviors and outputs. Techniques include few-shot learning, chain-of-thought reasoning, role-playing, and structured templates. Advanced prompt engineering can significantly improve model performance on specific tasks without requiring model fine-tuning or retraining.\n", + "\"\"\"\n", + "\n", + "# Split knowledge base into documents by topic\n", + "def create_agent_documents(text: str) -> list[AgentDocument]:\n", + " \"\"\"Create document objects from knowledge base text.\"\"\"\n", + " paragraphs = [p.strip() for p in text.strip().split('\\n\\n') if p.strip()]\n", + " documents = []\n", + " \n", + " for i, paragraph in enumerate(paragraphs):\n", + " # Extract topic from first few words\n", + " topic = paragraph.split()[0:2]\n", + " topic_str = \" \".join(topic)\n", + " \n", + " documents.append(AgentDocument(\n", + " id=f\"doc_{i}\",\n", + " text=paragraph,\n", + " topic=topic_str\n", + " ))\n", + " \n", + " return documents\n", + "\n", + "# Create document collection\n", + "agent_documents = create_agent_documents(AGENT_KNOWLEDGE_BASE)\n", + "\n", + "# Set up vector collection\n", + "document_collection = InMemoryCollection(record_type=AgentDocument)\n", + "await document_collection.ensure_collection_exists()\n", + "\n", + "# Index documents with embeddings\n", + "await document_collection.upsert(agent_documents)\n", + "\n", + "# Create search function and add to kernel\n", + "agent_kernel.add_function(\n", + " \"Knowledge\",\n", + " document_collection.create_search_function(\n", + " function_name=\"search_knowledge\",\n", + " description=\"Searches the agent's knowledge base for information about AI, ML, and technology topics. Use this for domain-specific questions about artificial intelligence, machine learning, and software development.\",\n", + " string_mapper=lambda x: f\"Topic: {x.record.topic}\\nContent: {x.record.text}\",\n", + " ),\n", + ")\n", + "\n", + "print(f\"āœ“ Knowledge base created with {len(agent_documents)} documents\")\n", + "print(\"āœ“ Vector embeddings generated for all documents\")\n", + "print(\"āœ“ Document search function 'Knowledge.search_knowledge' added to agent\")\n", + "print(\"āœ“ Agent can now search its knowledge base automatically!\")" + ] + }, + { + "cell_type": "markdown", + "id": "fc7a26c7", + "metadata": {}, + "source": [ + "## Section 5: Build Agent with Auto Function Calling\n", + "\n", + "Now for the magic! Let's configure our agent to automatically select and call the appropriate tools based on user requests.\n", + "\n", + "### Auto Function Calling Architecture\n", + "\n", + "With `FunctionChoiceBehavior.Auto()`, our agent will:\n", + "\n", + "1. **Analyze user intent** - Understand what the user is asking for\n", + "2. **Select appropriate tools** - Choose from Calculator, Utility, Search, or Knowledge functions\n", + "3. **Execute functions** - Call the selected tools with proper parameters\n", + "4. **Synthesize results** - Combine tool outputs into coherent responses\n", + "5. **Chain operations** - Use multiple tools sequentially when needed\n", + "\n", + "### Agent Intelligence Levels\n", + "\n", + "Our agent can handle increasingly complex scenarios:\n", + "\n", + "- **Simple queries** - Direct answers without tool usage\n", + "- **Single tool tasks** - Calculate math, search web, format text\n", + "- **Multi-tool workflows** - Search knowledge base, then perform calculations\n", + "- **Reasoning chains** - Combine information from multiple sources\n", + "\n", + "### Creating the Agent Persona\n", + "\n", + "We'll give our agent a helpful, knowledgeable personality that:\n", + "- Explains its tool usage transparently\n", + "- Shows step-by-step reasoning \n", + "- Provides detailed, accurate responses\n", + "- Adapts to user needs and context\n", + "\n", + "Let's bring our agent to life!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "29b4b040", + "metadata": {}, + "outputs": [], + "source": [ + "# Configure auto function calling for the agent\n", + "agent_execution_settings = agent_kernel.get_prompt_execution_settings_from_service_id(\"agent_chat\")\n", + "agent_execution_settings.function_choice_behavior = FunctionChoiceBehavior.Auto()\n", + "\n", + "# Define the agent's personality and capabilities\n", + "AGENT_SYSTEM_PROMPT = \"\"\"\n", + "You are SKAgent, an intelligent AI assistant powered by Microsoft Semantic Kernel. You have access to multiple tools and capabilities that you can use automatically to help users.\n", + "\n", + "## Your Available Tools:\n", + "- **Calculator**: Perform mathematical calculations, statistics, and numerical analysis\n", + "- **Utility**: Get current time, analyze text, format text in various ways \n", + "- **Search**: Search the web for current information and get definitions\n", + "- **Knowledge**: Search your knowledge base for information about AI, ML, and technology topics\n", + "\n", + "## Your Behavior Guidelines:\n", + "1. **Be proactive**: Automatically use tools when they would be helpful\n", + "2. **Be transparent**: Explain which tools you're using and why\n", + "3. **Be thorough**: Provide comprehensive answers with relevant details\n", + "4. **Be intelligent**: Chain multiple tools together when needed\n", + "5. **Be helpful**: Always aim to fully address the user's needs\n", + "\n", + "## When to Use Each Tool:\n", + "- Use **Calculator** for any mathematical operations, statistics, or numerical analysis\n", + "- Use **Utility** for text processing, formatting, or getting current time\n", + "- Use **Search** for current events, general web information, or definitions of common terms\n", + "- Use **Knowledge** for detailed information about AI, machine learning, Semantic Kernel, or technical topics\n", + "\n", + "## Multi-Tool Workflows:\n", + "You can combine tools creatively:\n", + "- Search knowledge base for technical info, then calculate related metrics\n", + "- Get definitions, then format the response appropriately\n", + "- Retrieve information from multiple sources and synthesize comprehensive answers\n", + "\n", + "Always explain your reasoning and show your work when using tools.\n", + "\"\"\"\n", + "\n", + "# Create the main agent function\n", + "async def run_agent(user_message: str, show_reasoning: bool = True) -> str:\n", + " \"\"\"\n", + " Runs the agent with auto function calling enabled.\n", + " \n", + " Args:\n", + " user_message: The user's question or request\n", + " show_reasoning: Whether to show the agent's reasoning process\n", + " \"\"\"\n", + " \n", + " # Create the full prompt with system instructions\n", + " full_prompt = f\"\"\"\n", + " {AGENT_SYSTEM_PROMPT}\n", + " \n", + " User Message: {user_message}\n", + " \n", + " Please help the user with their request. Use your available tools as needed and provide a comprehensive response.\n", + " \"\"\"\n", + " \n", + " try:\n", + " # Execute with auto function calling\n", + " result = await agent_kernel.invoke_prompt(\n", + " prompt=full_prompt,\n", + " function_name=\"agent_response\",\n", + " plugin_name=\"SKAgent\",\n", + " arguments=KernelArguments(settings=agent_execution_settings)\n", + " )\n", + " \n", + " return str(result)\n", + " \n", + " except Exception as e:\n", + " return f\"Error: {str(e)}\"\n", + "\n", + "# Test the agent setup\n", + "print(\"āœ… Agent configured with auto function calling!\")\n", + "print(\"āœ… System prompt defined with tool usage guidelines\")\n", + "print(\"āœ… Agent function created and ready to use\")\n", + "print(\"\\nAgent capabilities:\")\n", + "print(\"🧮 Calculator - Mathematical operations and statistics\")\n", + "print(\"šŸ”§ Utility - Text processing and time functions\")\n", + "print(\"🌐 Search - Web search and definitions\")\n", + "print(\"šŸ“š Knowledge - AI/ML knowledge base search\")\n", + "print(\"\\nšŸ¤– SKAgent is ready to help!\")" + ] + }, + { + "cell_type": "markdown", + "id": "be18baae", + "metadata": {}, + "source": [ + "## Section 6: Add Conversation Memory and State Management \n", + "\n", + "Let's enhance our agent with memory capabilities to maintain context across multiple interactions!\n", + "\n", + "### Agent Memory Architecture\n", + "\n", + "Our enhanced agent will include:\n", + "\n", + "1. **Conversation History** - Remember previous messages and responses\n", + "2. **Context Awareness** - Build upon earlier interactions \n", + "3. **Session Management** - Maintain state within conversation sessions\n", + "4. **Persistent Context** - Reference earlier calculations, searches, or information\n", + "\n", + "### Why Memory Matters for Agents\n", + "\n", + "Memory transforms our agent from a stateless responder to an intelligent conversational partner:\n", + "\n", + "- **Continuity** - \"Remember what we calculated earlier\"\n", + "- **Personalization** - Learn user preferences and context\n", + "- **Efficiency** - Avoid repeating searches or calculations\n", + "- **Complex workflows** - Build multi-step processes over time\n", + "\n", + "Let's implement conversation memory!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "72374b31", + "metadata": {}, + "outputs": [], + "source": [ + "from typing import List, Dict\n", + "from dataclasses import dataclass\n", + "from datetime import datetime\n", + "\n", + "@dataclass\n", + "class ConversationMessage:\n", + " \"\"\"Represents a single message in the conversation.\"\"\"\n", + " role: str # \"user\" or \"assistant\"\n", + " content: str\n", + " timestamp: datetime\n", + " tools_used: List[str] = None # Track which tools were used\n", + "\n", + "class AgentMemory:\n", + " \"\"\"Manages conversation memory and state for the agent.\"\"\"\n", + " \n", + " def __init__(self):\n", + " self.conversation_history: List[ConversationMessage] = []\n", + " self.session_context: Dict[str, any] = {}\n", + " self.tool_results_cache: Dict[str, any] = {}\n", + " \n", + " def add_message(self, role: str, content: str, tools_used: List[str] = None):\n", + " \"\"\"Add a message to conversation history.\"\"\"\n", + " message = ConversationMessage(\n", + " role=role,\n", + " content=content,\n", + " timestamp=datetime.now(),\n", + " tools_used=tools_used or []\n", + " )\n", + " self.conversation_history.append(message)\n", + " \n", + " def get_conversation_summary(self, last_n: int = 5) -> str:\n", + " \"\"\"Get a summary of recent conversation.\"\"\"\n", + " if not self.conversation_history:\n", + " return \"No previous conversation history.\"\n", + " \n", + " recent_messages = self.conversation_history[-last_n:]\n", + " summary = \"## Recent Conversation History:\\\\n\"\n", + " \n", + " for msg in recent_messages:\n", + " role_icon = \"šŸ‘¤\" if msg.role == \"user\" else \"šŸ¤–\"\n", + " tools_info = f\" (Used: {', '.join(msg.tools_used)})\" if msg.tools_used else \"\"\n", + " summary += f\"{role_icon} **{msg.role.title()}**: {msg.content[:100]}{'...' if len(msg.content) > 100 else ''}{tools_info}\\\\n\"\n", + " \n", + " return summary\n", + " \n", + " def set_context(self, key: str, value: any):\n", + " \"\"\"Store context information for the session.\"\"\"\n", + " self.session_context[key] = value\n", + " \n", + " def get_context(self, key: str, default=None):\n", + " \"\"\"Retrieve context information.\"\"\"\n", + " return self.session_context.get(key, default)\n", + " \n", + " def cache_tool_result(self, tool_call: str, result: str):\n", + " \"\"\"Cache tool results to avoid repeated calls.\"\"\"\n", + " self.tool_results_cache[tool_call] = {\n", + " 'result': result,\n", + " 'timestamp': datetime.now()\n", + " }\n", + " \n", + " def get_cached_result(self, tool_call: str) -> str:\n", + " \"\"\"Retrieve cached tool result if available and recent.\"\"\"\n", + " cached = self.tool_results_cache.get(tool_call)\n", + " if cached:\n", + " # Consider cache valid for 5 minutes\n", + " time_diff = datetime.now() - cached['timestamp']\n", + " if time_diff.seconds < 300: # 5 minutes\n", + " return cached['result']\n", + " return None\n", + "\n", + "# Initialize agent memory\n", + "agent_memory = AgentMemory()\n", + "\n", + "# Enhanced agent function with memory\n", + "async def run_agent_with_memory(user_message: str, show_reasoning: bool = True) -> str:\n", + " \"\"\"\n", + " Runs the agent with memory and conversation context.\n", + " \"\"\"\n", + " \n", + " # Add user message to memory\n", + " agent_memory.add_message(\"user\", user_message)\n", + " \n", + " # Get conversation context\n", + " conversation_context = agent_memory.get_conversation_summary()\n", + " \n", + " # Create enhanced prompt with memory context\n", + " memory_enhanced_prompt = f\"\"\"\n", + " {AGENT_SYSTEM_PROMPT}\n", + " \n", + " {conversation_context}\n", + " \n", + " ## Current User Request: {user_message}\n", + " \n", + " Please help the user with their request. Consider the conversation history and use your available tools as needed. \n", + " If the user refers to \"earlier\" calculations or information, check the conversation history above.\n", + " Provide a comprehensive response and remember this interaction for future reference.\n", + " \"\"\"\n", + " \n", + " try:\n", + " # Execute with auto function calling\n", + " result = await agent_kernel.invoke_prompt(\n", + " prompt=memory_enhanced_prompt,\n", + " function_name=\"agent_memory_response\",\n", + " plugin_name=\"SKAgent\",\n", + " arguments=KernelArguments(settings=agent_execution_settings)\n", + " )\n", + " \n", + " response = str(result)\n", + " \n", + " # Add agent response to memory\n", + " # Note: In a real implementation, you'd track which tools were actually used\n", + " agent_memory.add_message(\"assistant\", response, [\"auto-detected\"])\n", + " \n", + " return response\n", + " \n", + " except Exception as e:\n", + " error_response = f\"Error: {str(e)}\"\n", + " agent_memory.add_message(\"assistant\", error_response)\n", + " return error_response\n", + "\n", + "# Conversation management functions\n", + "def start_new_conversation():\n", + " \"\"\"Start a new conversation session.\"\"\"\n", + " global agent_memory\n", + " agent_memory = AgentMemory()\n", + " print(\"šŸ”„ New conversation started. Memory cleared.\")\n", + "\n", + "def show_conversation_history():\n", + " \"\"\"Display the current conversation history.\"\"\"\n", + " if not agent_memory.conversation_history:\n", + " print(\"šŸ“ No conversation history yet.\")\n", + " return\n", + " \n", + " print(\"šŸ“œ **Conversation History:**\")\n", + " for i, msg in enumerate(agent_memory.conversation_history, 1):\n", + " role_icon = \"šŸ‘¤\" if msg.role == \"user\" else \"šŸ¤–\"\n", + " tools_info = f\" [Tools: {', '.join(msg.tools_used)}]\" if msg.tools_used else \"\"\n", + " print(f\"{i}. {role_icon} **{msg.role.title()}** ({msg.timestamp.strftime('%H:%M:%S')}){tools_info}\")\n", + " print(f\" {msg.content[:200]}{'...' if len(msg.content) > 200 else ''}\")\n", + " print()\n", + "\n", + "print(\"āœ… Agent memory system initialized!\")\n", + "print(\"āœ… Conversation history tracking enabled\")\n", + "print(\"āœ… Session context management ready\")\n", + "print(\"āœ… Tool result caching implemented\")\n", + "print(\"\\n🧠 Agent now has memory and can maintain conversation context!\")" + ] + }, + { + "cell_type": "markdown", + "id": "03f14b05", + "metadata": {}, + "source": [ + "## Section 7: Test Agent with Tool Usage\n", + "\n", + "Time to put our agent to the test! Let's see how it automatically selects and uses different tools.\n", + "\n", + "### Test Scenarios\n", + "\n", + "We'll test our agent with different types of queries to demonstrate:\n", + "\n", + "1. **Calculator Usage** - Mathematical problems and statistics\n", + "2. **Knowledge Base Search** - AI and technology questions \n", + "3. **Utility Functions** - Text processing and time queries\n", + "4. **Web Search** - Current information and definitions\n", + "5. **Multi-tool Workflows** - Complex tasks requiring multiple tools\n", + "\n", + "### Agent Intelligence Demo\n", + "\n", + "Watch how the agent:\n", + "- **Analyzes** the user's intent\n", + "- **Selects** appropriate tools automatically\n", + "- **Executes** functions with proper parameters\n", + "- **Synthesizes** coherent responses\n", + "- **Explains** its reasoning process\n", + "\n", + "Let's see our agent in action!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "11cfe713", + "metadata": {}, + "outputs": [], + "source": [ + "# Test 1: Calculator Tool Usage\n", + "print(\"🧮 **Test 1: Calculator Tool Usage**\")\n", + "print(\"=\"*50)\n", + "\n", + "test_math = await run_agent_with_memory(\n", + " \"Can you calculate the square root of 144 and then find the mean of the numbers 10, 15, 20, 25, 30?\"\n", + ")\n", + "print(f\"User: Can you calculate the square root of 144 and then find the mean of the numbers 10, 15, 20, 25, 30?\")\n", + "print(f\"Agent: {test_math}\")\n", + "print()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bd1c619d", + "metadata": {}, + "outputs": [], + "source": [ + "# Test 2: Knowledge Base Search\n", + "print(\"šŸ“š **Test 2: Knowledge Base Search**\")\n", + "print(\"=\"*50)\n", + "\n", + "test_knowledge = await run_agent_with_memory(\n", + " \"What is RAG and how does it work with embeddings?\"\n", + ")\n", + "print(f\"User: What is RAG and how does it work with embeddings?\")\n", + "print(f\"Agent: {test_knowledge}\")\n", + "print()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "360e2c15", + "metadata": {}, + "outputs": [], + "source": [ + "# Test 3: Utility Functions\n", + "print(\"šŸ”§ **Test 3: Utility Functions**\")\n", + "print(\"=\"*50)\n", + "\n", + "test_utility = await run_agent_with_memory(\n", + " \"What's the current time and can you analyze this text: 'Semantic Kernel is a powerful framework for building AI applications with function calling capabilities'?\"\n", + ")\n", + "print(f\"User: What's the current time and can you analyze this text: 'Semantic Kernel is a powerful framework for building AI applications with function calling capabilities'?\")\n", + "print(f\"Agent: {test_utility}\")\n", + "print()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3dbbf73c", + "metadata": {}, + "outputs": [], + "source": [ + "# Test 4: Web Search\n", + "print(\"🌐 **Test 4: Web Search**\")\n", + "print(\"=\"*50)\n", + "\n", + "test_search = await run_agent_with_memory(\n", + " \"Can you search for information about machine learning and give me a definition of 'agent'?\"\n", + ")\n", + "print(f\"User: Can you search for information about machine learning and give me a definition of 'agent'?\")\n", + "print(f\"Agent: {test_search}\")\n", + "print()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "570a6dad", + "metadata": {}, + "outputs": [], + "source": [ + "# Test 5: Memory and Context\n", + "print(\"🧠 **Test 5: Memory and Context**\")\n", + "print(\"=\"*50)\n", + "\n", + "test_memory = await run_agent_with_memory(\n", + " \"Based on our earlier conversation, can you remind me what we calculated and then format it as a title?\"\n", + ")\n", + "print(f\"User: Based on our earlier conversation, can you remind me what we calculated and then format it as a title?\")\n", + "print(f\"Agent: {test_memory}\")\n", + "print()\n", + "\n", + "# Show conversation history\n", + "print(\"šŸ“œ **Conversation History So Far:**\")\n", + "show_conversation_history()" + ] + }, + { + "cell_type": "markdown", + "id": "321119fa", + "metadata": {}, + "source": [ + "## Section 8: Implement Streaming Agent Responses\n", + "\n", + "Let's add streaming capabilities to provide real-time responses as our agent works!\n", + "\n", + "### Why Streaming Matters for Agents\n", + "\n", + "Streaming enhances the user experience by:\n", + "\n", + "- **Real-time feedback** - Users see responses as they're generated\n", + "- **Progress indication** - Show when tools are being called\n", + "- **Transparency** - Reveal the agent's thinking process step-by-step \n", + "- **Engagement** - Keep users engaged during longer operations\n", + "\n", + "### Streaming Architecture\n", + "\n", + "Our streaming agent will:\n", + "1. **Stream text generation** - Show response as it's being created\n", + "2. **Indicate tool calls** - Show when functions are being executed\n", + "3. **Display intermediate results** - Show tool outputs as they complete\n", + "4. **Provide status updates** - Keep users informed of progress\n", + "\n", + "This creates a more interactive and transparent agent experience!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ed0f435b", + "metadata": {}, + "outputs": [], + "source": [ + "import asyncio\n", + "import sys\n", + "from typing import AsyncGenerator\n", + "\n", + "class StreamingAgent:\n", + " \"\"\"Enhanced agent with streaming capabilities.\"\"\"\n", + " \n", + " def __init__(self, kernel: Kernel, memory: AgentMemory):\n", + " self.kernel = kernel\n", + " self.memory = memory\n", + " self.execution_settings = kernel.get_prompt_execution_settings_from_service_id(\"agent_chat\")\n", + " self.execution_settings.function_choice_behavior = FunctionChoiceBehavior.Auto()\n", + " \n", + " async def stream_response(self, user_message: str) -> AsyncGenerator[str, None]:\n", + " \"\"\"\n", + " Stream agent response with real-time updates.\n", + " \"\"\"\n", + " # Add user message to memory\n", + " self.memory.add_message(\"user\", user_message)\n", + " \n", + " # Status update\n", + " yield \"šŸ¤– **SKAgent is thinking...**\\n\\n\"\n", + " await asyncio.sleep(0.5) # Brief pause for effect\n", + " \n", + " # Get conversation context\n", + " conversation_context = self.memory.get_conversation_summary()\n", + " \n", + " # Create enhanced prompt\n", + " memory_enhanced_prompt = f\"\"\"\n", + " {AGENT_SYSTEM_PROMPT}\n", + " \n", + " {conversation_context}\n", + " \n", + " ## Current User Request: {user_message}\n", + " \n", + " Please help the user with their request. Consider the conversation history and use your available tools as needed.\n", + " \"\"\"\n", + " \n", + " try:\n", + " yield \"šŸ” **Analyzing request and selecting tools...**\\n\\n\"\n", + " await asyncio.sleep(0.5)\n", + " \n", + " # Execute with function calling (in real implementation, you'd hook into the streaming)\n", + " result = await self.kernel.invoke_prompt(\n", + " prompt=memory_enhanced_prompt,\n", + " function_name=\"streaming_agent_response\",\n", + " plugin_name=\"SKAgent\",\n", + " arguments=KernelArguments(settings=self.execution_settings)\n", + " )\n", + " \n", + " # Simulate streaming the response\n", + " response_text = str(result)\n", + " \n", + " yield \"āœ… **Tools executed, generating response:**\\n\\n\"\n", + " await asyncio.sleep(0.3)\n", + " \n", + " # Stream the response word by word for demo\n", + " words = response_text.split()\n", + " current_text = \"\"\n", + " \n", + " for i, word in enumerate(words):\n", + " current_text += word + \" \"\n", + " \n", + " # Stream every few words\n", + " if i % 3 == 0 or i == len(words) - 1:\n", + " yield current_text[len(current_text) - len(word) - 1:]\n", + " await asyncio.sleep(0.1)\n", + " \n", + " # Add to memory\n", + " self.memory.add_message(\"assistant\", response_text, [\"auto-detected\"])\n", + " \n", + " except Exception as e:\n", + " error_msg = f\"\\n\\nāŒ **Error:** {str(e)}\"\n", + " yield error_msg\n", + " self.memory.add_message(\"assistant\", error_msg)\n", + "\n", + "# Create streaming agent instance\n", + "streaming_agent = StreamingAgent(agent_kernel, agent_memory)\n", + "\n", + "async def demo_streaming_response(query: str):\n", + " \"\"\"Demonstrate streaming agent response.\"\"\"\n", + " print(f\"šŸ‘¤ **User:** {query}\\n\")\n", + " \n", + " complete_response = \"\"\n", + " async for chunk in streaming_agent.stream_response(query):\n", + " print(chunk, end=\"\", flush=True)\n", + " complete_response += chunk\n", + " \n", + " print(\"\\n\" + \"=\"*60 + \"\\n\")\n", + " return complete_response\n", + "\n", + "print(\"āœ… Streaming agent implementation ready!\")\n", + "print(\"āœ… Real-time response generation enabled\")\n", + "print(\"āœ… Progressive tool execution feedback\")\n", + "print(\"\\n⚔ Ready to demonstrate streaming capabilities!\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c898b12d", + "metadata": {}, + "outputs": [], + "source": [ + "# Demo streaming responses\n", + "print(\"🌊 **Streaming Agent Demo**\")\n", + "print(\"=\"*50)\n", + "\n", + "# Test streaming with a complex query that requires multiple tools\n", + "streaming_response = await demo_streaming_response(\n", + " \"Calculate the area of a circle with radius 7, then search your knowledge base for information about transformers, and format the result nicely\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "eac1caa6", + "metadata": {}, + "source": [ + "## Section 9: Add Multi-Tool Agent Workflows\n", + "\n", + "Let's create complex scenarios where our agent chains multiple tools together to solve sophisticated problems!\n", + "\n", + "### Advanced Agent Workflows\n", + "\n", + "Our agent can now handle complex multi-step processes:\n", + "\n", + "1. **Sequential Tool Chaining** - Use results from one tool as input to another\n", + "2. **Conditional Logic** - Choose different tools based on intermediate results\n", + "3. **Data Processing Pipelines** - Search → Calculate → Format → Present\n", + "4. **Contextual Reasoning** - Build complex answers from multiple information sources\n", + "\n", + "### Real-World Scenarios\n", + "\n", + "These advanced workflows enable our agent to handle tasks like:\n", + "\n", + "- **Research & Analysis** - Search for data, perform calculations, format results\n", + "- **Content Generation** - Retrieve information, process text, create summaries\n", + "- **Problem Solving** - Break down complex problems into tool-solvable steps\n", + "- **Decision Support** - Gather data from multiple sources and provide recommendations\n", + "\n", + "### Multi-Tool Intelligence\n", + "\n", + "Watch how our agent demonstrates true intelligence by:\n", + "- **Planning** multi-step approaches to complex problems\n", + "- **Adapting** its strategy based on intermediate results \n", + "- **Combining** information from diverse sources\n", + "- **Reasoning** through complex logical sequences\n", + "\n", + "Let's test these advanced capabilities!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c31dfe1e", + "metadata": {}, + "outputs": [], + "source": [ + "# Complex Multi-Tool Workflow Test 1: Research and Analysis\n", + "print(\"šŸ”— **Multi-Tool Workflow 1: Research and Analysis**\")\n", + "print(\"=\"*60)\n", + "\n", + "workflow_1 = await run_agent_with_memory(\n", + " \"I need to understand Semantic Kernel agents. First, search your knowledge base for information about AI agents, then calculate how many words are in a typical agent description, and finally format the key points in title case.\"\n", + ")\n", + "print(f\"User: I need to understand Semantic Kernel agents. First, search your knowledge base for information about AI agents, then calculate how many words are in a typical agent description, and finally format the key points in title case.\")\n", + "print(f\"Agent: {workflow_1}\")\n", + "print()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ef632816", + "metadata": {}, + "outputs": [], + "source": [ + "# Complex Multi-Tool Workflow Test 2: Data Processing Pipeline\n", + "print(\"šŸ“Š **Multi-Tool Workflow 2: Data Processing Pipeline**\")\n", + "print(\"=\"*60)\n", + "\n", + "workflow_2 = await run_agent_with_memory(\n", + " \"Let's do some analysis: First get the current time, then calculate statistics for these performance scores: 85, 92, 78, 96, 88, 91, 84. Finally, search for information about machine learning performance metrics in your knowledge base.\"\n", + ")\n", + "print(f\"User: Let's do some analysis: First get the current time, then calculate statistics for these performance scores: 85, 92, 78, 96, 88, 91, 84. Finally, search for information about machine learning performance metrics in your knowledge base.\")\n", + "print(f\"Agent: {workflow_2}\")\n", + "print()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "df0c6c37", + "metadata": {}, + "outputs": [], + "source": [ + "# Final workflow test with memory reference\n", + "print(\"🧠 **Multi-Tool Workflow 3: Memory-Based Decision Making**\")\n", + "print(\"=\"*60)\n", + "\n", + "workflow_3 = await run_agent_with_memory(\n", + " \"Based on all our previous conversations and calculations, can you summarize what we've learned about agent capabilities, include the statistics we calculated earlier, and search for information about how this relates to real-world AI applications?\"\n", + ")\n", + "print(f\"User: Based on all our previous conversations and calculations, can you summarize what we've learned about agent capabilities, include the statistics we calculated earlier, and search for information about how this relates to real-world AI applications?\")\n", + "print(f\"Agent: {workflow_3}\")\n", + "print()\n", + "\n", + "print(\"šŸŽÆ **Multi-Tool Workflow Analysis Complete!**\")\n", + "print(\"=\"*60)\n", + "print(\"āœ… Agent successfully demonstrated:\")\n", + "print(\" • Sequential tool chaining\")\n", + "print(\" • Memory-based context awareness\") \n", + "print(\" • Complex reasoning workflows\")\n", + "print(\" • Information synthesis across tools\")\n", + "print(\" • Adaptive response generation\")" + ] + }, + { + "cell_type": "markdown", + "id": "9c546df1", + "metadata": {}, + "source": [ + "---\n", + "\n", + "## šŸŽ“ Conclusion: Building Intelligent Agents with Semantic Kernel\n", + "\n", + "Congratulations! You've successfully built a complete intelligent agent using Microsoft Semantic Kernel. This tutorial has taken you from basic tool creation to advanced multi-tool workflows and memory management.\n", + "\n", + "### šŸ—ļø What You've Built\n", + "\n", + "Your **SKAgent** now includes:\n", + "\n", + "| Component | Capability | Implementation |\n", + "|-----------|------------|----------------|\n", + "| **🧮 Calculator Plugin** | Mathematical operations & statistics | `@kernel_function` decorators |\n", + "| **šŸ”§ Utility Plugin** | Text processing & time functions | Native Python functions |\n", + "| **🌐 Search Plugin** | Web search & definitions | Simulated search API |\n", + "| **šŸ“š Knowledge Plugin** | Vector-based document search | InMemoryCollection + embeddings |\n", + "| **🧠 Memory System** | Conversation context & history | Custom AgentMemory class |\n", + "| **⚔ Streaming** | Real-time response generation | AsyncGenerator streaming |\n", + "| **šŸ”— Multi-Tool Workflows** | Complex reasoning chains | Auto function calling |\n", + "\n", + "### šŸš€ Agent Capabilities Demonstrated\n", + "\n", + "Throughout this tutorial, your agent has shown:\n", + "\n", + "1. **Autonomous Tool Selection** - Automatically choosing appropriate functions\n", + "2. **Context Awareness** - Remembering and building upon previous interactions\n", + "3. **Multi-Step Reasoning** - Chaining tools together for complex tasks\n", + "4. **Real-Time Feedback** - Streaming responses as they're generated\n", + "5. **Intelligent Synthesis** - Combining information from multiple sources\n", + "\n", + "### šŸ”‘ Key Semantic Kernel Concepts Mastered\n", + "\n", + "| Concept | Purpose | Agent Benefit |\n", + "|---------|---------|---------------|\n", + "| **Kernel** | Central orchestrator | Unified service management |\n", + "| **@kernel_function** | Tool registration | Automatic function discovery |\n", + "| **FunctionChoiceBehavior.Auto()** | Autonomous tool selection | Intelligent decision making |\n", + "| **InMemoryCollection** | Vector storage | Semantic knowledge search |\n", + "| **Prompt Templates** | Structured prompting | Consistent agent behavior |\n", + "| **Memory Management** | State persistence | Conversational continuity |\n", + "\n", + "### šŸ†š Agent vs. Chatbot Comparison\n", + "\n", + "**Traditional Chatbot:**\n", + "- āŒ Static responses from training data\n", + "- āŒ No tool access or external capabilities\n", + "- āŒ No memory between conversations\n", + "- āŒ Limited to text generation only\n", + "\n", + "**Your Semantic Kernel Agent:**\n", + "- āœ… **Dynamic tool usage** - Can perform calculations, searches, data processing\n", + "- āœ… **External knowledge access** - Retrieves up-to-date information \n", + "- āœ… **Persistent memory** - Remembers conversation context\n", + "- āœ… **Multi-modal capabilities** - Text, calculations, search, analysis\n", + "- āœ… **Reasoning chains** - Combines multiple tools intelligently\n", + "\n", + "### šŸ› ļø Production Considerations\n", + "\n", + "To deploy your agent in production, consider:\n", + "\n", + "1. **Security**\n", + " - Validate all tool inputs\n", + " - Implement rate limiting\n", + " - Use secure API key management\n", + "\n", + "2. **Scalability**\n", + " - Replace InMemoryCollection with production vector DB (Azure AI Search, Qdrant)\n", + " - Implement persistent memory storage\n", + " - Add load balancing for high traffic\n", + "\n", + "3. **Monitoring**\n", + " - Track tool usage and performance\n", + " - Log conversation flows\n", + " - Monitor costs and API usage\n", + "\n", + "4. **Enhanced Tools**\n", + " - Integrate real web search APIs (Bing, Google)\n", + " - Add database connectivity\n", + " - Include file processing capabilities\n", + " - Connect to business systems\n", + "\n", + "### šŸ”® Advanced Extensions\n", + "\n", + "Ready for more? Extend your agent with:\n", + "\n", + "1. **Specialized Domains**\n", + " ```python\n", + " class DatabasePlugin:\n", + " @kernel_function\n", + " def query_database(self, sql: str) -> str:\n", + " # Execute SQL queries\n", + " ```\n", + "\n", + "2. **File Processing**\n", + " ```python\n", + " class FilePlugin:\n", + " @kernel_function\n", + " def process_document(self, file_path: str) -> str:\n", + " # Read and analyze documents\n", + " ```\n", + "\n", + "3. **API Integrations**\n", + " ```python\n", + " class APIPlugin:\n", + " @kernel_function\n", + " def call_rest_api(self, endpoint: str, data: str) -> str:\n", + " # Make REST API calls\n", + " ```\n", + "\n", + "4. **Multi-Agent Coordination**\n", + " - Create specialized agents for different domains\n", + " - Implement agent-to-agent communication\n", + " - Build hierarchical agent systems\n", + "\n", + "### šŸ“š Next Steps & Resources\n", + "\n", + "**Continue Learning:**\n", + "- [Semantic Kernel Documentation](https://learn.microsoft.com/semantic-kernel/)\n", + "- [Azure OpenAI Service](https://learn.microsoft.com/azure/ai-services/openai/)\n", + "- [Semantic Kernel Samples](https://github.com/microsoft/semantic-kernel/tree/main/python/samples)\n", + "\n", + "**Build Production Agents:**\n", + "- Implement proper error handling and retries\n", + "- Add comprehensive logging and monitoring\n", + "- Create agent configuration management\n", + "- Build user authentication and authorization\n", + "- Design multi-tenant agent architectures\n", + "\n", + "**Explore Advanced Topics:**\n", + "- **Planners** - Multi-step reasoning and planning\n", + "- **Memory Connectors** - Persistent storage solutions\n", + "- **Custom Connectors** - Integrate any LLM or service\n", + "- **Agent Orchestration** - Coordinate multiple specialized agents\n", + "\n", + "---\n", + "\n", + "### šŸ™ Thank You!\n", + "\n", + "You now have the knowledge and tools to build production-ready intelligent agents with Microsoft Semantic Kernel. Your agent demonstrates the full spectrum of capabilities - from simple tool usage to complex multi-step reasoning with memory.\n", + "\n", + "**Key Takeaways:**\n", + "- āœ… Semantic Kernel provides a unified framework for agent development\n", + "- āœ… The plugin architecture makes tools modular and reusable\n", + "- āœ… Auto function calling enables true agent intelligence\n", + "- āœ… Memory management creates conversational continuity\n", + "- āœ… Multi-tool workflows solve complex real-world problems\n", + "\n", + "**Keep Building! šŸš€**\n", + "\n", + "The future of AI is agentic - systems that can perceive, reason, and act autonomously. With Semantic Kernel, you're well-equipped to build the next generation of intelligent applications.\n", + "\n", + "Happy coding! šŸŽ‰" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "99fa3594", + "metadata": {}, + "outputs": [], + "source": [ + "# Start a fresh conversation for complex workflow tests\n", + "start_new_conversation()\n", + "\n", + "print(\"šŸ”„ **Multi-Tool Workflow Tests**\")\n", + "print(\"=\"*60)\n", + "\n", + "# Test 1: Research, Calculate, and Format Workflow\n", + "print(\"\\nšŸ”¬ **Test 1: Research → Calculate → Format Workflow**\")\n", + "print(\"-\" * 50)\n", + "\n", + "workflow_test_1 = await run_agent_with_memory(\n", + " \"\"\"I need help with a machine learning project analysis. Can you:\n", + " 1. Search your knowledge base for information about transformer architectures\n", + " 2. Calculate the total parameters if a transformer has 12 layers, each with 768 hidden units, and vocabulary size of 30,000\n", + " 3. Format the final analysis as a nice summary\n", + " \n", + " Please walk me through each step of your analysis.\"\"\"\n", + ")\n", + "\n", + "print(f\"šŸ¤– Agent Response:\\n{workflow_test_1}\")\n", + "print(\"\\n\" + \"=\"*60)" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}