{ "cells": [ { "cell_type": "markdown", "id": "69f48405", "metadata": {}, "source": [ "# توصیههای سفر با هماهنگی همزمان\n", "\n", "این دفترچه یادداشت **هماهنگی همزمان** را با استفاده از چارچوب عامل مایکروسافت نشان میدهد. ما یک سیستم پیشنهاد سفر میسازیم که دارای سه عامل تخصصی است که به موازات هم کار میکنند تا بینشهای جامع سفر را فراهم کنند.\n", "\n", "## آنچه میآموزید:\n", "1. **هماهنگی همزمان**: اجرای چندین عامل به موازات هم (الگوی fan-out/fan-in)\n", "2. **ConcurrentBuilder**: رابط برنامهنویسی سطح بالا برای ساخت جریانهای کاری همزمان\n", "3. **توصیههای سفر**: سه عامل تخصصی که با هم کار میکنند\n", "4. **ادغام پیشفرض**: ترکیب چندین پاسخ عامل\n", "5. **مزایای عملکرد**: اجرای موازی در مقابل پردازش متوالی\n", "\n", "## سه عامل تخصصی:\n", "\n", "1. **عامل جاذبهها**: جاذبههای گردشگری، فعالیتها، مکانهای دیدنی\n", "2. **عامل غذاخوری**: غذاهای محلی، رستورانها، تجربههای غذایی\n", "3. **عامل تاریخ**: حقایق تاریخی، اهمیت فرهنگی، زمینهها\n" ] }, { "cell_type": "code", "execution_count": null, "id": "1c8918b5", "metadata": {}, "outputs": [], "source": [ "import asyncio\n", "import json\n", "import os\n", "from typing import Any, cast\n", "\n", "from agent_framework import (\n", " Executor,\n", " Message,\n", " WorkflowBuilder,\n", " WorkflowContext,\n", " handler,\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": "2733c34d", "metadata": {}, "source": [ "## مرحله ۱: تعریف مدلهای Pydantic برای خروجیهای ساختاریافته\n", "\n", "این مدلها طرح ساختاری را تعریف میکنند که هر عامل تخصصی باز میگرداند. این کار تضمین میکند که پاسخها از همه عوامل به صورت یکنواخت و قابل تجزیه باشند.\n" ] }, { "cell_type": "markdown", "id": "0d144c4c", "metadata": {}, "source": [ "## گام ۱: تعریف مدلهای Pydantic برای خروجیهای ساختار یافته\n", "\n", "این مدلها ساختاری را تعریف میکنند که هر عامل تخصصی آن را بازمیگرداند. این اطمینان حاصل میکند که پاسخها از همه عوامل سازگار و قابل تحلیل باشند.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "e0749818", "metadata": {}, "outputs": [], "source": [ "class AttractionsRecommendation(BaseModel):\n", " \"\"\"Tourist attractions and activities recommendations.\"\"\"\n", "\n", " destination: str\n", " top_attractions: list[str]\n", " activities: list[str]\n", " best_time_to_visit: str\n", " transportation_tips: str \n", "\n", "\n", "class DiningRecommendation(BaseModel):\n", " \"\"\"Food and dining recommendations.\"\"\"\n", "\n", " destination: str\n", " local_cuisine: str\n", " must_try_dishes: list[str]\n", " recommended_restaurants: list[str]\n", " food_experiences: list[str]\n", " dining_etiquette: str\n", "\n", "\n", "class HistoryRecommendation(BaseModel):\n", " \"\"\"Historical and cultural information.\"\"\"\n", "\n", " destination: str\n", " historical_significance: str\n", " cultural_highlights: list[str]\n", " important_periods: list[str]\n", " cultural_experiences: list[str]\n", " interesting_facts: list[str]" ] }, { "cell_type": "markdown", "id": "979521fb", "metadata": {}, "source": [ "## مرحله ۲: بارگذاری متغیرهای محیطی و پیکربندی ارائهدهنده Foundry\n", "\n", "از `AzureAIProjectAgentProvider` با احراز هویت بدون کلید `AzureCliCredential` استفاده کنید، مطابق الگویی که در درسهای ۰۱ تا ۱۳ به کار رفته است.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "c5179ca3", "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())\n", "\n", "print(\"Azure AI Foundry provider configured successfully!\")" ] }, { "cell_type": "markdown", "id": "8e4eb398", "metadata": {}, "source": [ "## مرحله ۳: ایجاد سه نماینده سفر تخصصی \n" ] }, { "cell_type": "code", "execution_count": null, "id": "6a9571c6", "metadata": {}, "outputs": [], "source": [ "# Agent 1: Tourist Attractions Expert\n", "attractions_agent = await provider.create_agent(\n", " name=\"attractions-agent\",\n", " instructions=(\n", " \"You are a tourism expert specializing in attractions and activities. \"\n", " \"When given a travel destination, provide comprehensive recommendations for \"\n", " \"tourist attractions, activities, best times to visit, and transportation tips. \"\n", " \"Focus on popular landmarks, unique experiences, and practical travel advice. \"\n", " \"Return structured JSON matching the AttractionsRecommendation schema.\"\n", " ),\n", ")\n", "\n", "# Agent 2: Food and Dining Expert\n", "dining_agent = await provider.create_agent(\n", " name=\"dining-agent\",\n", " instructions=(\n", " \"You are a culinary expert specializing in local food and dining experiences. \"\n", " \"When given a travel destination, provide recommendations for local cuisine, \"\n", " \"must-try dishes, recommended restaurants, and unique food experiences. \"\n", " \"Include dining etiquette and cultural food customs. \"\n", " \"Return structured JSON matching the DiningRecommendation schema.\"\n", " ),\n", ")\n", "\n", "\n", "# Agent 3: History and Culture Expert\n", "history_agent = await provider.create_agent(\n", " name=\"history-agent\",\n", " instructions=(\n", " \"You are a historian and cultural expert. \"\n", " \"When given a travel destination, provide historical context, cultural significance, \"\n", " \"important historical periods, cultural experiences, and interesting facts. \"\n", " \"Focus on helping travelers understand the cultural heritage and historical importance. \"\n", " \"Return structured JSON matching the HistoryRecommendation schema.\"\n", " ),\n", ")" ] }, { "cell_type": "markdown", "id": "2b22d245", "metadata": {}, "source": [ "# مرحله ۴: ساخت گردش کار همزمان\n", "\n", "`WorkflowBuilder` با یک مجری دیسپچر کوچک و `add_fan_out_edges`:\n", "1. **دیسپچر** همان ورودی را به هر سه عامل ارسال میکند\n", "2. **سه عامل** به صورت همزمان اجرا میشوند\n", "3. **خروجی** پاسخ هر عامل را به طور جداگانه جمعآوری میکند\n" ] }, { "cell_type": "code", "execution_count": null, "id": "4bad34b0", "metadata": {}, "outputs": [], "source": [ "# A passthrough executor that broadcasts the user input to every agent in parallel.\n", "class InputDispatcher(Executor):\n", " \"\"\"Forward the user input unchanged to all participating agents.\"\"\"\n", "\n", " @handler\n", " async def forward(self, text: str, ctx: WorkflowContext[str]) -> None:\n", " await ctx.send_message(text)\n", "\n", "\n", "dispatcher = InputDispatcher(id=\"dispatcher\")\n", "agents = [attractions_agent, dining_agent, history_agent]\n", "\n", "workflow = (\n", " WorkflowBuilder(\n", " start_executor=dispatcher,\n", " output_executors=agents,\n", " )\n", " .add_fan_out_edges(dispatcher, agents)\n", " .build()\n", ")\n", "\n", "display(HTML(\"\"\"\n", "
\n",
" Architecture:
\n",
" • Input → Dispatcher (fan-out)
\n",
" • 3 Agents run in parallel (attractions, dining, history)
\n",
" • Output → 3 AgentResponse objects, one per agent\n",
"
Status: Running 3 agents concurrently...
\n", "Generated by 3 concurrent agents
\n", "Testing with destination: Barcelona
\n", "{concurrent_time:.2f}s
\n", "{concurrent_count} agent responses
\n", "{sequential_time:.2f}s
\n", "{sequential_count} agent responses
\n", "{improvement:.1f}% faster
\n", "\n", " Saved {sequential_time - concurrent_time:.2f} seconds with concurrent execution\n", "
\n", "