ai-agents-for-beginners

Jak navrhnout dobré AI agenty

(Klikněte na obrázek výše pro zhlédnutí videa této lekce)

Návrhový vzor pro používání nástrojů

Nástroje jsou zajímavé, protože umožňují AI agentům mít širší škálu schopností. Místo toho, aby agent měl omezenou sadu akcí, které může provádět, přidáním nástroje může nyní provádět širokou škálu akcí. V této kapitole se podíváme na návrhový vzor pro používání nástrojů, který popisuje, jak mohou AI agenti používat specifické nástroje k dosažení svých cílů.

Úvod

V této lekci se snažíme odpovědět na následující otázky:

Cíle učení

Po dokončení této lekce budete schopni:

Co je návrhový vzor pro používání nástrojů?

Návrhový vzor pro používání nástrojů se zaměřuje na umožnění LLMs (Large Language Models) interagovat s externími nástroji za účelem dosažení specifických cílů. Nástroje jsou kód, který může být agentem vykonán k provádění akcí. Nástroj může být jednoduchá funkce, jako je kalkulačka, nebo API volání na službu třetí strany, například vyhledávání cen akcií nebo předpověď počasí. V kontextu AI agentů jsou nástroje navrženy tak, aby je agenti mohli vykonávat v reakci na funkční volání generované modelem.

Na jaké případy použití lze tento vzor aplikovat?

AI agenti mohou využívat nástroje k dokončení složitých úkolů, získávání informací nebo rozhodování. Návrhový vzor pro používání nástrojů se často používá ve scénářích vyžadujících dynamickou interakci s externími systémy, jako jsou databáze, webové služby nebo interprety kódu. Tato schopnost je užitečná pro řadu různých případů použití, včetně:

Jaké prvky/stavební bloky jsou potřebné k implementaci návrhového vzoru pro používání nástrojů?

Tyto stavební bloky umožňují AI agentovi provádět širokou škálu úkolů. Podívejme se na klíčové prvky potřebné k implementaci návrhového vzoru pro používání nástrojů:

Dále se podíváme na volání funkcí/nástrojů podrobněji.

Volání funkcí/nástrojů

Volání funkcí je primární způsob, jak umožnit velkým jazykovým modelům (LLMs) interagovat s nástroji. Často uvidíte, že se ‘funkce’ a ‘nástroje’ používají zaměnitelně, protože ‘funkce’ (bloky opakovaně použitelného kódu) jsou ‘nástroje’, které agenti používají k provádění úkolů. Aby mohl být kód funkce vyvolán, musí LLM porovnat požadavek uživatele s popisem funkce. K tomu je LLM odesláno schéma obsahující popisy všech dostupných funkcí. LLM poté vybere nejvhodnější funkci pro daný úkol a vrátí její název a argumenty. Vybraná funkce je vyvolána, její odpověď je odeslána zpět LLM, které použije informace k odpovědi na požadavek uživatele.

Pro vývojáře, kteří chtějí implementovat volání funkcí pro agenty, budete potřebovat:

  1. Model LLM, který podporuje volání funkcí
  2. Schéma obsahující popisy funkcí
  3. Kód pro každou popsanou funkci

Použijme příklad získání aktuálního času ve městě k ilustraci:

  1. Inicializace LLM, které podporuje volání funkcí:

    Ne všechny modely podporují volání funkcí, takže je důležité ověřit, že LLM, které používáte, to umožňuje. Azure OpenAI podporuje volání funkcí. Můžeme začít inicializací klienta 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"
     )
    
  2. Vytvoření schématu funkcí:

    Dále definujeme JSON schéma, které obsahuje název funkce, popis toho, co funkce dělá, a názvy a popisy parametrů funkce. Poté toto schéma předáme klientovi vytvořenému dříve spolu s požadavkem uživatele na nalezení času v San Franciscu. Důležité je poznamenat, že je vráceno volání nástroje, nikoli konečná odpověď na otázku. Jak bylo zmíněno dříve, LLM vrací název funkce, kterou vybralo pro daný úkol, a argumenty, které budou předány.

     # 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')])
    
  3. Kód funkce potřebný k provedení úkolu:

    Nyní, když LLM vybralo, kterou funkci je třeba spustit, je třeba implementovat a vykonat kód, který úkol provede. Můžeme implementovat kód pro získání aktuálního času v Pythonu. Budeme také muset napsat kód pro extrakci názvu a argumentů z response_message, abychom získali konečný výsledek.

       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.
    

Volání funkcí je jádrem většiny, ne-li všech návrhů používání nástrojů agentů, avšak jeho implementace od nuly může být někdy náročná. Jak jsme se naučili v Lekci 2, agentické rámce nám poskytují předem vytvořené stavební bloky pro implementaci používání nástrojů.

Příklady používání nástrojů s agentickými rámci

Zde jsou některé příklady, jak můžete implementovat návrhový vzor pro používání nástrojů pomocí různých agentických rámců:

Semantic Kernel

Semantic Kernel je open-source AI rámec pro vývojáře v .NET, Pythonu a Javě pracující s velkými jazykovými modely (LLMs). Zjednodušuje proces používání volání funkcí tím, že automaticky popisuje vaše funkce a jejich parametry modelu prostřednictvím procesu nazývaného serializace. Také spravuje komunikaci mezi modelem a vaším kódem. Další výhodou používání agentického rámce, jako je Semantic Kernel, je to, že vám umožňuje přístup k předem vytvořeným nástrojům, jako je Vyhledávání souborů a Interpret kódu.

Následující diagram ilustruje proces volání funkcí pomocí Semantic Kernel:

volání funkcí

V Semantic Kernel jsou funkce/nástroje nazývány Pluginy. Můžeme převést funkci get_current_time, kterou jsme viděli dříve, na plugin tím, že ji proměníme na třídu s funkcí uvnitř. Můžeme také importovat dekorátor kernel_function, který přijímá popis funkce. Když poté vytvoříte kernel s GetCurrentTimePlugin, kernel automaticky serializuje funkci a její parametry, čímž vytvoří schéma, které se odešle 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 Agent Service

Azure AI Agent Service je novější agentický rámec, který je navržen tak, aby umožnil vývojářům bezpečně vytvářet, nasazovat a škálovat vysoce kvalitní a rozšiřitelné AI agenty bez nutnosti spravovat základní výpočetní a úložné zdroje. Je obzvláště užitečný pro podnikové aplikace, protože je plně spravovanou službou s bezpečností na úrovni podniku.

Ve srovnání s vývojem přímo pomocí LLM API poskytuje Azure AI Agent Service některé výhody, včetně:

Nástroje dostupné v Azure AI Agent Service lze rozdělit do dvou kategorií:

  1. Nástroje pro znalosti:
  2. Nástroje pro akce:

Agent Service nám umožňuje používat tyto nástroje společně jako toolset. Také využívá threads, které sledují historii zpráv z konkrétní konverzace.

Představte si, že jste obchodní agent ve společnosti Contoso. Chcete vyvinout konverzačního agenta, který dokáže odpovídat na otázky týkající se vašich obchodních dat.

Následující obrázek ilustruje, jak byste mohli použít Azure AI Agent Service k analýze vašich obchodních dat:

Agentická služba v akci

Pro použití některého z těchto nástrojů se službou můžeme vytvořit klienta a definovat nástroj nebo sadu nástrojů. Pro praktickou implementaci můžeme použít následující Python kód. LLM bude schopno podívat se na sadu nástrojů a rozhodnout, zda použít uživatelem vytvořenou funkci fetch_sales_data_using_sqlite_query, nebo předem připravený interpret kódu, v závislosti na požadavku uživatele.

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
)

Jaké jsou zvláštní úvahy při používání návrhového vzoru pro budování důvěryhodných AI agentů?

Běžnou obavou u SQL dynamicky generovaného LLMs je bezpečnost, zejména riziko SQL injekce nebo škodlivých akcí, jako je mazání nebo manipulace s databází. I když jsou tyto obavy oprávněné, lze je účinně zmírnit správnou konfigurací oprávnění k přístupu k databázi. U většiny databází to zahrnuje konfiguraci databáze jako pouze pro čtení. U databázových služeb, jako je PostgreSQL nebo Azure SQL, by aplikaci měla být přidělena role pouze pro čtení (SELECT). Spuštění aplikace v zabezpečeném prostředí dále zvyšuje ochranu. V podnikových scénářích jsou data obvykle extrahována a transformována z provozních systémů do databáze nebo datového skladu určeného pouze pro čtení s uživatelsky přívětivým schématem. Tento přístup zajišťuje, že data jsou bezpečná, optimalizovaná pro výkon a dostupnost, a že aplikace má omezený přístup pouze pro čtení.

Máte další otázky ohledně návrhových vzorů pro použití nástroje?

Připojte se na Azure AI Foundry Discord, kde se můžete setkat s dalšími studenty, zúčastnit se konzultačních hodin a získat odpovědi na své otázky ohledně AI Agentů.

Další zdroje

Předchozí lekce

Porozumění návrhovým vzorům agentů

Další lekce

Agentic RAG


Prohlášení:
Tento dokument byl přeložen pomocí služby AI pro překlady Co-op Translator. I když se snažíme o přesnost, mějte prosím na paměti, že automatizované překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace se doporučuje profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.