ai-agents-for-beginners

Hoe Goede AI-Agenten Ontwerpen

(Klik op de afbeelding hierboven om de video van deze les te bekijken)

Toolgebruik Ontwerpprincipe

Tools zijn interessant omdat ze AI-agenten in staat stellen een breder scala aan mogelijkheden te hebben. In plaats van dat de agent een beperkte set acties kan uitvoeren, kan de agent door een tool toe te voegen nu een breed scala aan acties uitvoeren. In dit hoofdstuk bekijken we het Toolgebruik Ontwerpprincipe, dat beschrijft hoe AI-agenten specifieke tools kunnen gebruiken om hun doelen te bereiken.

Introductie

In deze les proberen we de volgende vragen te beantwoorden:

Leerdoelen

Na het voltooien van deze les kun je:

Wat is het Toolgebruik Ontwerpprincipe?

Het Toolgebruik Ontwerpprincipe richt zich op het geven van LLM’s de mogelijkheid om te communiceren met externe tools om specifieke doelen te bereiken. Tools zijn code die door een agent kan worden uitgevoerd om acties uit te voeren. Een tool kan een eenvoudige functie zijn, zoals een rekenmachine, of een API-aanroep naar een externe dienst, zoals het opzoeken van aandelenkoersen of weersvoorspellingen. In de context van AI-agenten zijn tools ontworpen om door agenten te worden uitgevoerd als reactie op door het model gegenereerde functieaanroepen.

Voor welke toepassingen kan het worden gebruikt?

AI-agenten kunnen tools gebruiken om complexe taken uit te voeren, informatie op te halen of beslissingen te nemen. Het toolgebruik ontwerpprincipe wordt vaak gebruikt in scenario’s die dynamische interactie met externe systemen vereisen, zoals databases, webservices of code-interpreters. Deze mogelijkheid is nuttig voor verschillende toepassingen, waaronder:

Wat zijn de elementen/bouwstenen die nodig zijn om het toolgebruik ontwerpprincipe te implementeren?

Deze bouwstenen stellen de AI-agent in staat een breed scala aan taken uit te voeren. Laten we de belangrijkste elementen bekijken die nodig zijn om het Toolgebruik Ontwerpprincipe te implementeren:

Laten we vervolgens Functie-/Toolaanroepen in meer detail bekijken.

Functie-/Toolaanroepen

Functieaanroepen zijn de primaire manier waarop we Grote Taalmodellen (LLM’s) in staat stellen om met tools te communiceren. Je zult vaak ‘Functie’ en ‘Tool’ door elkaar zien gebruikt, omdat ‘functies’ (blokken herbruikbare code) de ‘tools’ zijn die agenten gebruiken om taken uit te voeren. Om de code van een functie aan te roepen, moet een LLM het verzoek van de gebruiker vergelijken met de beschrijving van de functie. Hiervoor wordt een schema met de beschrijvingen van alle beschikbare functies naar de LLM gestuurd. De LLM selecteert vervolgens de meest geschikte functie voor de taak en retourneert de naam en argumenten ervan. De geselecteerde functie wordt aangeroepen, de reactie wordt teruggestuurd naar de LLM, die de informatie gebruikt om te reageren op het verzoek van de gebruiker.

Om functieaanroepen voor agenten te implementeren, hebben ontwikkelaars nodig:

  1. Een LLM-model dat functieaanroepen ondersteunt
  2. Een schema met functiebeschrijvingen
  3. De code voor elke beschreven functie

Laten we het voorbeeld gebruiken van het verkrijgen van de huidige tijd in een stad om dit te illustreren:

  1. Initialiseer een LLM die functieaanroepen ondersteunt:

    Niet alle modellen ondersteunen functieaanroepen, dus het is belangrijk om te controleren of de LLM die je gebruikt dit doet. Azure OpenAI ondersteunt functieaanroepen. We kunnen beginnen met het initiëren van de Azure OpenAI-client.

     # 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. Maak een Functieschema:

    Vervolgens definiëren we een JSON-schema dat de functienaam, beschrijving van wat de functie doet, en de namen en beschrijvingen van de functieparameters bevat. We nemen dit schema en sturen het naar de eerder gemaakte client, samen met het verzoek van de gebruiker om de tijd in San Francisco te vinden. Wat belangrijk is om op te merken, is dat een toolaanroep wordt geretourneerd, niet het uiteindelijke antwoord op de vraag. Zoals eerder vermeld, retourneert de LLM de naam van de functie die is geselecteerd voor de taak en de argumenten die eraan worden doorgegeven.

     # 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. De functiecode die nodig is om de taak uit te voeren:

    Nu de LLM heeft gekozen welke functie moet worden uitgevoerd, moet de code die de taak uitvoert worden geïmplementeerd en uitgevoerd. We kunnen de code implementeren om de huidige tijd in Python te verkrijgen. We moeten ook de code schrijven om de naam en argumenten uit het response_message te halen om het uiteindelijke resultaat te verkrijgen.

       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.
    

Functieaanroepen vormen de kern van de meeste, zo niet alle ontwerpen voor toolgebruik door agenten, maar het implementeren ervan vanaf nul kan soms uitdagend zijn. Zoals we hebben geleerd in Les 2 bieden agentische frameworks ons vooraf gebouwde bouwstenen om toolgebruik te implementeren.

Voorbeelden van Toolgebruik met Agentische Frameworks

Hier zijn enkele voorbeelden van hoe je het Toolgebruik Ontwerpprincipe kunt implementeren met verschillende agentische frameworks:

Semantic Kernel

Semantic Kernel is een open-source AI-framework voor .NET-, Python- en Java-ontwikkelaars die werken met Grote Taalmodellen (LLM’s). Het vereenvoudigt het proces van functieaanroepen door automatisch je functies en hun parameters te beschrijven aan het model via een proces genaamd serialiseren. Het beheert ook de communicatie tussen het model en je code. Een ander voordeel van het gebruik van een agentisch framework zoals Semantic Kernel is dat het je toegang geeft tot vooraf gebouwde tools zoals Bestand Zoeken en Code Interpreter.

Het volgende diagram illustreert het proces van functieaanroepen met Semantic Kernel:

functieaanroepen

In Semantic Kernel worden functies/tools Plugins genoemd. We kunnen de get_current_time-functie die we eerder zagen omzetten in een plugin door deze om te zetten in een klasse met de functie erin. We kunnen ook de kernel_function-decorator importeren, die de beschrijving van de functie accepteert. Wanneer je vervolgens een kernel maakt met de GetCurrentTimePlugin, serialiseert de kernel automatisch de functie en haar parameters, waardoor het schema wordt gemaakt om naar de LLM te sturen.

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 is een nieuwer agentisch framework dat is ontworpen om ontwikkelaars in staat te stellen veilig hoogwaardige en uitbreidbare AI-agenten te bouwen, implementeren en schalen zonder dat ze de onderliggende compute- en opslagbronnen hoeven te beheren. Het is bijzonder nuttig voor zakelijke toepassingen, omdat het een volledig beheerde service is met beveiliging van ondernemingsniveau.

In vergelijking met het ontwikkelen met de LLM-API rechtstreeks biedt Azure AI Agent Service enkele voordelen, waaronder:

De tools die beschikbaar zijn in Azure AI Agent Service kunnen worden onderverdeeld in twee categorieën:

  1. Kennis Tools:
  2. Actie Tools:

De Agent Service stelt ons in staat om deze tools samen te gebruiken als een toolset. Het maakt ook gebruik van threads die de geschiedenis van berichten van een bepaalde conversatie bijhouden.

Stel je voor dat je een verkoopagent bent bij een bedrijf genaamd Contoso. Je wilt een conversatieagent ontwikkelen die vragen over je verkoopgegevens kan beantwoorden.

De volgende afbeelding illustreert hoe je Azure AI Agent Service kunt gebruiken om je verkoopgegevens te analyseren:

Agentic Service In Action

Om een van deze tools met de service te gebruiken, kunnen we een client maken en een tool of toolset definiëren. Om dit praktisch te implementeren, kunnen we de volgende Python-code gebruiken. De LLM kan naar de toolset kijken en beslissen of de door de gebruiker gemaakte functie, fetch_sales_data_using_sqlite_query, of de vooraf gebouwde Code Interpreter wordt gebruikt, afhankelijk van het verzoek van de gebruiker.

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
)

Wat zijn de speciale overwegingen voor het gebruik van het Toolgebruik Ontwerpprincipe om betrouwbare AI-agenten te bouwen?

Een veelvoorkomende zorg bij SQL die dynamisch wordt gegenereerd door LLM’s is beveiliging, met name het risico van SQL-injectie of kwaadaardige acties, zoals het verwijderen of manipuleren van de database. Hoewel deze zorgen geldig zijn, kunnen ze effectief worden verminderd door de toegangsrechten van de database correct te configureren. Voor de meeste databases houdt dit in dat de database wordt geconfigureerd als alleen-lezen. Voor databaseservices zoals PostgreSQL of Azure SQL moet de app een alleen-lezen (SELECT) rol krijgen. Het uitvoeren van de app in een veilige omgeving biedt extra bescherming. In zakelijke situaties wordt data meestal geëxtraheerd en getransformeerd van operationele systemen naar een alleen-lezen database of datawarehouse met een gebruiksvriendelijke structuur. Deze aanpak zorgt ervoor dat de data veilig is, geoptimaliseerd voor prestaties en toegankelijkheid, en dat de app beperkte, alleen-lezen toegang heeft.

Meer vragen over het gebruik van ontwerpprincipes?

Word lid van de Azure AI Foundry Discord om andere leerlingen te ontmoeten, spreekuren bij te wonen en antwoorden te krijgen op je vragen over AI Agents.

Aanvullende bronnen

Vorige les

Agentische Ontwerpprincipes Begrijpen

Volgende les

Agentic RAG


Disclaimer:
Dit document is vertaald met behulp van de AI-vertalingsservice Co-op Translator. Hoewel we streven naar nauwkeurigheid, dient u zich ervan bewust te zijn dat geautomatiseerde vertalingen fouten of onnauwkeurigheden kunnen bevatten. Het originele document in de oorspronkelijke taal moet worden beschouwd als de gezaghebbende bron. Voor cruciale informatie wordt professionele menselijke vertaling aanbevolen. Wij zijn niet aansprakelijk voor misverstanden of verkeerde interpretaties die voortvloeien uit het gebruik van deze vertaling.