microsoft--ai-agents-for-beginners
631 行
28 KiB
Plaintext
631 行
28 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "4b2cf5f5",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import asyncio\n",
|
||
"import json\n",
|
||
"import os\n",
|
||
"from typing import Annotated, Any, Never\n",
|
||
"\n",
|
||
"from agent_framework import (\n",
|
||
" AgentExecutor,\n",
|
||
" AgentExecutorRequest,\n",
|
||
" AgentExecutorResponse,\n",
|
||
" Message,\n",
|
||
" WorkflowBuilder,\n",
|
||
" WorkflowContext,\n",
|
||
" executor,\n",
|
||
" tool,\n",
|
||
")\n",
|
||
"from agent_framework.azure import AzureAIProjectAgentProvider\n",
|
||
"from azure.identity import AzureCliCredential\n",
|
||
"from dotenv import load_dotenv\n",
|
||
"from IPython.display import HTML, display\n",
|
||
"from pydantic import BaseModel\n",
|
||
"\n",
|
||
"print(\"✅ All imports successful!\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "001c224e",
|
||
"metadata": {},
|
||
"source": [
|
||
"## گام ۱: تعریف مدلهای Pydantic برای خروجیهای ساختار یافته\n",
|
||
"\n",
|
||
"این مدلها **طرح**ی را که عاملها بازمیگردانند تعریف میکنند. استفاده از `response_format` همراه با Pydantic تضمین میکند:\n",
|
||
"- ✅ استخراج دادهها با نوع ایمن\n",
|
||
"- ✅ اعتبارسنجی خودکار\n",
|
||
"- ✅ بدون خطاهای تجزیه از پاسخهای متنی آزاد\n",
|
||
"- ✅ مسیریابی شرطی آسان بر اساس فیلدها\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "6c2ef582",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"class BookingCheckResult(BaseModel):\n",
|
||
" \"\"\"Result from checking hotel availability at a destination.\"\"\"\n",
|
||
"\n",
|
||
" destination: str\n",
|
||
" has_availability: bool\n",
|
||
" message: str\n",
|
||
"\n",
|
||
"\n",
|
||
"class AlternativeResult(BaseModel):\n",
|
||
" \"\"\"Suggested alternative destination when no rooms available.\"\"\"\n",
|
||
"\n",
|
||
" alternative_destination: str\n",
|
||
" reason: str\n",
|
||
"\n",
|
||
"\n",
|
||
"class BookingConfirmation(BaseModel):\n",
|
||
" \"\"\"Booking suggestion when rooms are available.\"\"\"\n",
|
||
"\n",
|
||
" destination: str\n",
|
||
" action: str\n",
|
||
" message: str\n",
|
||
"\n",
|
||
"\n",
|
||
"print(\"✅ Pydantic models defined:\")\n",
|
||
"print(\" - BookingCheckResult (availability check)\")\n",
|
||
"print(\" - AlternativeResult (alternative suggestion)\")\n",
|
||
"print(\" - BookingConfirmation (booking confirmation)\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "48423ecc",
|
||
"metadata": {},
|
||
"source": [
|
||
"## مرحله ۲: ایجاد ابزار رزرو هتل\n",
|
||
"\n",
|
||
"این ابزار همان چیزی است که **availability_agent** برای بررسی در دسترس بودن اتاقها فراخوانی خواهد کرد. ما از دکوراتور `@ai_function` استفاده میکنیم تا:\n",
|
||
"- یک تابع پایتون را به ابزاری قابل فراخوانی توسط هوش مصنوعی تبدیل کنیم\n",
|
||
"- بهطور خودکار طرحواره JSON برای LLM ایجاد کنیم\n",
|
||
"- اعتبارسنجی پارامترها را مدیریت کنیم\n",
|
||
"- اجازه فراخوانی خودکار توسط عوامل را فعال کنیم\n",
|
||
"\n",
|
||
"برای این دموی آزمایشی:\n",
|
||
"- **استکهلم، سیاتل، توکیو، لندن، آمستردام** → دارای اتاق ✅\n",
|
||
"- **تمام شهرهای دیگر** → بدون اتاق ❌\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "aad7e7ec",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"@tool(description=\"Check hotel room availability for a destination city\")\n",
|
||
"def hotel_booking(destination: Annotated[str, \"The destination city to check for hotel rooms\"]) -> str:\n",
|
||
" \"\"\"\n",
|
||
" Simulates checking hotel room availability.\n",
|
||
"\n",
|
||
" Returns JSON string with availability status.\n",
|
||
" \"\"\"\n",
|
||
" display(\n",
|
||
" HTML(f\"\"\"\n",
|
||
" <div style='padding: 15px; background: #e3f2fd; border-left: 4px solid #2196f3; border-radius: 4px; margin: 10px 0;'>\n",
|
||
" <strong>🔍 Tool Invoked:</strong> hotel_booking(\"{destination}\")\n",
|
||
" </div>\n",
|
||
" \"\"\")\n",
|
||
" )\n",
|
||
"\n",
|
||
" # Simulate availability check\n",
|
||
" cities_with_rooms = [\"stockholm\", \"seattle\", \"tokyo\", \"london\", \"amsterdam\"]\n",
|
||
" has_rooms = destination.lower() in cities_with_rooms\n",
|
||
"\n",
|
||
" result = {\"has_availability\": has_rooms, \"destination\": destination}\n",
|
||
"\n",
|
||
" return json.dumps(result)\n",
|
||
"\n",
|
||
"\n",
|
||
"print(\"✅ hotel_booking tool created with @tool decorator\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "134c54b0",
|
||
"metadata": {},
|
||
"source": [
|
||
"## مرحله ۳: تعریف توابع شرطی برای مسیریابی\n",
|
||
"\n",
|
||
"این توابع پاسخ عامل را بررسی کرده و تعیین میکنند که در جریان کار از کدام مسیر استفاده شود.\n",
|
||
"\n",
|
||
"**الگوی کلیدی:**\n",
|
||
"۱. بررسی کنید که پیام `AgentExecutorResponse` باشد \n",
|
||
"۲. خروجی ساختاریافته (مدل Pydantic) را تجزیه کنید \n",
|
||
"۳. بازگردانی مقدار `True` یا `False` برای کنترل مسیریابی\n",
|
||
"\n",
|
||
"جریان کار این شرایط را روی **لبهها** ارزیابی میکند تا تصمیم بگیرد کدام اجراکننده را به عنوان گام بعدی فراخوانی کند.\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "6960edd1",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def has_availability_condition(message: Any) -> bool:\n",
|
||
" \"\"\"\n",
|
||
" Condition for routing when hotels ARE available.\n",
|
||
" \n",
|
||
" Returns True if the destination has hotel rooms.\n",
|
||
" \"\"\"\n",
|
||
" if not isinstance(message, AgentExecutorResponse):\n",
|
||
" return True # Default to True if unexpected type\n",
|
||
"\n",
|
||
" try:\n",
|
||
" result = BookingCheckResult.model_validate_json(message.agent_run_response.text)\n",
|
||
"\n",
|
||
" display(\n",
|
||
" HTML(f\"\"\"\n",
|
||
" <div style='padding: 12px; background: #c8e6c9; border-left: 4px solid #4caf50; border-radius: 4px; margin: 10px 0;'>\n",
|
||
" <strong>✅ Condition Check:</strong> has_availability = <strong>{result.has_availability}</strong> for {result.destination}\n",
|
||
" </div>\n",
|
||
" \"\"\")\n",
|
||
" )\n",
|
||
"\n",
|
||
" return result.has_availability\n",
|
||
" except Exception as e:\n",
|
||
" display(\n",
|
||
" HTML(f\"\"\"\n",
|
||
" <div style='padding: 12px; background: #ffcdd2; border-left: 4px solid #f44336; border-radius: 4px; margin: 10px 0;'>\n",
|
||
" <strong>⚠️ Error:</strong> {str(e)}\n",
|
||
" </div>\n",
|
||
" \"\"\")\n",
|
||
" )\n",
|
||
" return False\n",
|
||
"\n",
|
||
"\n",
|
||
"def no_availability_condition(message: Any) -> bool:\n",
|
||
" \"\"\"\n",
|
||
" Condition for routing when hotels are NOT available.\n",
|
||
" \n",
|
||
" Returns True if the destination has no hotel rooms.\n",
|
||
" \"\"\"\n",
|
||
" if not isinstance(message, AgentExecutorResponse):\n",
|
||
" return False\n",
|
||
"\n",
|
||
" try:\n",
|
||
" result = BookingCheckResult.model_validate_json(message.agent_run_response.text)\n",
|
||
"\n",
|
||
" display(\n",
|
||
" HTML(f\"\"\"\n",
|
||
" <div style='padding: 12px; background: #ffecb3; border-left: 4px solid #ff9800; border-radius: 4px; margin: 10px 0;'>\n",
|
||
" <strong>❌ Condition Check:</strong> no_availability for {result.destination}\n",
|
||
" </div>\n",
|
||
" \"\"\")\n",
|
||
" )\n",
|
||
"\n",
|
||
" return not result.has_availability\n",
|
||
" except Exception as e:\n",
|
||
" return False\n",
|
||
"\n",
|
||
"\n",
|
||
"print(\"✅ Condition functions defined:\")\n",
|
||
"print(\" - has_availability_condition (routes when rooms exist)\")\n",
|
||
"print(\" - no_availability_condition (routes when no rooms)\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "9dc783ba",
|
||
"metadata": {},
|
||
"source": [
|
||
"## مرحله ۴: ایجاد اجراکننده نمایش سفارشی\n",
|
||
"\n",
|
||
"اجراکنندهها اجزای جریان کاری هستند که تبدیلها یا اثرات جانبی را انجام میدهند. ما از دکوراتور `@executor` برای ایجاد یک اجراکننده سفارشی که نتیجه نهایی را نمایش میدهد استفاده میکنیم.\n",
|
||
"\n",
|
||
"**مفاهیم کلیدی:**\n",
|
||
"- `@executor(id=\"...\")` - ثبت یک تابع به عنوان اجراکننده جریان کاری\n",
|
||
"- `WorkflowContext[Never, str]` - نکات نوع برای ورودی/خروجی\n",
|
||
"- `ctx.yield_output(...)` - بازگرداندن نتیجه نهایی جریان کاری\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "c67f6b55",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"@executor(id=\"display_result\")\n",
|
||
"async def display_result(response: AgentExecutorResponse, ctx: WorkflowContext[Never, str]) -> None:\n",
|
||
" \"\"\"\n",
|
||
" Display the final result as workflow output.\n",
|
||
" \n",
|
||
" This executor receives the final agent response and yields it as the workflow output.\n",
|
||
" \"\"\"\n",
|
||
" display(\n",
|
||
" HTML(\"\"\"\n",
|
||
" <div style='padding: 15px; background: #f3e5f5; border-left: 4px solid #9c27b0; border-radius: 4px; margin: 10px 0;'>\n",
|
||
" <strong>📤 Display Executor:</strong> Yielding workflow output\n",
|
||
" </div>\n",
|
||
" \"\"\")\n",
|
||
" )\n",
|
||
"\n",
|
||
" await ctx.yield_output(response.agent_run_response.text)\n",
|
||
"\n",
|
||
"\n",
|
||
"print(\"✅ display_result executor created with @executor decorator\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "7de6eb90",
|
||
"metadata": {},
|
||
"source": [
|
||
"## مرحله ۵: بارگذاری متغیرهای محیطی\n",
|
||
"\n",
|
||
"کلاینت LLM را پیکربندی کنید. این مثال با موارد زیر کار میکند:\n",
|
||
"- **مدلهای GitHub** (سطح رایگان با توکن GitHub)\n",
|
||
"- **Azure OpenAI**\n",
|
||
"- **OpenAI**\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "1e8f0d88",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Load environment variables\n",
|
||
"load_dotenv()\n",
|
||
"\n",
|
||
"# Configure the Azure AI Foundry provider with keyless authentication\n",
|
||
"provider = AzureAIProjectAgentProvider(credential=AzureCliCredential())"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "3fc61fe7",
|
||
"metadata": {},
|
||
"source": [
|
||
"## گام ۶: ایجاد عاملهای هوش مصنوعی با خروجیهای ساختاریافته\n",
|
||
"\n",
|
||
"ما **سه عامل تخصصی** ایجاد میکنیم که هر یک در یک `AgentExecutor` بستهبندی شدهاند:\n",
|
||
"\n",
|
||
"۱. **availability_agent** - بررسی موجودیت هتل با استفاده از ابزار\n",
|
||
"۲. **alternative_agent** - پیشنهاد شهرهای جایگزین (زمانی که اتاقی موجود نیست)\n",
|
||
"۳. **booking_agent** - ترغیب به رزرو (زمانی که اتاقها موجود باشند)\n",
|
||
"\n",
|
||
"**ویژگیهای کلیدی:**\n",
|
||
"- `tools=[hotel_booking]` - ابزار را در اختیار عامل قرار میدهد\n",
|
||
"- `response_format=PydanticModel` - خروجی JSON ساختاریافته را اجبار میکند\n",
|
||
"- `AgentExecutor(..., id=\"...\")` - عامل را برای استفاده در جریان کاری بستهبندی میکند\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "66466dda",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Agent 1: Check availability with tool\n",
|
||
"availability_agent = AgentExecutor(\n",
|
||
" await provider.create_agent(\n",
|
||
" name=\"availability-agent\",\n",
|
||
" instructions=(\n",
|
||
" \"You are a hotel booking assistant that checks room availability. \"\n",
|
||
" \"Use the hotel_booking tool to check if rooms are available at the destination. \"\n",
|
||
" \"Return JSON with fields: destination (string), has_availability (bool), and message (string). \"\n",
|
||
" \"The message should summarize the availability status.\"\n",
|
||
" ),\n",
|
||
" tools=[hotel_booking],\n",
|
||
" default_options={\"response_format\": BookingCheckResult},\n",
|
||
" ),\n",
|
||
" id=\"availability_agent\",\n",
|
||
")\n",
|
||
"\n",
|
||
"# Agent 2: Suggest alternative (when no rooms)\n",
|
||
"alternative_agent = AgentExecutor(\n",
|
||
" await provider.create_agent(\n",
|
||
" name=\"alternative-agent\",\n",
|
||
" instructions=(\n",
|
||
" \"You are a helpful travel assistant. When a user cannot find hotels in their requested city, \"\n",
|
||
" \"suggest an alternative nearby city that has availability. \"\n",
|
||
" \"Return JSON with fields: alternative_destination (string) and reason (string). \"\n",
|
||
" \"Make your suggestion sound appealing and helpful.\"\n",
|
||
" ),\n",
|
||
" default_options={\"response_format\": AlternativeResult},\n",
|
||
" ),\n",
|
||
" id=\"alternative_agent\",\n",
|
||
")\n",
|
||
"\n",
|
||
"# Agent 3: Suggest booking (when rooms available)\n",
|
||
"booking_agent = AgentExecutor(\n",
|
||
" await provider.create_agent(\n",
|
||
" name=\"booking-agent\",\n",
|
||
" instructions=(\n",
|
||
" \"You are a booking assistant. The user has found available hotel rooms. \"\n",
|
||
" \"Encourage them to book by highlighting the destination's appeal. \"\n",
|
||
" \"Return JSON with fields: destination (string), action (string), and message (string). \"\n",
|
||
" \"The action should be 'book_now' and message should be encouraging.\"\n",
|
||
" ),\n",
|
||
" default_options={\"response_format\": BookingConfirmation},\n",
|
||
" ),\n",
|
||
" id=\"booking_agent\",\n",
|
||
")\n",
|
||
"\n",
|
||
"display(\n",
|
||
" HTML(\"\"\"\n",
|
||
" <div style='padding: 15px; background: #e3f2fd; border-left: 4px solid #2196f3; border-radius: 4px; margin: 10px 0;'>\n",
|
||
" <strong>✅ Created 3 Agents:</strong>\n",
|
||
" <ul style='margin: 10px 0 0 0;'>\n",
|
||
" <li><strong>availability_agent</strong> - Checks availability with hotel_booking tool</li>\n",
|
||
" <li><strong>alternative_agent</strong> - Suggests alternative cities</li>\n",
|
||
" <li><strong>booking_agent</strong> - Encourages booking</li>\n",
|
||
" </ul>\n",
|
||
" </div>\n",
|
||
"\"\"\")\n",
|
||
")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "7879a0cb",
|
||
"metadata": {},
|
||
"source": [
|
||
"## گام ۷: ساخت جریان کاری با لبههای شرطی\n",
|
||
"\n",
|
||
"اکنون از `WorkflowBuilder` برای ساخت گراف با مسیر دهی شرطی استفاده میکنیم:\n",
|
||
"\n",
|
||
"**ساختار جریان کاری:**\n",
|
||
"```\n",
|
||
"availability_agent (START)\n",
|
||
" ↓\n",
|
||
" Evaluate conditions\n",
|
||
" ↙ ↘\n",
|
||
"[no_availability] [has_availability]\n",
|
||
" ↓ ↓\n",
|
||
"alternative_agent booking_agent\n",
|
||
" ↓ ↓\n",
|
||
" display_result ←───┘\n",
|
||
"```\n",
|
||
"\n",
|
||
"**متدهای کلیدی:**\n",
|
||
"- `.set_start_executor(...)` - تعیین نقطه ورود\n",
|
||
"- `.add_edge(from, to, condition=...)` - افزودن لبه شرطی\n",
|
||
"- `.build()` - نهایی کردن جریان کاری\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "90bb29dd",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Build the workflow with conditional routing\n",
|
||
"workflow = (\n",
|
||
" WorkflowBuilder(\n",
|
||
" start_executor=availability_agent,\n",
|
||
" output_executors=[display_result],\n",
|
||
" )\n",
|
||
" # NO AVAILABILITY PATH\n",
|
||
" .add_edge(availability_agent, alternative_agent, condition=no_availability_condition)\n",
|
||
" .add_edge(alternative_agent, display_result)\n",
|
||
" # HAS AVAILABILITY PATH\n",
|
||
" .add_edge(availability_agent, booking_agent, condition=has_availability_condition)\n",
|
||
" .add_edge(booking_agent, display_result)\n",
|
||
" .build()\n",
|
||
")\n",
|
||
"\n",
|
||
"display(\n",
|
||
" HTML(\"\"\"\n",
|
||
" <div style='padding: 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border-radius: 8px; margin: 10px 0;'>\n",
|
||
" <h3 style='margin: 0 0 15px 0;'>✅ Workflow Built Successfully!</h3>\n",
|
||
" <p style='margin: 0; line-height: 1.6;'>\n",
|
||
" <strong>Conditional Routing:</strong><br>\n",
|
||
" • If <strong>NO availability</strong> → alternative_agent → display_result<br>\n",
|
||
" • If <strong>availability</strong> → booking_agent → display_result\n",
|
||
" </p>\n",
|
||
" </div>\n",
|
||
"\"\"\")\n",
|
||
")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "0a3ad845",
|
||
"metadata": {},
|
||
"source": [
|
||
"## گام ۸: اجرای مورد آزمایشی ۱ - شهر بدون دسترسی (پاریس)\n",
|
||
"\n",
|
||
"بیایید مسیر **بدون دسترسی** را با درخواست هتلها در پاریس (که در شبیهسازی ما اتاقی ندارد) آزمایش کنیم.\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "af1538cd",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"display(\n",
|
||
" HTML(\"\"\"\n",
|
||
" <div style='padding: 20px; background: #fff3e0; border-left: 4px solid #ff9800; border-radius: 8px; margin: 20px 0;'>\n",
|
||
" <h3 style='margin: 0 0 10px 0; color: #e65100;'>🧪 TEST CASE 1: Paris (No Availability)</h3>\n",
|
||
" <p style='margin: 0;'>Expected workflow path: availability_agent → alternative_agent → display_result</p>\n",
|
||
" </div>\n",
|
||
"\"\"\")\n",
|
||
")\n",
|
||
"\n",
|
||
"# Create request for Paris\n",
|
||
"request_paris = AgentExecutorRequest(\n",
|
||
" messages=[Message(role=\"user\", text=\"I want to book a hotel in Paris\")], should_respond=True\n",
|
||
")\n",
|
||
"\n",
|
||
"# Run the workflow\n",
|
||
"events_paris = await workflow.run(request_paris)\n",
|
||
"outputs_paris = events_paris.get_outputs()\n",
|
||
"\n",
|
||
"# Display results\n",
|
||
"if outputs_paris:\n",
|
||
" result_paris = AlternativeResult.model_validate_json(outputs_paris[0])\n",
|
||
"\n",
|
||
" display(\n",
|
||
" HTML(f\"\"\"\n",
|
||
" <div style='padding: 25px; background: linear-gradient(135deg, #FFD700 0%, #FFA500 100%); border-radius: 12px; box-shadow: 0 4px 12px rgba(255,165,0,0.3); margin: 20px 0;'>\n",
|
||
" <h3 style='margin: 0 0 15px 0; color: #333;'>🏆 WORKFLOW RESULT (Paris)</h3>\n",
|
||
" <div style='background: white; padding: 20px; border-radius: 8px;'>\n",
|
||
" <p style='margin: 0 0 10px 0; font-size: 16px;'><strong>Status:</strong> ❌ No rooms in Paris</p>\n",
|
||
" <p style='margin: 0 0 10px 0; font-size: 16px;'><strong>Alternative Suggestion:</strong> 🏨 {result_paris.alternative_destination}</p>\n",
|
||
" <p style='margin: 0; font-size: 14px; color: #666;'><strong>Reason:</strong> {result_paris.reason}</p>\n",
|
||
" </div>\n",
|
||
" </div>\n",
|
||
" \"\"\")\n",
|
||
" )"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "408a3f60",
|
||
"metadata": {},
|
||
"source": [
|
||
"## مرحله ۹: اجرای مورد آزمون ۲ - شهر با موجودی (استکهلم)\n",
|
||
"\n",
|
||
"حال بیایید مسیر **موجودی** را با درخواست هتلها در استکهلم (که در شبیهسازی ما اتاق دارد) آزمایش کنیم.\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "e1471000",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"display(\n",
|
||
" HTML(\"\"\"\n",
|
||
" <div style='padding: 20px; background: #e8f5e9; border-left: 4px solid #4caf50; border-radius: 8px; margin: 20px 0;'>\n",
|
||
" <h3 style='margin: 0 0 10px 0; color: #1b5e20;'>🧪 TEST CASE 2: Stockholm (Has Availability)</h3>\n",
|
||
" <p style='margin: 0;'>Expected workflow path: availability_agent → booking_agent → display_result</p>\n",
|
||
" </div>\n",
|
||
"\"\"\")\n",
|
||
")\n",
|
||
"\n",
|
||
"# Create request for Stockholm\n",
|
||
"request_stockholm = AgentExecutorRequest(\n",
|
||
" messages=[Message(role=\"user\", text=\"I want to book a hotel in Stockholm\")], should_respond=True\n",
|
||
")\n",
|
||
"\n",
|
||
"# Run the workflow\n",
|
||
"events_stockholm = await workflow.run(request_stockholm)\n",
|
||
"outputs_stockholm = events_stockholm.get_outputs()\n",
|
||
"\n",
|
||
"# Display results\n",
|
||
"if outputs_stockholm:\n",
|
||
" result_stockholm = BookingConfirmation.model_validate_json(outputs_stockholm[0])\n",
|
||
"\n",
|
||
" display(\n",
|
||
" HTML(f\"\"\"\n",
|
||
" <div style='padding: 25px; background: linear-gradient(135deg, #4caf50 0%, #8bc34a 100%); color: white; border-radius: 12px; box-shadow: 0 4px 12px rgba(76,175,80,0.3); margin: 20px 0;'>\n",
|
||
" <h3 style='margin: 0 0 15px 0;'>🏆 WORKFLOW RESULT (Stockholm)</h3>\n",
|
||
" <div style='background: white; color: #333; padding: 20px; border-radius: 8px;'>\n",
|
||
" <p style='margin: 0 0 10px 0; font-size: 16px;'><strong>Status:</strong> ✅ Rooms Available!</p>\n",
|
||
" <p style='margin: 0 0 10px 0; font-size: 16px;'><strong>Destination:</strong> 🏨 {result_stockholm.destination}</p>\n",
|
||
" <p style='margin: 0 0 10px 0; font-size: 16px;'><strong>Action:</strong> {result_stockholm.action}</p>\n",
|
||
" <p style='margin: 0; font-size: 14px; color: #666;'><strong>Message:</strong> {result_stockholm.message}</p>\n",
|
||
" </div>\n",
|
||
" </div>\n",
|
||
" \"\"\")\n",
|
||
" )"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "a415537c",
|
||
"metadata": {},
|
||
"source": [
|
||
"## نکات کلیدی و گامهای بعدی\n",
|
||
"\n",
|
||
"### ✅ آنچه یاد گرفتهاید:\n",
|
||
"\n",
|
||
"1. **الگوی WorkflowBuilder**\n",
|
||
" - استفاده از `.set_start_executor()` برای تعریف نقطه ورود\n",
|
||
" - استفاده از `.add_edge(from, to, condition=...)` برای مسیر دهی شرطی\n",
|
||
" - فراخوانی `.build()` برای نهایی کردن جریان کار\n",
|
||
"\n",
|
||
"2. **مسیر دهی شرطی**\n",
|
||
" - توابع شرط، `AgentExecutorResponse` را بررسی میکنند\n",
|
||
" - خروجیهای ساختاریافته را برای اتخاذ تصمیمهای مسیریابی تجزیه میکنند\n",
|
||
" - بازگشت `True` برای فعالسازی یک لبه، `False` برای رد کردن آن\n",
|
||
"\n",
|
||
"3. **ادغام ابزارها**\n",
|
||
" - استفاده از `@ai_function` برای تبدیل توابع پایتون به ابزارهای هوش مصنوعی\n",
|
||
" - عاملها هنگام نیاز به صورت خودکار ابزارها را فرا میخوانند\n",
|
||
" - ابزارها JSON باز میگردانند که عاملها میتوانند تجزیه کنند\n",
|
||
"\n",
|
||
"4. **خروجیهای ساختاریافته**\n",
|
||
" - استفاده از مدلهای Pydantic برای استخراج دادههای ایمن از نظر نوع\n",
|
||
" - تنظیم `response_format=MyModel` هنگام ایجاد عاملها\n",
|
||
" - تجزیه پاسخها با `Model.model_validate_json()`\n",
|
||
"\n",
|
||
"5. **اجراکنندههای سفارشی**\n",
|
||
" - استفاده از `@executor(id=\"...\")` برای ایجاد اجزای جریان کار\n",
|
||
" - اجراکنندهها میتوانند دادهها را تغییر دهند یا عملیات جانبی انجام دهند\n",
|
||
" - استفاده از `ctx.yield_output()` برای تولید نتایج جریان کار\n",
|
||
"\n",
|
||
"### 🚀 کاربردهای واقعی:\n",
|
||
"\n",
|
||
"- **رزرو سفر**: بررسی در دسترس بودن، پیشنهاد گزینههای جایگزین، مقایسه گزینهها\n",
|
||
"- **خدمات مشتری**: مسیر دهی بر اساس نوع مشکل، احساسات، اولویت\n",
|
||
"- **تجارت الکترونیک**: بررسی موجودی، پیشنهاد جایگزینها، پردازش سفارشات\n",
|
||
"- **نظارت بر محتوا**: مسیر دهی بر اساس نمرات سمی بودن، گزارشهای کاربران\n",
|
||
"- **جریانهای تصویب**: مسیر دهی بر اساس مبلغ، نقش کاربر، سطح ریسک\n",
|
||
"- **پردازش چندمرحلهای**: مسیر دهی بر اساس کیفیت داده، کامل بودن\n",
|
||
"\n",
|
||
"### 📚 گامهای بعدی:\n",
|
||
"\n",
|
||
"- افزودن شرایط پیچیدهتر (معیارهای چندگانه)\n",
|
||
"- پیادهسازی حلقهها با مدیریت حالت جریان کار\n",
|
||
"- افزودن زیر جریانهای کاری برای اجزای قابل استفاده مجدد\n",
|
||
"- ادغام با APIهای واقعی (رزرو هتل، سیستمهای موجودی)\n",
|
||
"- افزودن مدیریت خطا و مسیرهای جایگزین\n",
|
||
"- بصریسازی جریانهای کاری با ابزارهای بصریسازی داخلی\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"---\n\n<!-- CO-OP TRANSLATOR DISCLAIMER START -->\n**سلب مسئولیت**:\nاین سند با استفاده از سرویس ترجمه هوش مصنوعی [Co-op Translator](https://github.com/Azure/co-op-translator) ترجمه شده است. در حالی که ما در تلاش برای دقت هستیم، لطفاً توجه داشته باشید که ترجمههای خودکار ممکن است شامل خطاها یا نادرستیهایی باشند. سند اصلی به زبان مادری خود باید به عنوان منبع معتبر در نظر گرفته شود. برای اطلاعات حیاتی، ترجمه حرفهای انسانی توصیه میشود. ما در قبال هرگونه سوء تفاهم یا برداشت نادرست ناشی از استفاده از این ترجمه مسئولیتی نداریم.\n<!-- CO-OP TRANSLATOR DISCLAIMER END -->\n"
|
||
]
|
||
}
|
||
],
|
||
"metadata": {
|
||
"kernelspec": {
|
||
"display_name": ".venv (3.12.12)",
|
||
"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.12"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 5
|
||
} |