项目文件夹

文件
2026-07-13 12:59:43 +08:00

561 行
25 KiB
Plaintext

{
"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",
"<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;'>Concurrent Workflow Built Successfully!</h3>\n",
" <p style='margin: 0; line-height: 1.6;'>\n",
" <strong>Architecture:</strong><br>\n",
" • Input → <strong>Dispatcher</strong> (fan-out)<br>\n",
" • <strong>3 Agents</strong> run in parallel (attractions, dining, history)<br>\n",
" • Output → 3 AgentResponse objects, one per agent\n",
" </p>\n",
"</div>\n",
"\"\"\"))"
]
},
{
"cell_type": "markdown",
"id": "e920f2f6",
"metadata": {},
"source": [
"## گام ۵: مورد آزمایشی ۱ - توصیه‌های سفر به توکیو\n",
"\n",
"بیایید جریان کاری همزمان خود را با توکیو به عنوان مقصد آزمایش کنیم. هر سه نماینده به طور همزمان کار خواهند کرد تا توصیه‌های جامع سفر را ارائه دهند.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "090ae929",
"metadata": {},
"outputs": [],
"source": [
"async def display_travel_recommendations(destination: str):\n",
" \"\"\"Run the concurrent workflow and display formatted results.\"\"\"\n",
"\n",
" display(HTML(f\"\"\"\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;'>Processing Travel Recommendations for {destination}</h3>\n",
" <p style='margin: 0;'><strong>Status:</strong> Running 3 agents concurrently...</p>\n",
" </div>\n",
" \"\"\"))\n",
"\n",
" # Run the workflow. With WorkflowBuilder(output_executors=[a1, a2, a3]),\n",
" # outputs is a list of AgentResponse objects in the same order as output_executors.\n",
" events = await workflow.run(f\"I want comprehensive travel recommendations for {destination}\")\n",
" outputs = events.get_outputs()\n",
"\n",
" # Display results header\n",
" display(HTML(f\"\"\"\n",
" <div style='padding: 25px; background: linear-gradient(135deg, #4caf50 0%, #8bc34a 100%); color: white; border-radius: 12px;\n",
" box-shadow: 0 4px 12px rgba(76,175,80,0.3); margin: 20px 0;'>\n",
" <h2 style='margin: 0 0 20px 0;'>Complete Travel Guide for {destination}</h2>\n",
" <p style='margin: 0; font-size: 14px; opacity: 0.9;'>Generated by 3 concurrent agents</p>\n",
" </div>\n",
" \"\"\"))\n",
"\n",
" sections = [\n",
" (\"attractions-agent\", AttractionsRecommendation, display_attractions_section),\n",
" (\"dining-agent\", DiningRecommendation, display_dining_section),\n",
" (\"history-agent\", HistoryRecommendation, display_history_section),\n",
" ]\n",
"\n",
" for i, (agent_name, schema, render) in enumerate(sections):\n",
" if i >= len(outputs):\n",
" continue\n",
" text = outputs[i].text\n",
" try:\n",
" data = schema.model_validate_json(text)\n",
" render(data)\n",
" except Exception as e:\n",
" display(HTML(f\"\"\"\n",
" <div style='padding: 15px; background: #ffcdd2; border-left: 4px solid #f44336; border-radius: 4px; margin: 10px 0;'>\n",
" <strong>Error parsing {agent_name} response:</strong> {str(e)}\n",
" <details><summary>Raw response</summary>{text}</details>\n",
" </div>\n",
" \"\"\"))\n",
"\n",
"\n",
"def display_attractions_section(data: AttractionsRecommendation):\n",
" \"\"\"Display attractions recommendations in a formatted section.\"\"\"\n",
" attractions_list = \"\".join([f\"<li>{attraction}</li>\" for attraction in data.top_attractions])\n",
" activities_list = \"\".join([f\"<li>{activity}</li>\" for activity in data.activities])\n",
"\n",
" display(HTML(f\"\"\"\n",
" <div style='padding: 20px; background: #e3f2fd; border-radius: 8px; margin: 15px 0; border-left: 4px solid #2196f3;'>\n",
" <h3 style='margin: 0 0 15px 0; color: #1976d2;'>🏛️ Tourist Attractions & Activities</h3>\n",
" <div style='margin-bottom: 15px;'>\n",
" <h4 style='margin: 0 0 8px 0; color: #333;'>Top Attractions:</h4>\n",
" <ul style='margin: 0; padding-left: 20px; color: #555;'>{attractions_list}</ul>\n",
" </div>\n",
" <div style='margin-bottom: 15px;'>\n",
" <h4 style='margin: 0 0 8px 0; color: #333;'>Recommended Activities:</h4>\n",
" <ul style='margin: 0; padding-left: 20px; color: #555;'>{activities_list}</ul>\n",
" </div>\n",
" <div style='margin-bottom: 10px;'>\n",
" <strong style='color: #333;'>Best Time to Visit:</strong> {data.best_time_to_visit}\n",
" </div>\n",
" <div>\n",
" <strong style='color: #333;'>Transportation Tips:</strong> {data.transportation_tips}\n",
" </div>\n",
" </div>\n",
" \"\"\"))\n",
"\n",
"\n",
"def display_dining_section(data: DiningRecommendation):\n",
" \"\"\"Display dining recommendations in a formatted section.\"\"\"\n",
" dishes_list = \"\".join(\n",
" [f\"<li>{dish}</li>\" for dish in data.must_try_dishes])\n",
" restaurants_list = \"\".join(\n",
" [f\"<li>{restaurant}</li>\" for restaurant in data.recommended_restaurants])\n",
" experiences_list = \"\".join(\n",
" [f\"<li>{exp}</li>\" for exp in data.food_experiences])\n",
"\n",
" display(HTML(f\"\"\"\n",
" <div style='padding: 20px; background: #fff3e0; border-radius: 8px; margin: 15px 0; border-left: 4px solid #ff9800;'>\n",
" <h3 style='margin: 0 0 15px 0; color: #f57c00;'>🍜 Food & Dining Experiences</h3>\n",
" <div style='margin-bottom: 15px;'>\n",
" <strong style='color: #333;'>Local Cuisine:</strong> {data.local_cuisine}\n",
" </div>\n",
" <div style='margin-bottom: 15px;'>\n",
" <h4 style='margin: 0 0 8px 0; color: #333;'>Must-Try Dishes:</h4>\n",
" <ul style='margin: 0; padding-left: 20px; color: #555;'>{dishes_list}</ul>\n",
" </div>\n",
" <div style='margin-bottom: 15px;'>\n",
" <h4 style='margin: 0 0 8px 0; color: #333;'>Recommended Restaurants:</h4>\n",
" <ul style='margin: 0; padding-left: 20px; color: #555;'>{restaurants_list}</ul>\n",
" </div>\n",
" <div style='margin-bottom: 15px;'>\n",
" <h4 style='margin: 0 0 8px 0; color: #333;'>Food Experiences:</h4>\n",
" <ul style='margin: 0; padding-left: 20px; color: #555;'>{experiences_list}</ul>\n",
" </div>\n",
" <div>\n",
" <strong style='color: #333;'>Dining Etiquette:</strong> {data.dining_etiquette}\n",
" </div>\n",
" </div>\n",
" \"\"\"))\n",
"\n",
"\n",
"def display_history_section(data: HistoryRecommendation):\n",
" \"\"\"Display history recommendations in a formatted section.\"\"\"\n",
" highlights_list = \"\".join(\n",
" [f\"<li>{highlight}</li>\" for highlight in data.cultural_highlights])\n",
" periods_list = \"\".join(\n",
" [f\"<li>{period}</li>\" for period in data.important_periods])\n",
" experiences_list = \"\".join(\n",
" [f\"<li>{exp}</li>\" for exp in data.cultural_experiences])\n",
" facts_list = \"\".join(\n",
" [f\"<li>{fact}</li>\" for fact in data.interesting_facts])\n",
"\n",
" display(HTML(f\"\"\"\n",
" <div style='padding: 20px; background: #f3e5f5; border-radius: 8px; margin: 15px 0; border-left: 4px solid #9c27b0;'>\n",
" <h3 style='margin: 0 0 15px 0; color: #7b1fa2;'>📚 History & Culture</h3>\n",
" <div style='margin-bottom: 15px;'>\n",
" <strong style='color: #333;'>Historical Significance:</strong> {data.historical_significance}\n",
" </div>\n",
" <div style='margin-bottom: 15px;'>\n",
" <h4 style='margin: 0 0 8px 0; color: #333;'>Cultural Highlights:</h4>\n",
" <ul style='margin: 0; padding-left: 20px; color: #555;'>{highlights_list}</ul>\n",
" </div>\n",
" <div style='margin-bottom: 15px;'>\n",
" <h4 style='margin: 0 0 8px 0; color: #333;'>Important Historical Periods:</h4>\n",
" <ul style='margin: 0; padding-left: 20px; color: #555;'>{periods_list}</ul>\n",
" </div>\n",
" <div style='margin-bottom: 15px;'>\n",
" <h4 style='margin: 0 0 8px 0; color: #333;'>Cultural Experiences:</h4>\n",
" <ul style='margin: 0; padding-left: 20px; color: #555;'>{experiences_list}</ul>\n",
" </div>\n",
" <div>\n",
" <h4 style='margin: 0 0 8px 0; color: #333;'>Interesting Facts:</h4>\n",
" <ul style='margin: 0; padding-left: 20px; color: #555;'>{facts_list}</ul>\n",
" </div>\n",
" </div>\n",
" \"\"\"))\n",
"\n",
"\n",
"# Test with Tokyo\n",
"await display_travel_recommendations(\"Tokyo\")"
]
},
{
"cell_type": "markdown",
"id": "454fa849",
"metadata": {},
"source": [
"# مرحله ۶: مورد آزمایشی ۲ - توصیه‌های سفر به پاریس\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8a23dbc4",
"metadata": {},
"outputs": [],
"source": [
"await display_travel_recommendations(\"Paris\")"
]
},
{
"cell_type": "markdown",
"id": "7b173674",
"metadata": {},
"source": [
"## مرحله ۷: تحلیل عملکرد - همزمان در مقابل توالی\n",
"\n",
"بیایید تفاوت عملکرد بین اجرای همزمان و توالی را اندازه‌گیری کنیم تا مزایای ارکستراسیون همزمان را نشان دهیم.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e0badd2e",
"metadata": {},
"outputs": [],
"source": [
"import time\n",
"\n",
"\n",
"async def measure_concurrent_performance(destination: str):\n",
" \"\"\"Measure concurrent execution time.\"\"\"\n",
" start_time = time.time()\n",
"\n",
" events = await workflow.run(f\"I want travel recommendations for {destination}\")\n",
" outputs = events.get_outputs()\n",
"\n",
" end_time = time.time()\n",
" return end_time - start_time, len(outputs)\n",
"\n",
"\n",
"async def measure_sequential_performance(destination: str):\n",
" \"\"\"Measure sequential execution time.\"\"\"\n",
" # Build a sequential workflow that chains the same agents one after another.\n",
" sequential_workflow = (\n",
" WorkflowBuilder(\n",
" start_executor=attractions_agent,\n",
" output_executors=[attractions_agent, dining_agent, history_agent],\n",
" )\n",
" .add_chain([attractions_agent, dining_agent, history_agent])\n",
" .build()\n",
" )\n",
" start_time = time.time()\n",
"\n",
" events = await sequential_workflow.run(f\"I want travel recommendations for {destination}\")\n",
" outputs = events.get_outputs()\n",
"\n",
" end_time = time.time()\n",
" return end_time - start_time, len(outputs)\n",
"\n",
"\n",
"async def performance_comparison():\n",
" \"\"\"Compare concurrent vs sequential performance.\"\"\"\n",
" test_destination = \"Barcelona\"\n",
"\n",
" display(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;'>Performance Comparison Test</h3>\n",
" <p style='margin: 0;'>Testing with destination: <strong>Barcelona</strong></p>\n",
" </div>\n",
" \"\"\"))\n",
"\n",
" # Test concurrent execution\n",
" print(\"Running concurrent workflow...\")\n",
" concurrent_time, concurrent_count = await measure_concurrent_performance(test_destination)\n",
"\n",
" # Test sequential execution\n",
" print(\"Running sequential workflow...\")\n",
" sequential_time, sequential_count = await measure_sequential_performance(test_destination)\n",
"\n",
" # Calculate performance improvement\n",
" improvement = ((sequential_time - concurrent_time) / sequential_time) * 100\n",
"\n",
" display(HTML(f\"\"\"\n",
" <div style='padding: 25px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border-radius: 12px;\n",
" box-shadow: 0 4px 12px rgba(102,126,234,0.4); margin: 20px 0;'>\n",
" <h2 style='margin: 0 0 20px 0;'>Performance Results</h2>\n",
" <div style='display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 20px;'>\n",
" <div style='background: rgba(255,255,255,0.1); padding: 15px; border-radius: 8px;'>\n",
" <h4 style='margin: 0 0 10px 0;'>⚡ Concurrent Execution</h4>\n",
" <p style='margin: 0; font-size: 24px; font-weight: bold;'>{concurrent_time:.2f}s</p>\n",
" <p style='margin: 5px 0 0 0; font-size: 14px; opacity: 0.9;'>{concurrent_count} agent responses</p>\n",
" </div>\n",
" <div style='background: rgba(255,255,255,0.1); padding: 15px; border-radius: 8px;'>\n",
" <h4 style='margin: 0 0 10px 0;'>🔄 Sequential Execution</h4>\n",
" <p style='margin: 0; font-size: 24px; font-weight: bold;'>{sequential_time:.2f}s</p>\n",
" <p style='margin: 5px 0 0 0; font-size: 14px; opacity: 0.9;'>{sequential_count} agent responses</p>\n",
" </div>\n",
" </div>\n",
" <div style='background: rgba(255,255,255,0.15); padding: 15px; border-radius: 8px;'>\n",
" <h4 style='margin: 0 0 10px 0;'>Performance Improvement</h4>\n",
" <p style='margin: 0; font-size: 20px; font-weight: bold;'>{improvement:.1f}% faster</p>\n",
" <p style='margin: 5px 0 0 0; font-size: 14px; opacity: 0.9;'>\n",
" Saved {sequential_time - concurrent_time:.2f} seconds with concurrent execution\n",
" </p>\n",
" </div>\n",
" </div>\n",
" \"\"\"))\n",
"\n",
"\n",
"# Run performance comparison\n",
"await performance_comparison()"
]
},
{
"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
}