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

261 lines
9.2 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "a1b2c3d4",
"metadata": {},
"source": [
"# Lesson 10 - AI Agents in Production\n",
"\n",
"In this lesson you will learn **production patterns** for AI agents using the Microsoft Agent Framework (Python). We cover:\n",
"\n",
"- **Observability** — adding timing and logging to agent interactions\n",
"- **Evaluation** — using an evaluator agent to score response quality\n",
"- **Cost management** — strategies for token optimization and model selection\n",
"\n",
"The scenario is a **travel agent** that helps users plan trips, with monitoring and evaluation layered on top."
]
},
{
"cell_type": "markdown",
"id": "b2c3d4e5",
"metadata": {},
"source": [
"## Setup"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c3d4e5f6",
"metadata": {},
"outputs": [],
"source": [
"%pip install agent-framework azure-ai-projects azure-identity python-dotenv -U -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 time\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 DefaultAzureCredential\n",
"\n",
"dotenv.load_dotenv()\n",
"\n",
"endpoint = os.getenv(\"AZURE_AI_PROJECT_ENDPOINT\")\n",
"deployment_name = os.getenv(\"AZURE_AI_MODEL_DEPLOYMENT_NAME\")\n",
"\n",
"missing = [k for k, v in {\n",
" \"AZURE_AI_PROJECT_ENDPOINT\": endpoint,\n",
" \"AZURE_AI_MODEL_DEPLOYMENT_NAME\": deployment_name\n",
"}.items() if not v]\n",
"\n",
"if missing:\n",
" raise ValueError(\n",
" f\"Missing required environment variables: {', '.join(missing)}. \"\n",
" \"Please set them as environment variables (e.g., in your .env file or shell environment).\"\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e5f6a7b8",
"metadata": {},
"outputs": [],
"source": [
"# Create the Microsoft Foundry client\n",
"client = FoundryChatClient(\n",
" project_endpoint=endpoint,\n",
" model=deployment_name,\n",
" credential=DefaultAzureCredential()\n",
")"
]
},
{
"cell_type": "markdown",
"id": "f6a7b8c9",
"metadata": {},
"source": [
"## Production Considerations\n",
"\n",
"Moving AI agents from prototypes to production requires careful attention to three pillars:\n",
"\n",
"1. **Observability** — You need visibility into what the agent is doing, how long it takes, and which tools it calls. Without tracing and logging, debugging production issues is nearly impossible.\n",
"\n",
"2. **Evaluation** — Automated quality checks ensure the agent's responses remain accurate, complete, and helpful over time. An evaluator agent can score responses against defined criteria.\n",
"\n",
"3. **Cost Management** — Token usage directly impacts cost. Strategies like prompt optimization, model selection, and caching help keep expenses under control without sacrificing quality."
]
},
{
"cell_type": "markdown",
"id": "a7b8c9d0",
"metadata": {},
"source": [
"## Building an Observable Agent\n",
"\n",
"We define travel tools and wrap the agent call with timing so we can monitor latency. In production you would integrate with OpenTelemetry or a similar tracing backend."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b8c9d0e1",
"metadata": {},
"outputs": [],
"source": [
"@tool(approval_mode=\"never_require\")\n",
"def get_flight_info(destination: Annotated[str, \"The destination city\"]) -> str:\n",
" \"\"\"Get flight information for a destination.\"\"\"\n",
" flights = {\n",
" \"Paris\": \"BA 304, 08:30-11:45, $350\",\n",
" \"Tokyo\": \"JL 044, 11:00-07:00+1, $890\",\n",
" \"Barcelona\": \"VY 7821, 07:15-10:30, $280\",\n",
" }\n",
" return flights.get(destination, f\"No flights found to {destination}\")\n",
"\n",
"\n",
"@tool(approval_mode=\"never_require\")\n",
"def get_activity_suggestions(destination: Annotated[str, \"The destination city\"]) -> str:\n",
" \"\"\"Get activity suggestions for a destination.\"\"\"\n",
" activities = {\n",
" \"Paris\": \"Louvre Museum, Eiffel Tower, Seine River Cruise, Montmartre walking tour\",\n",
" \"Tokyo\": \"Senso-ji Temple, Tsukiji Market tour, Shibuya Crossing, teamLab Borderless\",\n",
" \"Barcelona\": \"Sagrada Familia, Park Güell, La Boqueria Market, Gothic Quarter walk\",\n",
" }\n",
" return activities.get(destination, f\"No activities found for {destination}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c9d0e1f2",
"metadata": {},
"outputs": [],
"source": [
"agent = client.as_agent(\n",
" tools=[get_flight_info, get_activity_suggestions],\n",
" name=\"TravelAgent\",\n",
" instructions=\"You are a helpful travel agent. Use the available tools to help users plan their trips. Provide comprehensive, actionable travel advice.\",\n",
")\n",
"\n",
"# Simple observability: track timing\n",
"start_time = time.time()\n",
"response = await agent.run(\n",
" \"I want to plan a day trip in Paris. What flights and activities do you recommend?\",\n",
" )\n",
"elapsed = time.time() - start_time\n",
"print(f\"Response ({elapsed:.2f}s):\\n{response}\")"
]
},
{
"cell_type": "markdown",
"id": "d0e1f2a3",
"metadata": {},
"source": [
"## Evaluation Patterns\n",
"\n",
"A common production pattern is to use a second agent as an **evaluator**. The evaluator scores the primary agent's response against predefined criteria such as completeness, accuracy, and helpfulness.\n",
"\n",
"This enables:\n",
"- Automated quality gates before responses reach users\n",
"- Regression detection when prompts or models change\n",
"- Continuous monitoring of agent performance over time"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e1f2a3b4",
"metadata": {},
"outputs": [],
"source": [
"evaluator = client.as_agent(\n",
" name=\"ResponseEvaluator\",\n",
" instructions=\"\"\"You evaluate travel agent responses on these criteria:\n",
"1. Completeness (1-5): Did it cover flights AND activities?\n",
"2. Accuracy (1-5): Is the information consistent?\n",
"3. Helpfulness (1-5): Would a traveler find this actionable?\n",
"4. Overall Score (1-5)\n",
"Provide scores and a brief explanation for each.\"\"\",\n",
")\n",
"\n",
"evaluation = await evaluator.run(f\"Evaluate this travel agent response:\\n\\n{response}\")\n",
"print(f\"Evaluation:\\n{evaluation}\")"
]
},
{
"cell_type": "markdown",
"id": "f2a3b4c5",
"metadata": {},
"source": [
"## Cost Management Strategies\n",
"\n",
"Controlling costs is critical for production AI agents. Here are key strategies:\n",
"\n",
"| Strategy | Description |\n",
"|---|---|\n",
"| **Prompt optimization** | Keep system instructions concise. Remove redundant context to reduce input tokens. |\n",
"| **Model selection** | Use smaller, cheaper models (e.g. GPT-4o-mini) for simple tasks like classification or extraction, and reserve larger models for complex reasoning. |\n",
"| **Caching** | Cache tool results and frequent queries to avoid redundant API calls. |\n",
"| **Token budgets** | Set `max_tokens` limits to prevent unexpectedly long responses. |\n",
"| **Batching** | Group multiple user queries into a single API call where possible. |\n",
"\n",
"In practice, a tiered approach works well: route straightforward requests to a fast, inexpensive model and escalate only complex queries to a more capable one."
]
},
{
"cell_type": "markdown",
"id": "a3b4c5d6",
"metadata": {},
"source": [
"## Summary\n",
"\n",
"In this lesson you learned how to:\n",
"\n",
"1. **Add observability** to agent interactions with timing and logging, laying the groundwork for tracing and monitoring.\n",
"2. **Evaluate agent responses** automatically using an evaluator agent that scores completeness, accuracy, and helpfulness.\n",
"3. **Manage costs** through prompt optimization, model selection, caching, and token budgets.\n",
"\n",
"These production patterns help ensure your AI agents are reliable, measurable, and cost-effective at scale."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.13"
}
},
"nbformat": 4,
"nbformat_minor": 5
}