ai-agents-for-beginners

כיצד לעצב סוכני AI טובים

(לחצו על התמונה למעלה לצפייה בווידאו של השיעור)

תבנית עיצוב שימוש בכלים

כלים מעניינים כי הם מאפשרים לסוכני AI להחזיק בטווח רחב יותר של יכולות. במקום שהסוכן יוכל לבצע רק סט מוגבל של פעולות, על ידי הוספת כלי, הסוכן יכול כעת לבצע מגוון רחב של פעולות. בפרק זה נבחן את תבנית העיצוב שימוש בכלים, המתארת כיצד סוכני AI יכולים להשתמש בכלים ספציפיים כדי להשיג את מטרותיהם.

מבוא

בשיעור זה אנחנו מעוניינים לענות על השאלות הבאות:

מטרות הלמידה

בסיום שיעור זה תוכלו:

מהי תבנית עיצוב שימוש בכלים?

תבנית העיצוב שימוש בכלים מתמקדת במתן יכולת למודלי שפה גדולים (LLMs) לקיים אינטראקציה עם כלים חיצוניים כדי להשיג מטרות ספציפיות. כלים הם קוד שניתן להפעילו על ידי סוכן לביצוע פעולות. כלי יכול להיות פונקציה פשוטה כמו מחשבון, או קריאת API לשירות צד שלישי כגון חיפוש מחירי מניות או תחזית מזג אוויר. בהקשר של סוכני AI, כלים מיועדים להיות מופעלים על ידי סוכנים בתגובה לקריאות פונקציה שנוצרות על ידי המודל.

לאילו שימושים ניתן ליישם אותה?

סוכני AI יכולים לנצל כלים כדי להשלים משימות מורכבות, לאחזר מידע או לקבל החלטות. תבנית עיצוב שימוש בכלים משמשת לעיתים קרובות בתרחישים הדורשים אינטראקציה דינמית עם מערכות חיצוניות, כגון מסדי נתונים, שירותי רשת או מפרשי קוד. יכולת זו שימושית למספר מקרים שונים כגון:

מהם האלמנטים/הלבנים הנדרשים ליישום תבנית עיצוב שימוש בכלים?

הלבנים האלו מאפשרים לסוכן AI לבצע מגוון רחב של משימות. הבה נבחן את האלמנטים המרכזיים הדרושים ליישום תבנית עיצוב שימוש בכלים:

נעבור כעת לפירוט נוסף על קריאת פונקציות/כלים.

קריאת פונקציות/כלים

קריאת פונקציות היא הדרך העיקרית שבאמצעותה מאפשרים למודלים גדולים של שפה (LLMs) לקיים אינטראקציה עם כלים. לעיתים קרובות תראו ש’פונקציה’ ו’כלי’ משמשים להחלפה זה עם זה משום ש’פונקציות’ (קטעי קוד שניתן להשתמש בהם שוב) הן הכלים שהסוכנים משתמשים בהם לצורך ביצוע משימות. כדי שהקוד של פונקציה יופעל, ה-LLM חייב להשוות את הבקשה של המשתמש עם תיאור הפונקציה. לשם כך נשלח ל-LLM סכימה הכוללת תיאורים של כל הפונקציות הזמינות. ה-LLM בוחר אז את הפונקציה המתאימה ביותר למשימה ומחזיר את שמה וארגומנטיה. הפונקציה שנבחרה מופעלת, תגובתה נשלחת חזרה ל-LLM שמשתמש במידע כדי להגיב לבקשת המשתמש.

כדי שמפתחים יוכלו ליישם קריאת פונקציות לסוכנים, תצטרכו:

  1. מודל LLM התומך בקריאת פונקציות
  2. סכימה הכוללת תיאורי פונקציות
  3. הקוד של כל פונקציה שמתואר

נשתמש בדוגמה של קבלת השעה הנוכחית בעיר כדי להמחיש:

  1. הפעלת מודל LLM התומך בקריאת פונקציות:

    לא כל המודלים תומכים בקריאת פונקציות, לכן חשוב לבדוק שה-LLM שאתם משתמשים בו עושה זאת. Azure OpenAI תומך בקריאת פונקציות. נתחיל ביצירת לקוח Azure OpenAI.

     # אתחל את לקוח Azure OpenAI
     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 מחזיר את שם הפונקציה שנבחרה למשימה ואת הארגומנטים שיועברו לה.

     # תיאור הפונקציה למודל לקריאה
     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"],
                 },
             }
         }
     ]
    
      
     # הודעת משתמש התחלתית
     messages = [{"role": "user", "content": "What's the current time in San Francisco"}] 
      
     # קריאת API ראשונה: בקש מהמודל להשתמש בפונקציה
       response = client.chat.completions.create(
           model=deployment_name,
           messages=messages,
           tools=tools,
           tool_choice="auto",
       )
      
       # עיבוד תגובת המודל
       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"})
    
      # טיפול בקריאות לפונקציות
       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.")  
      
       # קריאה שנייה ל-API: קבלת התגובה הסופית מהמודל
       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.
    

קריאת פונקציות היא בלב ליבה של רוב, אם לא כל, תבניות עיצוב השימוש בכלים לסוכנים, אך יישומה מאפס יכול להיות מאתגר לפעמים. כפי שלמדנו ב-שיעור 2 מסגרות agentic מספקות לנו לבנים מוכנות מראש ליישום שימוש בכלים.

דוגמאות לשימוש בכלים עם מסגרות Agentic

להלן כמה דוגמאות כיצד ניתן ליישם את תבנית העיצוב שימוש בכלים באמצעות מסגרות agentic שונות:

Semantic Kernel

Semantic Kernel היא מסגרת AI בקוד פתוח לפיתוחי .NET, Python ו-Java עם מודלים גדולים של שפה (LLMs). היא מפשטת את תהליך השימוש בקריאות פונקציות על ידי תיאור אוטומטי של הפונקציות ופרמטריהן למודל בתהליך הנקרא סריאליזציה. היא גם מנהלת את התקשורת ההדדית בין המודל לקוד שלך. יתרון נוסף בשימוש במסגרת agentic כמו Semantic Kernel הוא שהיא מאפשרת גישה לכלים מוכנים מראש כמו חיפוש קבצים ו-מפרש קוד.

התמונה הבאה ממחישה את תהליך קריאת הפונקציות עם Semantic Kernel:

function calling

ב-Semantic Kernel פונקציות/כלים נקראים תוספים. נוכל להמיר את הפונקציה get_current_time שראינו קודם לתוסף על ידי הפיכתה למחלקה עם הפונקציה בתוכה. נוכל גם לייבא את הדקורטור kernel_function, שלוקח את תיאור הפונקציה. כאשר ניצור Kernel עם 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

# צור את הליבה
kernel = Kernel()

# צור את התוסף
get_current_time_plugin = GetCurrentTimePlugin(location)

# הוסף את התוסף לליבה
kernel.add_plugin(get_current_time_plugin)

שירות Azure AI Agent

שירות Azure AI Agent היא מסגרת agentic חדשה שנועדה לאפשר למפתחים לבנות, לפרוס ולהרחיב סוכני AI אמינים ובטוחים ללא הצורך לנהל את משאבי החישוב והאחסון התשתיתיים. השירות שימושי במיוחד לאפליקציות ארגוניות שכן הוא שירות מנוהל במלואו ברמת אבטחה ארגונית.

בהשוואה לפיתוח ישיר עם ממשק ה-API של LLM, שירות Azure AI Agent מספק מספר יתרונות, כולל:

הכלים הזמינים בשירות Azure AI Agent מתחלקים לשתי קטגוריות:

  1. כלים מבוססי ידע:
  2. כלים לפעולות:

שירות ה-Agent מאפשר לנו להשתמש בכלים אלו יחד כtoolset. הוא גם משתמש בthreads שמנטרים את היסטוריית ההודעות משיחה ספציפית.

תדמיינו שאתם סוכן מכירות בחברה בשם Contoso. אתם רוצים לפתח סוכן שיחה שיכול לענות על שאלות בנוגע לנתוני המכירה שלכם.

התמונה הבאה ממחישה כיצד ניתן להשתמש בשירות Azure AI Agent לניתוח נתוני המכירות:

Agentic Service In Action

כדי להשתמש בכלים אלה עם השירות, ניתן ליצור לקוח ולהגדיר כלי או toolset. ליישום מעשי ניתן להשתמש בקוד פייתון הבא. ה-LLM יוכל לבחון את ה-toolset ולהחליט אם להשתמש בפונקציה שהמשתמש יצר, 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 שניתן למצוא בקובץ fetch_sales_data_functions.py.
from azure.ai.projects.models import ToolSet, FunctionTool, CodeInterpreterTool

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

# אתחול סט הכלים
toolset = ToolSet()

# אתחול סוכן קריאת פונקציות עם הפונקציה fetch_sales_data_using_sqlite_query והוספתה לסט הכלים
fetch_data_function = FunctionTool(fetch_sales_data_using_sqlite_query)
toolset.add(fetch_data_function)

# אתחול כלי מפרש הקוד והוספתו לסט הכלים.
code_interpreter = code_interpreter = CodeInterpreterTool()
toolset.add(code_interpreter)

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

מהן ההתחשבויות המיוחדות לשימוש בתבנית עיצוב שימוש בכלים לבניית סוכני AI אמינים?

חשש נפוץ לגבי SQL שנוצר דינמית על ידי LLMs הוא אבטחה, במיוחד הסיכון להזרקת SQL או פעולות זדוניות כגון מחיקה או מניפולציה במסד הנתונים. למרות חששות אלו תקפים, ניתן למזערם ביעילות על ידי הקונפיגורציה הנכונה של הרשאות גישה למסד הנתונים. ברוב מסדי הנתונים זה כולל הגדרת מסד הנתונים לקריאה בלבד. עבור שירותי מסדי נתונים כמו PostgreSQL או Azure SQL, יש להקצות לאפליקציה תפקיד קריאה בלבד (SELECT). הרצת האפליקציה בסביבה מאובטחת משפרת עוד יותר את ההגנה. בתרחישים ארגוניים, הנתונים בדרך כלל נוצרים ומעובדים ממערכות תפעוליות למסד נתונים או מחסן נתונים לקריאה בלבד עם סכימה ידידותית למשתמש. גישה זו מבטיחה שהנתונים מאובטחים, מותאמים לביצועים ונגישות, ושהאפליקציה מוגבלת לגישה לקריאה בלבד.

דוגמאות קוד

יש לך עוד שאלות על דפוסי עיצוב לכלי?

הצטרף ל-Azure AI Foundry Discord כדי לפגוש לומדים נוספים, להשתתף בשעות קבלה ולקבל מענה לשאלות שלך בנושא סוכני AI.

משאבים נוספים

שיעור קודם

הבנת דפוסי עיצוב סוכניים

שיעור הבא

Agentic RAG


כתב ויתור: מסמך זה תורגם באמצעות שירות תרגום מבוסס בינה מלאכותית Co-op Translator. למרות שאנו שואפים לדייק, יש לקחת בחשבון שתרגומים אוטומטיים עלולים להכיל שגיאות או אי-דיוקים. המסמך המקורי בשפת המקור שלו נחשב למקור הסמכותי. למידע קריטי מומלץ להשתמש בתרגום מקצועי של אנשים. איננו אחראים לכל אי-הבנות או פרשנויות שגויות הנובעות משימוש בתרגום זה.