项目文件夹

文件
2026-07-13 12:59:43 +08:00

283 行
9.7 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "a1b2c3d4",
"metadata": {},
"source": [
"# Lesson 09 - Metacognition Design Pattern"
]
},
{
"cell_type": "markdown",
"id": "b2c3d4e5",
"metadata": {},
"source": [
"## Setup\n",
"\n",
"This notebook demonstrates the Metacognition design pattern using the Microsoft Agent Framework.\n",
"\n",
"**Prerequisites:**\n",
"- Azure OpenAI deployment configured via environment variables\n",
"- Azure CLI authenticated (`az login`)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c3d4e5f6",
"metadata": {},
"outputs": [],
"source": [
"%pip install agent-framework azure-ai-projects azure-identity 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 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": [
"## What is Metacognition?\n",
"\n",
"Metacognition is **thinking about thinking**. In the context of AI agents, it means building agents that can:\n",
"\n",
"- **Self-reflect** on their own outputs and reasoning process\n",
"- **Detect errors** and recover gracefully instead of failing silently\n",
"- **Evaluate** whether their responses are complete and helpful\n",
"- **Adapt** their strategy when an initial approach doesn't work (e.g., falling back to a backup system)\n",
"\n",
"A metacognitive agent doesn't just answer questions — it monitors its own performance and adjusts on the fly."
]
},
{
"cell_type": "markdown",
"id": "a7b8c9d0",
"metadata": {},
"source": [
"## Primary and Backup Tools\n",
"\n",
"A common metacognition pattern is the **fallback strategy**. The agent tries a primary tool first; if it fails (e.g., a 404 error), the agent recognizes the failure and transparently switches to a backup tool.\n",
"\n",
"This mirrors real-world systems where primary services may be unavailable and agents must self-diagnose the issue before choosing an alternative path.\n",
"\n",
"Below we define two flight lookup tools:\n",
"- **Primary** — covers Paris, Tokyo, and Barcelona\n",
"- **Backup** — covers Berlin, Sydney, and New York City"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b8c9d0e1",
"metadata": {},
"outputs": [],
"source": [
"@tool(approval_mode=\"never_require\")\n",
"def get_flight_times(\n",
" destination: Annotated[str, \"The destination city\"]\n",
") -> str:\n",
" \"\"\"Get available flight times for a destination (primary source).\"\"\"\n",
" flights = {\n",
" \"Paris\": \"Departures: 08:00, 12:30, 17:45 — from $350\",\n",
" \"Tokyo\": \"Departures: 11:00, 23:30 — from $890\",\n",
" \"Barcelona\": \"Departures: 07:15, 14:00, 19:30 — from $280\",\n",
" }\n",
" if destination in flights:\n",
" return flights[destination]\n",
" raise Exception(f\"404: No flights found for {destination} in primary system\")\n",
"\n",
"\n",
"@tool(approval_mode=\"never_require\")\n",
"def get_flight_times_backup(\n",
" destination: Annotated[str, \"The destination city\"]\n",
") -> str:\n",
" \"\"\"Get available flight times from backup system (used when primary fails).\"\"\"\n",
" backup_flights = {\n",
" \"Berlin\": \"Departures: 09:00, 16:00 — from $220\",\n",
" \"Sydney\": \"Departures: 22:00 — from $1200\",\n",
" \"New York City\": \"Departures: 06:00, 10:30, 15:00, 20:00 — from $450\",\n",
" }\n",
" return backup_flights.get(\n",
" destination,\n",
" f\"No flights found for {destination} in any system. Please try again later.\",\n",
" )"
]
},
{
"cell_type": "markdown",
"id": "c9d0e1f2",
"metadata": {},
"source": [
"## Self-Reflecting Agent with Error Recovery\n",
"\n",
"The agent below is instructed to try the primary flight system first, recognize failures, and transparently fall back to the backup system. After each response it briefly self-evaluates whether it fully answered the user's question."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d0e1f2a3",
"metadata": {},
"outputs": [],
"source": [
"agent = client.as_agent(\n",
" tools=[get_flight_times, get_flight_times_backup],\n",
" name=\"FlightBookingAgent\",\n",
" instructions=\"\"\"You are a flight booking agent with self-reflection capabilities.\n",
"\n",
"When looking up flights:\n",
"1. Try the primary flight system first (get_flight_times)\n",
"2. If the primary system fails (404 error), acknowledge the error and try the backup system (get_flight_times_backup)\n",
"3. Always explain to the user what happened — be transparent about fallbacks\n",
"4. If both systems fail, apologize and suggest alternatives\n",
"\n",
"After each response, briefly evaluate whether your answer was complete and helpful.\"\"\",\n",
")\n",
"\n",
"# Test with a destination in primary system\n",
"print(\"=== Test 1: Destination in primary system ===\")\n",
"response = await agent.run(\n",
" \"What flights are available to Paris?\",\n",
" )\n",
"print(response)\n",
"\n",
"# Test with a destination only in backup system\n",
"print(\"\\n=== Test 2: Destination only in backup system ===\")\n",
"response = await agent.run(\n",
" \"What flights are available to Berlin?\",\n",
" )\n",
"print(response)"
]
},
{
"cell_type": "markdown",
"id": "e1f2a3b4",
"metadata": {},
"source": [
"## Self-Evaluation Pattern\n",
"\n",
"Another facet of metacognition is **self-evaluation**: a separate agent (or the same agent in a second pass) reviews a response for completeness, accuracy, and helpfulness.\n",
"\n",
"Below we create a `ResponseEvaluator` agent that scores travel-agent responses on three dimensions."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f2a3b4c5",
"metadata": {},
"outputs": [],
"source": [
"evaluation_agent = client.as_agent(\n",
" tools=[get_flight_times, get_flight_times_backup],\n",
" name=\"ResponseEvaluator\",\n",
" instructions=\"\"\"You are a quality evaluator for travel agent responses.\n",
"Given a travel question and the agent's response, evaluate:\n",
"1. Completeness: Did it answer all parts of the question? (1-5)\n",
"2. Accuracy: Is the information correct? (1-5)\n",
"3. Helpfulness: Would a traveler find this useful? (1-5)\n",
"Provide a brief evaluation with scores and one suggestion for improvement.\"\"\",\n",
")\n",
"\n",
"# Evaluate the agent's response from Test 1\n",
"eval_prompt = f\"\"\"Question: What flights are available to Paris?\n",
"Agent Response: {response}\n",
"\n",
"Please evaluate the above response.\"\"\"\n",
"\n",
"evaluation = await evaluation_agent.run(eval_prompt)\n",
"print(\"=== Self-Evaluation ===\")\n",
"print(evaluation)"
]
},
{
"cell_type": "markdown",
"id": "a3b4c5d6",
"metadata": {},
"source": [
"## Summary\n",
"\n",
"In this lesson you learned how to build **metacognitive agents** using the Microsoft Agent Framework:\n",
"\n",
"- **Self-reflection**: Agents that monitor their own reasoning and transparently communicate what happened.\n",
"- **Error recovery with fallbacks**: A primary + backup tool pattern where the agent detects failures (e.g., 404 errors) and automatically tries an alternative source.\n",
"- **Self-evaluation**: A separate evaluator agent that scores responses for completeness, accuracy, and helpfulness.\n",
"\n",
"These patterns make agents more robust, transparent, and trustworthy — critical qualities for production deployments."
]
}
],
"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
}