Files
2026-07-13 13:31:35 +08:00

404 lines
18 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "b8c57858",
"metadata": {},
"source": [
"# סוכני Azure AI עם תמיכה ב-Model Context Protocol (MCP) - Python\n",
"\n",
"מחברת זו מדגימה כיצד להשתמש בסוכני Azure AI עם כלים של Model Context Protocol (MCP) ב-Python. היא מציגה כיצד ליצור סוכן חכם שיכול לנצל שרתי MCP חיצוניים (כמו Microsoft Learn) לשיפור יכולות באמצעות אימות ללא מפתחות.\n"
]
},
{
"cell_type": "markdown",
"id": "2e6e4234",
"metadata": {},
"source": [
"## התקנת חבילות Python נדרשות\n",
"\n",
"ראשית, עלינו להתקין את חבילות ה-Python הנחוצות:\n",
"- **azure-ai-projects**: SDK מרכזי לפרויקטים של Azure AI \n",
"- **azure-ai-agents**: SDK של Azure AI Agents ליצירה וניהול של סוכנים \n",
"- **azure-identity**: מספק אימות ללא מפתחות באמצעות DefaultAzureCredential \n",
"- **mcp**: יישום של פרוטוקול Model Context עבור Python \n"
]
},
{
"cell_type": "markdown",
"id": "6a2e9a05",
"metadata": {},
"source": [
"## יתרונות אימות ללא מפתחות\n",
"\n",
"מחברת זו מדגימה **אימות ללא מפתחות**, שמציע מספר יתרונות:\n",
"- ✅ **אין צורך לנהל מפתחות API** - משתמש באימות מבוסס זהות של Azure\n",
"- ✅ **אבטחה משופרת** - אין סודות שמאוחסנים בקוד או בקבצי תצורה\n",
"- ✅ **סיבוב אישורים אוטומטי** - Azure מטפל בניהול מחזור החיים של האישורים\n",
"- ✅ **בקרת גישה מבוססת תפקידים** - משתמש ב-RBAC של Azure להרשאות מדויקות\n",
"- ✅ **תמיכה בריבוי סביבות** - עובד בצורה חלקה בין פיתוח לסביבת ייצור\n",
"\n",
"ה-`DefaultAzureCredential` בוחר באופן אוטומטי את מקור האישורים הטוב ביותר הזמין:\n",
"1. **Managed Identity** (כאשר פועל ב-Azure)\n",
"2. אישורי **Azure CLI** (במהלך פיתוח מקומי)\n",
"3. אישורי **Visual Studio**\n",
"4. **משתני סביבה** (אם הוגדרו)\n",
"5. אימות **דפדפן אינטראקטיבי** (כאופציה אחרונה)\n"
]
},
{
"cell_type": "markdown",
"id": "43efa94d",
"metadata": {},
"source": [
"## הגדרת אימות ללא מפתחות\n",
"\n",
"**דרישות מוקדמות לאימות ללא מפתחות:**\n",
"\n",
"### עבור פיתוח מקומי:\n",
"```bash\n",
"# Install Azure CLI and login\n",
"az login\n",
"# Verify your identity\n",
"az account show\n",
"```\n",
"\n",
"### עבור סביבות Azure:\n",
"- הפעלת **זהות מנוהלת מוקצת מערכתית** במשאב Azure שלך \n",
"- הקצאת **תפקידי RBAC** מתאימים לזהות המנוהלת: \n",
" - `Cognitive Services OpenAI User` עבור גישה ל-Azure OpenAI \n",
" - `AI Developer` עבור גישה לפרויקטי Azure AI \n",
"\n",
"### משתני סביבה (אופציונלי):\n",
"```python\n",
"# These are automatically detected by DefaultAzureCredential\n",
"# AZURE_CLIENT_ID=<your-client-id>\n",
"# AZURE_CLIENT_SECRET=<your-client-secret>\n",
"# AZURE_TENANT_ID=<your-tenant-id>\n",
"```\n",
"\n",
"**אין צורך במפתחות API או במחרוזות חיבור!** 🔐 \n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2e21387d",
"metadata": {},
"outputs": [],
"source": [
"! pip install azure-ai-projects -U\n",
"! pip install azure-ai-agents==1.1.0b4 -U\n",
"! pip install azure-identity -U\n",
"! pip install mcp==1.11.0 -U"
]
},
{
"cell_type": "markdown",
"id": "b31c8873",
"metadata": {},
"source": [
"## ייבוא ספריות נדרשות\n",
"\n",
"ייבא את המודולים הנחוצים של פייתון:\n",
"- **os, time**: ספריות סטנדרטיות של פייתון עבור משתני סביבה ועיכובים\n",
"- **AIProjectClient**: לקוח ראשי עבור פרויקטים של Azure AI\n",
"- **DefaultAzureCredential**: אימות ללא מפתח עבור שירותי Azure\n",
"- **MCP-related classes**: ליצירה וניהול של כלי MCP וטיפול באישורים\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "43667b32",
"metadata": {},
"outputs": [],
"source": [
"import os, time\n",
"from azure.ai.projects import AIProjectClient\n",
"from azure.identity import DefaultAzureCredential\n",
"from azure.ai.agents.models import McpTool, RequiredMcpToolCall, SubmitToolApprovalAction, ToolApproval\n"
]
},
{
"cell_type": "markdown",
"id": "721355e5",
"metadata": {},
"source": [
"## הגדרת הגדרות שרת MCP\n",
"\n",
"הגדר את תצורת שרת MCP באמצעות משתני סביבה עם ערכי ברירת מחדל:\n",
"- **MCP_SERVER_URL**: כתובת ה-URL של שרת MCP (ברירת מחדל היא Microsoft Learn API)\n",
"- **MCP_SERVER_LABEL**: תווית לזיהוי שרת MCP (ברירת מחדל היא \"mslearn\")\n",
"\n",
"גישה זו מאפשרת תצורה גמישה בסביבות שונות.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "189f3d55",
"metadata": {},
"outputs": [],
"source": [
"mcp_server_url = os.environ.get(\"MCP_SERVER_URL\", \"https://learn.microsoft.com/api/mcp\")\n",
"mcp_server_label = os.environ.get(\"MCP_SERVER_LABEL\", \"mslearn\")"
]
},
{
"cell_type": "markdown",
"id": "20612d9a",
"metadata": {},
"source": [
"## יצירת לקוח פרויקט Azure AI (אימות ללא מפתח)\n",
"\n",
"אתחל את לקוח פרויקט Azure AI באמצעות **אימות ללא מפתח**:\n",
"- **endpoint**: כתובת ה-URL של נקודת הקצה של פרויקט Azure AI Foundry\n",
"- **credential**: משתמש ב-`DefaultAzureCredential()` לאימות מאובטח ללא מפתח\n",
"- **אין צורך במפתחות API**: מזהה ומשתמש באופן אוטומטי באישורים הטובים ביותר הזמינים\n",
"\n",
"**תהליך האימות:**\n",
"1. בודק זהות מנוהלת (בסביבות Azure)\n",
"2. עובר לאישורי Azure CLI (לצורך פיתוח מקומי)\n",
"3. משתמש במקורות אישור אחרים לפי הצורך\n",
"\n",
"גישה זו מבטלת את הצורך לנהל מפתחות API או מחרוזות חיבור בקוד שלך.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "36b1dbd8",
"metadata": {},
"outputs": [],
"source": [
"project_client = AIProjectClient(\n",
" endpoint=\"Your Azure AI Foundry Endpoint\",\n",
" credential=DefaultAzureCredential(),\n",
")"
]
},
{
"cell_type": "markdown",
"id": "cdb6ab8c",
"metadata": {},
"source": [
"## יצירת הגדרת כלי MCP\n",
"\n",
"צור כלי MCP שמתחבר לשרת MCP של Microsoft Learn:\n",
"- **server_label**: מזהה עבור שרת ה-MCP\n",
"- **server_url**: נקודת קצה URL של שרת ה-MCP\n",
"- **allowed_tools**: רשימה אופציונלית להגבלת הכלים שניתן להשתמש בהם (רשימה ריקה מאפשרת את כל הכלים)\n",
"\n",
"כלי זה יאפשר לסוכן גישה לתיעוד ולמשאבים של Microsoft Learn.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "51e7e136",
"metadata": {},
"outputs": [],
"source": [
"mcp_tool = McpTool(\n",
" server_label=mcp_server_label,\n",
" server_url=mcp_server_url,\n",
" allowed_tools=[], # Optional: specify allowed tools\n",
")\n"
]
},
{
"cell_type": "markdown",
"id": "6e894b0b",
"metadata": {},
"source": [
"## יצירת סוכן וביצוע שיחה (תהליך ללא מפתחות)\n",
"\n",
"החלק המקיף הזה מציג את תהליך העבודה המלא של **סוכן ללא מפתחות**:\n",
"\n",
"1. **יצירת סוכן AI**: הגדרת סוכן עם מודל GPT-4.1 nano וכלי MCP \n",
"2. **יצירת שרשור**: הקמת שרשור שיחה לצורך תקשורת \n",
"3. **שליחת הודעה**: שאל את הסוכן על ההבדלים בין Azure OpenAI ל-OpenAI \n",
"4. **אישור כלי**: אישור אוטומטי של קריאות לכלי MCP במידת הצורך \n",
"5. **מעקב אחר ביצוע**: מעקב אחר התקדמות הסוכן וטיפול בפעולות נדרשות \n",
"6. **הצגת תוצאות**: הצגת פרטי השיחה והשימוש בכלים \n",
"\n",
"**תכונות ללא מפתחות:**\n",
"- ✅ **ללא סודות מקודדים מראש** - כל האימות מתבצע באמצעות זהות Azure \n",
"- ✅ **מאובטח כברירת מחדל** - משתמש בבקרת גישה מבוססת תפקידים \n",
"- ✅ **פריסה פשוטה** - אין צורך בניהול אישורים \n",
"- ✅ **ידידותי לביקורת** - כל הגישה מתועדת באמצעות זהות Azure \n",
"\n",
"הסוכן ישתמש בכלי MCP כדי לגשת למשאבי Microsoft Learn עם אבטחה מלאה וללא צורך בניהול מפתחות API.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "68c49af5",
"metadata": {},
"outputs": [],
"source": [
"with project_client:\n",
" agents_client = project_client.agents\n",
"\n",
" # Create a new agent with keyless authentication\n",
" # NOTE: To reuse existing agent, fetch it with get_agent(agent_id)\n",
" agent = agents_client.create_agent(\n",
" model=\"Your Azure OpenAI Model Deployment Name\",\n",
" name=\"my-mcp-agent\",\n",
" instructions=\"You are a helpful agent that can use MCP tools to assist users. Use the available MCP tools to answer questions and perform tasks.\",\n",
" tools=mcp_tool.definitions,\n",
" )\n",
" print(f\"Created agent, ID: {agent.id}\")\n",
" print(f\"MCP Server: {mcp_tool.server_label} at {mcp_tool.server_url}\")\n",
"\n",
" # Create thread for communication\n",
" thread = agents_client.threads.create()\n",
" print(f\"Created thread, ID: {thread.id}\")\n",
"\n",
" # Create message to thread\n",
" message = agents_client.messages.create(\n",
" thread_id=thread.id,\n",
" role=\"user\",\n",
" content=\"What's difference between Azure OpenAI and OpenAI?\",\n",
" )\n",
" print(f\"Created message, ID: {message.id}\")\n",
"\n",
" # KEYLESS APPROACH: Handle tool approvals without hardcoded secrets\n",
" \n",
" # Option 1: Completely keyless (recommended for Azure identity-enabled MCP servers)\n",
" # run = agents_client.runs.create(thread_id=thread.id, agent_id=agent.id, tool_resources=mcp_tool.resources)\n",
" \n",
" # Option 2: With minimal headers (if MCP server requires specific headers)\n",
" # For demonstration purposes, using a placeholder header\n",
" mcp_tool.update_headers(\"SuperSecret\", \"123456\") # Replace with actual auth if needed\n",
" \n",
" # Set approval mode - uncomment next line to disable approval requirement completely\n",
" # mcp_tool.set_approval_mode(\"never\") # Fully automated, no approval needed\n",
" \n",
" run = agents_client.runs.create(thread_id=thread.id, agent_id=agent.id, tool_resources=mcp_tool.resources)\n",
" print(f\"Created run, ID: {run.id}\")\n",
"\n",
" while run.status in [\"queued\", \"in_progress\", \"requires_action\"]:\n",
" time.sleep(1)\n",
" run = agents_client.runs.get(thread_id=thread.id, run_id=run.id)\n",
"\n",
" if run.status == \"requires_action\" and isinstance(run.required_action, SubmitToolApprovalAction):\n",
" tool_calls = run.required_action.submit_tool_approval.tool_calls\n",
" if not tool_calls:\n",
" print(\"No tool calls provided - cancelling run\")\n",
" agents_client.runs.cancel(thread_id=thread.id, run_id=run.id)\n",
" break\n",
"\n",
" tool_approvals = []\n",
" for tool_call in tool_calls:\n",
" if isinstance(tool_call, RequiredMcpToolCall):\n",
" try:\n",
" print(f\"Approving tool call: {tool_call}\")\n",
" \n",
" # KEYLESS APPROVAL OPTIONS:\n",
" \n",
" # Option 1: No headers (fully keyless)\n",
" # tool_approvals.append(\n",
" # ToolApproval(\n",
" # tool_call_id=tool_call.id,\n",
" # approve=True,\n",
" # headers={} # No headers needed for keyless\n",
" # )\n",
" # )\n",
" \n",
" # Option 2: With headers (if MCP server requires them)\n",
" tool_approvals.append(\n",
" ToolApproval(\n",
" tool_call_id=tool_call.id,\n",
" approve=True,\n",
" headers=mcp_tool.headers, # Uses configured headers if needed\n",
" )\n",
" )\n",
" except Exception as e:\n",
" print(f\"Error approving tool_call {tool_call.id}: {e}\")\n",
"\n",
" print(f\"tool_approvals: {tool_approvals}\")\n",
" if tool_approvals:\n",
" agents_client.runs.submit_tool_outputs(\n",
" thread_id=thread.id, run_id=run.id, tool_approvals=tool_approvals\n",
" )\n",
"\n",
" print(f\"Current run status: {run.status}\")\n",
"\n",
" print(f\"Run completed with status: {run.status}\")\n",
" if run.status == \"failed\":\n",
" print(f\"Run failed: {run.last_error}\")\n",
"\n",
" # Display run steps and tool calls\n",
" run_steps = agents_client.run_steps.list(thread_id=thread.id, run_id=run.id)\n",
"\n",
" # Loop through each step\n",
" for step in run_steps:\n",
" print(f\"Step {step['id']} status: {step['status']}\")\n",
"\n",
" # Check if there are tool calls in the step details\n",
" step_details = step.get(\"step_details\", {})\n",
" tool_calls = step_details.get(\"tool_calls\", [])\n",
"\n",
" if tool_calls:\n",
" print(\" MCP Tool calls:\")\n",
" for call in tool_calls:\n",
" print(f\" Tool Call ID: {call.get('id')}\")\n",
" print(f\" Type: {call.get('type')}\")\n",
"\n",
" print() # add an extra newline between steps\n",
"\n",
" # Fetch and log all messages\n",
" messages = agents_client.messages.list(thread_id=thread.id)\n",
" print(\"\\nConversation:\")\n",
" print(\"-\" * 50)\n",
" for msg in messages:\n",
" if msg.text_messages:\n",
" last_text = msg.text_messages[-1]\n",
" print(f\"{msg.role.upper()}: {last_text.text.value}\")\n",
" print(\"-\" * 50)\n",
"\n",
" # Example of dynamic tool management (keyless)\n",
" print(f\"\\nDemonstrating keyless dynamic tool management:\")\n",
" print(f\"Current allowed tools: {mcp_tool.allowed_tools}\")\n",
" print(\"✅ All operations completed using keyless authentication!\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**כתב ויתור**: \nמסמך זה תורגם באמצעות שירות תרגום מבוסס בינה מלאכותית [Co-op Translator](https://github.com/Azure/co-op-translator). בעוד שאנו שואפים לדיוק, יש להיות מודעים לכך שתרגומים אוטומטיים עשויים להכיל שגיאות או אי דיוקים. המסמך המקורי בשפתו המקורית צריך להיחשב כמקור סמכותי. עבור מידע קריטי, מומלץ להשתמש בתרגום מקצועי על ידי אדם. איננו נושאים באחריות לאי הבנות או לפרשנויות שגויות הנובעות משימוש בתרגום זה.\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "demo",
"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.10.15"
},
"coopTranslator": {
"original_hash": "39a035fea0d10767dfcb0662bd3528fa",
"translation_date": "2025-08-26T21:36:15+00:00",
"source_file": "05-AdvancedTopics/mcp-foundry-agent-integration/mcp_support_python.ipynb",
"language_code": "he"
}
},
"nbformat": 4,
"nbformat_minor": 5
}