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 תומך בקריאת פונקציה. נוכל להתחיל בהפעלת לקוח OpenAI מול API לתגובות של Azure OpenAI (נקודת הקצה היציבה /openai/v1/ — ללא צורך ב-api_version).

     # Initialize the OpenAI client for Azure OpenAI (Responses API, v1 endpoint)
     client = OpenAI(
         base_url=f"{os.environ['AZURE_OPENAI_ENDPOINT'].rstrip('/')}/openai/v1/",
         api_key=os.environ["AZURE_OPENAI_API_KEY"],
     )
     deployment_name = os.environ["AZURE_OPENAI_DEPLOYMENT"]
    
  2. צור סכמת פונקציה:

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

     # Function description for the model to read (Responses API flat tool format)
     tools = [
         {
             "type": "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.responses.create(
         model=deployment_name,
         input=messages,
         tools=tools,
         tool_choice="auto",
         store=False,
     )
    
     # The Responses API returns tool calls as function_call items in response.output.
     # Append them to the conversation so the model has full context on the next turn.
     messages += response.output
    
     print("Model's response:")
     print(response.output)
      
    
     Model's response:
     [ResponseFunctionToolCall(arguments='{"location":"San Francisco"}', call_id='call_pOsKdUlqvdyttYB67MOj434b', name='get_current_time', type='function_call')]
    
  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
     tool_calls = [item for item in response.output if item.type == "function_call"]
     if tool_calls:
         for tool_call in tool_calls:
             if tool_call.name == "get_current_time":
    
                 function_args = json.loads(tool_call.arguments)
    
                 time_response = get_current_time(
                     location=function_args.get("location")
                 )
    
                 # Return the tool result as a function_call_output item
                 messages.append({
                     "type": "function_call_output",
                     "call_id": tool_call.call_id,
                     "output": 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.responses.create(
         model=deployment_name,
         input=messages,
         tools=tools,
         store=False,
     )
    
     return final_response.output_text
    
       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 שונות:

Microsoft Agent Framework

Microsoft Agent Framework היא מסגרת AI בקוד פתוח לבניית סוכני AI. היא מפשטת את התהליך של שימוש בקריאת פונקציות על ידי הגדרת כלים כפונקציות פייתון עם הדקורטור @tool. המסגרת מנהלת את התקשורת הלוך וחזור בין המודל לבין הקוד שלך. היא גם מספקת גישה לכלים שבנויים מראש כמו חיפוש בקבצים ומפרש קוד באמצעות FoundryChatClient.

התרשים הבא ממחיש את תהליך קריאת הפונקציה במסגרת Microsoft Agent Framework:

function calling

במסגרת Microsoft Agent Framework הכלים מוגדרים כפונקציות עם דקורטורים. נוכל להמיר את הפונקציה get_current_time שראינו קודם לכלי על ידי שימוש בדקורטור @tool. המסגרת תסדר אוטומטית את הפונקציה ופרמטריה, ותיצור את הסכמה לשליחה ל-LLM.

import os
from agent_framework import tool
from agent_framework.foundry import FoundryChatClient
from azure.identity import AzureCliCredential

@tool(approval_mode="never_require")
def get_current_time(location: str) -> str:
    """Get the current time for a given location"""
    ...

# Create the client
provider = FoundryChatClient(
    project_endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"],
    model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
    credential=AzureCliCredential(),
)

# Create an agent and run with the tool
agent = provider.as_agent(name="TimeAgent", instructions="Use available tools to answer questions.", tools=get_current_time)
response = await agent.run("What time is it?")

כלים משרת MCP

כלים לא חייבים להיות פונקציות בקוד שלך. שרת שמדבר את פרוטוקול הקשר של הדגם (Model Context Protocol - MCP, שנלמד בשיעור 11) מפרסם את הכלים שלו יחד עם הסכמות שלהם, והמסגרת יכולה לטעון אותם באותה הדרך שהיא מסדרת פונקציה עם דקורטור. MCPStreamableHTTPTool מתחבר לשרת כזה דרך HTTP, קורא את סכמות הכלים, ומציע אותם למודל יחד עם כלים מקומיים.

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

from agent_framework import MCPStreamableHTTPTool

web_search = MCPStreamableHTTPTool(
    name="Keenable web search",
    url="https://api.keenable.ai/mcp",
)

# Connecting loads the server's tool schemas; the agent decides when to call them
async with web_search:
    agent = provider.as_agent(
        name="ResearchAgent",
        instructions="Use available tools to answer questions.",
        tools=[web_search],
    )
    response = await agent.run("What is new in the latest Python release?")
    print(response.text)

השרת מפרסם שני כלים, search_web_pages ו-fetch_page_content. כשהשאלה דורשת מידע עדכני, המודל קורא ל-search_web_pages, מקבל כותרות, כתובות URL וקטעי טקסט, וכותב את התשובה שלו מהם, בלופ זהה לדוגמה get_current_time למעלה.

Microsoft Foundry Agent Service

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

בהשוואה לפיתוח ישיר עם ה-API של LLM, Microsoft Foundry Agent Service מספקת מספר יתרונות, ביניהם:

הכלים הזמינים בשירות Microsoft Foundry Agent ניתן לחלק לשתי קטגוריות:

  1. כלים לידע:
  2. כלים לפעולה:

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

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

התמונה הבאה מדגימה כיצד ניתן להשתמש בשירות Microsoft Foundry Agent לניתוח נתוני המכירות:

Agentic Service In Action

לשימוש בכל אחד מהכלים הללו עם השירות נוכל ליצור לקוח ולהגדיר כלי או קבוצת כלים. ליישום מעשי נשתמש בקוד הפייתון הבא. ה-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 toolset
toolset = ToolSet()

# 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.add(fetch_data_function)

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

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

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

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

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

דוגמאות קוד

יש לכם עוד שאלות לגבי תבניות עיצוב לשימוש בכלים?

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

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

בדיקת עשן לסוכן זה (אופציונלי)

לאחר שלמדתם לפרוס סוכנים בשיעור 16, תוכלו לבצע בדיקת עשן לTravelToolAgent של השיעור הזה (האם הוא עדיין קורא לכלים שלו ועונה?) עם tests/lesson-04-smoke-tests.json. ראו tests/README.md כיצד להפעיל אותו.

שיעור קודם

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

השיעור הבא

Agentic RAG


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