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

404 lines
23 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "b8c57858",
"metadata": {},
"source": [
"# ตัวแทน AI ของ Azure พร้อมการสนับสนุน Model Context Protocol (MCP) - Python\n",
"\n",
"สมุดบันทึกนี้แสดงวิธีการใช้ตัวแทน AI ของ Azure พร้อมเครื่องมือ 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 Projects\n",
"- **azure-ai-agents**: SDK สำหรับ Azure AI Agents เพื่อสร้างและจัดการเอเจนต์\n",
"- **azure-identity**: ให้การรับรองความถูกต้องแบบไม่ใช้คีย์ด้วย DefaultAzureCredential\n",
"- **mcp**: การใช้งาน Model Context Protocol สำหรับ Python\n"
]
},
{
"cell_type": "markdown",
"id": "6a2e9a05",
"metadata": {},
"source": [
"## ข้อดีของการยืนยันตัวตนแบบไม่ใช้คีย์\n",
"\n",
"สมุดบันทึกนี้แสดงตัวอย่างของ **การยืนยันตัวตนแบบไม่ใช้คีย์** ซึ่งมีข้อดีหลายประการ:\n",
"- ✅ **ไม่ต้องจัดการ API keys** - ใช้การยืนยันตัวตนตาม Azure identity\n",
"- ✅ **เพิ่มความปลอดภัย** - ไม่มีการเก็บข้อมูลลับในโค้ดหรือไฟล์การตั้งค่า\n",
"- ✅ **การหมุนเวียนข้อมูลรับรองอัตโนมัติ** - Azure จัดการวงจรชีวิตของข้อมูลรับรองให้\n",
"- ✅ **การควบคุมการเข้าถึงตามบทบาท** - ใช้ Azure RBAC เพื่อกำหนดสิทธิ์อย่างละเอียด\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",
"- เปิดใช้งาน **System-assigned Managed Identity** บนทรัพยากร Azure ของคุณ\n",
"- กำหนด **RBAC roles** ที่เหมาะสมให้กับ Managed Identity:\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 keys หรือ connection strings!** 🔐\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",
"นำเข้าโมดูล Python ที่จำเป็น:\n",
"- **os, time**: ห้องสมุดมาตรฐานของ Python สำหรับตัวแปรสภาพแวดล้อมและการหน่วงเวลา\n",
"- **AIProjectClient**: ไคลเอนต์หลักสำหรับ Azure AI Projects\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 Project Client (การยืนยันตัวตนแบบไม่ใช้คีย์)\n",
"\n",
"เริ่มต้นใช้งาน Azure AI Project client ด้วย **การยืนยันตัวตนแบบไม่ใช้คีย์**:\n",
"- **endpoint**: URL ของ Azure AI Foundry project endpoint\n",
"- **credential**: ใช้ `DefaultAzureCredential()` เพื่อการยืนยันตัวตนที่ปลอดภัยและไม่ต้องใช้คีย์\n",
"- **ไม่ต้องใช้ API keys**: ระบบจะค้นหาและใช้ credential ที่เหมาะสมที่สุดโดยอัตโนมัติ\n",
"\n",
"**ขั้นตอนการยืนยันตัวตน:**\n",
"1. ตรวจสอบ Managed Identity (ในสภาพแวดล้อมของ Azure)\n",
"2. หากไม่มี จะใช้ Azure CLI credentials (สำหรับการพัฒนาบนเครื่องท้องถิ่น)\n",
"3. ใช้แหล่งข้อมูล credential อื่น ๆ ตามความจำเป็น\n",
"\n",
"วิธีนี้ช่วยลดความยุ่งยากในการจัดการ API keys หรือ connection strings ในโค้ดของคุณ\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 ที่เชื่อมต่อกับเซิร์ฟเวอร์ Microsoft Learn MCP:\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 Agent**: ตั้งค่าเอเจนต์ด้วยโมเดล GPT-4.1 nano และเครื่องมือ MCP \n",
"2. **สร้างเธรด**: สร้างเธรดสำหรับการสนทนา \n",
"3. **ส่งข้อความ**: ถามเอเจนต์เกี่ยวกับความแตกต่างระหว่าง Azure OpenAI และ OpenAI \n",
"4. **จัดการการอนุมัติเครื่องมือ**: อนุมัติการเรียกใช้เครื่องมือ MCP โดยอัตโนมัติเมื่อจำเป็น \n",
"5. **ติดตามการดำเนินการ**: ตรวจสอบความคืบหน้าของเอเจนต์และจัดการการดำเนินการที่จำเป็น \n",
"6. **แสดงผลลัพธ์**: แสดงรายละเอียดการสนทนาและการใช้งานเครื่องมือ \n",
"\n",
"**คุณสมบัติของเวิร์กโฟลว์แบบไม่ใช้คีย์:**\n",
"- ✅ **ไม่มีความลับที่ฮาร์ดโค้ด** - การยืนยันตัวตนทั้งหมดจัดการโดย Azure identity \n",
"- ✅ **ปลอดภัยโดยค่าเริ่มต้น** - ใช้การควบคุมการเข้าถึงตามบทบาท \n",
"- ✅ **การปรับใช้ง่าย** - ไม่ต้องจัดการข้อมูลรับรอง \n",
"- ✅ **เหมาะสำหรับการตรวจสอบ** - การเข้าถึงทั้งหมดถูกติดตามผ่าน Azure identity \n",
"\n",
"เอเจนต์จะใช้เครื่องมือ MCP เพื่อเข้าถึงทรัพยากร Microsoft Learn ด้วยความปลอดภัยเต็มรูปแบบและไม่ต้องจัดการ API key\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เอกสารนี้ได้รับการแปลโดยใช้บริการแปลภาษา AI [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:33:06+00:00",
"source_file": "05-AdvancedTopics/mcp-foundry-agent-integration/mcp_support_python.ipynb",
"language_code": "th"
}
},
"nbformat": 4,
"nbformat_minor": 5
}