Files
microsoft--ai-agents-for-be…/02-explore-agentic-frameworks/code_samples/02-python-agent-framework.ipynb
T
2026-07-13 12:59:43 +08:00

259 lines
8.5 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"cells": [
{
"cell_type": "markdown",
"id": "a1b2c3d4",
"metadata": {},
"source": [
"# Lesson 02 - Exploring Microsoft Agent Framework\n",
"\n",
"The **Microsoft Agent Framework (MAF)** is a unified framework for building AI agents. It provides a clean, composable architecture with four core building blocks:\n",
"\n",
"- **Client** connects to an AI model endpoint and handles communication\n",
"- **Agent** wraps a client with instructions and tool definitions\n",
"- **Tools** extend agent capabilities with custom functions the model can call\n",
"- **Session** maintains conversation history for multi-turn interactions\n",
"\n",
"In this lesson, we'll build a **travel booking agent** that checks destination availability using these concepts."
]
},
{
"cell_type": "markdown",
"id": "b2c3d4e5",
"metadata": {},
"source": [
"## Setup"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c3d4e5f6",
"metadata": {},
"outputs": [],
"source": [
"# Install the Microsoft Agent Framework package\n",
"! pip install agent-framework azure-ai-projects -U -q\n",
"! pip install python-dotenv -q"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d4e5f6a7",
"metadata": {},
"outputs": [],
"source": [
"import logging\n",
"logging.getLogger(\"agent_framework.foundry\").setLevel(logging.ERROR)\n",
"\n",
"import os\n",
"import asyncio\n",
"import dotenv\n",
"from typing import Annotated\n",
"\n",
"from agent_framework import tool\n",
"from agent_framework.foundry import FoundryChatClient\n",
"from azure.identity import AzureCliCredential\n",
"\n",
"dotenv.load_dotenv(dotenv.find_dotenv())"
]
},
{
"cell_type": "markdown",
"id": "e5f6a7b8",
"metadata": {},
"source": [
"## Understanding the Agent Framework Architecture\n",
"\n",
"The Microsoft Agent Framework follows a layered architecture:\n",
"\n",
"```\n",
"Client → Agent → Tools\n",
" → Session\n",
"```\n",
"\n",
"1. **Client** A `FoundryChatClient` connects to an Azure OpenAI deployment. It handles authentication, request formatting, and response parsing.\n",
"2. **Agent** Created from the client via `provider.create_agent()`, the agent combines model access with instructions (system prompt) and tools.\n",
"3. **Tools** Python functions decorated with `@tool` that the agent can invoke to perform actions or retrieve data.\n",
"4. **Session** An `AgentSession` object (created via `agent.create_session()`) that stores conversation history, enabling multi-turn dialogue where the agent remembers prior context.\n",
"\n",
"Let's build each layer step by step."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f6a7b8c9",
"metadata": {},
"outputs": [],
"source": [
"# Create the client this is the connection to the AI model\n",
"endpoint = os.getenv(\"AZURE_AI_PROJECT_ENDPOINT\")\n",
"model = os.getenv(\"AZURE_AI_MODEL_DEPLOYMENT_NAME\")\n",
"\n",
"if not endpoint or not model:\n",
" raise ValueError(\n",
" \"Missing required environment variables. \"\n",
" \"Please set AZURE_AI_PROJECT_ENDPOINT and AZURE_AI_MODEL_DEPLOYMENT_NAME as environment variables (e.g., in your .env file or shell environment).\"\n",
" )\n",
"\n",
"provider = FoundryChatClient(\n",
" project_endpoint=endpoint,\n",
" model=model,\n",
" credential=AzureCliCredential()\n",
")"
]
},
{
"cell_type": "markdown",
"id": "a7b8c9d0",
"metadata": {},
"source": [
"## Adding Tools with the @tool Decorator\n",
"\n",
"Tools let agents take actions beyond generating text. The `@tool` decorator converts a regular Python function into something the agent can call.\n",
"\n",
"Key points:\n",
"- Use `Annotated[type, \"description\"]` so the model understands each parameter.\n",
"- The docstring becomes the tool description the model sees.\n",
"- `approval_mode=\"never_require\"` means the tool runs automatically without user confirmation."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b8c9d0e1",
"metadata": {},
"outputs": [],
"source": [
"@tool(approval_mode=\"never_require\")\n",
"def check_destination_availability(\n",
" destination: Annotated[str, \"The destination to check availability for\"]\n",
") -> str:\n",
" \"\"\"Check if a vacation destination is currently available for booking.\"\"\"\n",
" available = {\n",
" \"Barcelona\": True,\n",
" \"Tokyo\": True,\n",
" \"Cape Town\": False,\n",
" \"Vancouver\": True,\n",
" \"Dubai\": False,\n",
" }\n",
" is_available = available.get(destination, False)\n",
" return f\"{destination} is {'available' if is_available else 'not available'} for booking.\""
]
},
{
"cell_type": "markdown",
"id": "c9d0e1f2",
"metadata": {},
"source": [
"## Creating an Agent with Tools\n",
"\n",
"Now we combine the client, instructions, and tools into an agent. The `instructions` act as the system prompt — they define the agent's persona and behaviour."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d0e1f2a3",
"metadata": {},
"outputs": [],
"source": [
"agent = provider.as_agent(\n",
" name=\"TravelAvailabilityAgent\",\n",
" instructions=(\n",
" \"You are a travel booking agent. Help users check destination availability \"\n",
" \"and make recommendations. Always check availability before recommending a destination.\"\n",
" ),\n",
" tools=[check_destination_availability],\n",
")"
]
},
{
"cell_type": "markdown",
"id": "e1f2a3b4",
"metadata": {},
"source": [
"## Multi-Turn Conversations with Sessions\n",
"\n",
"An `AgentSession` (created via `agent.create_session()`) keeps track of all messages in a conversation. By passing the same session to each `agent.run()` call, the agent has access to the full conversation history and can refer back to earlier messages.\n",
"\n",
"We pass `tools=[check_destination_availability]` so the agent can call our availability checker during each turn."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f2a3b4c5",
"metadata": {},
"outputs": [],
"source": [
"session = agent.create_session()\n",
"\n",
"# Turn 1: Ask about available destinations\n",
"response = await agent.run(\n",
" \"Which destinations do you have available?\",\n",
" session=session,\n",
")\n",
"print(f\"Agent: {response}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a3b4c5d6",
"metadata": {},
"outputs": [],
"source": [
"# Turn 2: Follow-up question — the agent remembers the conversation\n",
"response = await agent.run(\n",
" \"I'd like to go somewhere warm. What's available?\",\n",
" session=session,\n",
")\n",
"print(f\"Agent: {response}\")"
]
},
{
"cell_type": "markdown",
"id": "b4c5d6e7",
"metadata": {},
"source": [
"## Summary\n",
"\n",
"In this lesson you explored the four pillars of the Microsoft Agent Framework:\n",
"\n",
"| Concept | What You Learned |\n",
"|---------|------------------|\n",
"| **Client** | `FoundryChatClient` connects to Azure OpenAI with credential-based auth |\n",
"| **Agent** | `provider.create_agent()` bundles a model connection with instructions and a name |\n",
"| **Tools** | The `@tool` decorator exposes Python functions for the agent to call |\n",
"| **Session** | `agent.create_session()` maintains conversation history across multiple turns |\n",
"\n",
"These building blocks compose together to create agents that can hold natural conversations, call external functions, and maintain context — the foundation for more advanced agentic patterns in later lessons."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"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.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}