ai-agents-for-beginners

Як проектувати хороших AI агентів

(Натисніть на зображення вище, щоб переглянути відео цього уроку)

Патерн проектування використання інструментів

Інструменти цікаві тим, що вони дозволяють AI агентам мати ширший спектр можливостей. Замість того, щоб агент мав обмежений набір дій, які він може виконувати, додавання інструменту дозволяє агенту виконувати широкий спектр дій. У цьому розділі ми розглянемо патерн проектування використання інструментів, який описує, як AI агенти можуть використовувати конкретні інструменти для досягнення своїх цілей.

Вступ

У цьому уроці ми прагнемо відповісти на наступні питання:

Цілі навчання

Після проходження цього уроку ви зможете:

Що таке патерн проектування використання інструментів?

Патерн проектування використання інструментів зосереджений на тому, щоб надати великим мовним моделям (LLM) можливість взаємодіяти з зовнішніми інструментами для досягнення конкретних цілей. Інструменти — це код, який агент може виконувати для здійснення дій. Інструментом може бути проста функція, наприклад калькулятор, або виклик API до стороннього сервісу, наприклад, для пошуку цін на акції чи прогнозу погоди. В контексті AI агентів, інструменти створені для виконання агентами у відповідь на виклики функцій, згенеровані моделлю.

До яких випадків застосування його можна застосувати?

AI агенти можуть використовувати інструменти для виконання складних завдань, отримання інформації або прийняття рішень. Патерн проектування використання інструментів часто застосовується в ситуаціях, що вимагають динамічної взаємодії із зовнішніми системами, такими як бази даних, веб-сервіси або інтерпретатори коду. Ця здатність корисна для різноманітних випадків використання, зокрема:

Які елементи/будівельні блоки потрібні для впровадження патерну проектування використання інструментів?

Ці будівельні блоки дозволяють AI агенту виконувати широкий спектр завдань. Розглянемо ключові елементи, необхідні для впровадження патерну проектування використання інструментів:

Далі розглянемо виклик функцій/інструментів більш детально.

Виклик функцій/інструментів

Виклик функцій — це основний спосіб, яким ми дозволяємо великим мовним моделям (LLM) взаємодіяти з інструментами. Часто слова «функція» і «інструмент» використовуються як синоніми, оскільки «функції» (блоки багаторазового коду) є «інструментами», які агенти використовують для виконання завдань. Щоб викликати код функції, LLM має порівняти запит користувача із описом функцій. Для цього в LLM надсилається схема, що містить описи всіх доступних функцій. LLM потім обирає найбільш відповідну функцію для завдання і повертає її ім’я та аргументи. Вибрана функція виконується, її відповідь надсилається назад до LLM, який використовує цю інформацію, щоб відповісти на запит користувача.

Для розробників, які хочуть реалізувати виклик функцій для агентів, знадобиться:

  1. LLM модель, яка підтримує виклик функцій
  2. Схема, що містить описи функцій
  3. Код для кожної описаної функції

Розглянемо приклад отримання поточного часу в місті:

  1. Ініціалізувати 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"
     )
    
  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 вибрав, яку функцію потрібно виконати, треба реалізувати і виконати код, який виконує завдання. Ми можемо реалізувати код для отримання поточного часу на 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, агентні фреймворки надають нам готові будівельні блоки для реалізації використання інструментів.

Приклади використання інструментів з агентними фреймворками

Ось кілька прикладів того, як можна впровадити патерн використання інструментів за допомогою різних агентних фреймворків:

Microsoft Agent Framework

Microsoft Agent Framework — це відкритий AI фреймворк для створення AI агентів. Він спрощує процес використання виклику функцій, дозволяючи визначати інструменти як Python-функції за допомогою декоратора @tool. Фреймворк обробляє двонаправлену комунікацію між моделлю і вашим кодом. Також він надає доступ до готових інструментів, таких як пошук файлів і інтерпретатор коду через AzureAIProjectAgentProvider.

Наступна діаграма ілюструє процес виклику функцій у Microsoft Agent Framework:

function calling

У 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

Azure AI Agent Service — це новіший агентний фреймворк, створений для того, щоб надати розробникам можливість безпечно будувати, розгортати і масштабувати високоякісних, розширюваних AI агентів без необхідності керувати обчислювальними та сховищними ресурсами. Він особливо корисний для корпоративних додатків, оскільки є повністю керованим сервісом із корпоративним рівнем безпеки.

Порівняно із розробкою безпосередньо через API LLM, Azure AI Agent Service надає такі переваги:

Інструменти, доступні в Azure AI Agent Service, можна поділити на дві категорії:

  1. Інструменти знань:
  2. Інструменти дій:

Agent Service дає змогу використовувати ці інструменти разом як toolset. Він також використовує threads, які відстежують історію повідомлень конкретної розмови.

Уявіть, що ви агент з продажу в компанії Contoso. Ви хочете розробити розмовного агента, який може відповідати на питання щодо ваших даних про продажі.

Наступне зображення ілюструє, як можна використати Azure AI Agent Service для аналізу ваших продажів:

Agentic Service In Action

Щоб використовувати будь-який із цих інструментів за допомогою сервісу, ми можемо створити клієнта і визначити інструмент або набір інструментів. Для практичної реалізації можна використати наступний Python код. 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, яку можна знайти у файлі 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 = 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, динамічно згенерованим LLM, — це безпека, особливо ризик ін’єкції SQL або шкідливих дій, таких як видалення чи пошкодження бази даних. Хоча ці занепокоєння є виправданими, їх можна ефективно пом’якшити, правильно налаштувавши права доступу до бази даних. Для більшості баз даних це означає налаштування бази як тільки для читання. Для сервісів баз даних, таких як PostgreSQL або Azure SQL, додатку слід присвоїти роль лише для читання (SELECT).

Запуск додатку у безпечному середовищі додатково підвищує захист. У корпоративних сценаріях дані зазвичай експортуються та трансформуються з операційних систем у базу даних тільки для читання або сховище даних з зручною схемою. Такий підхід забезпечує безпеку даних, оптимізує продуктивність і доступність, а також гарантує, що додаток має обмежений доступ лише для читання.

Приклади коду

Маєте більше запитань про патерн використання інструментів?

Приєднуйтесь до Microsoft Foundry Discord, щоб зустрічатися з іншими учнями, брати участь у office hours і отримувати відповіді на ваші запитання щодо AI агентів.

Додаткові ресурси

Попередній урок

Розуміння агентних патернів проектування

Наступний урок

Agentic RAG


Відмова від відповідальності: Цей документ було перекладено за допомогою сервісу штучного інтелекту для перекладу Co-op Translator. Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ рідною мовою слід вважати авторитетним джерелом. Для критично важливої інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникли внаслідок використання цього перекладу.