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

404 lines
17 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "b8c57858",
"metadata": {},
"source": [
"# Azure AI-agenter med Model Context Protocol (MCP)-understøttelse - Python\n",
"\n",
"Denne notebook demonstrerer, hvordan man bruger Azure AI-agenter med Model Context Protocol (MCP)-værktøjer i Python. Den viser, hvordan man opretter en intelligent agent, der kan udnytte eksterne MCP-servere (som Microsoft Learn) for forbedrede funktioner ved hjælp af nøglefri autentifikation.\n"
]
},
{
"cell_type": "markdown",
"id": "2e6e4234",
"metadata": {},
"source": [
"## Installer Nødvendige Python Pakker\n",
"\n",
"Først skal vi installere de nødvendige Python-pakker:\n",
"- **azure-ai-projects**: Core Azure AI Projects SDK\n",
"- **azure-ai-agents**: Azure AI Agents SDK til oprettelse og administration af agenter\n",
"- **azure-identity**: Giver nøglefri autentifikation ved hjælp af DefaultAzureCredential\n",
"- **mcp**: Implementering af Model Context Protocol for Python\n"
]
},
{
"cell_type": "markdown",
"id": "6a2e9a05",
"metadata": {},
"source": [
"## Fordele ved nøglefri godkendelse\n",
"\n",
"Denne notebook demonstrerer **nøglefri godkendelse**, som giver flere fordele:\n",
"- ✅ **Ingen API-nøgler at administrere** - Bruger Azure-identitetsbaseret godkendelse\n",
"- ✅ **Forbedret sikkerhed** - Ingen hemmeligheder gemt i kode eller konfigurationsfiler\n",
"- ✅ **Automatisk rotation af legitimationsoplysninger** - Azure håndterer livscyklusstyring af legitimationsoplysninger\n",
"- ✅ **Rollebaseret adgangskontrol** - Bruger Azure RBAC til detaljerede tilladelser\n",
"- ✅ **Understøttelse af flere miljøer** - Fungerer problemfrit på tværs af udvikling og produktion\n",
"\n",
"`DefaultAzureCredential` vælger automatisk den bedst tilgængelige kilde til legitimationsoplysninger:\n",
"1. **Managed Identity** (når det kører i Azure)\n",
"2. **Azure CLI** legitimationsoplysninger (under lokal udvikling)\n",
"3. **Visual Studio** legitimationsoplysninger\n",
"4. **Miljøvariabler** (hvis konfigureret)\n",
"5. **Interaktiv browser**-godkendelse (som en sidste udvej)\n"
]
},
{
"cell_type": "markdown",
"id": "43efa94d",
"metadata": {},
"source": [
"## Opsætning af nøglefri autentifikation\n",
"\n",
"**Forudsætninger for nøglefri autentifikation:**\n",
"\n",
"### Til lokal udvikling:\n",
"```bash\n",
"# Install Azure CLI and login\n",
"az login\n",
"# Verify your identity\n",
"az account show\n",
"```\n",
"\n",
"### Til Azure-miljøer:\n",
"- Aktiver **System-tildelt Managed Identity** på din Azure-ressource\n",
"- Tildel passende **RBAC-roller** til den administrerede identitet:\n",
" - `Cognitive Services OpenAI User` for adgang til Azure OpenAI\n",
" - `AI Developer` for adgang til Azure AI-projekter\n",
"\n",
"### Miljøvariabler (valgfrit):\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",
"**Ingen API-nøgler eller forbindelsesstrenge nødvendige!** 🔐\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": [
"## Importer nødvendige biblioteker\n",
"\n",
"Importer de nødvendige Python-moduler:\n",
"- **os, time**: Standard Python-biblioteker til miljøvariabler og forsinkelser\n",
"- **AIProjectClient**: Hovedklienten til Azure AI Projects\n",
"- **DefaultAzureCredential**: Nøglefri autentificering til Azure-tjenester\n",
"- **MCP-relaterede klasser**: Til oprettelse og administration af MCP-værktøjer og håndtering af godkendelser\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": [
"## Konfigurer MCP-serverindstillinger\n",
"\n",
"Opsæt MCP-serverkonfigurationen ved hjælp af miljøvariabler med standardværdier som fallback:\n",
"- **MCP_SERVER_URL**: URL'en til MCP-serveren (standard er Microsoft Learn API)\n",
"- **MCP_SERVER_LABEL**: En etiket til at identificere MCP-serveren (standard er \"mslearn\")\n",
"\n",
"Denne tilgang muliggør fleksibel konfiguration på tværs af forskellige miljøer.\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": [
"## Opret Azure AI Project Client (Nøglefri Godkendelse)\n",
"\n",
"Initialiser Azure AI Project-klienten ved hjælp af **nøglefri godkendelse**:\n",
"- **endpoint**: URL'en til Azure AI Foundry-projektets endpoint\n",
"- **credential**: Bruger `DefaultAzureCredential()` til sikker, nøglefri godkendelse\n",
"- **Ingen API-nøgler påkrævet**: Finder og bruger automatisk den bedst tilgængelige godkendelse\n",
"\n",
"**Godkendelsesflow:**\n",
"1. Tjekker for Managed Identity (i Azure-miljøer)\n",
"2. Fald tilbage til Azure CLI-legitimationsoplysninger (til lokal udvikling)\n",
"3. Bruger andre tilgængelige godkendelseskilder efter behov\n",
"\n",
"Denne tilgang eliminerer behovet for at administrere API-nøgler eller forbindelsesstrenge i din kode.\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": [
"## Opret MCP-værktøjsdefinition\n",
"\n",
"Opret et MCP-værktøj, der forbinder til Microsoft Learn MCP-serveren:\n",
"- **server_label**: Identifikator for MCP-serveren\n",
"- **server_url**: URL-endepunkt for MCP-serveren\n",
"- **allowed_tools**: Valgfri liste til at begrænse, hvilke værktøjer der kan bruges (tom liste tillader alle værktøjer)\n",
"\n",
"Dette værktøj giver agenten mulighed for at få adgang til Microsoft Learn-dokumentation og ressourcer.\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": [
"## Opret agent og udfør samtale (Nøglefri arbejdsgang)\n",
"\n",
"Denne omfattende sektion demonstrerer den komplette **nøglefri agentarbejdsgang**:\n",
"\n",
"1. **Opret AI-agent**: Opsæt en agent med GPT-4.1 nano-model og MCP-værktøjer\n",
"2. **Opret tråd**: Etabler en samtaletråd til kommunikation\n",
"3. **Send besked**: Spørg agenten om forskellene mellem Azure OpenAI og OpenAI\n",
"4. **Håndter værktøjsgodkendelser**: Godkend automatisk MCP-værktøjsanmodninger, når det er nødvendigt\n",
"5. **Overvåg udførelse**: Følg agentens fremskridt og håndter eventuelle nødvendige handlinger\n",
"6. **Vis resultater**: Vis samtalen og detaljer om værktøjsbrug\n",
"\n",
"**Nøglefri funktioner:**\n",
"- ✅ **Ingen hardkodede hemmeligheder** - Al autentificering håndteres af Azure-identitet\n",
"- ✅ **Sikker som standard** - Bruger rollebaseret adgangskontrol\n",
"- ✅ **Forenklet implementering** - Ingen behov for håndtering af legitimationsoplysninger\n",
"- ✅ **Revisionsvenlig** - Al adgang spores via Azure-identitet\n",
"\n",
"Agenten vil bruge MCP-værktøjer til at få adgang til Microsoft Learn-ressourcer med fuld sikkerhed og uden behov for API-nøgleadministration.\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**Ansvarsfraskrivelse**: \nDette dokument er blevet oversat ved hjælp af AI-oversættelsestjenesten [Co-op Translator](https://github.com/Azure/co-op-translator). Selvom vi bestræber os på nøjagtighed, skal du være opmærksom på, at automatiserede oversættelser kan indeholde fejl eller unøjagtigheder. Det originale dokument på dets oprindelige sprog bør betragtes som den autoritative kilde. For kritisk information anbefales professionel menneskelig oversættelse. Vi er ikke ansvarlige for eventuelle misforståelser eller fejltolkninger, der opstår som følge af brugen af denne oversættelse.\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:34:08+00:00",
"source_file": "05-AdvancedTopics/mcp-foundry-agent-integration/mcp_support_python.ipynb",
"language_code": "da"
}
},
"nbformat": 4,
"nbformat_minor": 5
}