(לחץ על התמונה למעלה לצפייה בסרטון של השיעור)
כלים מעניינים מכיוון שהם מאפשרים לסוכני בינה מלאכותית טיפוס רחב יותר של יכולות. במקום שהסוכן יוגבל למערך פעולות מצומצם שהוא יכול לבצע, על ידי הוספת כלי, הסוכן יכול כעת לבצע מגוון רחב של פעולות. בפרק זה נבחן את דפוס העיצוב לשימוש בכלים, המתאר כיצד סוכני בינה מלאכותית יכולים להשתמש בכלים ספציפיים כדי להשיג את מטרותיהם.
בשיעור זה אנו מנסים לענות על השאלות הבאות:
לאחר השלמת שיעור זה, תוכל/י:
הדפוס דפוס העיצוב לשימוש בכלים מתמקד במתן היכולת ל-LLMs לקיים אינטראקציה עם כלים חיצוניים על מנת להשיג מטרות ספציפיות. כלים הם קוד שניתן לבצע על-ידי סוכן כדי לבצע פעולות. כלי יכול להיות פונקציה פשוטה כמו מחשבון, או קריאת API לשירות צד שלישי כמו בדיקת מחיר מניה או תחזית מזג אוויר. בהקשר של סוכני בינה מלאכותית, כלים מעוצבים כך שיופעלו על-ידי סוכנים בתגובה לקריאות לפונקציות שנוצרות על ידי המודל.
סוכני בינה מלאכותית יכולים לנצל כלים כדי להשלים משימות מורכבות, לשלוף מידע או לקבל החלטות. דפוס העיצוב לשימוש בכלים משמש לעתים קרובות בתרחישים הדורשים אינטראקציה דינמית עם מערכות חיצוניות, כגון מסדי נתונים, שירותי רשת או מפרשי קוד. יכולת זו שימושית למספר מקרים שונים הכוללים:
בלוקי הבנייה הללו מאפשרים לסוכן הבינה לבצע מגוון רחב של משימות. בואו נסתכל על המרכיבים המרכזיים הדרושים ליישום דפוס העיצוב לשימוש בכלים:
בהמשך, נבחן את קריאת פונקציות/כלים בפירוט רב יותר.
קריאת פונקציות היא הדרך העיקרית שמאפשרת למודלים לשפה גדולים (LLMs) לקיים אינטראקציה עם כלים. תתקל לעתים קרובות בשימוש במונחים ‘Function’ ו-‘Tool’ לסירוגין כי ‘functions’ (בלוקים של קוד שניתן לשימוש חוזר) הם ה’כלים’ שהסוכנים משתמשים בהם כדי לבצע משימות. כדי שניתן יהיה לקרוא לקוד של פונקציה, ה-LLM חייב להשוות את בקשת המשתמש לתיאור הפונקציות. לשם כך נשלחת ל-LLM סכמה המכילה את התיאורים של כל הפונקציות הזמינות. ה-LLM ואז בוחר את הפונקציה המתאימה ביותר למשימה ומחזיר את שמה ואת הטיעונים שלה. הפונקציה שנבחרה מופעלת, התגובה שלה נשלחת חזרה ל-LLM, שהופך את המידע לתשובה לבקשת המשתמש.
כדי שמפתחים יוכלו ליישם קריאת פונקציות עבור סוכנים, תצטרכו:
בואו נשתמש בדוגמה של קבלת השעה הנוכחית בעיר להמחשה:
אתחול מודל LLM שתומך בקריאת פונקציות:
לא כל הדגמים תומכים בקריאת פונקציות, לכן חשוב לבדוק שה-LLM שבו אתם משתמשים תומך בכך. Azure OpenAI תומך בקריאת פונקציות. נוכל להתחיל על-ידי איתחול הלקוח של Azure OpenAI.
# אתחל את לקוח Azure OpenAI
client = AzureOpenAI(
azure_endpoint = os.getenv("AZURE_AI_PROJECT_ENDPOINT"),
api_key=os.getenv("AZURE_OPENAI_API_KEY"),
api_version="2024-05-01-preview"
)
יצירת סכמה של פונקציה:
לאחר מכן נגדיר סכמה ב-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')])
הקוד של הפונקציה הנדרש לביצוע המשימה:
עכשיו כאשר ה-LLM בחר איזו פונקציה יש להריץ, יש ליישם ולהריץ את הקוד שמבצע את המשימה. נוכל לממש את הקוד לקבלת השעה הנוכחית ב-Python. נצטרך גם לכתוב את הקוד לחלץ את השם והארגומנטים מתוך 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 שונות:
Microsoft Agent Framework היא מסגרת AI קוד-פתוח לבניית סוכני בינה מלאכותית. היא מפשטת את תהליך קריאת הפונקציות על-ידי כך שהיא מאפשרת להגדיר כלים כפונקציות Python עם הדקורטור @tool. המסגרת מטפלת בתקשורת הלוך-ושוב בין המודל לבין הקוד שלכם. היא גם מספקת גישה לכלים מובנים מראש כמו חיפוש קבצים (File Search) ומפרש קוד (Code Interpreter) דרך ה-AzureAIProjectAgentProvider.
הדיאגרמה הבאה ממחישה את תהליך קריאת הפונקציות עם Microsoft Agent Framework:

ב-Microsoft Agent Framework, כלים מוגדרים כפונקציות עם דקורטורים. אנו יכולים להמיר את הפונקציה get_current_time שראינו קודם לכלי על-ידי שימוש בדקורטור @tool. המסגרת תסדר באופן אוטומטי את הפונקציה ואת הפרמטרים שלה, ותייצר את הסכמה שתשלח ל-LLM.
from agent_framework import tool
from agent_framework.azure import AzureAIProjectAgentProvider
from azure.identity import AzureCliCredential
@tool
def get_current_time(location: str) -> str:
"""Get the current time for a given location"""
...
# צור את הלקוח
provider = AzureAIProjectAgentProvider(credential=AzureCliCredential())
# צור סוכן והרץ אותו באמצעות הכלי
agent = await provider.create_agent(name="TimeAgent", instructions="Use available tools to answer questions.", tools=get_current_time)
response = await agent.run("What time is it?")
Azure AI Agent Service היא מסגרת סוכנים חדשה יותר שמטרתה להעצים מפתחים לבנות, לפרוס ולשכפל סוכני בינה איכותיים ומורחבים בצורה מאובטחת, ללא צורך בניהול המשאבים המחשוביים והאחסון הבסיסיים. היא שימושית במיוחד לאפליקציות ארגוניות שכן היא שירות מנוהל לחלוטין ברמת אבטחה ארגונית.
בהשוואה לפיתוח ישיר עם API של LLM, Azure AI Agent Service מספקת כמה יתרונות, כולל:
הכלים הזמינים ב-Azure AI Agent Service ניתנים לחלוקה לשתי קטגוריות:
שירות הסוכנים מאפשר לנו להשתמש בכלים אלה יחד כ-toolset. הוא גם מנצל threads שמתעדים את היסטוריית ההודעות משיחה מסוימת.
דמיינו שאתם נציגי מכירות בחברה בשם Contoso. אתם רוצים לפתח סוכן שיחה שיכול לענות על שאלות אודות נתוני המכירות שלכם.
התמונה הבאה ממחישה כיצד ניתן להשתמש ב-Azure AI Agent Service כדי לנתח את נתוני המכירות שלכם:

כדי להשתמש בכלים אלה עם השירות ניתן ליצור לקוח ולהגדיר כלי או toolset. ליישום מעשי ניתן להשתמש בקוד Python הבא. ה-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
)
דאגה נפוצה לגבי SQL שנוצר באופן דינמי על-ידי LLMs היא אבטחה, במיוחד הסיכון של SQL injection או פעולות זדוניות, כגון מחיקה או מניפולציה של בסיס הנתונים. בעוד שדאגות אלה מוצדקות, ניתן להפחית אותן ביעילות על-ידי קביעת הרשאות גישה למסד הנתונים כראוי. עבור רוב מסדי הנתונים זה כולל קונפיגורציה של מסד הנתונים במצב קריאה בלבד. עבור שירותי מסדי נתונים כמו PostgreSQL או Azure SQL, יש להקצות לאפליקציה תפקיד קריאה בלבד (SELECT).
הרצת האפליקציה בסביבה מאובטחת מחזקת עוד יותר את ההגנה. בתרחישים ארגוניים, הנתונים בדרך כלל מופקים ומעובדים ממערכות תפעוליות אל מסד נתונים לקריאה בלבד או לאחסון נתונים (data warehouse) עם סכימה ידידותית למשתמש. גישה זו מבטיחה שהנתונים מאובטחים, מותאמים לביצועים ונגישים, וכי לאפליקציה יש גישה מוגבלת לקריאה בלבד.
הצטרפו ל-Microsoft Foundry Discord כדי להיפגש עם לומדים נוספים, להשתתף בשעות מענה ולקבל תשובות על שאלותיכם בנושא סוכני בינה מלאכותית.
הצהרת אי-אחריות: מסמך זה תורגם באמצעות שירות תרגום בינה מלאכותית Co-op Translator. אף שאנו שואפים לדיוק, יש לשים לב כי תרגומים אוטומטיים עלולים להכיל שגיאות או אי-דיוקים. יש לראות במסמך המקורי בשפתו כמקור הסמכותי. לגבי מידע קריטי, מומלץ להסתייע בתרגום מקצועי שנערך על ידי מתרגם אנושי. איננו נושאים באחריות לכל אי-הבנה או פרשנות שגויה הנובעת משימוש בתרגום זה.