(برای مشاهده ویدئوی این درس روی تصویر بالا کلیک کنید)
ابزارها جالب هستند زیرا به عوامل هوش مصنوعی این امکان را میدهند که قابلیتهای گستردهتری داشته باشند. به جای اینکه عامل فقط مجموعه محدودی از اقدامات را انجام دهد، با افزودن یک ابزار، عامل میتواند طیف وسیعی از اقدامات را انجام دهد. در این فصل، به الگوی طراحی استفاده از ابزار میپردازیم که توضیح میدهد چگونه عوامل هوش مصنوعی میتوانند از ابزارهای خاص برای دستیابی به اهداف خود استفاده کنند.
در این درس، به دنبال پاسخ به سوالات زیر هستیم:
پس از اتمام این درس، شما قادر خواهید بود:
الگوی طراحی استفاده از ابزار بر توانمندسازی مدلهای زبانی بزرگ (LLM) برای تعامل با ابزارهای خارجی به منظور دستیابی به اهداف خاص تمرکز دارد. ابزارها کدهایی هستند که میتوانند توسط یک عامل اجرا شوند تا اقدامات خاصی انجام دهند. یک ابزار میتواند یک تابع ساده مانند یک ماشین حساب باشد یا یک فراخوانی API به یک سرویس شخص ثالث مانند جستجوی قیمت سهام یا پیشبینی آبوهوا. در زمینه عوامل هوش مصنوعی، ابزارها برای اجرا توسط عوامل در پاسخ به فراخوانیهای تابع تولید شده توسط مدل طراحی شدهاند.
عوامل هوش مصنوعی میتوانند از ابزارها برای انجام وظایف پیچیده، بازیابی اطلاعات یا تصمیمگیری استفاده کنند. الگوی طراحی استفاده از ابزار اغلب در سناریوهایی که نیاز به تعامل پویا با سیستمهای خارجی مانند پایگاههای داده، خدمات وب یا مفسرهای کد دارند، استفاده میشود. این قابلیت برای موارد استفاده مختلفی مفید است، از جمله:
این بلوکهای سازنده به عامل هوش مصنوعی امکان انجام طیف وسیعی از وظایف را میدهند. بیایید به عناصر کلیدی مورد نیاز برای پیادهسازی الگوی طراحی استفاده از ابزار نگاهی بیندازیم:
طرحهای تابع/ابزار: تعریفات دقیق ابزارهای موجود، شامل نام تابع، هدف، پارامترهای مورد نیاز و خروجیهای مورد انتظار. این طرحها به LLM کمک میکنند تا بفهمد چه ابزارهایی در دسترس هستند و چگونه درخواستهای معتبر بسازد.
منطق اجرای تابع: نحوه و زمان فراخوانی ابزارها را بر اساس قصد کاربر و زمینه مکالمه مدیریت میکند. این ممکن است شامل ماژولهای برنامهریز، مکانیزمهای مسیریابی یا جریانهای شرطی باشد که استفاده از ابزار را به صورت پویا تعیین میکنند.
سیستم مدیریت پیام: اجزایی که جریان مکالمه بین ورودیهای کاربر، پاسخهای LLM، فراخوانی ابزارها و خروجیهای ابزار را مدیریت میکنند.
چارچوب یکپارچهسازی ابزار: زیرساختی که عامل را به ابزارهای مختلف متصل میکند، چه این ابزارها توابع ساده باشند یا خدمات خارجی پیچیده.
مدیریت خطا و اعتبارسنجی: مکانیزمهایی برای مدیریت شکستها در اجرای ابزار، اعتبارسنجی پارامترها و مدیریت پاسخهای غیرمنتظره.
مدیریت وضعیت: پیگیری زمینه مکالمه، تعاملات قبلی با ابزارها و دادههای پایدار برای اطمینان از سازگاری در تعاملات چندمرحلهای.
در ادامه، به جزئیات بیشتری درباره فراخوانی تابع/ابزار میپردازیم.
فراخوانی تابع اصلیترین روش برای توانمندسازی مدلهای زبانی بزرگ (LLM) برای تعامل با ابزارها است. اغلب اصطلاحات “تابع” و “ابزار” به صورت متناوب استفاده میشوند زیرا “توابع” (بلوکهای کد قابل استفاده مجدد) همان “ابزارهایی” هستند که عوامل برای انجام وظایف از آنها استفاده میکنند. برای اینکه کد یک تابع فراخوانی شود، LLM باید درخواست کاربر را با توضیحات تابع مقایسه کند. برای این کار، یک طرح شامل توضیحات تمام توابع موجود به LLM ارسال میشود. سپس LLM مناسبترین تابع را برای وظیفه انتخاب کرده و نام و آرگومانهای آن را بازمیگرداند. تابع انتخابشده فراخوانی میشود، پاسخ آن به LLM ارسال میشود و LLM از این اطلاعات برای پاسخ به درخواست کاربر استفاده میکند.
برای پیادهسازی فراخوانی تابع برای عوامل، توسعهدهندگان به موارد زیر نیاز دارند:
بیایید از مثال دریافت زمان فعلی در یک شهر برای توضیح استفاده کنیم:
یک 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"
)
ایجاد یک طرح تابع:
سپس یک طرح 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')])
کد تابع مورد نیاز برای انجام وظیفه:
اکنون که 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 یک چارچوب هوش مصنوعی متنباز برای توسعهدهندگان .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 یک چارچوب عامل جدیدتر است که برای توانمندسازی توسعهدهندگان برای ساخت، استقرار و مقیاسبندی عوامل هوش مصنوعی با کیفیت بالا و قابل گسترش به صورت امن طراحی شده است، بدون نیاز به مدیریت منابع محاسباتی و ذخیرهسازی زیرین. این سرویس به ویژه برای برنامههای سازمانی مفید است زیرا یک سرویس کاملاً مدیریتشده با امنیت در سطح سازمانی است.
در مقایسه با توسعه با API مدل LLM به طور مستقیم، سرویس عامل Azure AI مزایایی ارائه میدهد، از جمله:
ابزارهای موجود در سرویس عامل Azure AI به دو دسته تقسیم میشوند:
سرویس عامل به ما این امکان را میدهد که بتوانیم از این ابزارها به صورت یک مجموعه ابزار استفاده کنیم. همچنین از رشتهها استفاده میکند که تاریخچه پیامهای یک مکالمه خاص را پیگیری میکنند.
تصور کنید شما یک نماینده فروش در شرکتی به نام 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 بپیوندید تا با دیگر یادگیرندگان ملاقات کنید، در ساعات مشاوره شرکت کنید و پاسخ سوالات خود درباره عوامل هوش مصنوعی را دریافت کنید.
سلب مسئولیت:
این سند با استفاده از سرویس ترجمه هوش مصنوعی Co-op Translator ترجمه شده است. در حالی که ما برای دقت تلاش میکنیم، لطفاً توجه داشته باشید که ترجمههای خودکار ممکن است شامل خطاها یا نادرستیها باشند. سند اصلی به زبان اصلی آن باید به عنوان منبع معتبر در نظر گرفته شود. برای اطلاعات حیاتی، ترجمه حرفهای انسانی توصیه میشود. ما هیچ مسئولیتی در قبال سوءتفاهمها یا تفسیرهای نادرست ناشی از استفاده از این ترجمه نداریم.