{ "cells": [ { "cell_type": "markdown", "id": "2012ea09", "metadata": {}, "source": [ "# ๐ŸŽจ Agentic Design Patterns with GitHub Models (Python)\n", "\n", "## ๐Ÿ“‹ Learning Objectives\n", "\n", "This notebook demonstrates essential design patterns for building intelligent agents using the Microsoft Agent Framework with GitHub Models integration. You'll learn proven patterns and architectural approaches that make agents more robust, maintainable, and effective.\n", "\n", "**Core Design Patterns Covered:**\n", "- ๐Ÿ—๏ธ **Agent Factory Pattern**: Standardized agent creation and configuration\n", "- ๐Ÿ”ง **Tool Registry Pattern**: Organized approach to managing agent capabilities\n", "- ๐Ÿงต **Conversation Management**: Effective patterns for multi-turn interactions\n", "- ๐Ÿ”„ **Response Processing**: Best practices for handling agent outputs\n", "\n", "## ๐ŸŽฏ Key Architectural Concepts\n", "\n", "### Design Principles\n", "- **Separation of Concerns**: Clear boundaries between agent logic, tools, and configuration\n", "- **Composability**: Building complex agents from reusable components\n", "- **Extensibility**: Patterns that allow easy addition of new capabilities\n", "- **Testability**: Design for easy unit testing and validation\n", "\n", "### GitHub Models Integration\n", "- **API Compatibility**: Leveraging OpenAI-compatible endpoints\n", "- **Model Selection**: Choosing appropriate models for different use cases\n", "- **Rate Limiting**: Handling API constraints gracefully\n", "- **Error Recovery**: Robust error handling and retry patterns\n", "\n", "## ๐Ÿ”ง Technical Architecture\n", "\n", "### Core Components\n", "- **Microsoft Agent Framework**: Python implementation with GitHub Models support\n", "- **GitHub Models API**: Access to state-of-the-art language models\n", "- **OpenAI Client Pattern**: Standardized API interaction patterns\n", "- **Environment Configuration**: Secure and flexible configuration management\n", "\n", "### Design Pattern Benefits\n", "- **Maintainability**: Clear code organization and structure\n", "- **Scalability**: Patterns that grow with your application needs\n", "- **Reliability**: Proven approaches that handle edge cases\n", "- **Performance**: Efficient resource utilization and API usage\n", "\n", "## โš™๏ธ Prerequisites & Setup\n", "\n", "**Required Dependencies:**\n", "```bash\n", "\n", "pip install agent-framework-core -U\n", "\n", "```\n", "\n", "**Environment Configuration (.env file):**\n", "```env\n", "GITHUB_TOKEN=your_github_personal_access_token\n", "GITHUB_ENDPOINT=https://models.inference.ai.azure.com\n", "GITHUB_MODEL_ID=gpt-4o-mini\n", "```\n", "\n", "**GitHub Models Access:**\n", "- GitHub account with Models access\n", "- Personal access token with appropriate permissions\n", "- Understanding of rate limits and usage patterns\n", "\n", "## ๐Ÿ“š Design Pattern Categories\n", "\n", "### 1. **Creational Patterns**\n", "- Agent factory and builder patterns\n", "- Configuration management patterns\n", "- Dependency injection for agent services\n", "\n", "### 2. **Behavioral Patterns**\n", "- Tool execution and orchestration\n", "- Conversation flow management \n", "- Response processing and formatting\n", "\n", "### 3. **Integration Patterns**\n", "- GitHub Models API integration\n", "- Error handling and retry logic\n", "- Resource management and cleanup\n", "\n", "## ๐Ÿš€ Best Practices Demonstrated\n", "\n", "- **Clean Architecture**: Layered design with clear responsibilities\n", "- **Error Handling**: Comprehensive exception management\n", "- **Configuration**: Environment-based setup for different environments\n", "- **Testing**: Patterns that enable effective unit and integration testing\n", "- **Documentation**: Self-documenting code with clear intent\n", "\n", "Ready to explore professional agent design patterns? Let's build something robust! ๐ŸŒŸ" ] }, { "cell_type": "code", "execution_count": 1, "id": "d9feb817", "metadata": {}, "outputs": [], "source": [ "# ! pip install -r ../../../Installation/requirements.txt -U" ] }, { "cell_type": "code", "execution_count": 2, "id": "c0df8a52", "metadata": {}, "outputs": [], "source": [ "# ๐Ÿ“ฆ Import Core Libraries for Agent Design Patterns\n", "import os # Environment variable access for configuration management\n", "from random import randint # Random selection utilities for tool functionality\n", "\n", "from dotenv import load_dotenv # Secure environment configuration loading" ] }, { "cell_type": "code", "execution_count": 3, "id": "151e0314", "metadata": {}, "outputs": [], "source": [ "# ๐Ÿค– Import Microsoft Agent Framework Components \n", "# ChatAgent: Core agent orchestration class following factory pattern\n", "# OpenAIChatClient: GitHub Models integration following adapter pattern\n", "from agent_framework import Agent\n", "from agent_framework.openai import OpenAIChatCompletionClient" ] }, { "cell_type": "code", "execution_count": 4, "id": "a6141584", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# ๐Ÿ”ง Configuration Loading Pattern\n", "# Implement configuration management pattern for secure credential handling\n", "# This follows the external configuration principle for cloud-native applications\n", "load_dotenv()" ] }, { "cell_type": "code", "execution_count": 5, "id": "a6507f83", "metadata": {}, "outputs": [], "source": [ "# ๐Ÿ› ๏ธ Tool Function Design Pattern\n", "# Implements the Strategy Pattern for pluggable agent capabilities\n", "# This demonstrates clean separation of business logic from agent orchestration\n", "def get_random_destination() -> str:\n", " \"\"\"Get a random vacation destination using Repository Pattern.\n", " \n", " This function exemplifies several design patterns:\n", " - Strategy Pattern: Interchangeable algorithm for destination selection\n", " - Repository Pattern: Encapsulates data access logic\n", " - Factory Method: Creates destination objects on demand\n", " \n", " Returns:\n", " str: A randomly selected destination following consistent format\n", " \"\"\"\n", " # Data Repository Pattern: Centralized destination data management\n", " destinations = [\n", " \"Barcelona, Spain\", # Mediterranean cultural hub\n", " \"Paris, France\", # European artistic center\n", " \"Berlin, Germany\", # Historical European capital\n", " \"Tokyo, Japan\", # Asian technology metropolis\n", " \"Sydney, Australia\", # Oceanic coastal city\n", " \"New York, USA\", # American urban center\n", " \"Cairo, Egypt\", # African historical capital\n", " \"Cape Town, South Africa\", # African scenic destination\n", " \"Rio de Janeiro, Brazil\", # South American beach city\n", " \"Bali, Indonesia\" # Southeast Asian island paradise\n", " ]\n", " \n", " # Factory Method Pattern: Create destination selection on demand\n", " return destinations[randint(0, len(destinations) - 1)]" ] }, { "cell_type": "code", "execution_count": 6, "id": "5d4f0568", "metadata": {}, "outputs": [], "source": [ "openai_chat_client = OpenAIChatCompletionClient(base_url=os.environ.get(\"GITHUB_ENDPOINT\"), api_key=os.environ.get(\"GITHUB_TOKEN\"), model=os.environ.get(\"GITHUB_MODEL_ID\"))" ] }, { "cell_type": "markdown", "id": "6d798d5e", "metadata": {}, "source": [ "## ๐Ÿ”— Create GitHub Models Chat Client\n", "\n", "Initialize the OpenAI-compatible chat client that connects to GitHub Models API.\n", "This client follows the **Adapter Pattern** to provide a unified interface for different AI model backends." ] }, { "cell_type": "code", "execution_count": 7, "id": "751668c5", "metadata": {}, "outputs": [], "source": [ "AGENT_NAME =\"TravelAgent\"\n", "\n", "AGENT_INSTRUCTIONS = \"\"\"You are a helpful AI Agent that can help plan vacations for customers.\n", "\n", "Important: When users specify a destination, always plan for that location. Only suggest random destinations when the user hasn't specified a preference.\n", "\n", "When the conversation begins, introduce yourself with this message:\n", "\"Hello! I'm your TravelAgent assistant. I can help plan vacations and suggest interesting destinations for you. Here are some things you can ask me:\n", "1. Plan a day trip to a specific location\n", "2. Suggest a random vacation destination\n", "3. Find destinations with specific features (beaches, mountains, historical sites, etc.)\n", "4. Plan an alternative trip if you don't like my first suggestion\n", "\n", "What kind of trip would you like me to help you plan today?\"\n", "\n", "Always prioritize user preferences. If they mention a specific destination like \"Bali\" or \"Paris,\" focus your planning on that location rather than suggesting alternatives.\n", "\"\"\"" ] }, { "cell_type": "markdown", "id": "0fda950d", "metadata": {}, "source": [ "## ๐Ÿค– Define Agent Identity and Instructions\n", "\n", "Configure the agent's name and comprehensive behavioral instructions.\n", "This demonstrates the **Configuration Pattern** for separating agent behavior from implementation." ] }, { "cell_type": "code", "execution_count": 8, "id": "cf5a4800", "metadata": {}, "outputs": [], "source": [ "agent = Agent(\n", " name = AGENT_NAME,\n", " client=openai_chat_client,\n", " instructions=AGENT_INSTRUCTIONS,\n", " tools=[get_random_destination]\n", ")" ] }, { "cell_type": "markdown", "id": "4707da21", "metadata": {}, "source": [ "## ๐Ÿญ Create Agent Using Factory Pattern\n", "\n", "Instantiate the ChatAgent with all configured components.\n", "This demonstrates the **Factory Pattern** for standardized agent creation with consistent configuration." ] }, { "cell_type": "code", "execution_count": 9, "id": "be18ac4f", "metadata": {}, "outputs": [], "source": [ "session = agent.create_session()" ] }, { "cell_type": "markdown", "id": "80bb1008", "metadata": {}, "source": [ "## ๐Ÿงต Initialize Conversation Thread\n", "\n", "Create a new conversation thread to maintain context across multiple interactions.\n", "Threads enable **Stateful Conversation Management** for multi-turn dialogues." ] }, { "cell_type": "code", "execution_count": 10, "id": "772e9481", "metadata": {}, "outputs": [], "source": [ "response1 = await agent.run(\"Plan me a day trip\",session= session)" ] }, { "cell_type": "markdown", "id": "6a57233c", "metadata": {}, "source": [ "## ๐Ÿš€ Execute Initial Travel Planning Request\n", "\n", "Run the agent with a travel planning request. The agent will:\n", "1. Analyze the request\n", "2. Call the `get_random_destination` tool if needed\n", "3. Generate a personalized travel itinerary" ] }, { "cell_type": "code", "execution_count": 11, "id": "a731b547", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Travel plan:\n", "Sure! To plan your day trip, could you please tell me if you have a specific destination in mind or any particular interests? For example, do you prefer a beach, mountains, historical sites, city exploration, or something else?\n" ] } ], "source": [ "\n", "last_message = response1.messages[-1]\n", "text_content = last_message.contents[0].text\n", "print(\"Travel plan:\")\n", "print(text_content)" ] }, { "cell_type": "markdown", "id": "380675a9", "metadata": {}, "source": [ "## ๐Ÿ“– Display First Travel Plan\n", "\n", "Extract and display the generated travel plan from the agent's response." ] }, { "cell_type": "code", "execution_count": 12, "id": "7d3fe00a", "metadata": {}, "outputs": [], "source": [ "response2 = await agent.run(\"I don't like that destination. Plan me another vacation.\",session= session)" ] }, { "cell_type": "markdown", "id": "8d995e46", "metadata": {}, "source": [ "## ๐Ÿ”„ Follow-up Request with Context\n", "\n", "Demonstrate multi-turn conversation by sending a follow-up request.\n", "The agent remembers the previous interaction through the conversation thread and provides an alternative suggestion." ] }, { "cell_type": "code", "execution_count": 13, "id": "ba50c92d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Change plan:\n", "How about a day trip to New York, USA? It's a vibrant city with iconic landmarks like Times Square, Central Park, and the Statue of Liberty. You can enjoy museums, great food, and Broadway shows. \n", "\n", "Would you like me to help plan a detailed itinerary for your day trip to New York?\n" ] } ], "source": [ "last_message = response2.messages[-1]\n", "text_content = last_message.contents[0].text\n", "print(\"Change plan:\")\n", "print(text_content)" ] }, { "cell_type": "markdown", "id": "07bc5219", "metadata": {}, "source": [ "## ๐Ÿ“– Display Alternative Travel Plan\n", "\n", "Show the agent's new recommendation based on the follow-up request." ] } ], "metadata": { "kernelspec": { "display_name": "agentdev", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.10" }, "polyglot_notebook": { "kernelInfo": { "defaultKernelName": "csharp", "items": [ { "aliases": [], "name": "csharp" } ] } } }, "nbformat": 4, "nbformat_minor": 5 }