ai-agents-for-beginners

چگونه عوامل هوش مصنوعی خوب طراحی کنیم

(برای مشاهده ویدئوی این درس روی تصویر بالا کلیک کنید)

الگوی طراحی استفاده از ابزار

ابزارها جالب هستند زیرا به عوامل هوش مصنوعی این امکان را می‌دهند که قابلیت‌های گسترده‌تری داشته باشند. به جای اینکه عامل فقط مجموعه محدودی از اقدامات را انجام دهد، با افزودن یک ابزار، عامل می‌تواند طیف وسیعی از اقدامات را انجام دهد. در این فصل، به الگوی طراحی استفاده از ابزار می‌پردازیم که توضیح می‌دهد چگونه عوامل هوش مصنوعی می‌توانند از ابزارهای خاص برای دستیابی به اهداف خود استفاده کنند.

مقدمه

در این درس، به دنبال پاسخ به سوالات زیر هستیم:

اهداف یادگیری

پس از اتمام این درس، شما قادر خواهید بود:

الگوی طراحی استفاده از ابزار چیست؟

الگوی طراحی استفاده از ابزار بر توانمندسازی مدل‌های زبانی بزرگ (LLM) برای تعامل با ابزارهای خارجی به منظور دستیابی به اهداف خاص تمرکز دارد. ابزارها کدهایی هستند که می‌توانند توسط یک عامل اجرا شوند تا اقدامات خاصی انجام دهند. یک ابزار می‌تواند یک تابع ساده مانند یک ماشین حساب باشد یا یک فراخوانی API به یک سرویس شخص ثالث مانند جستجوی قیمت سهام یا پیش‌بینی آب‌وهوا. در زمینه عوامل هوش مصنوعی، ابزارها برای اجرا توسط عوامل در پاسخ به فراخوانی‌های تابع تولید شده توسط مدل طراحی شده‌اند.

موارد استفاده‌ای که می‌توان آن را به کار برد چیست؟

عوامل هوش مصنوعی می‌توانند از ابزارها برای انجام وظایف پیچیده، بازیابی اطلاعات یا تصمیم‌گیری استفاده کنند. الگوی طراحی استفاده از ابزار اغلب در سناریوهایی که نیاز به تعامل پویا با سیستم‌های خارجی مانند پایگاه‌های داده، خدمات وب یا مفسرهای کد دارند، استفاده می‌شود. این قابلیت برای موارد استفاده مختلفی مفید است، از جمله:

عناصر/بلوک‌های سازنده مورد نیاز برای پیاده‌سازی الگوی طراحی استفاده از ابزار چیست؟

این بلوک‌های سازنده به عامل هوش مصنوعی امکان انجام طیف وسیعی از وظایف را می‌دهند. بیایید به عناصر کلیدی مورد نیاز برای پیاده‌سازی الگوی طراحی استفاده از ابزار نگاهی بیندازیم:

در ادامه، به جزئیات بیشتری درباره فراخوانی تابع/ابزار می‌پردازیم.

فراخوانی تابع/ابزار

فراخوانی تابع اصلی‌ترین روش برای توانمندسازی مدل‌های زبانی بزرگ (LLM) برای تعامل با ابزارها است. اغلب اصطلاحات “تابع” و “ابزار” به صورت متناوب استفاده می‌شوند زیرا “توابع” (بلوک‌های کد قابل استفاده مجدد) همان “ابزارهایی” هستند که عوامل برای انجام وظایف از آن‌ها استفاده می‌کنند. برای اینکه کد یک تابع فراخوانی شود، LLM باید درخواست کاربر را با توضیحات تابع مقایسه کند. برای این کار، یک طرح شامل توضیحات تمام توابع موجود به LLM ارسال می‌شود. سپس LLM مناسب‌ترین تابع را برای وظیفه انتخاب کرده و نام و آرگومان‌های آن را بازمی‌گرداند. تابع انتخاب‌شده فراخوانی می‌شود، پاسخ آن به LLM ارسال می‌شود و LLM از این اطلاعات برای پاسخ به درخواست کاربر استفاده می‌کند.

برای پیاده‌سازی فراخوانی تابع برای عوامل، توسعه‌دهندگان به موارد زیر نیاز دارند:

  1. یک مدل LLM که از فراخوانی تابع پشتیبانی کند
  2. یک طرح شامل توضیحات توابع
  3. کد هر تابع توصیف‌شده

بیایید از مثال دریافت زمان فعلی در یک شهر برای توضیح استفاده کنیم:

  1. یک LLM که از فراخوانی تابع پشتیبانی می‌کند را مقداردهی اولیه کنید:

    همه مدل‌ها از فراخوانی تابع پشتیبانی نمی‌کنند، بنابراین مهم است که بررسی کنید مدل LLM شما این قابلیت را دارد. Azure OpenAI از فراخوانی تابع پشتیبانی می‌کند. می‌توانیم با مقداردهی اولیه کلاینت Azure OpenAI شروع کنیم.

     # Initialize the Azure OpenAI client
     client = AzureOpenAI(
         azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT"), 
         api_key=os.getenv("AZURE_OPENAI_API_KEY"),  
         api_version="2024-05-01-preview"
     )
    
  2. ایجاد یک طرح تابع:

    سپس یک طرح JSON تعریف می‌کنیم که شامل نام تابع، توضیحی درباره کاری که تابع انجام می‌دهد و نام‌ها و توضیحات پارامترهای تابع است. این طرح را به همراه درخواست کاربر برای یافتن زمان در سان‌فرانسیسکو به کلاینتی که قبلاً ایجاد شده است ارسال می‌کنیم. نکته مهم این است که یک فراخوانی ابزار بازگردانده می‌شود، نه پاسخ نهایی به سوال. همان‌طور که قبلاً ذکر شد، LLM نام تابعی که برای وظیفه انتخاب کرده و آرگومان‌هایی که به آن ارسال می‌شود را بازمی‌گرداند.

     # Function description for the model to read
     tools = [
         {
             "type": "function",
             "function": {
                 "name": "get_current_time",
                 "description": "Get the current time in a given location",
                 "parameters": {
                     "type": "object",
                     "properties": {
                         "location": {
                             "type": "string",
                             "description": "The city name, e.g. San Francisco",
                         },
                     },
                     "required": ["location"],
                 },
             }
         }
     ]
    
      
     # Initial user message
     messages = [{"role": "user", "content": "What's the current time in San Francisco"}] 
      
     # First API call: Ask the model to use the function
       response = client.chat.completions.create(
           model=deployment_name,
           messages=messages,
           tools=tools,
           tool_choice="auto",
       )
      
       # Process the model's response
       response_message = response.choices[0].message
       messages.append(response_message)
      
       print("Model's response:")  
    
       print(response_message)
      
    
     Model's response:
     ChatCompletionMessage(content=None, role='assistant', function_call=None, tool_calls=[ChatCompletionMessageToolCall(id='call_pOsKdUlqvdyttYB67MOj434b', function=Function(arguments='{"location":"San Francisco"}', name='get_current_time'), type='function')])
    
  3. کد تابع مورد نیاز برای انجام وظیفه:

    اکنون که LLM انتخاب کرده است کدام تابع باید اجرا شود، کدی که وظیفه را انجام می‌دهد باید پیاده‌سازی و اجرا شود. می‌توانیم کد دریافت زمان فعلی را در پایتون پیاده‌سازی کنیم. همچنین باید کدی بنویسیم که نام و آرگومان‌ها را از response_message استخراج کند تا نتیجه نهایی را به دست آوریم.

       def get_current_time(location):
         """Get the current time for a given location"""
         print(f"get_current_time called with location: {location}")  
         location_lower = location.lower()
            
         for key, timezone in TIMEZONE_DATA.items():
             if key in location_lower:
                 print(f"Timezone found for {key}")  
                 current_time = datetime.now(ZoneInfo(timezone)).strftime("%I:%M %p")
                 return json.dumps({
                     "location": location,
                     "current_time": current_time
                 })
          
         print(f"No timezone data found for {location_lower}")  
         return json.dumps({"location": location, "current_time": "unknown"})
    
      # Handle function calls
       if response_message.tool_calls:
           for tool_call in response_message.tool_calls:
               if tool_call.function.name == "get_current_time":
         
                   function_args = json.loads(tool_call.function.arguments)
         
                   time_response = get_current_time(
                       location=function_args.get("location")
                   )
         
                   messages.append({
                       "tool_call_id": tool_call.id,
                       "role": "tool",
                       "name": "get_current_time",
                       "content": time_response,
                   })
       else:
           print("No tool calls were made by the model.")  
      
       # Second API call: Get the final response from the model
       final_response = client.chat.completions.create(
           model=deployment_name,
           messages=messages,
       )
      
       return final_response.choices[0].message.content
    
       get_current_time called with location: San Francisco
       Timezone found for san francisco
       The current time in San Francisco is 09:24 AM.
    

فراخوانی تابع در قلب اکثر طراحی‌های استفاده از ابزار عامل قرار دارد، اما پیاده‌سازی آن از ابتدا گاهی اوقات می‌تواند چالش‌برانگیز باشد. همان‌طور که در درس ۲ یاد گرفتیم، چارچوب‌های عامل به ما بلوک‌های سازنده از پیش ساخته‌شده‌ای برای پیاده‌سازی استفاده از ابزار ارائه می‌دهند.

مثال‌های استفاده از ابزار با چارچوب‌های عامل

در اینجا چند مثال از نحوه پیاده‌سازی الگوی طراحی استفاده از ابزار با استفاده از چارچوب‌های عامل مختلف آورده شده است:

Semantic Kernel

Semantic Kernel یک چارچوب هوش مصنوعی متن‌باز برای توسعه‌دهندگان .NET، پایتون و جاوا است که با مدل‌های زبانی بزرگ (LLM) کار می‌کنند. این چارچوب فرآیند استفاده از فراخوانی تابع را با توصیف خودکار توابع و پارامترهای آن‌ها به مدل از طریق فرآیندی به نام سریال‌سازی ساده می‌کند. همچنین ارتباطات بین مدل و کد شما را مدیریت می‌کند. یکی دیگر از مزایای استفاده از چارچوب عامل مانند Semantic Kernel این است که به شما امکان دسترسی به ابزارهای از پیش ساخته‌شده مانند جستجوی فایل و مفسر کد را می‌دهد.

نمودار زیر فرآیند فراخوانی تابع با Semantic Kernel را نشان می‌دهد:

فراخوانی تابع

در Semantic Kernel، توابع/ابزارها پلاگین نامیده می‌شوند. می‌توانیم تابع get_current_time که قبلاً دیدیم را با تبدیل آن به یک کلاس با تابع درون آن به یک پلاگین تبدیل کنیم. همچنین می‌توانیم دکوراتور kernel_function را وارد کنیم که توضیحات تابع را دریافت می‌کند. هنگامی که کرنلی با پلاگین GetCurrentTimePlugin ایجاد می‌کنید، کرنل به طور خودکار تابع و پارامترهای آن را سریال‌سازی کرده و طرحی برای ارسال به LLM ایجاد می‌کند.

from semantic_kernel.functions import kernel_function

class GetCurrentTimePlugin:
    async def __init__(self, location):
        self.location = location

    @kernel_function(
        description="Get the current time for a given location"
    )
    def get_current_time(location: str = ""):
        ...

from semantic_kernel import Kernel

# Create the kernel
kernel = Kernel()

# Create the plugin
get_current_time_plugin = GetCurrentTimePlugin(location)

# Add the plugin to the kernel
kernel.add_plugin(get_current_time_plugin)

سرویس عامل Azure AI

سرویس عامل Azure AI یک چارچوب عامل جدیدتر است که برای توانمندسازی توسعه‌دهندگان برای ساخت، استقرار و مقیاس‌بندی عوامل هوش مصنوعی با کیفیت بالا و قابل گسترش به صورت امن طراحی شده است، بدون نیاز به مدیریت منابع محاسباتی و ذخیره‌سازی زیرین. این سرویس به ویژه برای برنامه‌های سازمانی مفید است زیرا یک سرویس کاملاً مدیریت‌شده با امنیت در سطح سازمانی است.

در مقایسه با توسعه با API مدل LLM به طور مستقیم، سرویس عامل Azure AI مزایایی ارائه می‌دهد، از جمله:

ابزارهای موجود در سرویس عامل Azure AI به دو دسته تقسیم می‌شوند:

  1. ابزارهای دانش:
  2. ابزارهای عملیاتی:

سرویس عامل به ما این امکان را می‌دهد که بتوانیم از این ابزارها به صورت یک مجموعه ابزار استفاده کنیم. همچنین از رشته‌ها استفاده می‌کند که تاریخچه پیام‌های یک مکالمه خاص را پیگیری می‌کنند.

تصور کنید شما یک نماینده فروش در شرکتی به نام Contoso هستید. می‌خواهید یک عامل مکالمه‌ای توسعه دهید که بتواند به سوالات مربوط به داده‌های فروش شما پاسخ دهد.

تصویر زیر نشان می‌دهد که چگونه می‌توانید از سرویس عامل Azure AI برای تحلیل داده‌های فروش خود استفاده کنید:

سرویس عامل در عمل

برای استفاده از هر یک از این ابزارها با این سرویس، می‌توانیم یک کلاینت ایجاد کرده و یک ابزار یا مجموعه ابزار تعریف کنیم. برای پیاده‌سازی عملی این کار می‌توانیم از کد پایتون زیر استفاده کنیم. LLM می‌تواند به مجموعه ابزار نگاه کند و بسته به درخواست کاربر تصمیم بگیرد که آیا از تابع ایجادشده توسط کاربر، fetch_sales_data_using_sqlite_query، یا مفسر کد از پیش ساخته‌شده استفاده کند.

import os
from azure.ai.projects import AIProjectClient
from azure.identity import DefaultAzureCredential
from fetch_sales_data_functions import fetch_sales_data_using_sqlite_query # fetch_sales_data_using_sqlite_query function which can be found in a fetch_sales_data_functions.py file.
from azure.ai.projects.models import ToolSet, FunctionTool, CodeInterpreterTool

project_client = AIProjectClient.from_connection_string(
    credential=DefaultAzureCredential(),
    conn_str=os.environ["PROJECT_CONNECTION_STRING"],
)

# Initialize function calling agent with the fetch_sales_data_using_sqlite_query function and adding it to the toolset
fetch_data_function = FunctionTool(fetch_sales_data_using_sqlite_query)
toolset = ToolSet()
toolset.add(fetch_data_function)

# Initialize Code Interpreter tool and adding it to the toolset. 
code_interpreter = code_interpreter = CodeInterpreterTool()
toolset = ToolSet()
toolset.add(code_interpreter)

agent = project_client.agents.create_agent(
    model="gpt-4o-mini", name="my-agent", instructions="You are helpful agent", 
    toolset=toolset
)

ملاحظات خاص برای استفاده از الگوی طراحی استفاده از ابزار برای ساخت عوامل هوش مصنوعی قابل اعتماد چیست؟

یکی از نگرانی‌های رایج با SQL که به صورت پویا توسط LLMها تولید می‌شود، امنیت است، به ویژه خطر تزریق SQL یا اقدامات مخرب مانند حذف یا دستکاری پایگاه داده. در حالی که این نگرانی‌ها معتبر هستند، می‌توان آن‌ها را با پیکربندی صحیح مجوزهای دسترسی به پایگاه داده به طور مؤثر کاهش داد. برای اکثر پایگاه‌های داده، این شامل پیکربندی پایگاه داده به صورت فقط خواندنی است. برای خدمات پایگاه داده مانند PostgreSQL یا Azure SQL، باید به برنامه یک نقش فقط خواندنی (SELECT) اختصاص داده شود. اجرای برنامه در یک محیط امن، حفاظت را بیشتر تقویت می‌کند. در سناریوهای سازمانی، داده‌ها معمولاً از سیستم‌های عملیاتی استخراج و به یک پایگاه داده فقط خواندنی یا انبار داده با یک طرح کاربرپسند منتقل می‌شوند. این روش اطمینان می‌دهد که داده‌ها امن، بهینه برای عملکرد و دسترسی هستند و برنامه دسترسی محدود و فقط خواندنی دارد.

نمونه کدها

سوالات بیشتری درباره الگوهای طراحی ابزار دارید؟

به دیسکورد Azure AI Foundry بپیوندید تا با دیگر یادگیرندگان ملاقات کنید، در ساعات مشاوره شرکت کنید و پاسخ سوالات خود درباره عوامل هوش مصنوعی را دریافت کنید.

منابع اضافی

درس قبلی

درک الگوهای طراحی عامل‌محور

درس بعدی

عامل‌محور RAG


سلب مسئولیت:
این سند با استفاده از سرویس ترجمه هوش مصنوعی Co-op Translator ترجمه شده است. در حالی که ما برای دقت تلاش می‌کنیم، لطفاً توجه داشته باشید که ترجمه‌های خودکار ممکن است شامل خطاها یا نادرستی‌ها باشند. سند اصلی به زبان اصلی آن باید به عنوان منبع معتبر در نظر گرفته شود. برای اطلاعات حیاتی، ترجمه حرفه‌ای انسانی توصیه می‌شود. ما هیچ مسئولیتی در قبال سوءتفاهم‌ها یا تفسیرهای نادرست ناشی از استفاده از این ترجمه نداریم.